[缺陷] Harness 存在缺陷极可能诱导 PTC 模式(Code Mode)下工具调用频繁失败 #1605
Replies: 2 comments
|
逐条对着 master(47f943859b)核实 + 本地实测复现了两个偏移量——你的审计全部成立,补上实测数据和一个实现层面的精确性提醒。 实测确认① strip 包裹失败:
② 运行时异常 +3 恒定偏移:实测复现。 模型第 3 行抛
实现层面的精确性提醒:不要硬编码 +3+3 里的 +2 是 V8 引擎对 AsyncFunction 构造器源码的偏移,不是 harness 可控的——硬编码 3 在 Node 版本升级后可能漂移(V8 内部表示变化)。更稳的两种做法:
修复设计(模型可见文本应长这样)
修复点集中( |
现象两个独立 session(同模型 GLM-5.2、同 preset 第一个 session:模型不知道处于 code-only 模式,不知道 SDK section 存在。用户追问"你 system prompt 读全了吗",模型回答"无法逐字导出自己的完整 system prompt",回避了问题。用户多次追问后,模型仍坚称 system prompt 中没有工具清单。最终通过解压 session 日志才证实 SDK section 一直存在。 第二个 session:AGENTS.md 中添加"code 模式下,所有的工具调用都必须通过 run_code,仔细通读全部 system prompt"。结果:模型在 reasoning 中引用了"仔细通读"指令,但仍然只列出 "发现"后参数名仍然是错的:第二个 session 中,模型最终列出了完整工具清单并给出调用示例,但示例中的参数名与 SDK section 中的声明不一致:
这证明模型即使"发现"了工具,也没有读取 SDK section 中的 TypeScript 类型声明——工具名是从 证据通过解压 session 日志(
三者都在 system message(system role)中。模型在两个独立 session 中均未处理 #1 和 #2。模型处理了同 message 中的散文段落(persona、tool guidance 段、run_code 编写说明),但跳过了 code-only rule(1 句话,夹在 persona 和 tool guidance 之间)和 SDK section(64KB TypeScript 代码块)。 AGENTS.md(user role,~14KB 散文)被处理了——模型遵循了其中的规则、引用了其中的内容。但 AGENTS.md 中的 DSH Tool Mapping 表对 code mode 是错误的(把工具描述为可直接调用)。结果:错误信息被处理了,正确信息未被处理。 失败链总结以第二个 session 为例,完整的失败链:
这表明问题不在指令层面——无论怎么指示模型"读 system prompt",模型都不 reliably 处理 64KB TypeScript 代码块。 分析@lithium-chamber 在 Issue 3 中将问题归因为"run_code-only 规则只有一句话 + 后面十几段 'Use the X tool…' 的混合信号"。我的发现表明原因可能更深: 模型没有读到 code-only rule 和 SDK section,不是因为矛盾信号干扰,而是因为注意力没有处理这两段内容。 消除矛盾信号(删除 AGENTS.md 工具映射表)和添加显式读取指令("仔细通读 system prompt")均未能改变这一行为。两个独立 session 重复了同样的失败模式,表明这是系统性的,不是偶然。 code-only rule 是 1 句话,淹没在约 96KB 的 system message 中;SDK section 是约 64KB 的 TypeScript 代码块,占 system message 的 66%。模型处理了 system message 中的散文段落,但没有处理这 1 句话和这 64KB 代码块。 这意味着 @lithium-chamber 提出的修复方向——"调整提示词工程的兼容性"——可能不足以解决问题。矛盾指令确实是问题的一部分,但更根本的问题是:模型不 reliably 处理 system prompt 中的大段代码块,无论周围有多少指引。 验证方式如有其他人想验证:
补充:@argszero 回复中未覆盖的部分@argszero 的回复逐条确认了 Issue 1(strip 错误信息丢失)和 Issue 2(行号偏移),但未回应 Issue 3(提示工程层的 run_code-only 规则兼容性问题)。本回复补充的是 Issue 3 的根因分析,而非 Issue 1/2。 吐槽这个问题就像是,考试题不会做,题边上写着答案在某本书的第三页,不读;边上人提醒,不读;自己跑去图书馆翻了一圈,终于发现答案是在某本书的第三页,但仍然没有细看,题还是答错了。这种情况下,PTC(code mode)以及所有基于code-mode创建的自定义 preset,都是完全不可用的。不要把这个问题推给 GLM-5.2,这个模型在 Claude Code 中表现完美。AGENTS.MD 和用户级别的 prompt 都无法让它去通读 system prompt,这只能是 Harness 的问题。我从未见过任何一个哪怕很小的模型,在其他 Harness 环境下连读个 system prompt 都这么费劲。 |
Uh oh!
There was an error while loading. Please reload this page.
Harness 存在缺陷极可能诱导 PTC 模式(Code Mode)下工具调用频繁失败
总览(TL;DR)
PTC 模式(即
apps/cli/config/agent-presets/code/preset.yml对应的 Code Mode)下经常观察到几种工具调用报错:第一类错误
在个人的使用过程中,此类错误的Payload大概都遵循类似的风格:
{ "code": "*一行超级超级长的TypeScript代码", "description": "...blablabla..." }是模型写的TypeScript代码本身出现了问题,返回一行极为简短的报错:
Error: code run failed (exception): Expected ',', got 'inf'Error: code run failed (exception): Expected ',', got ')'Error: code run failed (exception): Expected ',', got 'hash'Result报错非常简短,此时模型只能猜哪里出错了。
第二类错误
Error: code run failed (exception): TypeError: "Some string...".result is not a function这种报错的Payload大致与第一类那种差不多,都是有一段很长的TS代码,然后出现了
"一段String".result这样的片段,而.result这个方法不存在,报错。第三类错误
模型会尝试调用不存在的工具。典型例子是PTC模式下询问用户问题的时候,模型理应使用TS脚本中的
tools.ask_user_question方法,但是却直接尝试调用一个不存在的工具ask_user_question:经逐段审计和重放,大致可以归因为:
Expected ',', got 'inf'/Expected ',', got ')'是模型生成的 TypeScript 本身有语法错误(在期望逗号的位置写了裸标识符——如inf(应为Infinity)、hash——或漏逗号、多右括号);"...".result is not a function是模型对工具结果套用了.result()包装器习惯。由于执行管线中不存在任何字符串转义规则异常或重格式化,也即code字符串从模型输出到 worker 执行全程零变换(见 Issue 0),所以可以确认为模型本身不适应PTC模式下这种用TS调用一切工具的形式——这点要麻烦DeepSeek团队加强一下模型对自家工具的适配后训练了。Observation:执行管线中
code字符串全程零变换通过AI Agent辅助,我们排除了"
code字符串可能经过了提示词没有强调的转义/重格式化"的想法。每一段都是 verbatim 传递。
packages/llm/llm-deepseek/src/translate.ts:152-170block.text += fragment),无任何处理JSON.parse(标准)snapshotJsonValue(lossless JSON)run_code传输packages/core/tools/src/code-mode.ts:611-622program: args.code原样交给 runtimepackages/code-runtime/code-runtime-worker-thread/src/index.ts:300-303stripTypeScriptTypes(STRIP_WRAP.prefix + request.program + STRIP_WRAP.suffix),包裹壳仅用于解析后按前缀/后缀长度切回workerData(结构化克隆)packages/code-runtime/code-runtime-worker-thread/src/bootstrap.ts:405-412'use strict';\n${data.code}直接进AsyncFunction因此后文所有报错均可归因于"模型写出的代码本身"+"Harness 如何报告这个错误",而不是任何中间层对字符串的改动。
Issue 1:
Error: code run failed (exception): Expected ',', got 'inf'/Expected ',', got ')'症状
模型执行 TS 脚本时收到:
等问题
基于当前管线的复现
按
index.ts:84, 302-303的包裹方式复现:两个异常对象的完整属性:
原因分析
直接原因:模型生成的代码在期望逗号的位置写了裸标识符(如
inf——应为Infinity;hash等),或漏了逗号、多了右括号。这是模型输出错误,不是 harness 改坏了字符串(见 Issue 0)。但是,Harness 存在放大此问题的设计缺陷:
stripTypeScriptTypes(Node 内置,amaro/SWC 实现)抛出的SyntaxError的.stack属性里原本带有完整定位信息——行号(:2)、代码框、^^^光标、错误码ERR_INVALID_TYPESCRIPT_SYNTAX——但 runtime 的 catch 分支只取了.message:于是模型只收到一句话
Expected ',', got 'inf',没有行号、没有代码框、没有光标定位。程序越长,模型越无法定位自己哪里写错了,只能尝试整段重写再撞一遍,这是 PTC 下"同类报错反复出现"的主要放大器。或者模型只会花更多精力在思考过程中检查TS代码中的问题,污染上下文,消耗更多token,这有可能使得PTC模式下的编程性能明显下降。附带事实:
.stack里的行号相对包裹后的源码(第 1 行是async function __dsh_program__() {),修复时减去 1 行即模型源码行号;代码框里那行 wrapper 也应剔除。源码位置
packages/code-runtime/code-runtime-worker-thread/src/index.ts:300-309messageOf():packages/code-runtime/code-runtime-worker-thread/src/index.ts:109-111packages/code-runtime/code-runtime-worker-thread/src/index.ts:84packages/core/tools/src/code-mode.ts:631-634(code run failed (${kind}): ${message})Issue 2:
Error: code run failed (exception): TypeError: "Some string...".result is not a function症状
程序能跑起来,但运行时抛:
复现
worker 重放(host 回复一个字符串工具结果,程序对其调用
.result()):我观察到的第二类错误中的
"Some string..."只是"模型在代码里内联了字符串字面量"的变体,本质是同一类错误。原因分析
.result()之类的包装器 API 套在工具结果上。经过全仓库的文件的检索,提示文本、工具描述、SDK 说明中没有任何地方教.result()(找到的唯一相近的是 workflow/ralph 输出 schema 里的result字段,见下)。tools:sdk段(packages/core/tools/src/ts-types.ts:250-292)给每个工具声明了精确输出类型(例如read返回{ path; offset; lines: {...}[]; totalLines },见官方快照examples/acp-agent/tests/snapshots/code-mode-turn/system-prompt.expected.md:343-351),.result()与任何声明都不符。但类型标注"advisory only"(擦除执行,无类型检查),且 SDK 说明没有任何否定性表述:没有一句话说"结果是裸 JSON 值,不存在.result()/.json()之类的包装方法"。以目前的 DeepSeek 模型性能来看,Prompt中显然需要这种显式否定。workflow与ralph的输出 schema 恰好声明了result: { type: 'json' }字段(packages/workflow/tool-workflow/src/index.ts:257-271、packages/workflow/tool-ralph/src/index.ts:380-383),SDK 里就长这样:workflow: {...; result: JsonValue}。这有可能让模型强化"工具结果都有.result"的印象。prepareException取error.stack ?? error.message,bootstrap.ts:216-229)里,真正有用的只有第一帧eval ... <anonymous>:N:C,其余全是 harness 内部噪音帧(绝对路径指向bootstrap.ts/worker.ts/module_job),这有可能干扰模型。<anonymous>:N的N = 模型源码行号 + 3,是恒定偏移:程序第 1/2/5 行抛错分别报:4/:5/:8;多行类型注解不破坏行计数(擦除用等长空格保留换行),列号保持。偏移来源 ='use strict';指令 +1 行 + V8 对AsyncFunction构造器源码的 +2 偏移。Harness 从未做任何重映射,也没有把内部帧裁剪掉。.agents/notes/implemented/feature/2026-06-15-code-mode.md:75声称 "position-preserving, so runtime error line numbers match the model's source"。我的AI Agent实测不符,也即上面提到的行号相差 +3偏移,且这段断言并未被任何测试覆盖(该文件相关测试只断言/enum|strip/i,packages/code-runtime/code-runtime-worker-thread/tests/runtime.spec.ts:128-133;全仓库也仅有src/index.ts一处引用stripTypeScriptTypes,设计文档声称的位置保持单测在当前测试套件中并不存在)。源码位置
packages/code-runtime/code-runtime-worker-thread/src/bootstrap.ts:216-229AsyncFunction构造与'use strict'前缀:packages/code-runtime/code-runtime-worker-thread/src/bootstrap.ts:405-412packages/core/tools/src/ts-types.ts:250-259result字段:packages/workflow/tool-workflow/src/index.ts:257-271、packages/workflow/tool-ralph/src/index.ts:380-383.agents/notes/implemented/feature/2026-06-15-code-mode.md:75Issue 3:PTC 下模型直接调用
ask_user_question等原生工具被拒症状
模型想向用户提问时,不写 TS 程序、不通过
tools.ask_user_question(...),而是直接发出原生工具调用,比如ask_user_question,PTC模式下,Harness 拒绝并返回:复现大致流程
PTC模式(
code模式)下:run_code——wireSchemas()把可见 schema 过滤为仅保留RUN_CODE_NAME(packages/core/tools/src/index.ts:980-1001),因此发给 DeepSeek API 的 function 列表只有run_code一个。ask_user_question原生调用(即它凭空"脑补"了一个 wire 上不存在的工具名,这可以被认为是 DeepSeek 模型对原生工具调用的强先验)。collapses()判定"非嵌套调用 + code 模式 + 名字不是 run_code"即拒绝(packages/core/tools/src/index.ts:1324-1326),拒绝文本即上面的引导语(:1436-1443),渲染为Error: <msg>(toolErrorResult,:1870-1878)。这个拒绝本身是设计好的、错误文本也有指导性(值得保留)。 这个 Issue 想要说明的是可能诱导或者加强此错误的提示词工程问题。
系统提示词与 run_code-only 规则兼容性似乎并不好
a. plan-mode 段。计划模式段(
packages/plan/plan-mode/src/index.ts:225-233,order 50)在 collapse 规则(order 99,packages/core/tools/src/index.ts:51, 58)之前渲染,且原文要求:(PTC 预设挂载的配置原文:
apps/cli/config/agent-presets/code/agent.cordis.yml:120-131。)在 PTC 下这条指令无法被字面执行:唯一的 wire tool 是
run_code,exit_plan_mode只能作为 run_code 程序内的子分发调用(tools.exit_plan_mode(...))。模型照字面执行 → 被拒 → 得到上面的报错。这有可能直接诱导"模型尝试直接调工具"。b. skill 目录提醒是模式无关的。
<system-reminder>用户消息(packages/skill/tool-skill/src/index.ts:264-268)原文:"call theskilltool with the exact skill name before taking task actions"。PTC 下同样只能tools.skill(...)进程序调用。c. 十余条工具 guidance 段全部以"直接调用"口吻写成,且全部排在 SDK 段(order 150,
packages/core/tools/src/code-mode.ts:23)之前:tool:read(100) "Use the read tool — not shell commands like cat…"、tool:write(101)、tool:edit(102)、tool:glob(103)、tool:grep(104)、tool:bash(105)、tool:jobs(106)、tool:web_search(110)、tool:web_fetch(111)、tool:lsp(112)、tool:goal(114)、tool:workflow(115)、tool:ralph(116)、tool:subagent(116.5)。它们不提"必须通过 run_code 程序调用",持续强化"工具可以直接调用"的心理模型。d. run_code-only 规则本身只有一句话(
packages/core/tools/src/index.ts:58):"run_codeis the only tool you can call directly — a tool call naming any other tool fails." 它确实排在最前面(官方快照examples/acp-agent/tests/snapshots/code-mode-turn/system-prompt.expected.md:8),但对一个预训练强烈偏向原生工具调用的模型,单句规则 + 后面十几段"Use the X tool…"的混合信号,可能不足以压过习惯,这与我观察到直调ask_user_question一致。源码位置
packages/core/tools/src/index.ts:980-1001packages/core/tools/src/index.ts:1324-1326;拒绝文本::1436-1443;错误渲染::1870-1878packages/core/tools/src/index.ts:51, 58packages/plan/plan-mode/src/index.ts:225-233;PTC 预设文本:apps/cli/config/agent-presets/code/agent.cordis.yml:120-131packages/skill/tool-skill/src/index.ts:264-268packages/core/tools/src/code-mode.ts:23附加发现
以下是我的DeepSeek Harness Agent在探索过程中发现的一些其他问题,在此一并上报。
invalid-output不指明违规值。实测return Infinity(或返回值含undefined/BigInt/循环引用):模型无法得知哪个值违规。相关:
packages/code-runtime/code-runtime-worker-thread/src/bootstrap.ts:166-190(prepareCompletion)+worker-json.ts:150-233(snapshotCodeJsonValue)。"erasable syntax only" 是黑话,无清单、无一次性预警。SDK 说明只有 "no
enumor namespaces"(ts-types.ts:252)。实测会在擦除阶段硬失败的构造(每轮只暴露一种,各耗一次往返):enumTypeScript enum is not supported in strip-only modeTypeScript parameter property is not supported in strip-only mode<T>x尖括号断言The angle-bracket syntax for type assertions ... use the 'as' syntaximport/export'import', and 'export' cannot be used outside of module code<div>hi</div>Expression expected0644Legacy octal literals are not available when targeting ECMAScript 5 and higherwithThe 'with' statement is not supported...let声明SyntaxError: Identifier 'x' has already been declared+ 噪音堆栈程序体在 strict mode 下执行,这一点提示词从未声明(
bootstrap.ts:410的'use strict';)。console是 5 方法 shim(log/info/warn/error/debug,bootstrap.ts:100-120),console.table/console.dir会得到TypeError: console.table is not a function这类毫无指引的报错。最后,感谢DS团队带来这么有趣的Harness,希望DS的模型和Harness都变得越来越好,辛苦了!
本人并非专业Harness工程师,以上分析大部分也是在AI Agent辅助下完成的。如果有任何错误的结论和矛盾的建议,还请不吝赐教。
All reactions