fix(consult): run the local skill's full technique spectrum on the web path
Web answers were thinner than a local Agent calling yinduzhanxing-skill: theme-subset vargas, no visible audit table, and a prompt that dropped the invocation contract. Bind the commercial method, compute D1–D60 plus Western layers, and deliver the same Full-Spectrum checklist. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+35
-2
@@ -4260,8 +4260,41 @@
|
||||
- 根因:两件事叠在一起。(一)激活的开销是逐轮的:咨询路径没有配 Mastra memory,也没有 `threadId`/`resourceId`;Agent 每次请求新建(`id` 里含 `requestId`,不进缓存);回放的 `history` 只有 `{role, text}` 纯文本,不含任何工具调用或工具结果。所以模型每一轮都必须重新激活一次技能,那份载荷逐轮重发;更糟的是一次请求内的 `retry`(契约不完整)与 `retryForAnswer`(空回答)都是 `agent.stream([...baseMessages, 追加一句])`,各起一个全新的模型循环、各自再激活一次,最坏情况单次请求付三遍。(二)模型看到的包内容不受哈希约束:`skills: [jyotishSkillPath]` 指向的是工作树视图 `skills/jyotish-vedic-astrology`,而那里的 `references` 是软链到 `../../references` 的 827 条全量树;完整性检查只逐字节比对 SKILL.md,registry 的 sha256 管不到激活时列举出来的那 1,592 条路径。生时纠正的 Agent 没有这个洞,它用的是 `resolveSkillPackageRuntimePath(skillPackage)`(先校验 sha256,再建一个以规范技能名命名的符号链接别名指向锁定版目录)——正确的机制仓库里早就有,只是咨询路径没用。
|
||||
- 修复:把技能从「模型的一次工具调用」改成「服务端在跑之前就绑定好」,与生时纠正对齐。新增 `frontend/src/mastra/skill-binding.ts`:从锁定版包读 SKILL.md、剥掉 frontmatter,包进 `<jyotish-skill name version>` 交给 instructions;`skills` 指向 `resolveSkillPackageRuntimePath()` 的哈希校验路径;用一个 `providesSkillDiscovery: "on-demand"` 的输入处理器撤掉 `skill` 与 `skill_search`,只留 `skill_read`(这是 Mastra 为「调用方自行负责技能发现与指令加载」留的声明位,不是绕路)。四个 Agent 统一走这个绑定,`Load the ... skill before answering` 一类句子改成声明方法已在提示里、并明确「以下是本产品的运行时契约,与 skill 方法冲突时以契约为准」。运行时状态的 `jyotishSkillLoaded` 改名 `jyotishSkillBound` 并在创建时即为真,绑定作为回执的第一步记下(不带耗时,因为确实没有取任何东西);`skill.started`/`skill.completed` 两个公开事件改由服务端在流开头宣告,客户端契约与文案不变,但首个 activity 从「等激活往返之后」提前到「立刻」。无出生分钟那条路径的契约重试整段删掉——它的 `requireTool` 为假、方法又已绑定,已经没有任何可修的契约了。那个处理器不只是个标记:它逐步检查系统提示里确实带着绑定标记,读不到提示就放过,能读到而没有方法则中止本轮——撤掉激活之后,一个装配时漏了方法块的 Agent 不会再报错,只会安静地在没有方法的情况下作答,这正是本轮要消掉的失败形态。
|
||||
- 验证:新增 `frontend/tests/skill-binding.test.ts` 4 项:绑定的正文与锁定版 SKILL.md 逐字一致且运行时路径落在 sha256 目录下;实测激活载荷与绑定载荷的比值(前者是后者两倍以上,后者不到前者 45%);绑定后的工具面恰好只有 `skill_read` 而技能仍被声明;系统提示缺方法时中止、带方法与读不到提示时都放过。实测数字:从锁定版包激活是 118,352 字节(`## References` 56,696、`## Scripts` 14,824),绑定后 47,289 字节,每次省 71,063 字节;相对生产当前实际发出的 129,651 字节省 82,362。顺带一项一致性:锁定版的 `references` 是 189 条的真目录,而工作树视图是软链进 827 条,所以 `skill_read` 能读到的范围与 `methodology.further_reading` 校验的范围现在第一次是同一棵树。非 DB 套件 1,666 项中 1,665 通过,唯一失败是 `onboarding-route.test.ts` 里 50ms 墙钟对 5ms 超时的竞速用例,单独跑通过(19ms)且该用例注入 `generateText`、不构建 Agent,与本轮无关。`tsc --noEmit` 清洁,改动文件 `eslint` 清洁(6 条既有 warning 都不在改动文件内)。未做的验证:没有在 staging 上比对绑定前后同一问题的回答差异,也没有实测冷启动多算一次包哈希的代价(`resolveActiveSkillPackage` 与 `resolveSkillPackageRuntimePath` 各算一次)。评审中被自己的测试抓到一个真 bug:守卫最初用 `JSON.stringify(system).includes(标记)`,而标记里带双引号、序列化后会被转义,那样每一轮都会误判「方法没绑上」并中止全部请求;改成按形状递归收集字符串。
|
||||
- 待跟进:`instructions` 现在 717+ 行,Mastra 仍在警告建议 <500。SKILL.md 里有相当一部分是仓库开发规范(`scripts/`、`references/`、`skills/` 该补成熟度而非重写之类),对回答一个用户的盘没有作用,但它是哈希锁定且本地 Agent 共用的产物,要瘦得重新发版——另开一轮。另外 general 与 onboarding 两条路径也各被绑了 47KB 的解盘方法,而它们一个不能做任何本命盘声明、一个只产四条建议问题;本轮为了不改行为先统一绑定,后续可以逐条裁。
|
||||
- 待跟进:Mastra 加载技能包时仍会对 SKILL.md 正文报行数警告(`skill_read` 仍要声明哈希目录),那是文件体积,不是 prompt 摘录。全谱系调用、强制工作流与 `strict-workflow-router.md` 的 Full-Spectrum / health-timing-strict 已写入商业入口并交付给网页模型,见 BUG-287。不要把研究仓入口绑进聊天 Agent。
|
||||
- 防复发:一次「模型可以忘记」的必要步骤,等于一条必然会出现的失败路径加一条修它的重试;当那一步的内容在服务端已经完全确定时,绑定比请求便宜,也比请求诚实。另一条:完整性检查必须覆盖模型实际看到的东西,而不只是入口文件——只比对 SKILL.md 的字节,会让人以为整个包都被钉住了。
|
||||
- 相关记录:BUG-284(同一条链路的上半段:先把方法按路由交付,本轮再撤掉激活)、BUG-282(生时纠正侧的服务端绑定与 `skill.bound`,本轮对齐的先例)、BUG-214(`runtime_contract_incomplete` 的门,本轮去掉了它对模型加载动作的依赖)
|
||||
- 相关记录:BUG-284(同一条链路的上半段:先把方法按路由交付,本轮再撤掉激活)、BUG-282(生时纠正侧的服务端绑定与 `skill.bound`,本轮对齐的先例)、BUG-214(`runtime_contract_incomplete` 的门,本轮去掉了它对模型加载动作的依赖)、BUG-286(摘录绑定并解开非解盘 Agent)
|
||||
- 复发自:无
|
||||
- 修复版本:待提交
|
||||
|
||||
## BUG-286 | 咨询 prompt 绑了整份 SKILL.md,general 与 onboarding 也各付 47KB 解盘方法
|
||||
|
||||
- 状态:resolved(本地修复,待提交与发布)
|
||||
- 首次发现:2026-08-18
|
||||
- 最近更新:2026-08-18
|
||||
- 影响面:`frontend/src/mastra/skill-binding.ts` 的绑定正文、`frontend/src/mastra/index.ts` 的四个 Agent 工厂、`frontend/src/app/api/consult/route.ts` 的无出生分钟路径注释。个人盘咨询、无出生分钟一般问答、引导问题生成。
|
||||
- 用户现象:没有直接报错。Mastra 对技能入口报 `Instructions have 717 lines (recommended: <500)`;无出生分钟问答与首页引导问题每次仍把约 47KB 解盘手册送进模型,而这两条路径一个不能做任何本命声明、一个只产主题建议问题。
|
||||
- 触发条件:任何一次个人盘咨询、无出生分钟咨询、或 onboarding 生成。
|
||||
- 根因:BUG-285 为了不改行为,把锁定版 `SKILL.md` 全文塞进 instructions,并让四条 Agent 共用同一绑定。商业入口相对研究稿只换了文件头,底下仍留着施工判断原则、37 个子命令、名人案例索引;这些对回答一个用户的盘没有作用。上游研究入口仍标 `6.9.14`,比产品快照只多一行 Formal Varga 审计,把它绑进 Mastra 会更胖,并与可见语音冲突。
|
||||
- 修复:咨询路径改为按标题从商业 `SKILL.md` 摘录运行时段落(商业路由、关联技法完整调取、五层硬约束、强制规则去掉开源复用边界、未闭环点、核心方法论、强制规范速查、注意事项),施工/CLI/案例索引留在包内供 `skill_read`。general 与 onboarding 不再插入方法块、不再声明 skill,与日签 Agent 对齐;onboarding 用一段产品范围条替代 47KB 方法。不绑研究入口。
|
||||
- 验证:`frontend/tests/skill-binding.test.ts` 断言摘录来自商业入口且不含施工/CLI/案例标题,并含关联技法完整调取;新增「只有解盘 Agent 绑定方法」。相关套件 `skill-binding` / `consultation-birth-time-mode` / `consultation-voice-contract` / `consultation-workflow-contract` / `onboarding-route` / `daily-starlanguage` / `consultation-agentic-runtime` / `consultation-methodology` 通过。`tsc --noEmit` 清洁,改动文件 `eslint` 清洁。Mastra 加载技能包时仍会对 SKILL.md 报行数警告,因为咨询 Agent 还要 `skill_read` 指向该目录;那是文件体积,不是 prompt 摘录。
|
||||
- 待跟进:SKILL.md 施工/CLI/案例段落仍在包内给本地 Agent 和 `skill_read`,聊天 prompt 继续只摘运行时段。未在 staging 上比对摘录前后同一问题的回答差异。
|
||||
- 防复发:哈希锁定的入口可以全文保留给本地 Agent,但聊天 prompt 只能摘运行时段落;一条不能解盘的路径不得绑解盘方法。Mastra 对技能文件的行数警告与 Agent.instructions 体积是两件事,不要用发版去修只属于 prompt 的问题。
|
||||
- 相关记录:BUG-285(全文绑定的直接前因)、BUG-284(路由方法论已随工具结果交付,本轮不再把同一份手册全文再塞一遍)、BUG-287(全谱系写入商业入口与咨询运行时)
|
||||
- 复发自:无
|
||||
- 修复版本:待提交
|
||||
|
||||
## BUG-287 | 咨询只算主题相关分盘,西洋层与技法审计表到不了回答
|
||||
|
||||
- 状态:resolved(本地修复,待提交与发布)
|
||||
- 首次发现:2026-08-18
|
||||
- 最近更新:2026-08-18
|
||||
- 影响面:`scripts/jyotish_api_server.py` 咨询本地层、`scripts/unified_consultation_orchestrator.py` 证据包与分盘调度、`scripts/consultation_plan_contract.py` 证据类别、`frontend/src/mastra/consultation-workflow.ts` 模型投影、`frontend/src/mastra/product-voice.ts` 可见回答格式、商业 `SKILL.md`、`references/strict-workflow-router.md`(与 `versions/6.9.14` 包内副本)。个人盘咨询。
|
||||
- 用户现象:没有直接报错。排盘只带 D2/D4/D9/D10/D11;其余 D1–D60 被写成「追问再展开」。西洋本命默认不算行运/回归/推运。模型上下文没有技法审计表,可见语音还禁止把它写进回答。对照本地 Agent 调用 `yinduzhanxing-skill`,网页还缺 Full-Spectrum 路由合同、健康清单、功能性吉凶星/Shadbala/Kakshya 进入作答,且口语被要求不要先写原始结构。
|
||||
- 触发条件:任何一次有出生分钟的个人盘咨询。
|
||||
- 根因:咨询路径按主题子集计算分盘以省成本;西洋 timing 要调用方逐项点名;`toModelOutput` 只投影四张卡片里的允许键,`runtime_evidence_log` 里的审计表从未进入模型上下文;VISIBLE VOICE 明确禁止复制 Technique Audit Table。
|
||||
- 修复:咨询默认计算 20 张正式分盘加其余 D-N 研究分盘,并自动挂上已实现的西洋本命与 timing 层(失败标 blocked,不静默省略)。consumer_context 带 `varga_spectrum`、`western_spectrum`、`technique_audit_table`。模型投影放行这些字段。可见回答末尾要求一张中文技法审计表(已执行 / 阻塞 / 不适用),口语须先用已交付的原始结构再综合。同一合同写入商业 `SKILL.md`(关联技法完整调取 / 全谱系真实调用 / 强制工作流 / P0-P1 观察层),并把 `yinduzhanxing-skill` 的 `Full-Spectrum Invocation Contract` 与 `health-timing-strict` 写入产品 `strict-workflow-router.md` 随方法论交付。咨询本地层补上 Functional Benefic/Malefic、Shadbala、Kakshya。重算 `6.9.14` 包哈希;不另维持一份产品覆盖层。
|
||||
- 验证:`tests/test_consultation_consumer_context.py` 断言正式 20 / 研究 40 张分盘及 Functional/Shadbala/Kakshya 本地层;`tests/test_western_chart_engine.py` 断言默认挂上已实现西洋 timing;前端 `consultation-context` / `consultation-voice-contract` / `consultation-plan` / `skill-binding` / `consultation-methodology` 断言审计表、全谱系合同、健康清单与商业入口强制工作流进入模型包。`skill-registry` 断言登记哈希与包树一致。
|
||||
- 防复发:主题相关分盘只决定优先解读,不得再把未算的正式分盘写成 deferred。西洋 natal 咨询不得再要求调用方点名每个 timing 层。模型包缺少 `technique_audit_table` 视为回归。商业 SKILL.md、`strict-workflow-router.md` 与咨询运行时必须是同一套调用面;改入口后必须同步根文件、`versions/6.9.14` 并重算 registry sha256。网页口语不得再禁止使用已交付的原始结构。健康域必须交付 `health-timing-strict`,不得再报「无清单」。
|
||||
- 相关记录:BUG-286(prompt 摘录,不靠发版修调用)、BUG-284(方法论随工具结果交付)
|
||||
- 复发自:无
|
||||
- 修复版本:待提交
|
||||
|
||||
Reference in New Issue
Block a user