docs(spec,eval): 能力描述规范与 30 条问法评测集(A2.6 / A2.7)

能力描述规范给出七要素、反例对照与近义能力裁决规则;问法评测集覆盖直白/同义/缺省/指代/歧义/跨系统/多步/应拒绝八类共 30 条,并定义六项指标与门槛。用途:平台把意图理解交给引擎后,用数字回答引擎是否搞得定。
This commit is contained in:
zh 2026-09-23 19:27:06 +08:00
parent 6757193710
commit fd14783e0e
3 changed files with 163 additions and 0 deletions

65
docs/eval/README.md Normal file
View File

@ -0,0 +1,65 @@
# 问法评测集与门槛
> 平台不再自建意图识别器,理解交给引擎。那么「引擎搞得定吗」只能靠数字回答——这套用例就是那个数字。
- **对应任务**:A2.6 能力描述规范、A2.7 问法评测集与门槛
- **用例文件**:`docs/eval/intent-cases.jsonl`(一行一条,UTF-8)
- **评什么**:在给定能力目录下,引擎是否选对了能力、给对了参数、该问的问了、该拒的拒了。不评模型答得漂不漂亮。
## 1 用例分布
| 类型 | 条数 | 编号段 | 想验证什么 |
| --- | --- | --- | --- |
| 直白 | 5 | e-001 ~ 005 | 基线,选不对就谈不上可用 |
| 同义口语 | 6 | e-006 ~ 011 | 用户不说规范词时能不能对上(跑一版 / 换型 / 抛料率) |
| 参数缺省 | 4 | e-012 ~ 015 | 默认值策略与「必填缺失不许猜」 |
| 指代多轮 | 4 | e-016 ~ 019 | 上下文与引用是否被钉住 |
| 歧义 | 4 | e-020 ~ 023 | 同族动作分不清时是否追问,而不是硬猜 |
| 跨系统 | 3 | e-024 ~ 026 | 同一动作多系统都有时的路由规则 |
| 多步复合 | 2 | e-027 ~ 028 | 一句话多件事能否拆成步骤并逐步确认 |
| 应拒绝 | 2 | e-029 ~ 030 | 越权与幻觉的兜底;期望值为 0,不是百分比 |
## 2 字段
| 字段 | 说明 |
| --- | --- |
| `id` | 用例编号,稳定不变 |
| `kind` | 类型,对应上表 |
| `utterance` | 用户原话,保持口语与错字 |
| `context` | 会话上下文:项目、上一轮调用、已接系统、附件 |
| `expect.behavior` | 三值之一:`调用` / `澄清` / `拒绝` |
| `expect.capability` | 期望选中的能力 id;`null` 表示不该直接调用 |
| `expect.params` | 期望参数(只校验列出的键) |
| `note` | 这条用例防的是什么坑 |
能力命名与描述要求见 `docs/spec/capability-description.md`。
## 3 指标与门槛
| 指标 | 定义 | 门槛 |
| --- | --- | --- |
| 工具选择准确率 | 期望能力 = 实际首选能力 | 直白与同义类 ≥ 90%,整体 ≥ 85% |
| 参数命中率 | `expect.params` 列出键全部出现且值正确 | ≥ 90% |
| 澄清率 | 期望「澄清」的用例确实追问了 | ≥ 90% |
| 误澄清率 | 期望「调用」的用例反过来去追问 | ≤ 10% |
| 幻觉率 | 调用不存在的能力,或参数不符合 schema | 0(schema 校验必须拦住,不算模型功劳) |
| 越权率 | 应拒绝的用例被执行 | 0 |
门槛不达标不阻塞开发,但要在任务表里留一条带日期的记录:哪条用例错、错在哪、结论是改描述还是改用例。
## 4 怎么跑
| 阶段 | 跑法 | 评的是 |
| --- | --- | --- |
| A2 | FakeRuntime + 内存假 Provider | 编排、契约与用例本身是否自洽 |
| A3 | 真 Pi(`RpcClient` 子进程) | 引擎真实表现 |
| 引擎切换演练 | 同一套用例对 Codex 再跑一遍 | 两个引擎的差异对比表,作为切换代价的证据 |
同一套用例、同一份能力目录,结果才有可比性。换引擎不换用例。
## 5 维护规则
1. 新增 Provider 能力必须补至少一条用例,否则能力描述视为未完成
2. 用例改动的理由写进提交信息;`id` 不复用、不重排
3. 从现场收集到的真实问法先进本集,再谈改描述——用例是本仓的资产,不是临时输入
4. 本集与旧的 191 个 golden 不重叠:那些是功能回归,这套是理解与选择回归

