标准模式切换到 PTC 模式后技能第一轮调用报错 #1755
Yeeeee1211
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
[Bug] 标准模式切换到 PTC 模式后,技能第一轮调用报错
unknown tool "skill",仅run_code可被直接调用一、现象与复现步骤
复现步骤
/skill,技能菜单正常出现(技能"看似已加载"),先不发送。codepreset(此路径要求会话未开始,因此报错必然出现在切换后的第一轮),此时skill由蓝色变为灰色。补充观察:技能正文实际已被注入上下文("AI 会查找这个 skill 并加入上下文")——说明
/name手势的 pre-step 注入是成功的;报错来自模型在 code 模式下对skill工具的顶层直接调用被工具注册表拒绝。模型随后读取错误信息自愈,所以只有第一轮报错、后续轮次正常。期望行为:切换模式后技能应正常可用——要么按 PTC 的 SDK 方式经
run_code程序内tools.skill(...)加载,要么第一轮就不应引导模型做一次必然失败的直接调用。二、根因分析(机制链)
PTC 模式 = Code Mode 呈现。
codepreset 的tool-presentation行声明mode: code(apps/cli/config/agent-presets/code/agent.cordis.ymlL259–262)。在 code 模式下,工具注册表只向模型展示run_code一个工具(wireSchemas过滤,packages/core/tools/src/index.tsL994–998),并确定性拒绝除run_code之外的任何模型直接调用(collapses(),L1324–1326;拒绝发生在 L1423–1444,错误文案 L1439–1442)。这是刻意的安全口径,有测试固定(packages/core/tools/tests/code-mode.spec.tsL1595–1613)。技能目录文案对呈现模式无感知(bug 本体)。
packages/skill/tool-skill/src/index.ts的 pre-step 监听器在每轮注入技能目录 system-reminder,其中固定写死:该指令以会话消息形式注入,位于系统提示(含 "only
run_codeis callable directly" 规则)之后、离模型回答最近,是模型最注意到的指令。标准模式下直接调用skill可执行,因此一切正常;PTC 模式下该指令引导模型做一次注册表必然拒绝的调用。第一轮必然触发:切换 PTC 后第一次发送
/grill,pre-step 注入技能正文(成功)+ 发布上述目录消息;模型按目录指令发出顶层skill调用 →collapses('skill', agent, false)判定 code 模式 →ToolNotFoundError,即用户看到的报错。结论:这不是"切换状态管理"的 bug——客户端缓存失效、host 端 recompose、事件转发链路均正确(均有单测覆盖)。这是技能目录的模型可见文案未随呈现模式(per-agent tool presentation,见 Agent Note
2026-08-05-per-agent-tool-presentation.md)更新的集成缺口:dsh-tool-skill早于 per-agent presentation 功能存在,其目录文案从未做过模式感知。三、为什么"切换模式"后必现
modeFor(agent) === 'native',直接调用skill可执行 → 正常。codepreset,modeFor(agent) === 'code',目录照常发布但文案不变 → 第一轮模型按旧文案直接调用 → 确定性拒绝。四、源代码位置
packages/skill/tool-skill/src/index.tsrenderCatalogMessage/renderCatalogUpdate),核心 L266、L286–287packages/skill/tool-skill/src/index.tsagent/pre-step)packages/core/tools/src/index.tscollapses()L1324–1326;拒绝 L1423–1444;modeFor()L900–911;wireSchemas()L994–998;ToolNotFoundErrorL494–510packages/core/tools/src/index.tsCODE_ONLY_INSTRUCTIONL58;collapseSectionL855–863;sdkSectionL875–892apps/cli/config/agent-presets/code/agent.cordis.ymltool-presentation,mode: code).agents/notes/implemented/feature/2026-08-05-per-agent-tool-presentation.mdpackages/core/tools/tests/code-mode.spec.tsL1595–1613;packages/skill/tool-skill/tests/tool-skill.spec.tsL289五、修复建议
方案 A(推荐):目录文案按 agent 有效呈现模式分支
①
packages/core/tools/src/index.ts— 暴露模式只读查询将私有
modeFor(L900–911)公开为modeOf(更新内部collapseSection/sdkSection/wireSchemas/view/collapses五处调用点):②
packages/skill/tool-skill/src/index.ts— 目录发布时按模式选文案pre-step 目录监听器中,渲染时传入 agent 的有效模式:
renderCatalogMessage/renderCatalogUpdate增加mode参数,并把固定的直接调用句抽为模式感知辅助函数:native/both分支保持原文不变(both下直接调用可执行,无需改)。为什么 digest 不需要改:会话一旦开始(发出第一轮)呈现模式即固定(host 只允许 blank 会话 recompose),同一会话内的目录帧文本不会变,现有 entry-only 的
digestCatalogEntries(L328–335)依旧正确,无需改动会话日志格式,也不影响history.visibleDigest的重放推导。可选加固:
skill工具的 description(packages/skill/tool-skill/src/index.tsL82–84,"Call this with the exact skill name…")在 code 模式下会进入 SDK 投影,可一并按模式限定措辞,进一步降低模型误判概率。方案 B(替代,改动最小)
不引入模式读取,把目录文案改为模式无关的中性表述,例如:
该方案不依赖
dsh-tools改动,但指令不如方案 A 精确(模型需要自行推断run_code路线),按仓库"模型视角、明确措辞"的约定,推荐方案 A。All reactions