构建企业问数 Agent:难点不是 SQL,而是数据治理
  AI

构建企业问数 Agent:难点不是 SQL,而是数据治理

 次点击
104 分钟阅读

为什么“会写 SQL”还不够

数据驱动决策的前提,是业务同事能快速问出问题,并理解答案背后的口径。

但在真实企业里,这件事往往比想象中难。

一位运营同事可能会这样问:

我想看最近 7 天放款金额。日报里有一列,财务口径里又是另一列,渠道复盘时还会出现第三种算法。我只是想知道业务跑得怎么样,为什么要先上一堂 SQL 课?

这不是某个业务人员“不专业”,而是企业数据天然存在的问题:同一句业务词,可能映射到不同环节、不同时间轴、不同表、不同状态过滤。

以“放款金额”为例,在消费信贷链路里至少可能有四种合法含义:

业务说法

可能含义

典型时间轴

提交放款金额

用户提交放款申请的金额

提交时间

签约金额

合同已签署的金额

签约时间

放款成功 / 到账金额

资金实际到账的金额

到账时间

渠道归因放款金额

用于投放效果分析的归因金额

注册日或归因 cohort

如果这些规则只存在于某个人脑子里、某张 BI 报表的列名里、某段复制过很多次的 SQL 里,再强的模型也只能猜。

所以,我们没有把目标定义成“让大模型直接连数仓、自由选表、自由写 SQL”。我们真正想建设的是一套企业问数能力:

业务问题
  -> 识别领域与指标
  -> 读取语义层与知识库
  -> 澄清歧义
  -> 只读执行 SQL
  -> 输出结论、口径、来源与置信信息
  -> 发现错误后回流为知识和评测

换句话说,企业问数 Agent 的核心不是 SQL 生成,而是口径治理、数据治理


外部经验给我们的启发

我们在设计这套能力时,重点参考了两个方向的公开实践。

Anthropic 在 How Anthropic enables self-service data analytics with Claude 中提到,自助分析 Agent 的挑战不只是模型会不会写查询,而是概念映射、知识新鲜度、检索路径和信任机制。

OpenAI 在 Inside OpenAI’s in-house data agent 中介绍了内部数据 Agent 的多层上下文策略:表使用信息、人工注释、代码增强、机构知识、记忆层、运行时探查,以及持续 eval。

这些经验给了我们三个判断:

  1. 不能让 Agent 直接在全量表里猜。
    企业里有大量近重复表、历史字段和口径遗留。没有治理层,模型越自信越危险。

  2. 上下文比 prompt 更重要。
    好的提示词只能减少偶发错误,稳定能力必须来自结构化知识、语义层、工具边界和评测闭环。

  3. 问数系统必须可运营。
    业务口径会变,指标会新增,报表会迁移。Agent 如果不能从纠错里学习,很快就会变成另一套过时文档。

因此,我们选择吸收大厂方法论,但不照搬规模。大型科技公司的难点可能是“海量表发现正确数据集”,而垂直业务场景的难点往往是“有限表上同一个词有多个口径”。后者更需要把业务概念拆深、讲透、评测住。


我们抽象出的三类失败模式

企业问数 Agent 最常见的失败,不是 SQL 报错,而是“看起来合理但业务口径错了”。

失败模式

典型表现

后果

概念与实体歧义

“放款金额”可能指提交、签约、到账或归因

数字看似正确,实际回答了另一个问题

知识陈旧

表迁移、字段替换、状态枚举变化后,Agent 仍按旧文档回答

旧口径被自动化放大

检索失败

正确知识存在,但 Agent 没读到,或读错了页面

组织已有经验无法被复用

如果没有治理,业务同事很难发现这些问题。因为错误答案通常也会有 SQL、有表格、有解释,看起来同样专业。

所以我们给系统定了一个约束:

Agent 可以生成 SQL,但必须先说明它采用的业务口径;口径不清时,必须先澄清或暴露默认假设。


架构原则:事实、流程、执行三层分离

我们把企业问数能力拆成三层。

层级

负责什么

不负责什么

事实层

指标口径、术语、表说明、歧义规则、典型问法、评测集

