muse-agent-example/docs/2026-07-24-Gate-A-正文智能体职责重构记录.md
zizi abadaa15e9 框架: 正文评测链职责重构收口(writer/detector/judge 单一职责)+决策修复+加固门+探针刷新
- writer/detector/judge 按父仓专题-03/04 单一职责拆分:WriterDraft v2(仅 candidateBody)、CandidateEnvelope v2(adapter 确定性绑定)、SemanticDetection v3(quote 唯一匹配/unknown-gapReason)、blind judge v3(双盲第三评中位);预算两层(启动预留=Σ plannedCalls×cap,修正旧 maxCalls×cap 的 $2250 阻断 bug)。

- 决策修复:补第六类混淆项「场景选择偏差」(集合级、只标注不改终态);模型归属口径(planner/writer/judge 固定 opus,extractor/detector 可用它模型,拆书走 M3 不经角色派发);eval 评分尺改链接+一句话引用 quality-gate。

- 加固执行门:探针合同绑定(probe.executionProfileSha256 须等于 writer profile 身份哈希),陈旧探针被机械阻断 EXECUTE_PROBE_CONTRACT_MISMATCH。

- 新增探针刷新工具 refresh_runtime_probe.py(可注入 invoker+失败关闭+重签同源 canonical_sha256),并已按新合同真实重测探针(绑定 9d319ea0,成本 $0.155)。

- 逐行复核后修复:省略号被当路径穿越误杀(claude_runtime 共用精确判定 contains_path_traversal,盲评/检测统一引用);检测 failed 分支测试缺口;评委报告↔模型原始输出绑定恢复(reviewerStructuredOutputs,防一致篡改报告评分);上下文 purpose 词汇两层对齐;盲评死代码清理。

- 全量离线测试约 800+ 项全绿(continuation/detect/quality-gate/read-context/replay-eval/parse-book 572/llm),不连库不调模型。
2026-07-25 04:44:10 +08:00

91 lines
6.7 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.

