Files
UHD_Media_Tool/docs/design/agent-prompt-eval.md
T
rootandClaude Opus 5.5 b61335eaf6 test: 测试按行为命名、server 测试统一到 test/、PG 测试分组并行
- server 的 src/modules/*/__tests__ 挪到 test/<模块>/;e2e 去掉 eN- 前缀,
  w5a2 / v2 / search2 / *-dh1 / *-md1 / *-md2、web 的 agui3 / search2、domain 的 id2 / id3 改为按行为命名
- vitest 分三组:unit、pg(真实 PG + 假引擎,文件并行,最多 6 个)、serial(真实引擎 / worker / e2e,串行);
  pg 组用例超时放宽到 60s(迁移类用例并行时排队等 schema 锁)。server 测试 615s → 约 350s
- CLAUDE.md 补测试约定;待办补 harness 去重与 continuous-series 偶发超时(疑似 Slot 评估竞争)
- ADR-004 补充:维持 Deno,记录实际只用到 --allow-run 白名单

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 16:54:04 +08:00

69 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AG-5 智能体提示评测:前后对比
对照样本:`docs/design/agent-report-sample-bad.md`(用户 2026-09-30 贴的反例与期望样子)。实现与跑法见 `docs/runbook/agent.md`「提示分层与 Skill」。
- **前**:main(0023872)的 `packages/agent/src/system-prompt.ts`,一段 15 条"必须遵守" + 6 条汇报格式 + 工作方式 + 约束里一行"可用能力:…"。
- **后**:分层提示(角色与边界 / 当前环境 / 能力地图 / Skill / 行为规则 / 汇报格式 / 本次目标)+ 6 个 Skill + 新能力 `download.list`。
## 1. 反例的问题逐条对应
| 反例里的问题 | 前:提示里有什么 | 后:改了什么 |
|---|---|---|
| 不知道有下载器,汇报"系统里没有它们的登记对象" | 一条规则"下载器…用 downloader.list 查;站点列表里没有下载器不代表没配置",混在 15 条里 | 「当前环境」层直接写出"下载器 1 个:「家里的 qB」qBittorrent,正常(刚刚),本工具管理 3 个任务…""媒体服务器:还没有接入",并说明"还没有接入就是真的没有";能力地图第一条路线就是"问下载器、媒体服务器、站点是否正常:downloader.list → site.list → site.user_data → site.health_check(需要批准)";「巡检」Skill 第 1–2 步 |
| 要用户给下载任务 ID / 种子 hash | 没有能列下载任务的能力,只有 `download.inspect {id|hash}` | 新增只读能力 `download.list`;能力地图"问下载 → download.list → download.inspect",提示"不要向用户要 ID 或种子 hash";行为规则"自己能查的不问用户" |
| 原始字节数 `upload 17008345370067` | 汇报格式没提单位 | 汇报格式"大小写成 GB / TB,时间写相对时间;不写原始字节数和 ISO 时间";`download.list` 输出直接给 "18.6 GB""63%""3 小时前";环境层也全是人话 |
| 表格列 ID / adapter | "不写函数名、工具名、字段名、参数、UUID 或 hash" | 加上 adapter、英文状态码;表格"只放名称和用户关心的 2–3 列" |
| "无证据不等于故障"式说教 | 无 | 行为规则"不说教",点名这句 |
| 授权缺失写成一段 | "工具返回 unauthorized 时如实报告缺少哪项授权" + 约束"被拒时说明缺少哪项授权"——等于鼓励展开 | "只写一句「没做:<动作>,需要你批准」,界面会给批准按钮;不解释授权机制";Skill 的「需要批准」节给出每个动作的一句话写法 |
| 结论"无法确认"、开头"检查结果",整体太长 | "第一句写结论";"不超过 10 行" | "第一句就是结论…不写「检查结果」「结论:」「以下是…」这类开头";≤8 行;异常放前、正常合并一句;每个 Skill 带期望汇报模板(巡检模板就是用户给的期望样子) |
## 2. 提示体积
同一套能力(不含浏览器 / 网页搜索 / 子会话)、三条提示,字符数:
| 提示 | 前 | 后 | 载入的 Skill |
|---|---|---|---|
| 检查站点、下载器和媒体服务器是否正常 | 2057 | 5516 | 巡检 |
| 把《沙丘 2》4K 收进来 | 2052 | 5336 | 收录一部作品 |
| 为什么沙丘2没入库 | 2048 | 5400 | 入库 / 整理问题排查 |
后者多约 3.4k 字符(中文约 2k token),主要是一个 Skill 全文(约 1.5–2k 字符)和环境层。每次只载入命中的 1–2 个 Skill,其余只列一行索引;前者约束里那行"可用能力:(30 多个能力名)"去掉了(工具定义里已有)。
## 3. fake 模型评测(e16,CI)
`apps/server/test/e2e/agent-prompt-eval.test.ts`,测试库数据仿反例现场:下载器「家里的 qB」(mock qB,3 个任务:下载中 / 文件缺失 / 已入库做种)、站点「憨憨」(上次检查正常,账号带原始用户数据)、没有媒体服务器、《沙丘2》(追更中订阅 + 1080p / 2160p 两个收录版本、一条 2160p 资源)、4 条已取消订阅、1 条待处理。
| # | 提示 | 载入的 Skill | 能力调用顺序 | 结果 |
|---|---|---|---|---|
| 1 | 检查站点、下载器和媒体服务器是否正常 | 巡检 | downloader.list → site.list → site.health_check(被拒)→ decision.list | 通过 |
| 2 | 把《沙丘 2》4K 收进来 | 收录一部作品 | catalog.lookup → inventory.query → download.list → release.search → download.plan → download.submit(被拒) | 通过 |
| 3 | 为什么沙丘2没入库 | 入库 / 整理问题排查 | inventory.query → download.list → download.inspect(ID 来自上一步) | 通过 |
| 4 | 订阅追更情况 | 订阅追更检查 | subscription.list | 通过 |
| 5 | 有没有失败的下载任务 | 下载排查 | download.list → download.inspect | 通过 |
| 6 | 空间不够了,看看能清理什么 | 数据清理与存储 | downloader.list → download.list | 通过 |
| 7 | 待处理里有什么要我处理的 | (不载入) | decision.list | 通过 |
| 8 | 站点憨憨的登录是不是掉了 | 巡检 | site.list | 通过 |
每条都断言:系统提示里有「当前环境」的下载器 / 媒体服务器 / 站点事实且不含地址;调用顺序;只读调用全部成功、需要批准的被拒绝;合格汇报(只用工具结果写)过 `lintReport`(无 UUID / hash / 原始字节 / ISO 时间 / 内部字段 / 能力名,≤8 行,开头不是套话)。反例原文过 `lintReport` 报 7 类问题(太长、原始字节、ISO 时间、内部字段、开头不是结论、向用户要 ID、说教),期望样子 0 个问题。
fake 模型只能证明"按提示的路线走得通、数据够写出合格汇报",不能证明真实模型会这么走,所以还要真实模型对比。
## 4. 真实模型对比(DeepSeek V4.1 Flash,OpenCode Go)
**本次没有跑,真跑 0 次。** 任务说明里的凭据文件 `.local/admin-credentials` 只有管理员、TMDB、Brave 搜索与 qB 的条目,没有 OpenCode Go 的 key;用户栈里配置的模型服务按约束不能碰。评测脚手架已就绪:
- `apps/server/test/e2e/agent-prompt-eval.real.test.ts`:同一套测试库数据,"前"用 main 的 `buildSystemPrompt`(`git show main:packages/agent/src/system-prompt.ts`)+ 旧约束 + 不含 `download.list` 的能力集,"后"用分层提示;缺省跑反例那条 + 收录 + 入库排查共 3 条 × 2 组 = 6 次会话(上限 12)。
- 结果写 JSON:每次的能力调用序列(含是否成功)、汇报原文、`lintReport` 结果、行数、token / 费用。
- 跑法见 runbook;拿到 key 后执行一次,把结果按下表补进本节:
| 提示 | 组 | 调用序列 | 行数 | lintReport | 摘要 |
|---|---|---|---|---|---|
| 检查站点、下载器和媒体服务器是否正常 | 前 | 待跑 | | | |
| 同上 | 后 | 待跑 | | | |
| 把《沙丘 2》4K 收进来 | 前 | 待跑 | | | |
| 同上 | 后 | 待跑 | | | |
| 为什么沙丘2没入库 | 前 | 待跑 | | | |
| 同上 | 后 | 待跑 | | | |
看点:前组是否复现"没有下载器 / 要用户给 ID / 原始字节 / 长段授权说明";后组第一句是否是结论、是否 ≤8 行、是否先 `downloader.list`、下载任务 ID 是否来自 `download.list`、被拒是否只写一句。