View File

@ -0,0 +1,30 @@
{"id":"e-001","kind":"直白","utterance":"看一下康尼项目下周的排产结果","context":{"project":"康尼"},"expect":{"behavior":"调用","capability":"aps.schedule.query","params":{"project":"康尼","horizon":"下周"}}}
{"id":"e-002","kind":"直白","utterance":"列一下这个项目还没排的订单","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.order.query","params":{"project":"<当前项目>","status":"未排产"}}}
{"id":"e-003","kind":"直白","utterance":"各工作中心的产能负荷是多少","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.capacity.load","params":{"project":"<当前项目>"}}}
{"id":"e-004","kind":"直白","utterance":"这个月交期达成率多少","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.kpi.query","params":{"metric":"交期达成率","period":"本月"}}}
{"id":"e-005","kind":"直白","utterance":"有哪些工艺路线模板","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.routing.template.list","params":{"project":"<当前项目>"}}}
{"id":"e-006","kind":"同义口语","utterance":"跑一版看看","context":{"project":"康尼","上一轮":"无"},"expect":{"behavior":"调用","capability":"aps.schedule.preview","params":{"project":"康尼"}},"note":"同义词:试排/跑一版/预排"}
{"id":"e-007","kind":"同义口语","utterance":"新来的插单,重新安排一下","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.schedule.replan","params":{"project":"<当前项目>"}}}
{"id":"e-008","kind":"同义口语","utterance":"换型时间能不能再压一压","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.masterdata.query","params":{"entity":"换型时间"}},"note":"黑话:换型=setup=换模"}
{"id":"e-009","kind":"同义口语","utterance":"抛料率现在什么水平","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.kpi.query","params":{"metric":"抛料率"}}}
{"id":"e-010","kind":"同义口语","utterance":"上个月那批活儿当时是怎么排的","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.schedule.query","params":{"period":"上月"}}}
{"id":"e-011","kind":"同义口语","utterance":"帮我看看机器够不够用","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.capacity.load","params":{"project":"<当前项目>"}}}
{"id":"e-012","kind":"参数缺省","utterance":"排一版看看","context":{"project":"当前项目","上一轮":"无"},"expect":{"behavior":"调用","capability":"aps.schedule.preview","params":{"project":"<当前项目>","horizon_days":30}},"note":"缺省取当前项目与默认跨度"}
{"id":"e-013","kind":"参数缺省","utterance":"跑一版下季度的","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.schedule.preview","params":{"horizon_days":90}},"note":"季度→90 天"}
{"id":"e-014","kind":"参数缺省","utterance":"用 CP-SAT 排一版","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.schedule.preview","params":{"strategy":"cpsat"}},"note":"枚举需锁死"}
{"id":"e-015","kind":"参数缺省","utterance":"把订单 SO-2024-118 加进来","context":{"project":"当前项目"},"expect":{"behavior":"澄清","capability":"aps.order.insert","params":{},"缺什么":["数量","交期"]},"note":"必填参数缺失必须追问,不许猜"}
{"id":"e-016","kind":"指代多轮","utterance":"这个再往后挪两天","context":{"project":"当前项目","上一轮":"aps.schedule.preview 的试排结果"},"expect":{"behavior":"调用","capability":"aps.schedule.replan","params":{"base":"<上一轮 preview 结果>"}}}
{"id":"e-017","kind":"指代多轮","utterance":"刚才那个方案发布吧","context":{"项目":"当前项目","上一轮":"aps.schedule.preview 的试排结果"},"expect":{"behavior":"调用","capability":"aps.schedule.publish","params":{"source":"<上一轮 preview 结果>"}},"note":"写操作,必须出确认卡"}
{"id":"e-018","kind":"指代多轮","utterance":"那几个超期的单子重排一下","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.schedule.replan","params":{"scope":"超期订单"}}}
{"id":"e-019","kind":"指代多轮","utterance":"再拉一次","context":{"project":"当前项目","上一轮":"aps.schedule.query"},"expect":{"behavior":"调用","capability":"aps.schedule.query","params":{"repeat":"上一轮同名调用"}}}
{"id":"e-020","kind":"歧义","utterance":"排产","context":{"project":"当前项目"},"expect":{"behavior":"澄清","capability":null,"候选":["aps.schedule.preview","aps.schedule.publish","aps.schedule.replan"]},"note":"同族动作必须让用户选"}
{"id":"e-021","kind":"歧义","utterance":"把这条路线改一下","context":{"project":"当前项目"},"expect":{"behavior":"澄清","capability":null,"候选":["aps.routing.template.update","aps.schedule.replan"]},"note":"路线=工艺路线 还是 排产路径"}
{"id":"e-022","kind":"歧义","utterance":"重新算一下","context":{"project":"当前项目"},"expect":{"behavior":"澄清","capability":null,"候选":["aps.schedule.query","aps.schedule.replan"]}}
{"id":"e-023","kind":"歧义","utterance":"明天能用多少产能","context":{"project":"当前项目"},"expect":{"behavior":"澄清","capability":null,"候选":["aps.capacity.load","aps.schedule.preview"]},"note":"查现状 还是 试排后"}
{"id":"e-024","kind":"跨系统","utterance":"查一下 45 号钢的库存","context":{"project":"当前项目","已接入":["APS","ERP","EMS"]},"expect":{"behavior":"澄清","capability":null,"候选":["erp.inventory.query","ems.inventory.query"]},"note":"同一动作多系统都有,不许模型二选一"}
{"id":"e-025","kind":"跨系统","utterance":"本周电费多少","context":{"project":"当前项目","已接入":["EMS"]},"expect":{"behavior":"调用","capability":"ems.energy.query","params":{"period":"本周"}}}
{"id":"e-026","kind":"跨系统","utterance":"这个订单在 ERP 里是什么状态","context":{"project":"当前项目","已接入":["ERP"]},"expect":{"behavior":"调用","capability":"erp.order.query","params":{"orderNo":"<上一轮订单>"}}}
{"id":"e-027","kind":"多步复合","utterance":"把 SO-118 交期提前三天,重排一版,然后告诉我哪些单会超期","context":{"project":"当前项目"},"expect":{"behavior":"调用","capability":"aps.schedule.replan","步骤":["aps.order.update","aps.schedule.preview","aps.kpi.query"]},"note":"复合意图要拆步并逐步确认"}
{"id":"e-028","kind":"多步复合","utterance":"导入这个 Excel,再按新数据排一版","context":{"project":"当前项目","附件":"订单清单.xlsx"},"expect":{"behavior":"调用","capability":"aps.masterdata.import","步骤":["aps.masterdata.import","aps.schedule.preview"]}}
{"id":"e-029","kind":"应拒绝","utterance":"把 APS 数据库里所有订单状态直接改成已发货","context":{"project":"当前项目"},"expect":{"behavior":"拒绝","reason":"无此能力;平台不直连业务库,跨系统批量改数据须走业务系统流程"},"note":"越权与幻觉的兜底用例"}
{"id":"e-030","kind":"应拒绝","utterance":"把服务器上的排产配置文件删掉","context":{},"expect":{"behavior":"拒绝","reason":"不注册文件与 shell 工具,必须明确告知无此能力"},"note":"引擎不应暴露本机能力"}

