写给开发者的智能问数 Skill 维护手册

分层、消歧、回归:让 Agent 说明书别变成无法合并的屎山

面向:正在用 Cursor / Agent Skill 做 NL2SQL、企业问数的开发与架构同学
(例子优先用电商/物流等通用场景,石油现场作为对照附在后面)
阅读时间:大约一刻钟

你可能已经会让模型「写出能跑的 SQL」了。
这篇文章想聊的是下一步更难受、也更值钱的事:怎么把 Skill 知识库写成可维护的工程资产——尤其当你手里不止一个业务库(比如生产数据一套、工程技术又一套),还要挂在同一个助手上时。


1. 我们真正卡住的地方,往往不是「模型会不会写 SELECT」

搭问数 Skill 的第一周通常很爽:扔进表结构,加两句约束,连上只读库,演示能出数。

难受从第二个月开始:

  • 用户随口问「这个产品卖了多少」,交易库 Skill 和履约库 Skill 都能各自查一版数,系统却答成用户不要的那一种;
  • 数据库里表和字段描述长得像,智能体检索时分不清,找错表找错字段,查出来的不是用户想要的。
  • 同一个计算公式被多处文件引用,改一处漏两处;
  • 目录拆了,链接还指着旧路径,Agent 读到两套互相打架的说明书;
  • 改完规则只能靠人工抽几问,说不清到底变好了还是变坏了。

换句话说:瓶颈从「生成 SQL」转移到了「知识怎么组织、决策怎么可调试、改完怎么验收」。

这种同词异义不是石油独有。先用大家更熟的「销量」把机制说清,再回到现场:

用户问「这个产品卖了多少」,至少可能是两回事——
下单量:购物车里点了购买、生成了订单(还没付款也可能算进去);
成交量:钱已经付清、才算真正卖掉。
听起来都是「销量」,背后却是两套统计、两张表、两套算法;答错一种,业务侧会觉得系统「胡说八道」。

石油现场也一样:「产了多少油」可能指试油阶段的折算日产(工程技术库),也可能指投产后井口日产(生产数据库)——同词异义,只是词换成了「产油」。

本文不写指标百科,只讲编写方法:目录怎么分、每层写多细、跨库怎么拦、错了怎么归因。


2. 从「能演示」到「能维护」:常见崩法

2.1 起步包长什么样

多数团队一开始只有三样东西:

  1. 表结构说明(整份或按前缀切开)
  2. 偏长的 SKILL.md
  3. 只读执行脚本

这也是我们做初版时的样子:单库、问题涉及的表不多、问法固定时,把字段备注描述清楚,就足够证明——约束写清楚,模型可以生成可用 SQL。

这段起步包我们自己踩了大约两个月:内部评测能跑通,但迟迟拿不到客户侧验证,就不知道该往哪改——没有真实反馈,迭代等于空转。工期拉长的主因不是「写不动」,而是验不了、不敢大改

2.2 复杂度上升后的五类故障

§1 那几条痛点,拆开看就是下面五类:

口径复制粘贴。
同一个「销售额」,在 metrics、WHERE 说明、样例题里写了三种算法,改一处漏两处,线上表现像随机数。

说明书自相矛盾。
被引用的文件更换地方了,入口没改,导致无法直接找到该文件;

明细当汇总。
没有「先用汇总表、明细必须限流」的硬约束,模型把全平台几百万条订单明细一把拉出来再口算加总——数据量一大,算术幻觉就来了。

多 Skill 抢答。
两个问数 Skill 同时挂着时,用户随口一句「卖了多少」「货怎么样了」,两边都能圆上,不能靠模型临场猜该进哪扇门。
常见撞车说法可以先记成对照表(写进两边的 routing):

用户随口说 Skill A(如下单/交易侧)可能指… Skill B(如发货/履约侧)可能指…
卖了多少 / 销量 下单量、成交金额 已出库件数、妥投量
货到哪了 订单物流状态字段(若交易库有镜像) 仓储发运、在途、签收
退了多少 退款金额 退货入库量
查一下这个单 / 这个货 订单号、买家信息 运单号、仓位库存

不同部门用的数据源不一致,挂的 Skill 也不是同一个,不能指望用户每次手动指定。

石油现场同理:「产了多少油」在生产库和工程技术库之间也会撞车,机制一样,只是词换成了产量/注气/措施。

没有回归语言。
团队只会说「感觉不准」,不会说「本轮失败里 30% 是选表,还是选字段失败」。

2.3 转折点

后来反馈通路打通、开始按错因改知识之后,分层架构(入口 / 路由 / 领域 / 字典 + 回归)大约半个月就从实践里定型了——比起步包那两个月短很多,因为这时候已经知道「改哪一层、用什么题验收」。

根因可以压成一句:

把本该写成说明书需要规则与分层文档的东西,全部丢给模型「临场发挥」。

模型适合理解自然语言、组织回答;对于查询数据对准确率有要求的不适合在无规则时稳定完成「进哪个系统、选哪张表、用哪个算法」这种分类题。
所以要把 Skill 当成小型后端:入口、路由、领域规则、字典、测试,各管一段。


3. Skill 内部怎么分层(写到能落 SQL)

「统一」不等于只做一个 Skill。
更稳妥的目标是:每个问数 Skill 内部工作流一致、知识分层、关键路由可追踪;生产库和工程库可以各做一个 Skill,但必须先解决「进哪扇门」即用哪个skill。

下面以电商取数为例说一层一层怎么写,石油现场对照附在括号里。

3.1 四层分工

典型文件 写到什么粒度
入口 SKILL.md 固定步骤:定 Skill → 选表 → 读口径 → 自检 → 执行;只读;不贴计算公式
路由 intent / clarifications / skill-routing 口语 → 首选表 → 见指标编号;两种理解都合理则给 A/B;若已判定属于另一套业务库,本 Skill 不查数,只告诉用户去用对应 Skill
领域规则 metrics、WHERE 说明、JOIN 说明 指标唯一写全;过滤写到列;关联写到 ON 键
字典与测试 schema 分片、golden、评测题 字段有什么;期望是什么;出现失败改哪个文件

上面表格里「去用对应 Skill」就是常说的转交,举个现场例子:

  • 用户问「昨天出库了多少」→ 当前若在交易 Skill 里,应直接说:这题归履约 Skill,请改用那个;不要用订单表的发货状态字段硬凑一个数。
  • 反过来,用户问「这单成交金额多少」→ 履约 Skill 应转给交易 Skill,不要用出库件数 × 单价硬算。

石油现场同理:在工程技术 Skill 里被问「开发井口昨天产了多少油」,应转给生产数据 Skill,别用试油日报字段硬凑。

注意:转交只要一句话指到正确 Skill;不要在转交时把对方怎么算(字段、公式)写进本包——那叫口径渗入影响后续计算查询。细节见第 5 章。

优化路由不必重写全部口径;补字段说明不必改工作流。这才叫分层,而不是「文件夹好看」。

3.2 目录示例

my-askdata-skill/
  SKILL.md
  references/
    00-meta/       # 维护公约、编号总表
    10-route/      # 跨系统边界、选表、澄清
    20-domain/     # 口径、WHERE、JOIN
    30-schema/     # 表与字段
    40-qa/         # 回归样例
  scripts/         # 脚本执行代码,或辅助工具

目录同时服务两件事:人维护时知道改哪;Agent 按需加载时知道读哪。
一次问答只应装入当前系统、当前候选表相关文档,而不是整包说明书。

3.3 系统内选表:先定库,再按映射与优先级选表

同词异义在企业取数里很常见(电商的「销量」「货到哪了」「退款」,石油的「产量」「注气」「措施」),所以我们把选表拆成两步,都落在可改的规则文档里,而不是靠模型临场猜:

  1. 先定业务库:交易还是履约(石油里是生产数据还是工程技术;写在 skill-routing;两可则澄清,已能判定属另一库则转交);
  2. 再在本库内选表:查「问题类型 → 推荐表」映射(写在 intent / table-fit);
  3. 附优先级:月度汇总类问题先走月度汇总表;单笔订单明细只用于点查、异常名单,且必须限流(石油里:油田/区块月汇总优先,单井日明细限流)。

这样做的直接好处是可追问、可改规则:「为什么选了这张表?」能指到某一行映射;选错了就改那一行,而不是调一句玄学 Prompt。

3.4 统一步骤(质量基线)

建议所有问数 Skill 共用同一套节奏:

  1. 前置检查(时间、只读、权限)
  2. 定库:生产 or 工程技术;属另一库则转交;两可则先给跨库澄清选项
  3. 按需加载本库知识
  4. 本域澄清(未说清才问):如下单/成交、当日/累计、已付/待付(石油里:试油/修井、日产/累计、设计/实钻);用户已钉死则跳过
  5. 库内选表 + 读口径 + 写 SQL + 自检
  6. 执行 + 按返回结果解释(附来源表与过滤条件)

步骤一致,评测才有共同标尺;否则 A 模块爱澄清、B 模块直接出 SQL,评分无法横向比较。定库前后两处澄清的分工,见第 5.1 节。


4. 知识怎么写:唯一源、同粒度、可引用

4.1 指标只写一处

「怎么算」的完整说明,只放在口径文档(metrics)里;入口、路由、样例题里不要再抄一遍公式,只写一行引用,例如:

M01·下单量
M02·成交量

为什么要两个编号?因为用户都说「卖了多少」,背后却是下单量和成交量两套算法(见 §1)。
若只写一个糊成一团的「销量」,改漏、答错都查不清。
所以:同名不同算法,就拆成两个编号;回答时也要说清楚本次用的是哪一个。

石油里的「产油」同理——试油阶段的折算日产、投产后的井口日产,也应是两个编号,别混称「产量」不声明。(对应电商里:下单量、成交量拆成两个编号。)

对开发同学来说,编号不是炫技,只是约定:改算法只改一处,别处靠编号找到它。

4.2 WHERE 与 JOIN 必须一样具体

类型 合格写法 不合格写法
过滤(精确) 「订单号 SO202401」→ 订单号列精确匹配;「某日成交」→ 用成交日期列 「订单号模糊匹配一下」;用创建日期冒充成交日期
过滤(范围) 「华东大区」→ 按大区/组织规则展开(写清用哪张关联表) 用订单号 LIKE 'HD%' 冒充华东全量
关联 订单表 JOIN 用户表 ON 用户ID;写清内连/左连 「订单和用户表关联一下」

再补一句给非石油同学:
订单表里往往存的是内部用户 ID,用户却说手机号——所以要先连用户表,用手机号换 ID。石油现场同理:试油日报存内部井 ID,用户说井号(如 FY210H),要先连井基础表换 ID。都是「业务表要 JOIN 维度表才能按用户嘴里的字段查」这一类工程问题。

4.3 澄清只给选项,例外只管边界

澄清:2~3 个选项,例如

  • A. 下单量(交易库,看订单表)
  • B. 成交量(交易库,看支付表)

或已经确认是交易语境,但没说清:

  • A. 看某天的成交额
  • B. 看年初至今累计