执行 SQL、连接生产库

流程层

理解问题、读取知识、澄清歧义、选择工具、组织回答

长期维护第二份业务口径

执行层

schema 核对、查询计划检查、只读 SQL 执行

定义业务含义

这个分层非常关键。

如果事实写在流程里,几周后就会出现“文档一套、Agent 一套”的漂移。
如果流程写在知识库里,业务同事又很难维护。
如果执行层顺便定义口径,SQL 工具就会越权成为业务规则来源。

因此,最稳的方式是:

业务事实只维护一份
流程只负责如何使用事实
执行工具只负责核对和只读查询

这也解释了为什么我们把“知识”做成独立资产,而不是塞进某个插件、某个 prompt 或某段代码里。


一次问数应该如何发生

以“最近 7 天签约金额和放款成功到账金额分别是多少”为例,理想流程不是直接写 SQL,而是:

  1. 识别业务领域:这是信贷动支 / 放款链路问题。

  2. 识别指标:签约金额、放款成功金额。

  3. 命中语义层:优先使用已经钦定的指标模板。

  4. 读取歧义规则:确认“签约”和“到账”不是同一个环节。

  5. 生成 SQL:使用受控表、受控字段、受控状态过滤。

  6. 执行前自审:时间字段、状态字段、粒度、JOIN、币种、范围是否正确。

  7. 只读执行:通过受控数据工具执行查询。

  8. 输出答案:结论先行,附口径、SQL、来源、owner 或置信说明。

伪 SQL 可能长这样:

-- 签约金额:按合同签署时间归属
SELECT DATE(contract_signed_at) AS stat_date,
       SUM(amount) AS signed_amount
FROM loan_contract_flow
WHERE contract_signed_at >= CURRENT_DATE - INTERVAL '7 days'
  AND contract_signed_at IS NOT NULL
  AND is_deleted = false
GROUP BY 1;

-- 放款成功金额:按实际到账时间归属
SELECT DATE(disbursed_at) AS stat_date,
       SUM(amount) AS success_amount
FROM loan_contract_flow
WHERE disbursed_at >= CURRENT_DATE - INTERVAL '7 days'
  AND disbursed_at IS NOT NULL
  AND disbursement_status = 'SUCCESS'
  AND is_deleted = false
GROUP BY 1;

注意这里没有把两列强行放在同一个时间轴里解释。签约看签约时间,到账看到账时间。按天对比时,两列不同是预期现象,不一定是 SQL 写错。

如果用户继续问“为什么两个值不一样”,Agent 应该解释业务动作:

签约金额表示合同已经签署。
放款成功金额表示资金已经实际到账。
二者之间可能存在处理中、失败、撤销等状态。
所以到账金额通常小于或等于签约金额。

一个好的问数 Agent,必须能把 SQL 翻译回业务动作。


上下文分层:让模型少猜一点

我们把 Agent 可用的上下文分成四层。

第一层:钦定数据源

高频指标必须有“默认数据源”,并列出不推荐使用的近重复表。

原因很简单:企业数仓里经常存在多张相似表。它们可能来自不同历史阶段、不同报表、不同加工链路。人知道哪张“现在该用”,模型不知道。

所以对每个高频概念,要明确:

  • 推荐表。

  • 适用场景。

  • 不适用场景。

  • 已弃用或仅用于历史对账的表。

第二层:语义层

语义层存放高频指标的机器可读定义,例如:

  • 指标名。

  • 统计对象。

  • 时间字段。

  • 状态过滤。

  • 默认维度。

  • 推荐 SQL 模板。

  • 应使用的数据工具。

命中语义层时,Agent 不应重新发明 SQL,而应优先使用钦定模板。

这和很多团队的直觉相反:我们不是让模型“更自由”,而是让模型在高频问题上“更少发挥”。

第三层:业务知识库

业务知识库维护人能看懂、能审阅、能持续更新的内容,包括:

  • 指标卡片。

  • 表说明。

  • 字段枚举。

  • 歧义规则。

  • 典型问法。

  • 纠错记录。

  • golden cases。

