Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
12 KiB
PROGRESS · 普通对话说人话、按人分段(2026-10-01)
- 任务书:
docs/tasks/TASK-consult-plain-answer-20261001.md(origin/staging00420f89,含 D8 不限字数) - 执行:Claude fork 子代理(直接执行模式,产品授权)
- 分支 / worktree:
codex/consult-plain-answer-20261001/.worktrees/consult-plain-answer-20261001,基线00420f89 - BUG 编号:开工核对
docs/BUG_HISTORY.md最大 BUG-1131;staging 上另一份任务书预留 1135~1139;本单用 1132~1134
基线与交付门(Node 22.14,/exec-daemon/node)
| 项 | 基线 00420f89 |
本分支 |
|---|---|---|
tsc --noEmit |
0 错 | 0 错 |
npm run lint |
0 error / 126 warning | 0 error / 126 warning |
npm test 总数 |
4,809(pass 4,744 / fail 24 / skip 41) | 4,813(pass 4,748 / fail 24 / skip 41) |
| 失败名单 | 24 条(全是数据库 / 部署脚本类,无 Docker) | 与基线逐条一致(diff 无差) |
next build |
/ ○ Static |
/ ○ Static |
.next/static 全部 js 逐个 gzip 合计 |
1,632,304 B | 1,632,341 B(+37 B,+0.002%) |
实现
| 任务 | 落点 |
|---|---|
| T1 新形状(BUG-1132) | frontend/src/mastra/product-voice.ts:删 OPENER SHAPE,新写 ANSWER SHAPE(先答 → 按对象分段 → 每段人话 + 括号依据 → 行动;人话自检与四条禁止;推断边界;降级路线两条);HOPE DISCIPLINE 去「扮演象」;Good 换成父母题按对象分段、单对象事业题不拆段;新增格局名 Bad(改写示意,非事故原文);顾问报告 Bad 理由改写;natalSpokenReportContract 改为对象段 → ## 盘上依据(可省)→ ## 时间怎么看(可省)→ ## 这周可以做的一件事,不设字数上限,Never 加空宫与格局名两条 |
| T2 收敛一处(D7) | frontend/src/lib/consultation-thinking-plan.ts 新增 NATAL_ANSWER_SHAPE_SUMMARY(英文唯一摘要)与 natalAnswerShapeBody()(中文用户轮唯一定义);REPORT_HEADING.support 改「盘上依据」;product-voice.ts、index.ts、skill-binding.ts、consultationSpokenHeadingRule("natal") 引用摘要;route.ts 旧路径用户回合引用 natalAnswerShapeBody();思考栏「用盘上的反差回答这个问题」→「先用一句话回答」,「这周可以扮演哪个象」→「这周可以做什么」;续写提示先补未写完的对象段 |
| T2 附带 | applyThinkingSectionProgress:开场节在出现任何 H2 时完成(对象段标题不是固定标题);某节标题出现后,它前面被省略的节一并算完成(盘上依据 可省)。原逻辑下开场节要等到「盘上依据」出现才完成,而它现在可能不出现 |
| T3 父母卡(BUG-1133) | frontend/src/lib/consultation-evidence-card.ts:parents 规格加 karakas: ["MK"] 与 roles;卡上 roles.mother(4 宫、宫主、月亮、MK、D12 第 4 宫星座与落星)/roles.father(9 宫、宫主、太阳、D12 第 9 宫);PiK 只在引擎表里有时才进(golden 三张盘都是 7 karaka,无 PiK,不记缺口);MK 值只在 section.karakas 存一份,角色里写代号;「母亲 / 父亲」进 EVIDENCE_CARD_LABELS。index.ts 数据卡说明加一句 roles 的用法 |
| T4 空宫(BUG-1134) | 共享口吻「推断边界」一行 + 合同 Never 一条 + 中文用户轮与英文摘要各一句 |
| T5 文档 | frontend/docs/VOICE.md 原则 6、7、口语层形状、首轮 / 追问说明与示例表;CHANGELOG.md;docs/BUG_HISTORY.md BUG-1132~1134;docs/tasks/README.md;真机清单 docs/testing/consult-plain-answer-20261001.md |
git grep -n "扮演\|谁在推\|命名成一个格局\|外松内紧" -- frontend/src → 0 行。普通对话提示词(product-voice.ts、index.ts 本命 / general / window、skill-binding.ts、consultation-thinking-plan.ts 本命与追问、route.ts)里没有字数上限。
改动的既有断言(原值 / 新值 / 原因)
| 文件 | 原值 | 新值 | 原因 |
|---|---|---|---|
consultation-voice-contract.test.ts |
open with the OPENER SHAPE above, heading-free |
follow the ANSWER SHAPE above. ${NATAL_ANSWER_SHAPE_SUMMARY} |
D1/D7 |
| 同上 | 有「别去应 X 的象,去扮演 Y 的象」「Spoken-layer total ≤ 400」 | 不得出现「扮演」「≤ 400」;须有「不设字数上限,讲清楚为准」 | D1/D8 |
| 同上 | binding 有「after a 3-6 sentence spoken reply」 | binding 有「as the evidence of the product's answer shape … ${NATAL_ANSWER_SHAPE_SUMMARY}」 | D2/D7 |
| 同上 | 合同里「## 盘里支持这个判断的地方, then ## 时间怎么看, then …」 | 对象段规则 + ${REPORT_HEADING.*} 三标题顺序且「盘上依据」可省 |
D2/D7 |
| 同上 | 「The opener carries no action list」 | 「开场不写标题、不写行动」 | 合同引用唯一定义 |
| 同上 | 「First-turn total ≤ 900」 | 不得含 900;「There is no length cap」 | D8 |
| 同上 | 「only what the opener did not already say」 | 「only what the opener and the sections did not already cite」 | D2 |
| 同上 | mastra「each thing said once, first-turn total ≤ 900 characters」 | mastra 引用摘要,不含 ≤900 / ≤400 / 反差 / 扮演 | D7/D8 |
| 同上 | binding「no action list in the opener」「the actions, once」 | binding 不含反差 / 扮演 / ≤400;「the actions appear once」 | D7(语义由摘要携带) |
| 同上 | route「先用不超过 400 字口语…」「别去应 X 的象…」 | route 引用 natalAnswerShapeBody(),不含扮演 / 400 / 900 字 |
D1/D7/D8 |
| 同上 | 整条 test「the opener is a shape — 反差…」 | 同位置改为「the answer is a shape — conclusion first…」,锁新形状各条 | D1–D4/D8 |
| 同上 | 「不是每个人都有转机,但每个人都有能扮演的象」 | 「…每个人这段时间都有能做的事」+「每次都要说清这段时间能做什么」 | D5 |
| 同上 | 整条 test「the pinned Good example carries the new shape…」(外松内紧定稿) | 「the pinned Good examples split by person…」:父母分段 Good、单对象 Good、格局名 Bad;顾问报告 Bad 理由改「没有盘上依据」 | D1/D2 |
| 同上 | 「A 和 B 都必须是盘上的结构」「反差写那个人…不写心思」 | 「问的是别人时,写那个人在你盘上对应的宫位与代表星说明了什么,不写那个人的心思」 | D1(BUG-1070 目的保留) |
| 同上 | 「本命解读里这三条不写在开场…」「…行动就写在开场结尾」 | 「本命解读里只写在最后一节…出现一次」「…行动就写在回答结尾」 | D2 |
consultation-thinking-plan.test.ts |
步骤标签「用盘上的反差回答这个问题」 | 「先用一句话回答」 | D1/T2 |
| 同上 | natal 含「这三个二级标题」 |
含对象分段规则与「然后依次写:」 | D2 |
| 同上 | natal 含「全文不超过 900 字」 |
含「不限字数,讲清楚为准」,且无「不超过 N 字」 | D8 |
| 同上 | natal 含「反差只写盘上的结构」 |
含人话自检与空宫规则,且无反差 / 扮演 / 谁在推 | D1/D3/D4 |
| 同上 | 追问含「不超过 200 字」 | 含「讲清楚为准,不限字数」,且无「不超过 N 字」 | D8 |
consult-answer-the-question-20260927.test.ts |
写作提示含「不超过 200 字」 | 含「讲清楚为准,不限字数」,且无「不超过 N 字」 | D8 |
| 同上 | 首轮开场步骤标签「用盘上的反差回答这个问题」 | 「先用一句话回答」 | D1/T2 |
consultation-entrypoint.test.ts |
route 含「先用不超过 400 字口语直接回答下面的问题…」 | route 含 natalAnswerShapeBody()…resolvedQuestion.modelQuestion |
D7/D8 |
consult-evidence-card-20260927.test.ts |
「每个卡值都是引擎值」白名单 = EVIDENCE_CARD_LABELS 两条 |
同一来源多「母亲」「父亲」两条,断言代码不变 | D6 |
新增测试 4 条:开场节在对象段标题处完成、被省略的节在后面标题出现时完成;形状只定义一处(摘要、合同、用户轮、思考栏标题与摘要一致,均无字数上限与旧修辞);父母卡 roles 逐字段对 golden 三张盘(宫主取自本节、MK、无 PiK 不记缺口、D12 宫位按 D12 上升推算);缺 MK 记缺口。测试总数 4,809 → 4,813。
T6 效果验证
模型离线对比:环境缺口。 本机 frontend/.env* 只有 .example,环境变量里没有任何模型 key,无法用新旧提示词各跑一次。四个问题(父母 / 只问妈妈 / 事业 / 伴侣)的新旧对比留到部署 staging 后按真机清单走。
长度副作用核对(只核对,未改任何上限):
| 项 | 代码里的值 | 位置 |
|---|---|---|
| 回答输出上限 | 16,384 token;回答步开 provider 思考时上限 = 16,384 + 8,192(思考)= 24,576 | frontend/src/lib/agent-generation-settings.ts AGENT_ANSWER_OUTPUT_TOKENS / AGENT_THINKING_OUTPUT_TOKENS;consultation-tools.ts 回答步 thinking: "enabled" |
| 答题时钟 | 70 s(工具阶段 110 s 另算,合计 180 s) | frontend/src/mastra/consultation-tools.ts CONSULTATION_ANSWER_TIMEOUT_MS;续写与重试共用同一个钟,钟到就中止并按未写完处理 |
| 时钟依据(代码注释里的实测) | 默认模型约 90–100 token/s(含首字延迟)→ 70 s 约 6,300–7,000 token;吞吐减半时约 3,000 token | 同上注释,引 PROGRESS-report-writer-failure-20260902 |
估算:中文正文按每字约 0.7–1.5 token 计,1,500–2,500 字 ≈ 1,100–3,750 token,远低于 16,384 的输出上限,不会被 token 上限截断。时钟方面:思考 token 也吃这 70 s;正常吞吐下 2,500 字正文 + 1,000–2,000 思考 token ≈ 2,100–5,750 token,放得下;吞吐掉到一半(约 45 token/s)时,2,000 字以上的回答加上思考就可能撞上 70 s,结果是最后一节写不完。所以风险只在「慢模型 / 高峰期 + 很长的回答」,已写进真机清单第 7 步,请产品遇到截断时报来;是否调钟由 Claude 与产品决定,本单未动。
偏离与未做
- 今日入口(
dailyAnswerShapeInstruction/consultationSpokenHeadingRule("daily")的「≤ 400」「每句 ≤ 30 字」)与index.ts今日星语短句、个人报告 headline 的字数限制没动:它们不是普通对话的回答形状,任务书 D8 列举的也只是开场 / 首轮 / 追问。如需一起放开另开单。 chat-answer-split.ts仍把旧标题「盘里支持这个判断的地方」缩写成「盘上依据」:历史会话里存的是旧标题,保留兼容;新回答直接就是「盘上依据」。- 纯寒暄豁免那句仍叫「不要套开场形状」(未改字,三处测试依赖这句原文,语义仍对)。
skills/未改,Skill 版本不 bump。
变基复跑
推分支前 origin/staging 前进到 c304cf3a(BUG-1140 构建修复 + 新增 runtime-sources-no-test-imports 测试 2 条)。本分支变基到其上后复跑:tsc 0;lint 0 error / 126 warning;npm test 4,815(pass 4,750 / fail 24 / skip 41),失败名单与基线逐条一致;next build / ○ Static。docs/BUG_HISTORY.md 冲突按编号顺序合并(1132~1134 在 1140 之前)。
Claude 验收(2026-10-01)
- 独立复跑:tsc 0;lint 0 error / 126 warning;
npm test4,815 条 fail 24,与基线c304cf3a逐条同名;next build后/Static。推 staging44cdd9c9(快进)。 - 真实模型对比(产品提供临时 DeepSeek key):见
docs/testing/consult-plain-answer-20261001-model-runs.md。旧提示词 3/3 复现事故形状,新提示词 5/5 无格局名 / 推修 / 扮演象,父母题均按妈妈、爸爸、他们怎么对你分段。 - 待产品决定:
deepseek-v4-pro一条 77 s 超过 70 s 答题时钟(会截断最后一节);flash 30–41 s 在钟内。