石油现场对应:A. 试油求产(工程技术库)B. 开发井口日产(生产数据库);进库后再问 A. 当天折算日产 B. 该层累计。

转交时只说「请用生产数据 / 工程技术 Skill」,不要把对方计算公式抄进本包。

4.4 表文档写「有什么」,口径文档写「怎么算」

字段列表服务于选列;计算公式服务于选算法。混在一起,改字段注释时容易误伤业务规则。
字段是否存在,以数据库元数据查询为准,不拿「中文长得像」当证据。

举个通俗例子:一张销售明细表里既有「当日销售额」,又有「年初至今累计销售额」。
用户问「昨天卖了多少」,却拿累计字段去答,数字会差得离谱——列没选错语法,但答非所问。
项目实践中石油日报里「日产油」和「累产油」并存,也是同一类坑。

4.5 新系统借鉴旧 Skill:只借壳,不借肉

把生产库 Skill 的写法搬到工程技术库时:

可以抄结构 必须重写内容
目录、步骤、自检形态、评测框架 连接配置、表映射、全部指标与 SQL 模板
编号指针写法、澄清文档形态 WHERE/JOIN 规则、回归题

自检句:删掉生产库特有的表名和算法后,工程技术包是否还能独立回答试油/钻井类问题?反过来亦然。


5. 多 Skill 并列:先关门禁,再进库选表

5.1 顺序不能反(含澄清)

完整一点应是:

问句
  → 定 Skill(交易 or 履约)
       ├─ 已能判定属另一库 → 转交,结束
       └─ 两库都像 → 先澄清(给 A/B,如:下单量 vs 成交量)
  → 进入本库后:本域澄清(用户没说清才问;已钉死则跳过)
       例如:下单还是成交?当天还是累计?已付还是待付?订单号精确还是模糊?
  → 以下接 §3.4 第 4 步起:库内选表 → 读口径 → 自检 → 执行

两处澄清不要混:

时机 问什么 举例
定库之前 进哪个 Skill A. 下单量(交易)B. 已出库件数(履约)
进库之后 本库内怎么收窄 A. 当天成交额 B. 年初至今累计;或 A. 下单 B. 退款

库都没定就生成 SQL,属于提前答题;本域条件没钉死就直接汇总,也容易答非所问。

5.2 对照表要写在 routing 里

把第 2.2 节那张对照表写进两边 Skill 的 skill-routing,并且对称

  • 交易侧遇到「出库了没、在途多少、仓库还剩多少」→ 转交履约/仓储 Skill;
  • 仓储侧遇到「成交金额、是否已付款、退款到账了没」→ 转交交易 Skill。

石油落地时同样对称即可:生产侧遇到试油日报/钻井/录井 → 转交工程技术;工程侧遇到井口日产/核实/措施增油 → 转交生产数据。机制相同,只是对照表里的词换成现场说法。

对照表的价值是:让模型少猜,让开发者改规则有落点。

5.3 对称铁律

两边 Skill 都要写:

  1. 不执行对方库 SQL
  2. 不用近似字段冒充(尤其禁止用「下单量」冒充「成交量」,或用「出库件数」冒充「成交件数」)
  3. 转交一句话,不讲对方算法
  4. 不把对方指标编号粘进本包 metrics

6. 回归:把「感觉不准」翻译成「改哪个文件」

6.1 最小评测闭环

题库批量提问 → 记录 SQL/用表/是否澄清/是否执行成功 → 对照期望 → 出通过率,并做错因统计。

样例题可以很土、很现场,例如:

  • 「订单 SO202401 成交金额多少」(应进交易库、带成交日期)
  • 「这个买家下过几单」(交易库用户维度,不必硬联物流表)
  • 「华东大区昨天卖了多少」(未说清下单还是成交 → 应澄清)
  • 「这批货出库了没」(交易库应转交履约,不得用订单状态硬答)

石油现场对应一组:试油日报产油、开钻完钻日期、哈得昨天产量(应澄清)、开发井口日产(工程库应转交)。

6.2 四类错因

错因 开发动作
选表错 改路由映射、适用/不适用说明
SQL 错 补字段确认、修模板、更新表结构文档
口径错 改 metrics / WHERE / JOIN(列选错、日期列用错也算)
该问没问 补澄清与跨系统对照

知识或路由变更后跑冒烟;合并前跑扩大回归。
评测脚手架可共用,题目按系统分目录,别拿生产库的题测工程库。

