AI AgentTechnical Deep Dive

Agent 数据分析:先把指标口径写清楚,再开放自然语言提问

发布时间2026/01/06
分类AI Agent
预计阅读10 分钟
作者吴长龙
*

数据分析 Agent 最容易做成一个会写 SQL 的聊天框,但真正难的是指标口径、权限边界、查询安全和结论解释。

01.数据分析 Agent 的难点,不只是把自然语言翻成 SQL

“让业务同学直接问数据库”听起来很吸引人,但如果系统只有一层 NL -> SQL -> answer,实际风险会非常高。

真正麻烦的地方通常在这里:

  • 同一个指标在不同团队里口径不同
  • 模型可能会引用不存在的表或字段
  • 查询权限、扫描成本和数据脱敏要求很严格
  • 结果解释容易脱离上下文,得出错误结论

所以数据分析 Agent 更像一个“分析流程编排器”,而不是一个只会写 SQL 的聊天框。

02.用一个更真实的问题来理解这个场景

假设运营同学问:

为什么昨天退款率突然升高?

这个问题如果直接丢给模型,会有很多隐含前提:

  • 退款率的定义是什么
  • “昨天”按哪个时区算
  • 对比的是前一天、上周同期,还是 7 日均值
  • 是否需要按渠道、地区或商品分类拆解
  • 有没有异常订单需要剔除

也就是说,真正要做的第一步并不是生成 SQL,而是把问题转成一个可执行、可审计的分析请求。

03.指标口径和语义层,应该先于 Agent 存在

很多数据分析 Agent 一开始就追求“任何问题都能问”,结果最先崩的是指标定义。

更稳的做法是先准备一层最小语义层,例如:

  • gmv
  • order_count
  • refund_rate
  • daily_active_users

每个指标都要明确:

  • 来源表
  • 过滤条件
  • 计算公式
  • 默认时间粒度
  • 是否允许按哪些维度拆解

这一步做好之后,Agent 才有可能在受控范围内生成稳定分析请求。

04.先把自然语言问题转成结构化分析请求

相比直接生成 SQL,我更建议先让模型输出一个结构化请求对象,再由系统编译成查询。

python snippetpython
from typing import Literal
from pydantic import BaseModel, Field


class AnalysisRequest(BaseModel):
    metric: Literal["order_count", "refund_rate", "gmv"]
    dimensions: list[str] = Field(default_factory=list)
    filters: dict[str, str] = Field(default_factory=dict)
    compare_with: Literal["none", "previous_day", "previous_week"] = "none"
    needs_chart: bool = False


METRIC_SQL = {
    "order_count": "count(*)",
    "refund_rate": "sum(refund_orders)::float / nullif(count(*), 0)",
    "gmv": "sum(pay_amount)",
}


def compile_query(request: AnalysisRequest) -> str:
    select_parts = [f"{METRIC_SQL[request.metric]} as value"]
    group_by = []

    for dimension in request.dimensions:
        select_parts.append(dimension)
        group_by.append(dimension)

    sql = f"select {', '.join(select_parts)} from mart_orders"
    if group_by:
        sql += f" group by {', '.join(group_by)}"
    return sql

这个模式的价值在于:

  • 模型只能在允许的指标和维度里组合
  • 查询逻辑可以落到可维护的编译层
  • 后续很容易对“问题解析是否正确”单独做评估

05.什么时候用 SQL,什么时候用 Python 容器

数据分析 Agent 并不只有一种执行路径。

更适合走查询编译链路的场景

  • 固定指标看板问答
  • 运营或产品的常见分析问题
  • 需要权限控制的数据库查询
  • 可以映射到既有语义层的问题

更适合走 Python / Code Interpreter 链路的场景

  • 上传 Excel、CSV 后做一次性探索
  • 清洗格式混乱的数据文件
  • 生成临时图表
  • 做统计检验、分布分析、异常值排查

这两种路径不要混成一锅。数据库查询强调权限、审计和口径一致;文件分析强调交互性和临时探索。它们的治理方式不一样。

06.执行安全是数据分析 Agent 的底线

一旦系统真的开始跑查询,安全和成本就必须前置考虑。

比较常见的控制包括:

  • 只给只读账号
  • 只开放 allowlist 表和视图
  • 限制最大扫描量和返回行数
  • 对高成本查询先做 explain 或成本估算
  • 对敏感字段做脱敏或直接禁止返回

如果后面接的是代码执行容器,还要再加一层限制:

  • 文件生命周期是否短暂可控
  • 运行环境是否隔离
  • 生成文件是否需要落回业务系统

不能因为它看起来像“分析助手”,就忽略它本质上仍然在操作真实数据。

07.解释结果时,系统要交代依据而不是只给结论

很多分析 Agent 的另一个问题是:查询没错,但解释太像评论。

更可靠的结果说明至少应该带上这些上下文:

  • 分析的指标定义
  • 时间窗口和时区
  • 使用的过滤条件
  • 主要对比基线
  • 图表或表格来自哪次查询

如果一句“退款率上升主要因为华东区某类订单异常”后面没有任何依据,这种回答在团队里很难真正被采纳。

08.对业务提问,最好同时保留“解释层”和“查询层”

一个更实用的输出方式通常分两层:

给业务同学看的解释层

  • 用自然语言总结变化
  • 标出最值得继续追查的维度
  • 推荐下一步分析动作

给分析或工程同学看的查询层

  • 结构化分析请求
  • 实际执行 SQL 或 Python 脚本摘要
  • 返回的关键字段和采样说明

这样既方便业务阅读,也方便技术同学复盘和纠错。

09.评估时要拆成三段,而不是只看最终答案

数据分析 Agent 的质量,至少可以拆成这三层:

问题解析是否正确

问题有没有被映射到正确指标、维度和时间范围。

查询执行是否正确

SQL 是否命中允许的表,是否返回了预期粒度的数据,是否触发了不必要的大查询。

结论解释是否忠于结果

自然语言总结有没有夸大因果、漏掉限制条件,或忽略样本量和时间窗口。

把这三层拆开评估,比只问“答案对不对”更容易持续迭代。

10.三个常见误区

1. 没有指标注册,就直接做 NL2SQL

这样一开始看起来很灵活,但很快就会因为口径漂移和字段幻觉出问题。

2. 让模型直接面对整库

表越多、权限越宽,系统越难控,错误查询和越权风险都会上升。

3. 只返回一句结论,不保留分析依据

没有查询上下文、指标定义和过滤条件,结论再像样也很难让人真正信任。

11.总结

数据分析 Agent 真正的价值,不是让每个人都能“随便问数据库”,而是把原本分散在提问、定义指标、写查询、解释结果这些步骤里的工作,整理成一条可追溯的分析流程:

  • 问题先结构化
  • 查询在受控范围内生成
  • 执行有权限与成本边界
  • 结论能回溯到依据

只要把这几个环节守住,Agent 才能真正帮团队缩短分析链路,而不是制造一层新的数据不确定性。

12.参考资料