# Gate A 正文智能体职责重构记录
> 类型:历史执行记录,非 SoT。
> 日期:2026-07-24
> 用途:保留 Gate A 调试证据、问题定位、用户决策和当时的实现漂移。不得使用本文替代稳定合同或推断代码运行态。
## 权威来源
- Writer、冻结和输出合同:[父仓专题-03](../../design-docs/专题-03-AI编排上下文与质量评测实现规范.md)。
- Gate 裁决:[父仓专题-04](../../design-docs/专题-04-生成质量门控与创作健康度设计方案.md)。
- adapter 隔离和执行边界:[父仓专题-05](../../design-docs/专题-05-AI统一交互协议与外部AgentAdapter设计.md)。
- Gate A 具体执行配置:`.claude/skills/replay-eval/configs/writer-gate-a-deep-space-v1.json`。
## 背景
Gate A 用《深空之影》5 个固定样本检查正文回放链路:489 战斗、321 人物对话、544 转折、199 信息揭示、523 老角色回归。每个样本冻结到 `targetChapter-1`,对比 A 通用原文检索、C 卡索引后回读原文和 B card-only 负对照。
work8 的 116 个升格窗口完成后,Gate A 进入正式执行前调试。该背景只说明执行顺序,不代表 Gate A 已通过。
## 旧 Writer 输出问题
当时的 `WriterOutput v1` 要求 writer 在一次 Claude 调用中同时输出:
- 一章 `candidateBody`;
- `claimLedger[]`;
- `evidenceRequests[]`;
- `newSettingDeclarations[]`;
- `selfCheck`;
- run/context/candidate 版本与接受状态;
- candidate/context hash;
- claim 的 Unicode code point offset 和重复 candidate hash。
这个合同把正文创作、事实抽取、补证规划、新设定申报和密码学/索引计算混在一轮。对于约 6000-7000 汉字正文,这些机械事项增加了大量非创作负载。
还发现一个事实合同矛盾:Gate A 的 A/C/B `factEvidence[]` 可能为空,而旧 claim ledger 要求 writer 填写 `factEvidenceId`。没有事实证据时,writer 既无法生成合法引用,也不应虚构 ID。`indexHints` 只是诊断索引,不能被当作事实证据。
## 运行调试证据
以下均是当时保留的受控调试事实,不代表后续配置或稳定合同的状态:
1. Claude CLI 路径为 `/Users/qingse/.nvm/versions/node/v24.15.0/bin/claude`,版本 `2.1.211`,二进制 SHA-256 为 `5a728a76198b6eca7f3c7cdbff43bab44b77b48c2108f7a3107d889773382629`,模型别名 `opus` 解析为 `claude-opus-4-8[1m]`。
2. 早期两次极小 Opus 探针等待约 177 秒和 186 秒后因 API 503 失败;响应同时出现 `subtype=success`、`is_error=true`、`terminal_reason=api_error`。因此 `subtype=success` 不能单独代表调用成功。
3. 一次旧 profile 的成功 structured-output 能力探针记录单次成本 `$0.003885`,证明 CLI envelope、完整模型 ID 和回执字段可解析。该回执绑定旧 schema/prompt,不能证明其他合同一致。
4. 一次小 writer smoke 在 600 秒 deadline 内约 90.8 秒完成,记录成本 `$0.097686`,输出通过当时的结构校验。
5. 544-A 长输入约 47.9k 字符,在 300 秒 deadline 下返回 `WRITER_TIMEOUT`;将 deadline 增加到 600 秒后仍返回 `WRITER_TIMEOUT`。
6. 将 544-A 的 deadline 增加到 1200 秒且单次 cap 设为 `$0.666666` 时,返回 `WRITER_BUDGET_EXCEEDED`。
7. 在一次临时调试中将单次 cap 提高到 `$6.666666`、deadline 保持 1200 秒,返回 `WRITER_SCHEMA_INVALID`。该结果只证明旧大 JSON 合同未稳定交付,不证明正文文学质量不可用。
raw prompt/response 被允许保留于仓库外受控 raw vault;本文不包含 raw 内容、raw 路径或认证 token。
## 预算决策与口径修正
用户批准 Gate A 总预算 `$300`,并将 writer、semantic detector、blind judge 的单次 Claude cap 设为 `$5`。三角色各最多 150 次是独立安全授权上限,不是 Gate A 的实际调用清单。
Gate A 5 个样本的预注册调用是:
| 角色 | 每样本 | 5 样本预注册上限 |
|---|---:|---:|
| writer | A/B/C 各 1 次 | 15 |
| semantic detector | 每候选 1 次 | 15 |
| blind judge | 2 次,不稳定时第 3 次 | 15 |
最多 45 次预注册角色调用在 `$5/次` cap 下的启动预留为 `$225`。当时的预算预检代码使用 `maxCalls * cap`,计算出 `$2250`并阻断启动。该口径混淆了“预注册调用清单”和“独立安全上限”。
职责重构决策同时要求:启动时按预注册调用清单预留;每次调用前同时检查累计实际成本、未结算预留和角色调用数;任一即将超过 `$300` 或对应 `maxCalls` 时,在下一调用前停止。补证、返修和重跑必须建立新的显式调用清单和预算预留。
## 职责重构决策
2026-07-24 确认的方向:
1. writer 的唯一创作输出是一章 `candidateBody`;可使用最小单字段 JSON envelope 适配 Claude structured output。
2. deterministic candidate adapter 在 writer 返回后负责 NFC/LF 规范化、`candidateSha256`、run/context/version/acceptance 绑定、篇幅检查和回执;adapter 不得创作或改写正文。
3. semantic detector 使用独立 fresh Claude 调用,输出事实 claims、证据/硬约束 verdict、新设定候选和证据缺口。模型不计算 hash 或 Unicode offset;它返回可定位 quote,adapter 确定性解析区间,歧义时失败关闭。
4. blind judge 的每个 reviewer 使用独立 fresh 调用,只评分和判定,不改正文、不代替 detector 做事实抽取。
5. detector/coverage gate 发现缺口后,由编排器生成新检索快照并启动新 writer 调用;不在旧 writer 输出中混入补证请求。
6. `factEvidence[]` 为空时,detector 显式输出 `gap/unknown/unsupported`;writer 不虚构 `factEvidenceId`,`indexHints` 不作为事实证据。
## 记录结束时的实现漂移
本记录形成时,`agent-example` 中的 writer schema/prompt/adapter、semantic detector 合同、judge 合同和预算启动预检仍主要面向旧合同。职责重构方向尚未形成与父仓唯一 SoT 一致的完整代码、schema、prompt、profile hash 和离线测试证据。
因此,该时点的 Gate A 不得继续使用旧大 JSON Writer 合同做正式执行,也不得从 dry-run、探针或单个 smoke 结果推断正文层已通过。
## 后续动作(历史待办)
1. 由父仓 Writer 合同唯一 owner 更新稳定设计,避免 `agent-example/docs` 产生第二份 SoT。
2. 依唯一 SoT 更新 writer/detector/judge 的 schema、prompt、adapter 和预算累计。
3. 为单一职责、空 `factEvidence`、quote 歧义、预算边界、raw vault 和 GateInputBuilder 增加离线测试。
4. 使用新 schema/prompt/profile 重新绑定 runtime probe。
5. 主代理复核代码差异、离线测试、预算合同和 dry-run 后,再决定 Gate A 正式执行。