6.3 执行前自检(示例)

  1. Schema 前缀正确,无串库表名
  2. 订单号优先精确匹配;禁止用订单号前缀模糊冒充全量(石油里:井号精确,禁止用前缀 LIKE 冒充全油田)
  3. 列已做元数据确认(成交额 vs 累计、成交日期 vs 创建日期;石油里:日产 vs 累产、日报日期 vs 创建日期)
  4. 指标钉死条件已写入
  5. 单笔/批量明细已限流,或先走汇总表(石油里:单井日明细限流)
  6. JOIN 键正确(常见:订单表 用户ID = 用户表 用户ID;石油里:业务表 井ID = 井基础表 井ID
  7. 仅只读

失败就报失败,禁止用「分析报告」口吻补造数字。


7. 我们认的几条工程原则

  1. 分类决策交给规则,语言理解留给模型。
  2. 上下文按路径加载,不靠整包硬灌。
  3. 计算公式只保留一份原文,其它地方引用编号。
  4. 过滤规则与关联规则写到同一工程粒度(列 / ON 键)。
  5. 复制目录可以,复制业务算法不行(交易 ↔ 履约尤其如此)。
  6. 用错因分布指导迭代,而不是用「我觉得」。

仍未自动解决的事

  • 取数对了,不等于会做「销量为什么掉了」的归因分析;两套能力如何共享知识要单独设计。(石油现场:「产量为什么掉了」同理。)
  • 线上表结构变更会导致文档「沉默过期」,需要元数据对比。
  • 用户体感还包括解释是否清楚、交互是否顺,不只是 SQL 对错。

模型会继续变强,但说明书是否分层、口径是否唯一、跨库是否门禁、改完是否可测,仍然决定你的系统能不能在真实企业里活过第三个月。


附录 目录树

my-askdata-skill/
  SKILL.md
  references/
    00-meta/
      doc-boundaries.md
      id-index.md
    10-route/
      skill-routing.md
      intent-routing.md
      clarifications.md
      table-fit.md
    20-domain/
      metrics-and-exceptions.md
      scope-filters.md
      joins.md
    30-schema/
      schema-index.md
      schema-by-prefix/
      tables.json
    40-qa/
      golden-queries.md
  scripts/
    execute_sql.py
    check_config.py

写给开发者的智能问数 Skill 维护手册

分层、消歧、回归:让 Agent 说明书别变成无法合并的屎山

面向:正在用 Cursor / Agent Skill 做 NL2SQL、企业问数的开发与架构同学
(例子优先用电商/物流等通用场景,石油现场作为对照附在后面)
阅读时间:大约一刻钟

你可能已经会让模型「写出能跑的 SQL」了。
这篇文章想聊的是下一步更难受、也更值钱的事:怎么把 Skill 知识库写成可维护的工程资产——尤其当你手里不止一个业务库(比如生产数据一套、工程技术又一套),还要挂在同一个助手上时。


1. 我们真正卡住的地方,往往不是「模型会不会写 SELECT」

搭问数 Skill 的第一周通常很爽:扔进表结构,加两句约束,连上只读库,演示能出数。

难受从第二个月开始:

  • 用户随口问「这个产品卖了多少」,交易库 Skill 和履约库 Skill 都能各自查一版数,系统却答成用户不要的那一种;
  • 数据库里表和字段描述长得像,智能体检索时分不清,找错表找错字段,查出来的不是用户想要的。
  • 同一个计算公式被多处文件引用,改一处漏两处;
  • 目录拆了,链接还指着旧路径,Agent 读到两套互相打架的说明书;
  • 改完规则只能靠人工抽几问,说不清到底变好了还是变坏了。

换句话说:瓶颈从「生成 SQL」转移到了「知识怎么组织、决策怎么可调试、改完怎么验收」。

这种同词异义不是石油独有。先用大家更熟的「销量」把机制说清,再回到现场:

用户问「这个产品卖了多少」,至少可能是两回事——
下单量:购物车里点了购买、生成了订单(还没付款也可能算进去);
成交量:钱已经付清、才算真正卖掉。
听起来都是「销量」,背后却是两套统计、两张表、两套算法;答错一种,业务侧会觉得系统「胡说八道」。

石油现场也一样:「产了多少油」可能指试油阶段的折算日产(工程技术库),也可能指投产后井口日产(生产数据库)——同词异义,只是词换成了「产油」。

本文不写指标百科,只讲编写方法:目录怎么分、每层写多细、跨库怎么拦、错了怎么归因。


2. 从「能演示」到「能维护」:常见崩法

2.1 起步包长什么样

多数团队一开始只有三样东西:

  1. 表结构说明(整份或按前缀切开)
  2. 偏长的 SKILL.md
  3. 只读执行脚本

这也是我们做初版时的样子:单库、问题涉及的表不多、问法固定时,把字段备注描述清楚,就足够证明——约束写清楚,模型可以生成可用 SQL。

这段起步包我们自己踩了大约两个月:内部评测能跑通,但迟迟拿不到客户侧验证,就不知道该往哪改——没有真实反馈,迭代等于空转。工期拉长的主因不是「写不动」,而是验不了、不敢大改

2.2 复杂度上升后的五类故障

§1 那几条痛点,拆开看就是下面五类:

口径复制粘贴。
同一个「销售额」,在 metrics、WHERE 说明、样例题里写了三种算法,改一处漏两处,线上表现像随机数。

说明书自相矛盾。
被引用的文件更换地方了,入口没改,导致无法直接找到该文件;

明细当汇总。
没有「先用汇总表、明细必须限流」的硬约束,模型把全平台几百万条订单明细一把拉出来再口算加总——数据量一大,算术幻觉就来了。

多 Skill 抢答。
两个问数 Skill 同时挂着时,用户随口一句「卖了多少」「货怎么样了」,两边都能圆上,不能靠模型临场猜该进哪扇门。
常见撞车说法可以先记成对照表(写进两边的 routing):

用户随口说 Skill A(如下单/交易侧)可能指… Skill B(如发货/履约侧)可能指…
卖了多少 / 销量 下单量、成交金额 已出库件数、妥投量
货到哪了 订单物流状态字段(若交易库有镜像) 仓储发运、在途、签收
退了多少 退款金额 退货入库量
查一下这个单 / 这个货 订单号、买家信息 运单号、仓位库存

不同部门用的数据源不一致,挂的 Skill 也不是同一个,不能指望用户每次手动指定。

石油现场同理:「产了多少油」在生产库和工程技术库之间也会撞车,机制一样,只是词换成了产量/注气/措施。

没有回归语言。
团队只会说「感觉不准」,不会说「本轮失败里 30% 是选表,还是选字段失败」。

2.3 转折点

后来反馈通路打通、开始按错因改知识之后,分层架构(入口 / 路由 / 领域 / 字典 + 回归)大约半个月就从实践里定型了——比起步包那两个月短很多,因为这时候已经知道「改哪一层、用什么题验收」。

根因可以压成一句:

把本该写成说明书需要规则与分层文档的东西,全部丢给模型「临场发挥」。

模型适合理解自然语言、组织回答;对于查询数据对准确率有要求的不适合在无规则时稳定完成「进哪个系统、选哪张表、用哪个算法」这种分类题。
所以要把 Skill 当成小型后端:入口、路由、领域规则、字典、测试,各管一段。


3. Skill 内部怎么分层(写到能落 SQL)

「统一」不等于只做一个 Skill。
更稳妥的目标是:每个问数 Skill 内部工作流一致、知识分层、关键路由可追踪;生产库和工程库可以各做一个 Skill,但必须先解决「进哪扇门」即用哪个skill。

下面以电商取数为例说一层一层怎么写,石油现场对照附在括号里。

3.1 四层分工

典型文件 写到什么粒度
入口 SKILL.md 固定步骤:定 Skill → 选表 → 读口径 → 自检 → 执行;只读;不贴计算公式
路由 intent / clarifications / skill-routing 口语 → 首选表 → 见指标编号;两种理解都合理则给 A/B;若已判定属于另一套业务库,本 Skill 不查数,只告诉用户去用对应 Skill
领域规则 metrics、WHERE 说明、JOIN 说明 指标唯一写全;过滤写到列;关联写到 ON 键
字典与测试 schema 分片、golden、评测题 字段有什么;期望是什么;出现失败改哪个文件

上面表格里「去用对应 Skill」就是常说的转交,举个现场例子:

  • 用户问「昨天出库了多少」→ 当前若在交易 Skill 里,应直接说:这题归履约 Skill,请改用那个;不要用订单表的发货状态字段硬凑一个数。
  • 反过来,用户问「这单成交金额多少」→ 履约 Skill 应转给交易 Skill,不要用出库件数 × 单价硬算。

石油现场同理:在工程技术 Skill 里被问「开发井口昨天产了多少油」,应转给生产数据 Skill,别用试油日报字段硬凑。

注意:转交只要一句话指到正确 Skill;不要在转交时把对方怎么算(字段、公式)写进本包——那叫口径渗入影响后续计算查询。细节见第 5 章。

优化路由不必重写全部口径;补字段说明不必改工作流。这才叫分层,而不是「文件夹好看」。

3.2 目录示例

my-askdata-skill/
  SKILL.md
  references/
    00-meta/       # 维护公约、编号总表
    10-route/      # 跨系统边界、选表、澄清
    20-domain/     # 口径、WHERE、JOIN
    30-schema/     # 表与字段
    40-qa/         # 回归样例
  scripts/         # 脚本执行代码,或辅助工具

目录同时服务两件事:人维护时知道改哪;Agent 按需加载时知道读哪。
一次问答只应装入当前系统、当前候选表相关文档,而不是整包说明书。

3.3 系统内选表:先定库,再按映射与优先级选表

同词异义在企业取数里很常见(电商的「销量」「货到哪了」「退款」,石油的「产量」「注气」「措施」),所以我们把选表拆成两步,都落在可改的规则文档里,而不是靠模型临场猜:

  1. 先定业务库:交易还是履约(石油里是生产数据还是工程技术;写在 skill-routing;两可则澄清,已能判定属另一库则转交);
  2. 再在本库内选表:查「问题类型 → 推荐表」映射(写在 intent / table-fit);
  3. 附优先级:月度汇总类问题先走月度汇总表;单笔订单明细只用于点查、异常名单,且必须限流(石油里:油田/区块月汇总优先,单井日明细限流)。

这样做的直接好处是可追问、可改规则:「为什么选了这张表?」能指到某一行映射;选错了就改那一行,而不是调一句玄学 Prompt。

3.4 统一步骤(质量基线)

建议所有问数 Skill 共用同一套节奏:

  1. 前置检查(时间、只读、权限)
  2. 定库:生产 or 工程技术;属另一库则转交;两可则先给跨库澄清选项
  3. 按需加载本库知识
  4. 本域澄清(未说清才问):如下单/成交、当日/累计、已付/待付(石油里:试油/修井、日产/累计、设计/实钻);用户已钉死则跳过
  5. 库内选表 + 读口径 + 写 SQL + 自检
  6. 执行 + 按返回结果解释(附来源表与过滤条件)

步骤一致,评测才有共同标尺;否则 A 模块爱澄清、B 模块直接出 SQL,评分无法横向比较。定库前后两处澄清的分工,见第 5.1 节。


4. 知识怎么写:唯一源、同粒度、可引用

4.1 指标只写一处

「怎么算」的完整说明,只放在口径文档(metrics)里;入口、路由、样例题里不要再抄一遍公式,只写一行引用,例如:

M01·下单量
M02·成交量

为什么要两个编号?因为用户都说「卖了多少」,背后却是下单量和成交量两套算法(见 §1)。
若只写一个糊成一团的「销量」,改漏、答错都查不清。
所以:同名不同算法,就拆成两个编号;回答时也要说清楚本次用的是哪一个。

石油里的「产油」同理——试油阶段的折算日产、投产后的井口日产,也应是两个编号,别混称「产量」不声明。(对应电商里:下单量、成交量拆成两个编号。)

对开发同学来说,编号不是炫技,只是约定:改算法只改一处,别处靠编号找到它。

4.2 WHERE 与 JOIN 必须一样具体

类型 合格写法 不合格写法
过滤(精确) 「订单号 SO202401」→ 订单号列精确匹配;「某日成交」→ 用成交日期列 「订单号模糊匹配一下」;用创建日期冒充成交日期
过滤(范围) 「华东大区」→ 按大区/组织规则展开(写清用哪张关联表) 用订单号 LIKE 'HD%' 冒充华东全量
关联 订单表 JOIN 用户表 ON 用户ID;写清内连/左连 「订单和用户表关联一下」

再补一句给非石油同学:
订单表里往往存的是内部用户 ID,用户却说手机号——所以要先连用户表,用手机号换 ID。石油现场同理:试油日报存内部井 ID,用户说井号(如 FY210H),要先连井基础表换 ID。都是「业务表要 JOIN 维度表才能按用户嘴里的字段查」这一类工程问题。

4.3 澄清只给选项,例外只管边界

澄清:2~3 个选项,例如

  • A. 下单量(交易库,看订单表)
  • B. 成交量(交易库,看支付表)

或已经确认是交易语境,但没说清:

  • A. 看某天的成交额
  • B. 看年初至今累计

石油现场对应:A. 试油求产(工程技术库)B. 开发井口日产(生产数据库);进库后再问 A. 当天折算日产 B. 该层累计。

转交时只说「请用生产数据 / 工程技术 Skill」,不要把对方计算公式抄进本包。

4.4 表文档写「有什么」,口径文档写「怎么算」

字段列表服务于选列;计算公式服务于选算法。混在一起,改字段注释时容易误伤业务规则。
字段是否存在,以数据库元数据查询为准,不拿「中文长得像」当证据。

举个通俗例子:一张销售明细表里既有「当日销售额」,又有「年初至今累计销售额」。
用户问「昨天卖了多少」,却拿累计字段去答,数字会差得离谱——列没选错语法,但答非所问。
项目实践中石油日报里「日产油」和「累产油」并存,也是同一类坑。

4.5 新系统借鉴旧 Skill:只借壳,不借肉

把生产库 Skill 的写法搬到工程技术库时:

可以抄结构 必须重写内容
目录、步骤、自检形态、评测框架 连接配置、表映射、全部指标与 SQL 模板
编号指针写法、澄清文档形态 WHERE/JOIN 规则、回归题

自检句:删掉生产库特有的表名和算法后,工程技术包是否还能独立回答试油/钻井类问题?反过来亦然。


5. 多 Skill 并列:先关门禁,再进库选表

5.1 顺序不能反(含澄清)

完整一点应是:

问句
  → 定 Skill(交易 or 履约)
       ├─ 已能判定属另一库 → 转交,结束
       └─ 两库都像 → 先澄清(给 A/B,如:下单量 vs 成交量)
  → 进入本库后:本域澄清(用户没说清才问;已钉死则跳过)
       例如:下单还是成交?当天还是累计?已付还是待付?订单号精确还是模糊?
  → 以下接 §3.4 第 4 步起:库内选表 → 读口径 → 自检 → 执行

两处澄清不要混:

时机 问什么 举例
定库之前 进哪个 Skill A. 下单量(交易)B. 已出库件数(履约)
进库之后 本库内怎么收窄 A. 当天成交额 B. 年初至今累计;或 A. 下单 B. 退款

库都没定就生成 SQL,属于提前答题;本域条件没钉死就直接汇总,也容易答非所问。

5.2 对照表要写在 routing 里

把第 2.2 节那张对照表写进两边 Skill 的 skill-routing,并且对称

  • 交易侧遇到「出库了没、在途多少、仓库还剩多少」→ 转交履约/仓储 Skill;
  • 仓储侧遇到「成交金额、是否已付款、退款到账了没」→ 转交交易 Skill。

石油落地时同样对称即可:生产侧遇到试油日报/钻井/录井 → 转交工程技术;工程侧遇到井口日产/核实/措施增油 → 转交生产数据。机制相同,只是对照表里的词换成现场说法。

对照表的价值是:让模型少猜,让开发者改规则有落点。

5.3 对称铁律

两边 Skill 都要写:

  1. 不执行对方库 SQL
  2. 不用近似字段冒充(尤其禁止用「下单量」冒充「成交量」,或用「出库件数」冒充「成交件数」)
  3. 转交一句话,不讲对方算法
  4. 不把对方指标编号粘进本包 metrics

6. 回归:把「感觉不准」翻译成「改哪个文件」

6.1 最小评测闭环

题库批量提问 → 记录 SQL/用表/是否澄清/是否执行成功 → 对照期望 → 出通过率,并做错因统计。

样例题可以很土、很现场,例如:

  • 「订单 SO202401 成交金额多少」(应进交易库、带成交日期)
  • 「这个买家下过几单」(交易库用户维度,不必硬联物流表)
  • 「华东大区昨天卖了多少」(未说清下单还是成交 → 应澄清)
  • 「这批货出库了没」(交易库应转交履约,不得用订单状态硬答)

石油现场对应一组:试油日报产油、开钻完钻日期、哈得昨天产量(应澄清)、开发井口日产(工程库应转交)。

6.2 四类错因

错因 开发动作
选表错 改路由映射、适用/不适用说明
SQL 错 补字段确认、修模板、更新表结构文档
口径错 改 metrics / WHERE / JOIN(列选错、日期列用错也算)
该问没问 补澄清与跨系统对照

知识或路由变更后跑冒烟;合并前跑扩大回归。
评测脚手架可共用,题目按系统分目录,别拿生产库的题测工程库。

6.3 执行前自检(示例)

  1. Schema 前缀正确,无串库表名
  2. 订单号优先精确匹配;禁止用订单号前缀模糊冒充全量(石油里:井号精确,禁止用前缀 LIKE 冒充全油田)
  3. 列已做元数据确认(成交额 vs 累计、成交日期 vs 创建日期;石油里:日产 vs 累产、日报日期 vs 创建日期)
  4. 指标钉死条件已写入
  5. 单笔/批量明细已限流,或先走汇总表(石油里:单井日明细限流)
  6. JOIN 键正确(常见:订单表 用户ID = 用户表 用户ID;石油里:业务表 井ID = 井基础表 井ID
  7. 仅只读

失败就报失败,禁止用「分析报告」口吻补造数字。


7. 我们认的几条工程原则

  1. 分类决策交给规则,语言理解留给模型。
  2. 上下文按路径加载,不靠整包硬灌。
  3. 计算公式只保留一份原文,其它地方引用编号。
  4. 过滤规则与关联规则写到同一工程粒度(列 / ON 键)。
  5. 复制目录可以,复制业务算法不行(交易 ↔ 履约尤其如此)。
  6. 用错因分布指导迭代,而不是用「我觉得」。

仍未自动解决的事

  • 取数对了,不等于会做「销量为什么掉了」的归因分析;两套能力如何共享知识要单独设计。(石油现场:「产量为什么掉了」同理。)
  • 线上表结构变更会导致文档「沉默过期」,需要元数据对比。
  • 用户体感还包括解释是否清楚、交互是否顺,不只是 SQL 对错。

模型会继续变强,但说明书是否分层、口径是否唯一、跨库是否门禁、改完是否可测,仍然决定你的系统能不能在真实企业里活过第三个月。


附录 目录树

my-askdata-skill/
  SKILL.md
  references/
    00-meta/
      doc-boundaries.md
      id-index.md
    10-route/
      skill-routing.md
      intent-routing.md
      clarifications.md
      table-fit.md
    20-domain/
      metrics-and-exceptions.md
      scope-filters.md
      joins.md
    30-schema/
      schema-index.md
      schema-by-prefix/
      tables.json
    40-qa/
      golden-queries.md
  scripts/
    execute_sql.py
    check_config.py

写给开发者的智能问数 Skill 维护手册

分层、消歧、回归:让 Agent 说明书别变成无法合并的屎山

面向:正在用 Cursor / Agent Skill 做 NL2SQL、企业问数的开发与架构同学
(例子优先用电商/物流等通用场景,石油现场作为对照附在后面)
阅读时间:大约一刻钟

你可能已经会让模型「写出能跑的 SQL」了。
这篇文章想聊的是下一步更难受、也更值钱的事:怎么把 Skill 知识库写成可维护的工程资产——尤其当你手里不止一个业务库(比如生产数据一套、工程技术又一套),还要挂在同一个助手上时。


1. 我们真正卡住的地方,往往不是「模型会不会写 SELECT」

搭问数 Skill 的第一周通常很爽:扔进表结构,加两句约束,连上只读库,演示能出数。

难受从第二个月开始:

  • 用户随口问「这个产品卖了多少」,交易库 Skill 和履约库 Skill 都能各自查一版数,系统却答成用户不要的那一种;
  • 数据库里表和字段描述长得像,智能体检索时分不清,找错表找错字段,查出来的不是用户想要的。
  • 同一个计算公式被多处文件引用,改一处漏两处;
  • 目录拆了,链接还指着旧路径,Agent 读到两套互相打架的说明书;
  • 改完规则只能靠人工抽几问,说不清到底变好了还是变坏了。

换句话说:瓶颈从「生成 SQL」转移到了「知识怎么组织、决策怎么可调试、改完怎么验收」。

这种同词异义不是石油独有。先用大家更熟的「销量」把机制说清,再回到现场:

用户问「这个产品卖了多少」,至少可能是两回事——
下单量:购物车里点了购买、生成了订单(还没付款也可能算进去);
成交量:钱已经付清、才算真正卖掉。
听起来都是「销量」,背后却是两套统计、两张表、两套算法;答错一种,业务侧会觉得系统「胡说八道」。

石油现场也一样:「产了多少油」可能指试油阶段的折算日产(工程技术库),也可能指投产后井口日产(生产数据库)——同词异义,只是词换成了「产油」。

本文不写指标百科,只讲编写方法:目录怎么分、每层写多细、跨库怎么拦、错了怎么归因。


2. 从「能演示」到「能维护」:常见崩法

2.1 起步包长什么样

多数团队一开始只有三样东西:

  1. 表结构说明(整份或按前缀切开)
  2. 偏长的 SKILL.md
  3. 只读执行脚本

这也是我们做初版时的样子:单库、问题涉及的表不多、问法固定时,把字段备注描述清楚,就足够证明——约束写清楚,模型可以生成可用 SQL。

这段起步包我们自己踩了大约两个月:内部评测能跑通,但迟迟拿不到客户侧验证,就不知道该往哪改——没有真实反馈,迭代等于空转。工期拉长的主因不是「写不动」,而是验不了、不敢大改

2.2 复杂度上升后的五类故障

§1 那几条痛点,拆开看就是下面五类:

口径复制粘贴。
同一个「销售额」,在 metrics、WHERE 说明、样例题里写了三种算法,改一处漏两处,线上表现像随机数。

说明书自相矛盾。
被引用的文件更换地方了,入口没改,导致无法直接找到该文件;

明细当汇总。
没有「先用汇总表、明细必须限流」的硬约束,模型把全平台几百万条订单明细一把拉出来再口算加总——数据量一大,算术幻觉就来了。

多 Skill 抢答。
两个问数 Skill 同时挂着时,用户随口一句「卖了多少」「货怎么样了」,两边都能圆上,不能靠模型临场猜该进哪扇门。
常见撞车说法可以先记成对照表(写进两边的 routing):

用户随口说 Skill A(如下单/交易侧)可能指… Skill B(如发货/履约侧)可能指…
卖了多少 / 销量 下单量、成交金额 已出库件数、妥投量
货到哪了 订单物流状态字段(若交易库有镜像) 仓储发运、在途、签收
退了多少 退款金额 退货入库量
查一下这个单 / 这个货 订单号、买家信息 运单号、仓位库存

不同部门用的数据源不一致,挂的 Skill 也不是同一个,不能指望用户每次手动指定。

石油现场同理:「产了多少油」在生产库和工程技术库之间也会撞车,机制一样,只是词换成了产量/注气/措施。

没有回归语言。
团队只会说「感觉不准」,不会说「本轮失败里 30% 是选表,还是选字段失败」。

2.3 转折点

后来反馈通路打通、开始按错因改知识之后,分层架构(入口 / 路由 / 领域 / 字典 + 回归)大约半个月就从实践里定型了——比起步包那两个月短很多,因为这时候已经知道「改哪一层、用什么题验收」。

根因可以压成一句:

把本该写成说明书需要规则与分层文档的东西,全部丢给模型「临场发挥」。

模型适合理解自然语言、组织回答;对于查询数据对准确率有要求的不适合在无规则时稳定完成「进哪个系统、选哪张表、用哪个算法」这种分类题。
所以要把 Skill 当成小型后端:入口、路由、领域规则、字典、测试,各管一段。


3. Skill 内部怎么分层(写到能落 SQL)

「统一」不等于只做一个 Skill。
更稳妥的目标是:每个问数 Skill 内部工作流一致、知识分层、关键路由可追踪;生产库和工程库可以各做一个 Skill,但必须先解决「进哪扇门」即用哪个skill。

下面以电商取数为例说一层一层怎么写,石油现场对照附在括号里。

3.1 四层分工

典型文件 写到什么粒度
入口 SKILL.md 固定步骤:定 Skill → 选表 → 读口径 → 自检 → 执行;只读;不贴计算公式
路由 intent / clarifications / skill-routing 口语 → 首选表 → 见指标编号;两种理解都合理则给 A/B;若已判定属于另一套业务库,本 Skill 不查数,只告诉用户去用对应 Skill
领域规则 metrics、WHERE 说明、JOIN 说明 指标唯一写全;过滤写到列;关联写到 ON 键
字典与测试 schema 分片、golden、评测题 字段有什么;期望是什么;出现失败改哪个文件

上面表格里「去用对应 Skill」就是常说的转交,举个现场例子:

  • 用户问「昨天出库了多少」→ 当前若在交易 Skill 里,应直接说:这题归履约 Skill,请改用那个;不要用订单表的发货状态字段硬凑一个数。
  • 反过来,用户问「这单成交金额多少」→ 履约 Skill 应转给交易 Skill,不要用出库件数 × 单价硬算。

石油现场同理:在工程技术 Skill 里被问「开发井口昨天产了多少油」,应转给生产数据 Skill,别用试油日报字段硬凑。

注意:转交只要一句话指到正确 Skill;不要在转交时把对方怎么算(字段、公式)写进本包——那叫口径渗入影响后续计算查询。细节见第 5 章。

优化路由不必重写全部口径;补字段说明不必改工作流。这才叫分层,而不是「文件夹好看」。

3.2 目录示例

my-askdata-skill/
  SKILL.md
  references/
    00-meta/       # 维护公约、编号总表
    10-route/      # 跨系统边界、选表、澄清
    20-domain/     # 口径、WHERE、JOIN
    30-schema/     # 表与字段
    40-qa/         # 回归样例
  scripts/         # 脚本执行代码,或辅助工具

目录同时服务两件事:人维护时知道改哪;Agent 按需加载时知道读哪。
一次问答只应装入当前系统、当前候选表相关文档,而不是整包说明书。

3.3 系统内选表:先定库,再按映射与优先级选表

同词异义在企业取数里很常见(电商的「销量」「货到哪了」「退款」,石油的「产量」「注气」「措施」),所以我们把选表拆成两步,都落在可改的规则文档里,而不是靠模型临场猜:

  1. 先定业务库:交易还是履约(石油里是生产数据还是工程技术;写在 skill-routing;两可则澄清,已能判定属另一库则转交);
  2. 再在本库内选表:查「问题类型 → 推荐表」映射(写在 intent / table-fit);
  3. 附优先级:月度汇总类问题先走月度汇总表;单笔订单明细只用于点查、异常名单,且必须限流(石油里:油田/区块月汇总优先,单井日明细限流)。

这样做的直接好处是可追问、可改规则:「为什么选了这张表?」能指到某一行映射;选错了就改那一行,而不是调一句玄学 Prompt。

3.4 统一步骤(质量基线)

建议所有问数 Skill 共用同一套节奏:

  1. 前置检查(时间、只读、权限)
  2. 定库:生产 or 工程技术;属另一库则转交;两可则先给跨库澄清选项
  3. 按需加载本库知识
  4. 本域澄清(未说清才问):如下单/成交、当日/累计、已付/待付(石油里:试油/修井、日产/累计、设计/实钻);用户已钉死则跳过
  5. 库内选表 + 读口径 + 写 SQL + 自检
  6. 执行 + 按返回结果解释(附来源表与过滤条件)

步骤一致,评测才有共同标尺;否则 A 模块爱澄清、B 模块直接出 SQL,评分无法横向比较。定库前后两处澄清的分工,见第 5.1 节。


4. 知识怎么写:唯一源、同粒度、可引用

4.1 指标只写一处

「怎么算」的完整说明,只放在口径文档(metrics)里;入口、路由、样例题里不要再抄一遍公式,只写一行引用,例如:

M01·下单量
M02·成交量

为什么要两个编号?因为用户都说「卖了多少」,背后却是下单量和成交量两套算法(见 §1)。
若只写一个糊成一团的「销量」,改漏、答错都查不清。
所以:同名不同算法,就拆成两个编号;回答时也要说清楚本次用的是哪一个。

石油里的「产油」同理——试油阶段的折算日产、投产后的井口日产,也应是两个编号,别混称「产量」不声明。(对应电商里:下单量、成交量拆成两个编号。)

对开发同学来说,编号不是炫技,只是约定:改算法只改一处,别处靠编号找到它。

4.2 WHERE 与 JOIN 必须一样具体

类型 合格写法 不合格写法
过滤(精确) 「订单号 SO202401」→ 订单号列精确匹配;「某日成交」→ 用成交日期列 「订单号模糊匹配一下」;用创建日期冒充成交日期
过滤(范围) 「华东大区」→ 按大区/组织规则展开(写清用哪张关联表) 用订单号 LIKE 'HD%' 冒充华东全量
关联 订单表 JOIN 用户表 ON 用户ID;写清内连/左连 「订单和用户表关联一下」

再补一句给非石油同学:
订单表里往往存的是内部用户 ID,用户却说手机号——所以要先连用户表,用手机号换 ID。石油现场同理:试油日报存内部井 ID,用户说井号(如 FY210H),要先连井基础表换 ID。都是「业务表要 JOIN 维度表才能按用户嘴里的字段查」这一类工程问题。

4.3 澄清只给选项,例外只管边界

澄清:2~3 个选项,例如

  • A. 下单量(交易库,看订单表)
  • B. 成交量(交易库,看支付表)

或已经确认是交易语境,但没说清:

  • A. 看某天的成交额
  • B. 看年初至今累计

石油现场对应:A. 试油求产(工程技术库)B. 开发井口日产(生产数据库);进库后再问 A. 当天折算日产 B. 该层累计。

转交时只说「请用生产数据 / 工程技术 Skill」,不要把对方计算公式抄进本包。

4.4 表文档写「有什么」,口径文档写「怎么算」

字段列表服务于选列;计算公式服务于选算法。混在一起,改字段注释时容易误伤业务规则。
字段是否存在,以数据库元数据查询为准,不拿「中文长得像」当证据。

举个通俗例子:一张销售明细表里既有「当日销售额」,又有「年初至今累计销售额」。
用户问「昨天卖了多少」,却拿累计字段去答,数字会差得离谱——列没选错语法,但答非所问。
项目实践中石油日报里「日产油」和「累产油」并存,也是同一类坑。

4.5 新系统借鉴旧 Skill:只借壳,不借肉

把生产库 Skill 的写法搬到工程技术库时:

可以抄结构 必须重写内容
目录、步骤、自检形态、评测框架 连接配置、表映射、全部指标与 SQL 模板
编号指针写法、澄清文档形态 WHERE/JOIN 规则、回归题

自检句:删掉生产库特有的表名和算法后,工程技术包是否还能独立回答试油/钻井类问题?反过来亦然。


5. 多 Skill 并列:先关门禁,再进库选表

5.1 顺序不能反(含澄清)

完整一点应是:

问句
  → 定 Skill(交易 or 履约)
       ├─ 已能判定属另一库 → 转交,结束
       └─ 两库都像 → 先澄清(给 A/B,如:下单量 vs 成交量)
  → 进入本库后:本域澄清(用户没说清才问;已钉死则跳过)
       例如:下单还是成交?当天还是累计?已付还是待付?订单号精确还是模糊?
  → 以下接 §3.4 第 4 步起:库内选表 → 读口径 → 自检 → 执行

两处澄清不要混:

时机 问什么 举例
定库之前 进哪个 Skill A. 下单量(交易)B. 已出库件数(履约)
进库之后 本库内怎么收窄 A. 当天成交额 B. 年初至今累计;或 A. 下单 B. 退款

库都没定就生成 SQL,属于提前答题;本域条件没钉死就直接汇总,也容易答非所问。

5.2 对照表要写在 routing 里

把第 2.2 节那张对照表写进两边 Skill 的 skill-routing,并且对称

  • 交易侧遇到「出库了没、在途多少、仓库还剩多少」→ 转交履约/仓储 Skill;
  • 仓储侧遇到「成交金额、是否已付款、退款到账了没」→ 转交交易 Skill。

石油落地时同样对称即可:生产侧遇到试油日报/钻井/录井 → 转交工程技术;工程侧遇到井口日产/核实/措施增油 → 转交生产数据。机制相同,只是对照表里的词换成现场说法。

对照表的价值是:让模型少猜,让开发者改规则有落点。

5.3 对称铁律

两边 Skill 都要写:

  1. 不执行对方库 SQL
  2. 不用近似字段冒充(尤其禁止用「下单量」冒充「成交量」,或用「出库件数」冒充「成交件数」)
  3. 转交一句话,不讲对方算法
  4. 不把对方指标编号粘进本包 metrics

6. 回归:把「感觉不准」翻译成「改哪个文件」

6.1 最小评测闭环

题库批量提问 → 记录 SQL/用表/是否澄清/是否执行成功 → 对照期望 → 出通过率,并做错因统计。

样例题可以很土、很现场,例如:

  • 「订单 SO202401 成交金额多少」(应进交易库、带成交日期)
  • 「这个买家下过几单」(交易库用户维度,不必硬联物流表)
  • 「华东大区昨天卖了多少」(未说清下单还是成交 → 应澄清)
  • 「这批货出库了没」(交易库应转交履约,不得用订单状态硬答)

石油现场对应一组:试油日报产油、开钻完钻日期、哈得昨天产量(应澄清)、开发井口日产(工程库应转交)。

6.2 四类错因

错因 开发动作
选表错 改路由映射、适用/不适用说明
SQL 错 补字段确认、修模板、更新表结构文档
口径错 改 metrics / WHERE / JOIN(列选错、日期列用错也算)
该问没问 补澄清与跨系统对照

知识或路由变更后跑冒烟;合并前跑扩大回归。
评测脚手架可共用,题目按系统分目录,别拿生产库的题测工程库。

6.3 执行前自检(示例)

  1. Schema 前缀正确,无串库表名
  2. 订单号优先精确匹配;禁止用订单号前缀模糊冒充全量(石油里:井号精确,禁止用前缀 LIKE 冒充全油田)
  3. 列已做元数据确认(成交额 vs 累计、成交日期 vs 创建日期;石油里:日产 vs 累产、日报日期 vs 创建日期)
  4. 指标钉死条件已写入
  5. 单笔/批量明细已限流,或先走汇总表(石油里:单井日明细限流)
  6. JOIN 键正确(常见:订单表 用户ID = 用户表 用户ID;石油里:业务表 井ID = 井基础表 井ID
  7. 仅只读

失败就报失败,禁止用「分析报告」口吻补造数字。


7. 我们认的几条工程原则

  1. 分类决策交给规则,语言理解留给模型。
  2. 上下文按路径加载,不靠整包硬灌。
  3. 计算公式只保留一份原文,其它地方引用编号。
  4. 过滤规则与关联规则写到同一工程粒度(列 / ON 键)。
  5. 复制目录可以,复制业务算法不行(交易 ↔ 履约尤其如此)。
  6. 用错因分布指导迭代,而不是用「我觉得」。

仍未自动解决的事

  • 取数对了,不等于会做「销量为什么掉了」的归因分析;两套能力如何共享知识要单独设计。(石油现场:「产量为什么掉了」同理。)
  • 线上表结构变更会导致文档「沉默过期」,需要元数据对比。
  • 用户体感还包括解释是否清楚、交互是否顺,不只是 SQL 对错。

模型会继续变强,但说明书是否分层、口径是否唯一、跨库是否门禁、改完是否可测,仍然决定你的系统能不能在真实企业里活过第三个月。


附录 目录树

my-askdata-skill/
  SKILL.md
  references/
    00-meta/
      doc-boundaries.md
      id-index.md
    10-route/
      skill-routing.md
      intent-routing.md
      clarifications.md
      table-fit.md
    20-domain/
      metrics-and-exceptions.md
      scope-filters.md
      joins.md
    30-schema/
      schema-index.md
      schema-by-prefix/
      tables.json
    40-qa/
      golden-queries.md
  scripts/
    execute_sql.py
    check_config.py

写给开发者的智能问数 Skill 维护手册

分层、消歧、回归:让 Agent 说明书别变成无法合并的屎山

面向:正在用 Cursor / Agent Skill 做 NL2SQL、企业问数的开发与架构同学
(例子优先用电商/物流等通用场景,石油现场作为对照附在后面)
阅读时间:大约一刻钟

你可能已经会让模型「写出能跑的 SQL」了。
这篇文章想聊的是下一步更难受、也更值钱的事:怎么把 Skill 知识库写成可维护的工程资产——尤其当你手里不止一个业务库(比如生产数据一套、工程技术又一套),还要挂在同一个助手上时。


1. 我们真正卡住的地方,往往不是「模型会不会写 SELECT」

搭问数 Skill 的第一周通常很爽:扔进表结构,加两句约束,连上只读库,演示能出数。

难受从第二个月开始:

  • 用户随口问「这个产品卖了多少」,交易库 Skill 和履约库 Skill 都能各自查一版数,系统却答成用户不要的那一种;
  • 数据库里表和字段描述长得像,智能体检索时分不清,找错表找错字段,查出来的不是用户想要的。
  • 同一个计算公式被多处文件引用,改一处漏两处;
  • 目录拆了,链接还指着旧路径,Agent 读到两套互相打架的说明书;
  • 改完规则只能靠人工抽几问,说不清到底变好了还是变坏了。

换句话说:瓶颈从「生成 SQL」转移到了「知识怎么组织、决策怎么可调试、改完怎么验收」。

这种同词异义不是石油独有。先用大家更熟的「销量」把机制说清,再回到现场:

用户问「这个产品卖了多少」,至少可能是两回事——
下单量:购物车里点了购买、生成了订单(还没付款也可能算进去);
成交量:钱已经付清、才算真正卖掉。
听起来都是「销量」,背后却是两套统计、两张表、两套算法;答错一种,业务侧会觉得系统「胡说八道」。

石油现场也一样:「产了多少油」可能指试油阶段的折算日产(工程技术库),也可能指投产后井口日产(生产数据库)——同词异义,只是词换成了「产油」。

本文不写指标百科,只讲编写方法:目录怎么分、每层写多细、跨库怎么拦、错了怎么归因。


2. 从「能演示」到「能维护」:常见崩法

2.1 起步包长什么样

多数团队一开始只有三样东西:

  1. 表结构说明(整份或按前缀切开)
  2. 偏长的 SKILL.md
  3. 只读执行脚本

这也是我们做初版时的样子:单库、问题涉及的表不多、问法固定时,把字段备注描述清楚,就足够证明——约束写清楚,模型可以生成可用 SQL。

这段起步包我们自己踩了大约两个月:内部评测能跑通,但迟迟拿不到客户侧验证,就不知道该往哪改——没有真实反馈,迭代等于空转。工期拉长的主因不是「写不动」,而是验不了、不敢大改

2.2 复杂度上升后的五类故障

§1 那几条痛点,拆开看就是下面五类:

口径复制粘贴。
同一个「销售额」,在 metrics、WHERE 说明、样例题里写了三种算法,改一处漏两处,线上表现像随机数。

说明书自相矛盾。
被引用的文件更换地方了,入口没改,导致无法直接找到该文件;

明细当汇总。
没有「先用汇总表、明细必须限流」的硬约束,模型把全平台几百万条订单明细一把拉出来再口算加总——数据量一大,算术幻觉就来了。

多 Skill 抢答。
两个问数 Skill 同时挂着时,用户随口一句「卖了多少」「货怎么样了」,两边都能圆上,不能靠模型临场猜该进哪扇门。
常见撞车说法可以先记成对照表(写进两边的 routing):

用户随口说 Skill A(如下单/交易侧)可能指… Skill B(如发货/履约侧)可能指…
卖了多少 / 销量 下单量、成交金额 已出库件数、妥投量
货到哪了 订单物流状态字段(若交易库有镜像) 仓储发运、在途、签收
退了多少 退款金额 退货入库量
查一下这个单 / 这个货 订单号、买家信息 运单号、仓位库存

不同部门用的数据源不一致,挂的 Skill 也不是同一个,不能指望用户每次手动指定。

石油现场同理:「产了多少油」在生产库和工程技术库之间也会撞车,机制一样,只是词换成了产量/注气/措施。

没有回归语言。
团队只会说「感觉不准」,不会说「本轮失败里 30% 是选表,还是选字段失败」。

2.3 转折点

后来反馈通路打通、开始按错因改知识之后,分层架构(入口 / 路由 / 领域 / 字典 + 回归)大约半个月就从实践里定型了——比起步包那两个月短很多,因为这时候已经知道「改哪一层、用什么题验收」。

根因可以压成一句:

把本该写成说明书需要规则与分层文档的东西,全部丢给模型「临场发挥」。

模型适合理解自然语言、组织回答;对于查询数据对准确率有要求的不适合在无规则时稳定完成「进哪个系统、选哪张表、用哪个算法」这种分类题。
所以要把 Skill 当成小型后端:入口、路由、领域规则、字典、测试,各管一段。


3. Skill 内部怎么分层(写到能落 SQL)

「统一」不等于只做一个 Skill。
更稳妥的目标是:每个问数 Skill 内部工作流一致、知识分层、关键路由可追踪;生产库和工程库可以各做一个 Skill,但必须先解决「进哪扇门」即用哪个skill。

下面以电商取数为例说一层一层怎么写,石油现场对照附在括号里。

3.1 四层分工

典型文件 写到什么粒度
入口 SKILL.md 固定步骤:定 Skill → 选表 → 读口径 → 自检 → 执行;只读;不贴计算公式
路由 intent / clarifications / skill-routing 口语 → 首选表 → 见指标编号;两种理解都合理则给 A/B;若已判定属于另一套业务库,本 Skill 不查数,只告诉用户去用对应 Skill
领域规则 metrics、WHERE 说明、JOIN 说明 指标唯一写全;过滤写到列;关联写到 ON 键
字典与测试 schema 分片、golden、评测题 字段有什么;期望是什么;出现失败改哪个文件

上面表格里「去用对应 Skill」就是常说的转交,举个现场例子:

  • 用户问「昨天出库了多少」→ 当前若在交易 Skill 里,应直接说:这题归履约 Skill,请改用那个;不要用订单表的发货状态字段硬凑一个数。
  • 反过来,用户问「这单成交金额多少」→ 履约 Skill 应转给交易 Skill,不要用出库件数 × 单价硬算。

石油现场同理:在工程技术 Skill 里被问「开发井口昨天产了多少油」,应转给生产数据 Skill,别用试油日报字段硬凑。

注意:转交只要一句话指到正确 Skill;不要在转交时把对方怎么算(字段、公式)写进本包——那叫口径渗入影响后续计算查询。细节见第 5 章。

优化路由不必重写全部口径;补字段说明不必改工作流。这才叫分层,而不是「文件夹好看」。

3.2 目录示例

my-askdata-skill/
  SKILL.md
  references/
    00-meta/       # 维护公约、编号总表
    10-route/      # 跨系统边界、选表、澄清
    20-domain/     # 口径、WHERE、JOIN
    30-schema/     # 表与字段
    40-qa/         # 回归样例
  scripts/         # 脚本执行代码,或辅助工具

目录同时服务两件事:人维护时知道改哪;Agent 按需加载时知道读哪。
一次问答只应装入当前系统、当前候选表相关文档,而不是整包说明书。

3.3 系统内选表:先定库,再按映射与优先级选表

同词异义在企业取数里很常见(电商的「销量」「货到哪了」「退款」,石油的「产量」「注气」「措施」),所以我们把选表拆成两步,都落在可改的规则文档里,而不是靠模型临场猜:

  1. 先定业务库:交易还是履约(石油里是生产数据还是工程技术;写在 skill-routing;两可则澄清,已能判定属另一库则转交);
  2. 再在本库内选表:查「问题类型 → 推荐表」映射(写在 intent / table-fit);
  3. 附优先级:月度汇总类问题先走月度汇总表;单笔订单明细只用于点查、异常名单,且必须限流(石油里:油田/区块月汇总优先,单井日明细限流)。

这样做的直接好处是可追问、可改规则:「为什么选了这张表?」能指到某一行映射;选错了就改那一行,而不是调一句玄学 Prompt。

3.4 统一步骤(质量基线)

建议所有问数 Skill 共用同一套节奏:

  1. 前置检查(时间、只读、权限)
  2. 定库:生产 or 工程技术;属另一库则转交;两可则先给跨库澄清选项
  3. 按需加载本库知识
  4. 本域澄清(未说清才问):如下单/成交、当日/累计、已付/待付(石油里:试油/修井、日产/累计、设计/实钻);用户已钉死则跳过
  5. 库内选表 + 读口径 + 写 SQL + 自检
  6. 执行 + 按返回结果解释(附来源表与过滤条件)

步骤一致,评测才有共同标尺;否则 A 模块爱澄清、B 模块直接出 SQL,评分无法横向比较。定库前后两处澄清的分工,见第 5.1 节。


4. 知识怎么写:唯一源、同粒度、可引用

4.1 指标只写一处

「怎么算」的完整说明,只放在口径文档(metrics)里;入口、路由、样例题里不要再抄一遍公式,只写一行引用,例如:

M01·下单量
M02·成交量

为什么要两个编号?因为用户都说「卖了多少」,背后却是下单量和成交量两套算法(见 §1)。
若只写一个糊成一团的「销量」,改漏、答错都查不清。
所以:同名不同算法,就拆成两个编号;回答时也要说清楚本次用的是哪一个。

石油里的「产油」同理——试油阶段的折算日产、投产后的井口日产,也应是两个编号,别混称「产量」不声明。(对应电商里:下单量、成交量拆成两个编号。)

对开发同学来说,编号不是炫技,只是约定:改算法只改一处,别处靠编号找到它。

4.2 WHERE 与 JOIN 必须一样具体

类型 合格写法 不合格写法
过滤(精确) 「订单号 SO202401」→ 订单号列精确匹配;「某日成交」→ 用成交日期列 「订单号模糊匹配一下」;用创建日期冒充成交日期
过滤(范围) 「华东大区」→ 按大区/组织规则展开(写清用哪张关联表) 用订单号 LIKE 'HD%' 冒充华东全量
关联 订单表 JOIN 用户表 ON 用户ID;写清内连/左连 「订单和用户表关联一下」

再补一句给非石油同学:
订单表里往往存的是内部用户 ID,用户却说手机号——所以要先连用户表,用手机号换 ID。石油现场同理:试油日报存内部井 ID,用户说井号(如 FY210H),要先连井基础表换 ID。都是「业务表要 JOIN 维度表才能按用户嘴里的字段查」这一类工程问题。

4.3 澄清只给选项,例外只管边界

澄清:2~3 个选项,例如

  • A. 下单量(交易库,看订单表)
  • B. 成交量(交易库,看支付表)

或已经确认是交易语境,但没说清:

  • A. 看某天的成交额
  • B. 看年初至今累计

石油现场对应:A. 试油求产(工程技术库)B. 开发井口日产(生产数据库);进库后再问 A. 当天折算日产 B. 该层累计。

转交时只说「请用生产数据 / 工程技术 Skill」,不要把对方计算公式抄进本包。

4.4 表文档写「有什么」,口径文档写「怎么算」

字段列表服务于选列;计算公式服务于选算法。混在一起,改字段注释时容易误伤业务规则。
字段是否存在,以数据库元数据查询为准,不拿「中文长得像」当证据。

举个通俗例子:一张销售明细表里既有「当日销售额」,又有「年初至今累计销售额」。
用户问「昨天卖了多少」,却拿累计字段去答,数字会差得离谱——列没选错语法,但答非所问。
项目实践中石油日报里「日产油」和「累产油」并存,也是同一类坑。

4.5 新系统借鉴旧 Skill:只借壳,不借肉

把生产库 Skill 的写法搬到工程技术库时:

可以抄结构 必须重写内容
目录、步骤、自检形态、评测框架 连接配置、表映射、全部指标与 SQL 模板
编号指针写法、澄清文档形态 WHERE/JOIN 规则、回归题

自检句:删掉生产库特有的表名和算法后,工程技术包是否还能独立回答试油/钻井类问题?反过来亦然。


5. 多 Skill 并列:先关门禁,再进库选表

5.1 顺序不能反(含澄清)

完整一点应是:

问句
  → 定 Skill(交易 or 履约)
       ├─ 已能判定属另一库 → 转交,结束
       └─ 两库都像 → 先澄清(给 A/B,如:下单量 vs 成交量)
  → 进入本库后:本域澄清(用户没说清才问;已钉死则跳过)
       例如:下单还是成交?当天还是累计?已付还是待付?订单号精确还是模糊?
  → 以下接 §3.4 第 4 步起:库内选表 → 读口径 → 自检 → 执行

两处澄清不要混:

时机 问什么 举例
定库之前 进哪个 Skill A. 下单量(交易)B. 已出库件数(履约)
进库之后 本库内怎么收窄 A. 当天成交额 B. 年初至今累计;或 A. 下单 B. 退款

库都没定就生成 SQL,属于提前答题;本域条件没钉死就直接汇总,也容易答非所问。

5.2 对照表要写在 routing 里

把第 2.2 节那张对照表写进两边 Skill 的 skill-routing,并且对称

  • 交易侧遇到「出库了没、在途多少、仓库还剩多少」→ 转交履约/仓储 Skill;
  • 仓储侧遇到「成交金额、是否已付款、退款到账了没」→ 转交交易 Skill。

石油落地时同样对称即可:生产侧遇到试油日报/钻井/录井 → 转交工程技术;工程侧遇到井口日产/核实/措施增油 → 转交生产数据。机制相同,只是对照表里的词换成现场说法。

对照表的价值是:让模型少猜,让开发者改规则有落点。

5.3 对称铁律

两边 Skill 都要写:

  1. 不执行对方库 SQL
  2. 不用近似字段冒充(尤其禁止用「下单量」冒充「成交量」,或用「出库件数」冒充「成交件数」)
  3. 转交一句话,不讲对方算法
  4. 不把对方指标编号粘进本包 metrics

6. 回归:把「感觉不准」翻译成「改哪个文件」

6.1 最小评测闭环

题库批量提问 → 记录 SQL/用表/是否澄清/是否执行成功 → 对照期望 → 出通过率,并做错因统计。

样例题可以很土、很现场,例如:

  • 「订单 SO202401 成交金额多少」(应进交易库、带成交日期)
  • 「这个买家下过几单」(交易库用户维度,不必硬联物流表)
  • 「华东大区昨天卖了多少」(未说清下单还是成交 → 应澄清)
  • 「这批货出库了没」(交易库应转交履约,不得用订单状态硬答)

石油现场对应一组:试油日报产油、开钻完钻日期、哈得昨天产量(应澄清)、开发井口日产(工程库应转交)。

6.2 四类错因

错因 开发动作
选表错 改路由映射、适用/不适用说明
SQL 错 补字段确认、修模板、更新表结构文档
口径错 改 metrics / WHERE / JOIN(列选错、日期列用错也算)
该问没问 补澄清与跨系统对照

知识或路由变更后跑冒烟;合并前跑扩大回归。
评测脚手架可共用,题目按系统分目录,别拿生产库的题测工程库。

6.3 执行前自检(示例)

  1. Schema 前缀正确,无串库表名
  2. 订单号优先精确匹配;禁止用订单号前缀模糊冒充全量(石油里:井号精确,禁止用前缀 LIKE 冒充全油田)
  3. 列已做元数据确认(成交额 vs 累计、成交日期 vs 创建日期;石油里:日产 vs 累产、日报日期 vs 创建日期)
  4. 指标钉死条件已写入
  5. 单笔/批量明细已限流,或先走汇总表(石油里:单井日明细限流)
  6. JOIN 键正确(常见:订单表 用户ID = 用户表 用户ID;石油里:业务表 井ID = 井基础表 井ID
  7. 仅只读

失败就报失败,禁止用「分析报告」口吻补造数字。


7. 我们认的几条工程原则

  1. 分类决策交给规则,语言理解留给模型。
  2. 上下文按路径加载,不靠整包硬灌。
  3. 计算公式只保留一份原文,其它地方引用编号。
  4. 过滤规则与关联规则写到同一工程粒度(列 / ON 键)。
  5. 复制目录可以,复制业务算法不行(交易 ↔ 履约尤其如此)。
  6. 用错因分布指导迭代,而不是用「我觉得」。

仍未自动解决的事

  • 取数对了,不等于会做「销量为什么掉了」的归因分析;两套能力如何共享知识要单独设计。(石油现场:「产量为什么掉了」同理。)
  • 线上表结构变更会导致文档「沉默过期」,需要元数据对比。
  • 用户体感还包括解释是否清楚、交互是否顺,不只是 SQL 对错。

模型会继续变强,但说明书是否分层、口径是否唯一、跨库是否门禁、改完是否可测,仍然决定你的系统能不能在真实企业里活过第三个月。


附录 目录树

my-askdata-skill/
  SKILL.md
  references/
    00-meta/
      doc-boundaries.md
      id-index.md
    10-route/
      skill-routing.md
      intent-routing.md
      clarifications.md
      table-fit.md
    20-domain/
      metrics-and-exceptions.md
      scope-filters.md
      joins.md
    30-schema/
      schema-index.md
      schema-by-prefix/
      tables.json
    40-qa/
      golden-queries.md
  scripts/
    execute_sql.py
    check_config.py

写给开发者的智能问数 Skill 维护手册

分层、消歧、回归:让 Agent 说明书别变成无法合并的屎山

面向:正在用 Cursor / Agent Skill 做 NL2SQL、企业问数的开发与架构同学
(例子优先用电商/物流等通用场景,石油现场作为对照附在后面)
阅读时间:大约一刻钟

你可能已经会让模型「写出能跑的 SQL」了。
这篇文章想聊的是下一步更难受、也更值钱的事:怎么把 Skill 知识库写成可维护的工程资产——尤其当你手里不止一个业务库(比如生产数据一套、工程技术又一套),还要挂在同一个助手上时。


1. 我们真正卡住的地方,往往不是「模型会不会写 SELECT」

搭问数 Skill 的第一周通常很爽:扔进表结构,加两句约束,连上只读库,演示能出数。

难受从第二个月开始:

  • 用户随口问「这个产品卖了多少」,交易库 Skill 和履约库 Skill 都能各自查一版数,系统却答成用户不要的那一种;
  • 数据库里表和字段描述长得像,智能体检索时分不清,找错表找错字段,查出来的不是用户想要的。
  • 同一个计算公式被多处文件引用,改一处漏两处;
  • 目录拆了,链接还指着旧路径,Agent 读到两套互相打架的说明书;
  • 改完规则只能靠人工抽几问,说不清到底变好了还是变坏了。

换句话说:瓶颈从「生成 SQL」转移到了「知识怎么组织、决策怎么可调试、改完怎么验收」。

这种同词异义不是石油独有。先用大家更熟的「销量」把机制说清,再回到现场:

用户问「这个产品卖了多少」,至少可能是两回事——
下单量:购物车里点了购买、生成了订单(还没付款也可能算进去);
成交量:钱已经付清、才算真正卖掉。
听起来都是「销量」,背后却是两套统计、两张表、两套算法;答错一种,业务侧会觉得系统「胡说八道」。

石油现场也一样:「产了多少油」可能指试油阶段的折算日产(工程技术库),也可能指投产后井口日产(生产数据库)——同词异义,只是词换成了「产油」。

本文不写指标百科,只讲编写方法:目录怎么分、每层写多细、跨库怎么拦、错了怎么归因。


2. 从「能演示」到「能维护」:常见崩法

2.1 起步包长什么样

多数团队一开始只有三样东西:

  1. 表结构说明(整份或按前缀切开)
  2. 偏长的 SKILL.md
  3. 只读执行脚本

这也是我们做初版时的样子:单库、问题涉及的表不多、问法固定时,把字段备注描述清楚,就足够证明——约束写清楚,模型可以生成可用 SQL。

这段起步包我们自己踩了大约两个月:内部评测能跑通,但迟迟拿不到客户侧验证,就不知道该往哪改——没有真实反馈,迭代等于空转。工期拉长的主因不是「写不动」,而是验不了、不敢大改

2.2 复杂度上升后的五类故障

§1 那几条痛点,拆开看就是下面五类:

口径复制粘贴。
同一个「销售额」,在 metrics、WHERE 说明、样例题里写了三种算法,改一处漏两处,线上表现像随机数。

说明书自相矛盾。
被引用的文件更换地方了,入口没改,导致无法直接找到该文件;

明细当汇总。
没有「先用汇总表、明细必须限流」的硬约束,模型把全平台几百万条订单明细一把拉出来再口算加总——数据量一大,算术幻觉就来了。

多 Skill 抢答。
两个问数 Skill 同时挂着时,用户随口一句「卖了多少」「货怎么样了」,两边都能圆上,不能靠模型临场猜该进哪扇门。
常见撞车说法可以先记成对照表(写进两边的 routing):

用户随口说 Skill A(如下单/交易侧)可能指… Skill B(如发货/履约侧)可能指…
卖了多少 / 销量 下单量、成交金额 已出库件数、妥投量
货到哪了 订单物流状态字段(若交易库有镜像) 仓储发运、在途、签收
退了多少 退款金额 退货入库量
查一下这个单 / 这个货 订单号、买家信息 运单号、仓位库存

不同部门用的数据源不一致,挂的 Skill 也不是同一个,不能指望用户每次手动指定。

石油现场同理:「产了多少油」在生产库和工程技术库之间也会撞车,机制一样,只是词换成了产量/注气/措施。

没有回归语言。
团队只会说「感觉不准」,不会说「本轮失败里 30% 是选表,还是选字段失败」。

2.3 转折点

后来反馈通路打通、开始按错因改知识之后,分层架构(入口 / 路由 / 领域 / 字典 + 回归)大约半个月就从实践里定型了——比起步包那两个月短很多,因为这时候已经知道「改哪一层、用什么题验收」。

根因可以压成一句:

把本该写成说明书需要规则与分层文档的东西,全部丢给模型「临场发挥」。

模型适合理解自然语言、组织回答;对于查询数据对准确率有要求的不适合在无规则时稳定完成「进哪个系统、选哪张表、用哪个算法」这种分类题。
所以要把 Skill 当成小型后端:入口、路由、领域规则、字典、测试,各管一段。


3. Skill 内部怎么分层(写到能落 SQL)

「统一」不等于只做一个 Skill。
更稳妥的目标是:每个问数 Skill 内部工作流一致、知识分层、关键路由可追踪;生产库和工程库可以各做一个 Skill,但必须先解决「进哪扇门」即用哪个skill。

下面以电商取数为例说一层一层怎么写,石油现场对照附在括号里。

3.1 四层分工

典型文件 写到什么粒度
入口 SKILL.md 固定步骤:定 Skill → 选表 → 读口径 → 自检 → 执行;只读;不贴计算公式
路由 intent / clarifications / skill-routing 口语 → 首选表 → 见指标编号;两种理解都合理则给 A/B;若已判定属于另一套业务库,本 Skill 不查数,只告诉用户去用对应 Skill
领域规则 metrics、WHERE 说明、JOIN 说明 指标唯一写全;过滤写到列;关联写到 ON 键
字典与测试 schema 分片、golden、评测题 字段有什么;期望是什么;出现失败改哪个文件

上面表格里「去用对应 Skill」就是常说的转交,举个现场例子:

  • 用户问「昨天出库了多少」→ 当前若在交易 Skill 里,应直接说:这题归履约 Skill,请改用那个;不要用订单表的发货状态字段硬凑一个数。
  • 反过来,用户问「这单成交金额多少」→ 履约 Skill 应转给交易 Skill,不要用出库件数 × 单价硬算。

石油现场同理:在工程技术 Skill 里被问「开发井口昨天产了多少油」,应转给生产数据 Skill,别用试油日报字段硬凑。

注意:转交只要一句话指到正确 Skill;不要在转交时把对方怎么算(字段、公式)写进本包——那叫口径渗入影响后续计算查询。细节见第 5 章。

优化路由不必重写全部口径;补字段说明不必改工作流。这才叫分层,而不是「文件夹好看」。

3.2 目录示例

my-askdata-skill/
  SKILL.md
  references/
    00-meta/       # 维护公约、编号总表
    10-route/      # 跨系统边界、选表、澄清
    20-domain/     # 口径、WHERE、JOIN
    30-schema/     # 表与字段
    40-qa/         # 回归样例
  scripts/         # 脚本执行代码,或辅助工具

目录同时服务两件事:人维护时知道改哪;Agent 按需加载时知道读哪。
一次问答只应装入当前系统、当前候选表相关文档,而不是整包说明书。

3.3 系统内选表:先定库,再按映射与优先级选表

同词异义在企业取数里很常见(电商的「销量」「货到哪了」「退款」,石油的「产量」「注气」「措施」),所以我们把选表拆成两步,都落在可改的规则文档里,而不是靠模型临场猜:

  1. 先定业务库:交易还是履约(石油里是生产数据还是工程技术;写在 skill-routing;两可则澄清,已能判定属另一库则转交);
  2. 再在本库内选表:查「问题类型 → 推荐表」映射(写在 intent / table-fit);
  3. 附优先级:月度汇总类问题先走月度汇总表;单笔订单明细只用于点查、异常名单,且必须限流(石油里:油田/区块月汇总优先,单井日明细限流)。

这样做的直接好处是可追问、可改规则:「为什么选了这张表?」能指到某一行映射;选错了就改那一行,而不是调一句玄学 Prompt。

3.4 统一步骤(质量基线)

建议所有问数 Skill 共用同一套节奏:

  1. 前置检查(时间、只读、权限)
  2. 定库:生产 or 工程技术;属另一库则转交;两可则先给跨库澄清选项
  3. 按需加载本库知识
  4. 本域澄清(未说清才问):如下单/成交、当日/累计、已付/待付(石油里:试油/修井、日产/累计、设计/实钻);用户已钉死则跳过
  5. 库内选表 + 读口径 + 写 SQL + 自检
  6. 执行 + 按返回结果解释(附来源表与过滤条件)

步骤一致,评测才有共同标尺;否则 A 模块爱澄清、B 模块直接出 SQL,评分无法横向比较。定库前后两处澄清的分工,见第 5.1 节。


4. 知识怎么写:唯一源、同粒度、可引用

4.1 指标只写一处

「怎么算」的完整说明,只放在口径文档(metrics)里;入口、路由、样例题里不要再抄一遍公式,只写一行引用,例如:

M01·下单量
M02·成交量

为什么要两个编号?因为用户都说「卖了多少」,背后却是下单量和成交量两套算法(见 §1)。
若只写一个糊成一团的「销量」,改漏、答错都查不清。
所以:同名不同算法,就拆成两个编号;回答时也要说清楚本次用的是哪一个。

石油里的「产油」同理——试油阶段的折算日产、投产后的井口日产,也应是两个编号,别混称「产量」不声明。(对应电商里:下单量、成交量拆成两个编号。)

对开发同学来说,编号不是炫技,只是约定:改算法只改一处,别处靠编号找到它。

4.2 WHERE 与 JOIN 必须一样具体

类型 合格写法 不合格写法
过滤(精确) 「订单号 SO202401」→ 订单号列精确匹配;「某日成交」→ 用成交日期列 「订单号模糊匹配一下」;用创建日期冒充成交日期
过滤(范围) 「华东大区」→ 按大区/组织规则展开(写清用哪张关联表) 用订单号 LIKE 'HD%' 冒充华东全量
关联 订单表 JOIN 用户表 ON 用户ID;写清内连/左连 「订单和用户表关联一下」

再补一句给非石油同学:
订单表里往往存的是内部用户 ID,用户却说手机号——所以要先连用户表,用手机号换 ID。石油现场同理:试油日报存内部井 ID,用户说井号(如 FY210H),要先连井基础表换 ID。都是「业务表要 JOIN 维度表才能按用户嘴里的字段查」这一类工程问题。

4.3 澄清只给选项,例外只管边界

澄清:2~3 个选项,例如

  • A. 下单量(交易库,看订单表)
  • B. 成交量(交易库,看支付表)

或已经确认是交易语境,但没说清:

  • A. 看某天的成交额
  • B. 看年初至今累计

石油现场对应:A. 试油求产(工程技术库)B. 开发井口日产(生产数据库);进库后再问 A. 当天折算日产 B. 该层累计。

转交时只说「请用生产数据 / 工程技术 Skill」,不要把对方计算公式抄进本包。

4.4 表文档写「有什么」,口径文档写「怎么算」

字段列表服务于选列;计算公式服务于选算法。混在一起,改字段注释时容易误伤业务规则。
字段是否存在,以数据库元数据查询为准,不拿「中文长得像」当证据。

举个通俗例子:一张销售明细表里既有「当日销售额」,又有「年初至今累计销售额」。
用户问「昨天卖了多少」,却拿累计字段去答,数字会差得离谱——列没选错语法,但答非所问。
项目实践中石油日报里「日产油」和「累产油」并存,也是同一类坑。

4.5 新系统借鉴旧 Skill:只借壳,不借肉

把生产库 Skill 的写法搬到工程技术库时:

可以抄结构 必须重写内容
目录、步骤、自检形态、评测框架 连接配置、表映射、全部指标与 SQL 模板
编号指针写法、澄清文档形态 WHERE/JOIN 规则、回归题

自检句:删掉生产库特有的表名和算法后,工程技术包是否还能独立回答试油/钻井类问题?反过来亦然。


5. 多 Skill 并列:先关门禁,再进库选表

5.1 顺序不能反(含澄清)

完整一点应是:

问句
  → 定 Skill(交易 or 履约)
       ├─ 已能判定属另一库 → 转交,结束
       └─ 两库都像 → 先澄清(给 A/B,如:下单量 vs 成交量)
  → 进入本库后:本域澄清(用户没说清才问;已钉死则跳过)
       例如:下单还是成交?当天还是累计?已付还是待付?订单号精确还是模糊?
  → 以下接 §3.4 第 4 步起:库内选表 → 读口径 → 自检 → 执行

两处澄清不要混:

时机 问什么 举例
定库之前 进哪个 Skill A. 下单量(交易)B. 已出库件数(履约)
进库之后 本库内怎么收窄 A. 当天成交额 B. 年初至今累计;或 A. 下单 B. 退款

库都没定就生成 SQL,属于提前答题;本域条件没钉死就直接汇总,也容易答非所问。

5.2 对照表要写在 routing 里

把第 2.2 节那张对照表写进两边 Skill 的 skill-routing,并且对称

  • 交易侧遇到「出库了没、在途多少、仓库还剩多少」→ 转交履约/仓储 Skill;
  • 仓储侧遇到「成交金额、是否已付款、退款到账了没」→ 转交交易 Skill。

石油落地时同样对称即可:生产侧遇到试油日报/钻井/录井 → 转交工程技术;工程侧遇到井口日产/核实/措施增油 → 转交生产数据。机制相同,只是对照表里的词换成现场说法。

对照表的价值是:让模型少猜,让开发者改规则有落点。

5.3 对称铁律

两边 Skill 都要写:

  1. 不执行对方库 SQL
  2. 不用近似字段冒充(尤其禁止用「下单量」冒充「成交量」,或用「出库件数」冒充「成交件数」)
  3. 转交一句话,不讲对方算法
  4. 不把对方指标编号粘进本包 metrics

6. 回归:把「感觉不准」翻译成「改哪个文件」

6.1 最小评测闭环

题库批量提问 → 记录 SQL/用表/是否澄清/是否执行成功 → 对照期望 → 出通过率,并做错因统计。

样例题可以很土、很现场,例如:

  • 「订单 SO202401 成交金额多少」(应进交易库、带成交日期)
  • 「这个买家下过几单」(交易库用户维度,不必硬联物流表)
  • 「华东大区昨天卖了多少」(未说清下单还是成交 → 应澄清)
  • 「这批货出库了没」(交易库应转交履约,不得用订单状态硬答)

石油现场对应一组:试油日报产油、开钻完钻日期、哈得昨天产量(应澄清)、开发井口日产(工程库应转交)。

6.2 四类错因

错因 开发动作
选表错 改路由映射、适用/不适用说明
SQL 错 补字段确认、修模板、更新表结构文档
口径错 改 metrics / WHERE / JOIN(列选错、日期列用错也算)
该问没问 补澄清与跨系统对照

知识或路由变更后跑冒烟;合并前跑扩大回归。
评测脚手架可共用,题目按系统分目录,别拿生产库的题测工程库。

6.3 执行前自检(示例)

  1. Schema 前缀正确,无串库表名
  2. 订单号优先精确匹配;禁止用订单号前缀模糊冒充全量(石油里:井号精确,禁止用前缀 LIKE 冒充全油田)
  3. 列已做元数据确认(成交额 vs 累计、成交日期 vs 创建日期;石油里:日产 vs 累产、日报日期 vs 创建日期)
  4. 指标钉死条件已写入
  5. 单笔/批量明细已限流,或先走汇总表(石油里:单井日明细限流)
  6. JOIN 键正确(常见:订单表 用户ID = 用户表 用户ID;石油里:业务表 井ID = 井基础表 井ID
  7. 仅只读

失败就报失败,禁止用「分析报告」口吻补造数字。


7. 我们认的几条工程原则

  1. 分类决策交给规则,语言理解留给模型。
  2. 上下文按路径加载,不靠整包硬灌。
  3. 计算公式只保留一份原文,其它地方引用编号。
  4. 过滤规则与关联规则写到同一工程粒度(列 / ON 键)。
  5. 复制目录可以,复制业务算法不行(交易 ↔ 履约尤其如此)。
  6. 用错因分布指导迭代,而不是用「我觉得」。

仍未自动解决的事

  • 取数对了,不等于会做「销量为什么掉了」的归因分析;两套能力如何共享知识要单独设计。(石油现场:「产量为什么掉了」同理。)
  • 线上表结构变更会导致文档「沉默过期」,需要元数据对比。
  • 用户体感还包括解释是否清楚、交互是否顺,不只是 SQL 对错。

模型会继续变强,但说明书是否分层、口径是否唯一、跨库是否门禁、改完是否可测,仍然决定你的系统能不能在真实企业里活过第三个月。


附录 目录树

my-askdata-skill/
  SKILL.md
  references/
    00-meta/
      doc-boundaries.md
      id-index.md
    10-route/
      skill-routing.md
      intent-routing.md
      clarifications.md
      table-fit.md
    20-domain/
      metrics-and-exceptions.md
      scope-filters.md
      joins.md
    30-schema/
      schema-index.md
      schema-by-prefix/
      tables.json
    40-qa/
      golden-queries.md
  scripts/
    execute_sql.py
    check_config.py

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