Files
Jyotisha/docs/tasks/PROGRESS-consult-plain-answer-20261001.md
T

12 KiB
Raw Blame History

PROGRESS · 普通对话说人话、按人分段(2026-10-01)

  • 任务书:docs/tasks/TASK-consult-plain-answer-20261001.md(origin/staging 00420f89,含 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 test 4,815 条 fail 24,与基线 c304cf3a 逐条同名;next build 后 / Static。推 staging 44cdd9c9(快进)。
  • 真实模型对比(产品提供临时 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 在钟内。