Replies: 3 comments
|
补充一组本机分布数据,用于缩小范围(同一批 1212 个会话文件,按 cwd 项目分组):
即:由外部程序驱动的会话(ACP / 无人值守)墓碑率约 6–8%,日常交互会话 0.8%,相差约 6–10 倍。 另一个更精确的模式:墓碑只出现在「需要等待」的工具上。全部 31 个墓碑对应的工具:
反例(同一次并行调用内的对照):某会话一次 assistant 同时发起 结论:进程在等待时被终止,正在等待的那个工具留下墓碑,瞬时完成的工具不受影响。也就是说,墓碑与「外部终止进程」强相关(在 ACP / 网关场景下尤其频繁),不是工具自身失败——正因如此,把它呈现为普通「工具失败」的代价更大:使用者会去查工具和网络,而真正该查的是「谁终止了引擎进程」。 |
|
我把这条链路从 repair 一路读到 client,三个源级确认,外加一个作者没提到的、能一次闭合「建议 1 + 建议 3」的落点。 一、机制确认,补两个边界
二、建议 2 的真实成本(比「改文案」重)现在被逐字符锁死的不只是 id:
也就是说这句文案是会话格式迁移判别契约的一部分,不是一个可以随手润色的字符串 —— 改它必须连带出一个新 format 世代。(顺带修正一处细节: 三、作者漏掉的:判别符早就在了,只是没人消费
问题是没有任何呈现层消费它。我 grep 了整个 packages:只有 而没有 即:「这是被中断,不是失败」这个信号在客户端早就存在、已有三个渲染器认它,只有崩溃恢复这一支没接上。 → 因此建议 1 与建议 3 是同一件事:把它做成一条沿节点传播的中断标记,而不是往合成文本里塞说明。你建议里那句「(或新增 recovered / cause 标记)透出给 UI 与插件」是成本最低、且与现有设计一致的一条。 四、字段级落点
五、一条对排查有用的推论因为 cold read 不落盘,判断「这个会话曾被恢复过」的唯一可靠依据是日志里有没有那条合成的 如果你需要,我可以把本机含墓碑的会话按「有落盘 closer / 只有 cold-read 合成」分成两类取个比例,用来看这个改动的收益面。 |
|
再补一条同一段文案的第二条产生路径:读取路径也会凭空合成这段文本——而此时根本没有任何中断。 一、现象(本机实证)2026-09-10 19:38 一个由外部程序(ACP 引擎,经网关投递)驱动的回合,在 Web GUI 里被显示为「工具调用失败」:
但该回合在磁盘上完整跑完,全程无异常:
按该次调用的唯一 二、机制(一手读码)
因此:由其他进程持有的会话,对本进程一律是「冷日志」。读到「已有 三、本机复现(与 GUI 显示逐字一致)把该会话截到「 四、影响(比原报告更重)
五、判别口径(本机现用,供参考)
六、建议
|
Uh oh!
There was an error while loading. Please reload this page.
崩溃恢复合成的工具结果缺少「恢复」语义:用户与模型都误判为真实工具失败
环境
0.1.5-rc.1(npm 全局安装,Windows 11)~/.dsh/sessions/,共 1212 个会话文件一、现象
引擎在工具执行期间非正常退出后,用户下次打开该会话,时间线里会出现「工具调用被中断」的失败卡片:
用户没有点过停止,也没有网络异常。卡片与普通工具失败长得一样,于是被理解成「工具坏了」。
本机实证:同一用户在 3 小时内两次把这些卡片原样复制出来追问原因(13:14 一次、13:55 一次),第二次甚至直接当成 Harness 的缺陷上报。界面上没有任何「引擎曾异常退出」的信号,用户无从判断该查什么。
二、机制(一手读码,非猜测)
出处:
@deepseek-ai/dsh-session/lib/types/repair.js。模块注释原文:interruptedTurnClosers()在加载崩溃遗留日志时合成收尾事件:tool/call、无结果{name:"ToolOutcomeUnknownError", code:"TOOL_OUTCOME_UNKNOWN"}tool/call未落盘{name:"ToolNotStartedError", code:"TOOL_NOT_STARTED"}关键实现细节(
repair.js:78-82):即:合成结果的时间戳 = 崩溃前最后一个真实事件的时间,而不是恢复发生的时间;并且合成结果走
tool/result+isError: true的同一条渲染路径。README.zh.md:152印证了这两段文案,但未提及时间戳语义。三、影响
1. 用户把「引擎崩溃」读成「工具失败」
墓碑在事件层与真实工具结果同形(
tool/result、isError: true)。用户看到「网页搜索 / 查看 失败」,第一反应是工具或网络出问题——而真正需要知道的是「Harness 刚才异常退出了,该查它为什么退出」。2. 模型按「重试」处理,但真问题不是重试能解决的
墓碑文本本身在引导模型「判断要不要重试」;而实际需要的是「引擎崩过」。两条处置路径完全不同,按前者走还会把崩溃本身掩盖掉。
3. 时间戳是假的,排查会被带偏
本机实例(会话
7ec895fd-634c-4d9f-9251-647ae4dc6719,cwdF:\agenttalk-core):tool/call(pwsh)tool/result(TOOL_OUTCOME_UNKNOWN)step/endturn/end {reason:{kind:"interrupted"}}session/end-seed(真实恢复时刻)按墓碑时间会得出「工具刚被记录就同一毫秒被杀」的结论;实际恢复发生在 3 分 42 秒之后。本机第一次排查确实被这个时间戳带偏过。
4. 规模
本机 1212 个会话文件中,21 个会话含此类合成墓碑、共 31 个事件(2026-08-15 ~ 2026-09-10)。不是冷路径。
四、建议(供参考)
error.code(或新增recovered/cause标记)透出给 UI 与插件,便于宿主自定义呈现。补充:崩溃恢复机制本身是正确且必要的(这次恢复也让会话能继续使用)——本条只反馈呈现层缺少「这是恢复合成」的信号这一点。
All reactions