其中“歧义规则”非常重要。它不只解释定义,还规定默认路由。

例如:

用户说法

推荐路由

“放款金额”且没有上下文

先反问具体环节

“提交放款”“放款监控”

走提交申请口径

“签约金额”“合同金额”

走签约口径

“到账”“放款成功”

走成功到账口径

“渠道放款”“投放效果”

走归因口径

这类规则如果只写在 prompt 里,很难被业务同事维护;如果写成知识页,就可以被评审、被链接、被评测。

第四层:流程技能

事实层告诉 Agent “什么是对的”。流程层告诉 Agent “该怎么做”。

流程技能包括:

  • 如何识别领域。

  • 先读语义层还是先读 Wiki。

  • 什么时候必须反问。

  • 什么时候可以直接出数。

  • 什么时候必须先跑查询计划检查。

  • 回答里必须包含哪些来源信息。

我们发现,知识和流程最好分开维护。事实经常由业务 owner 更新,流程则更像工程规范,需要由平台侧维护。


信任机制:让业务同事不用审 SQL,也能审口径

大多数业务用户不会逐行审 SQL,也不应该被要求这样做。

但业务用户必须能判断答案是否可信。

因此,每条高置信答案都应该带一段 provenance 信息:

来源:语义层 / 指标页 / 实时 schema 探查
口径:签约金额,按合同签署时间统计
执行:只读查询工具
时间范围:最近 7 天
数据新鲜度:最新数据时间 ...
Owner:指标负责人 / 数据负责人

这段信息不能让错误答案自动变正确,但能让使用者判断:

  • 这个答案能不能转发给团队?

  • 这个数字是否适合进入日报?

  • 如果有疑问应该找谁确认?

  • 这是知识库口径,还是模型临时推断?

我们把它称为信任基础设施。


对抗式自审:让 Agent 在执行前先挑自己的错

执行 SQL 前,Agent 应该像评审员一样检查自己的答案。

常见红线包括:

  • 时间字段是否选对。

  • 状态过滤是否选对。

  • 金额、人数、申请数是否混淆。

  • 日报口径和 cohort 口径是否混用。

  • 成功状态和提交状态是否混用。

  • 是否存在无界时间范围。

  • 是否用了 SELECT *

  • 是否引入 1:N JOIN 导致金额膨胀。

  • 是否选错数据工具或数据域。

这一步看起来像“多想一步”,但在企业问数里非常值钱。

因为最昂贵的错误不是 SQL 语法错,而是业务口径错。


纠错回流:不要只修复一次对话

Agent 第一次答错并不可怕。真正可怕的是同一个错误下周还会再发生。

所以我们把纠错定义为一条闭环:

业务指出错误
  -> 记录原问法
  -> 记录错误点
  -> 记录正确口径
  -> 补充证据:SQL、截图、owner 说明
  -> 更新指标页 / 歧义页 / 表说明
  -> 追加 eval case
  -> 跑质量门禁
  -> 合入知识库

业务同事不需要手写 Markdown。最小材料包只需要:

  1. 原问法。

  2. 哪里错了。

  3. 正确口径是什么。

  4. 证据在哪里。

剩下的结构化写作、目录定位、链接补齐、eval case 生成、门禁检查,可以由 Agent 辅助完成。

这背后的原则是:

每一次纠错,都不应该只修复当前对话,而应该修复下一次所有相似对话。


评测:判口径,不只判数字

问数 Agent 的评测不能只看“数字是否等于某个固定值”。

线上数据会每天变化,数字本身不是稳定断言。更稳定的评测对象是口径:

  • 是否用了正确时间字段。

  • 是否用了正确状态过滤。

  • 是否用了正确主表。

  • 是否先聚合再 JOIN。

  • 是否在模糊问题里先澄清。

  • 是否暴露默认口径。

  • 是否拒绝高风险查询。

因此,我们把评测分成三层。

层级

验证什么

结构门禁

文档是否有 frontmatter、单 H1、关联链接、无断链

离线口径评测

SQL 和回答是否符合口径要求

在线探针

钦定 SQL 是否能在只读数据源上实际执行