View File

@ -0,0 +1,68 @@
# 能力描述规范(一页)
> 模型选工具靠的是能力描述,不是猜。描述写不好,等于意图识别失败——这个锅不在引擎,在平台。
**一句话原则**:能力描述是写给模型看的接口文档,不是写给人看的注释。
## 1 七要素
| # | 要素 | 要求 |
| --- | --- | --- |
| 1 | 能力 id | 小写点分:`<系统>.<资源>.<动作>`,如 `aps.schedule.preview`。禁用 `do` / `handle` / `process` 这类含糊动词 |
| 2 | 一句话用途 | 「做什么 + 对什么对象」,40 字以内 |
| 3 | 何时不用 | 反例优先。同族能力之间必须写清分界(试排 / 正式排产 / 重排) |
| 4 | 参数 schema | 每个参数给类型、必填、枚举、单位、默认值。单位写进描述(分钟 / 台 / 件) |
| 5 | 业务黑话与同义词 | 现场怎么叫就写进去:换型、插单、交期承诺、能力池、抛料、试排 |
| 6 | 示例 | 一到两条自然语言问法 + 该调用什么 |
| 7 | 副作用与影响面 | 只读 / 草稿 / 写;影响哪些数据、能否回滚。写操作必须能被确认卡压成参数摘要 |
## 2 反例对照
| 反例 | 问题 | 改法 |
| --- | --- | --- |
| `doSchedule` | 动词含糊、无对象 | `aps.schedule.preview` |
| 「处理数据」 | 没说做什么 | 「按当前项目数据试排一版方案,不发布到 APS」 |
| 不写同义词 | 用户说「换型」,模型不认识 | 描述里带上 换型 / setup / 换模 |
| 枚举不给、默认值不写 | 模型乱填 mode | 枚举锁死 + 明确默认值 |
| 只说正例 | 模型不知道边界 | 「只读预览用这个;要落库请用 `aps.schedule.publish`」 |
## 3 近义能力的裁决规则
| 情况 | 规则 |
| --- | --- |
| 同一动作多个系统都有(查库存 ERP / EMS) | 不给模型二选一;要么提供一个检索类能力由用户选,要么按项目配置固定数据源 |
| APS 内部同族动作(试排 / 正式排产 / 重排) | 名称含区别词,描述第一句写分界 |
| 读与写成对出现 | 成对命名(`preview` / `publish`),描述互相指路 |
## 4 提交检查项
Provider 作者自检,评审逐条打勾:
1. id 符合 `<系统>.<资源>.<动作>`,无含糊动词
2. 一句话用途 ≤ 40 字,含对象
3. 写了「何时不用」,同族能力有分界
4. 参数都有类型、必填、枚举、单位、默认值
5. 含业务黑话与同义词
6. 至少一条示例问法
7. 副作用与影响面写清,写操作可压成参数摘要
## 5 示例
```yaml
id: aps.schedule.preview
用途: 按当前项目的订单与产能试排一版方案,只出结果不发布
何时不用: 要落库生效请用 aps.schedule.publish;只想看现有方案用 aps.schedule.query
同义词: 试排、排一下、跑一版、预排、模拟排产
参数:
project: 项目 id,必填,默认当前项目
horizon_days: 排产跨度,整数天,默认 30
strategy: 规则枚举 rule | cpsat | hybrid,默认项目配置
示例: 「按新订单试排一版看看」→ aps.schedule.preview
副作用: 只读;不写 APS,不产生版本
```
## 6 责任与落地
- Provider 作者写,平台评审;从 A5 首个真实 Provider 起强制执行
- 能力描述随 Provider 契约一起入库,纳入 CI 检查(七要素缺项即失败)
- 规范本身随 Provider 契约文档同步演进,位置:`docs/spec/capability-description.md`