Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LutgzyJqNhPpZy1nFsJtN3
11 KiB
11 KiB
TASK · 明说要校正时第一步就能打开(issue #54,BUG-1306 复发)
- 日期:2026-10-13
- 来源:Gitea issue #54(agent 循环试点),产品负责人在 staging 首页普通对话(deepseek-v4-flash)第一句说「请你帮我生时纠正」,回答「已完成 3 步、本轮技法 43 项」后写「生时校正这次我这边开不了,它走的是另一个入口……」,没有打开校正
- 执行方:Grok(Windows + Docker),分支
codex/rectification-step0-entry-20261013,只推这个分支 - 验收:Claude(Linux)
- BUG 编号:BUG-1317(BUG-1316 已预留给 issue #55;开工时核对
docs/BUG_HISTORY.md最大号)。BUG-1317 标「复发自 BUG-1306」,并在 BUG-1306 记录里补一行指向它
1. 基线
- 基线 commit:
origin/staging963276ca2 git log 586561eb..origin/staging -- frontend/src/mastra frontend/src/lib/consultation-thinking-plan.ts frontend/src/lib/rectification-in-chat*.ts frontend/src/lib/stream-agent-response.ts frontend/src/app/api/consult frontend/src/hooks/use-consultation-run.ts为空:BUG-1306 部署后这条链没人动过,不是代码回归。
2. 事故实证
- 产品负责人这一步就是
docs/testing/rectification-explicit-entry-20261012.md第 1 步(「请你帮我进行生时纠正」),未通过。该清单(BUG-1306 的 T5)因无模型凭据从未跑过(BLOCKED.md「TASK-rectification-explicit-entry-20261012:T0 日志、T5 模型」)。 - 用户看到的是模型自由写的整段解读。而工具只要收到
explicitRequest=true,不论放行还是拒绝,服务端都会用固定句覆盖模型正文(frontend/src/lib/rectification-in-chat.ts的RECTIFICATION_DIRECT_*_COPY,frontend/src/lib/stream-agent-response.ts::rectificationDirectRunCompleted)。所以模型没有带explicitRequest=true调用offer-birth-time-rectification,这是代码可证的,不是推测。 - 「另一个入口」「开不了」在提示词、skill、
frontend/src里都搜不到,是模型自己编的;「我也不会先用一两件事去反推一个更窄的时间」是在复述规则里的禁止句。
BUG-1306 的防复发措施逐条核对仍在:唯一规则 RECTIFICATION_OFFER_RULE(frontend/src/lib/consultation-thinking-plan.ts)注入首轮、追问轮与时段路线;createRectificationOfferTool 与 finishExplicitRectificationRequest(frontend/src/mastra/consultation-tools.ts);decideRectificationOfferWith(rectification-in-chat.ts);contractReady() 对 rectificationDirectEntry 放行(stream-agent-response.ts);浏览器自动打开(frontend/src/hooks/use-consultation-run.ts)。
3. 根因
- 第 0 步只给排盘工具。
consultationNatalPrepareStep/consultationWindowPrepareStep(consultation-tools.ts)在stepNumber === 0时activeTools只有排盘工具(BUG-923 定、BUG-937 改auto)。模型必须先排完整盘(43 项),此时已进入解盘状态,才轮到它考虑校正工具。 - 规则正向句埋在禁止句中间。
RECTIFICATION_OFFER_RULE以「用户说你推得不准时」开头,「明确要做校正就调用…explicitRequest=true」夹在「不承诺能收窄」「不在对话里收集经历」之间;模型照禁止句执行。 - 「纠正」撞词。 同一规则写「按纠正规则认下、改读」,
FOLLOW_UP_CORRECTION_RULE讲的是用户「纠正」解读;用户说「生时纠正」被归到「读法问题、不提校正」那一支。 - 没告诉模型校正就在本对话里可开。
- 为什么没拦住:
frontend/tests/rectification-explicit-entry-20261012.test.ts直接tool.execute({explicitRequest:true})并用正则查规则文本;「真实模型是否选择调用」只能靠 T5,而 T5 一直是环境缺口。
4. 决策记录
- 产品负责人 2026-10-13 在 issue #54 选 B:改规则 + 第 0 步可调用校正工具(备选 A 只改规则、C 每个新对话加一次小模型意图判断均未选)。
- 推翻 BUG-923「第 0 步只放排盘工具」:第 0 步
activeTools为「排盘工具 +offer-birth-time-rectification」(仅当本轮ctx.rectificationOffer存在,即该工具确实挂上时)。toolChoice仍为"auto"(BUG-282 / BUG-937 不变)。 - 保险沿用现有机制,不另造:第 0 步模型既没排盘、也没走直接进入时,
contractReady()为假,stream-agent-response.ts已有的runtime-contract-retry会重试,仍不就绪则按现有降级 / 失败处理。BUG-922 / 923 的「不看盘就写答案」不得因此复发。 - 不加关键词 / 正则分类器(BUG-976/977、BUG-1247 的既有决定不变)。
- 产品负责人已确认:普通问题(「看看事业」)仍先排盘再解读;「你说得不准」仍是认下改读、不主动拉去校正。
5. 硬红线
- 不写任何按关键词判断意图的代码(含正则、词表匹配进入校正)。规则里列举「校正 / 纠正 / 核对出生时间」等说法只作为给模型的说明。
toolChoice不得改成required或指名工具(BUG-282 / BUG-937)。- 第 0 步不得放出排盘与校正之外的工具;第 1 步起不变。
- 不改
decideRectificationOfferWith的资格判断(本人 / 产品开关 / 进行中的校正 / 价格)、不改固定句文案、不改计费。 - 规则只在
RECTIFICATION_OFFER_RULE一处定义(BUG-1248 / 1306),工具描述不复述规则。 - 不改数据库结构;不碰
frontend/src/app/(app)/page.tsx;不改.gitea/**。 - 改既有断言按 §7.3 写「原值 / 新值 / 原因」三栏。开工先 grep:
grep -rn "consultationNatalPrepareStep\|consultationWindowPrepareStep\|RECTIFICATION_OFFER_RULE\|纠正规则\|activeTools" frontend/tests tests(已知:frontend/tests/consultation-agentic-runtime.test.ts「natal first step exposes only the chart calculation tool」与 window 对应用例、frontend/tests/consult-single-pass-answer-20260927.test.ts、frontend/tests/rectification-explicit-entry-20261012.test.ts)。 - 改了普通对话提示词:按 AGENTS.md §10 需要名人生平回测,本轮无模型凭据,写成环境缺口(见 §10),不得写成通过。
6. 任务分解
T1 · 第 0 步放出校正工具
consultationNatalPrepareStep/consultationWindowPrepareStep改为能知道本轮是否挂了校正工具(例如改成工厂consultationNatalPrepareStepFor({ rectificationOffer: boolean }),或在route.ts组装时传入),第 0 步activeTools= 排盘工具 +(有则)RECTIFICATION_OFFER_TOOL_ID;没挂校正工具时与现在逐字节相同。- 第 0 步模型以非
explicitRequest方式调用校正工具(还没看过盘就想「顺口提议」):工具返回一句「先排盘,看过盘再决定要不要提」之类的说明,不记为已提议(不占用「同一次对话提议过就不再提」的额度),之后照常排盘。 - 验收:
consultation-agentic-runtime.test.ts两条第 0 步断言按三栏改,新增「没挂校正工具时第 0 步只有排盘工具」「挂了时第 0 步是两者」。- 新增运行时测试(用现有假模型 / 假流的写法):① 第 0 步直接
explicitRequest=true→ 不调用排盘、正文是固定过渡句、contractReady为真;② 第 0 步什么工具都不调用就写字 → 走runtime-contract-retry,最终答案来自排盘之后;③ 第 0 步非 explicit 调用校正工具 → 不记为已提议,随后排盘、正常作答。
T2 · 改写规则
RECTIFICATION_OFFER_RULE重排,正向句放第一句,大意:「校正就在这个对话里能开。用户这一轮明确要做出生时间校正(说法可能是校正、纠正、核对出生时间、看看出生时间准不准等),第一步就调用 offer-birth-time-rectification 并传 explicitRequest=true,不用先排盘,工具通过后只写那一句过渡。」其后才是「推得不准 → 先分读法 / 时间」与各禁止句。- 把规则里描述「用户不认同解释」那支的「纠正规则」改称「改读规则」(
FOLLOW_UP_CORRECTION_RULE的名字与内容不改,只改RECTIFICATION_OFFER_RULE里引用它的叫法),避免与「生时纠正」撞词。 - 提示词总长不得明显增长(BUG-1256 瘦身后的口径):新规则字数 ≤ 原规则 + 80 字,进度记录写原 / 新字数。
- 验收:
rectification-explicit-entry-20261012.test.ts里查规则文本的断言按三栏改;新增断言:规则第一句含explicitRequest=true,规则文本不含「纠正规则」。
T3 · 记录
docs/BUG_HISTORY.md新增 BUG-1317(复发自 BUG-1306:为何旧测试与 T5 没拦住、本次推翻 BUG-923 第 0 步限制的决策、保险机制),BUG-1306 记录补「复发:BUG-1317」。docs/tasks/PROGRESS-rectification-step0-entry-20261013.md、CHANGELOG.md。- 真机清单:在
docs/testing/rectification-explicit-entry-20261012.md第 1 步后补一行「新对话第一句:『请你帮我生时纠正』(不带『进行』)」,并加第 9 步「新对话问『看看我今年事业』:照常先排盘解读,不出现校正」;或另写docs/testing/rectification-step0-entry-20261013.md引用原清单。
7. 让步顺序
T1 与 T2 都必须做(只做 T2 就是产品没选的 A)。时间不够时 T1 的第③条(非 explicit 调用不占额度)可降为「记录在 BLOCKED.md,回报里说明」。
8. 验收命令分工
| 谁 | 命令 |
|---|---|
| Grok 自跑 | 前端 tsc --noEmit、npm run lint;node --test 跑 consultation-agentic-runtime.test.ts、consult-single-pass-answer-20260927.test.ts、rectification-explicit-entry-20261012.test.ts 及新增文件(fail 与 cancelled 都为 0)。前端全量 npm test、整站构建不跑,以 Claude 为准 |
| Claude 验收 | 上述 + 前端全量 npm test 与基线逐条比对 + next build(/ 仍 Static,首屏 gzip ±2%)+ 逐行审规则文本 |
| 不需要 | test:db、Python 快速门(不动 Python、不动数据库访问层) |
9. 开工前置命令
git fetch origin --prune
git worktree add -b codex/rectification-step0-entry-20261013 .worktrees/rectification-step0-entry-20261013 origin/staging
cd .worktrees/rectification-step0-entry-20261013
git log -1 --format=%h # 应为 963276ca2 或其后代
grep -n "^## BUG-" docs/BUG_HISTORY.md | tail -3 # 核对最大号;BUG-1316 已预留给 #55
grep -rn "consultationNatalPrepareStep\|consultationWindowPrepareStep\|RECTIFICATION_OFFER_RULE\|纠正规则\|activeTools" frontend/tests tests
10. 环境缺口(预告)
- 真实模型是否会在第一步调用校正工具,本机与 Grok 侧都没有模型凭据(供应商 key 加密存于管理端数据库),无法自动验证;名人生平回测同理。部署后由产品负责人按真机清单用 deepseek-v4-flash 与默认模型各走一遍(每个场景至少两次)。在此之前 BUG-1317 只能是
fixed-pending-verify。