这类评测不需要一开始很大。几十条高频 case,就足以拦住一批最容易出事故的问题。


我们学到的五个教训

教训一:先治理概念,再生成 SQL

“放款金额”这种词如果不先消歧,SQL 写得再漂亮也是错的。

企业问数的 ROI 不一定来自更复杂的 SQL 生成,而来自更早地把业务概念映射做对。

教训二:历史 SQL 是原材料,不是真理

很多团队想把历史查询日志直接塞给 Agent 做 RAG。

问题是,历史 SQL 往往缺少上下文:它当时回答什么问题?适用于什么范围?有哪些隐含过滤?为什么后来不用了?

更稳的做法是先做 SQL 口径审查:

这条 SQL 适合回答什么?
不适合回答什么?
应该沉淀成指标页、表页,还是歧义规则?

教训三:指导目标,不要写死路径

问法千变万化,过度处方会把 Agent 推向错误路径。

流程技能应该规定目标和红线,例如“先查语义层”“模糊词必须澄清”“大查询先解释计划”,但不要把每个问题都写成固定脚本。

教训四:工具面要克制

给 Agent 太多重叠工具,会增加选择错误。

我们更倾向于:

  • 工具边界清晰。

  • 默认只读。

  • 大查询先收窄。

  • 每个数据域有明确路由。

  • 工具只执行事实核对,不定义业务口径。

教训五:知识库和流程层必须分家

单一事实源不是口号。

如果纠错只改 prompt,不改知识库,几周后就会出现两份口径。
如果业务事实写进流程代码,业务 owner 就很难参与维护。

更可持续的方式是:

知识库管“是什么”
流程层管“怎么做”
执行层管“查事实”

与 OpenAI、Anthropic 实践的异同

维度

OpenAI 内部数据 Agent

Anthropic 自助分析实践

本文实践

核心痛点

大规模数据资产中找到正确上下文

概念映射、检索、知识陈旧

垂直业务里的口径歧义

上下文来源

元数据、注释、代码、机构知识、记忆、运行时探查

语义层、策展文档、skills、provenance

语义层、业务知识库、歧义规则、评测

用户对象

工程、财务、数据科学等混合用户

非技术业务用户

业务同事和分析团队协作

纠错方式

对话与评测反馈

自动化维护与人工校正

业务材料包 -> 知识回流 -> eval

适合重点

超大规模上下文发现

自助分析规模化

高频口径治理和可信执行

我们的结论是:不必一开始追求“大而全”的企业数据 Agent。

如果业务场景足够垂直,先把高频指标、钦定数据源、歧义规则和几十条 eval 做扎实,就能获得很大收益。


如果从零开始,建议先做这五件事

1. 选 10 个最高频问题

不要一开始覆盖所有表。

先找业务每天都问、反复对数、最容易争议的 10 个问题。

2. 为每个问题写清口径卡片

至少写清:

  • 指标解释。

  • 统计对象。

  • 时间字段。

  • 状态过滤。

  • 默认表。

  • 不适用场景。

  • owner。

3. 建一个薄语义层

把最高频、最稳定的指标做成机器可读模板。

不要让模型每次都重新理解。

4. 补歧义规则

把“完成率”“放款金额”“有效用户”“今日数据”这类模糊词单独维护。

模糊词不治理,Agent 就会把业务习惯误当成唯一事实。

5. 建最小评测集

几十条 case 就够开始。

重点不是覆盖率好看,而是覆盖那些“答错会造成业务误判”的问题。


结语:问数 Agent 的护城河不是模型,而是知识运营

模型会越来越强,SQL 生成会越来越容易。

但企业问数的长期护城河,不是让模型多写几行 SQL,而是:

  • 谁能把业务口径讲清楚。

  • 谁能把纠错沉淀下来。

  • 谁能持续维护知识新鲜度。

  • 谁能用评测防止能力退化。

  • 谁能让业务同事参与知识共建。

大模型不是数据治理的替代品。

更准确地说,它是把数据治理带到业务日常的一种新界面。


参考资料

© 本文著作权归作者所有,未经许可不得转载使用。