DeepSeek Harness fork 子会话回放失败:seed 未闭合 step 怎么补
父会话跑到一半,你 fork 一个子会话继续做分支任务;子会话创建成功,但第一次回放就报 step/start at seq 2600 arrived before turn 8/step 1 ended。 子会话文件没有写坏,是 fork 的那一刀切在了 step 中间:父会话还没有写 turn/step/end,seed 却已经把下一个 step/start 带过去了。DeepSeek Harness(DSH)的回放器按严格顺序校验,直接判定越界(来源)。
报错特征:确认是 DeepSeek Harness 的 seed 未闭合
只有 fork 出来的子会话失败、父会话正常、报错稳定指向某个 seq 与 step,才是 seed 未闭合;父会话也打不开就按会话损坏处理。
- 读报错,确认同时出现
step/start、arrived before和turn X/step Y ended。预期:三者都在。 - 在子会话日志开头找对应的
step/start,再找上一步的end。预期:start 在,end 不在。 - 重新 fork 一个已完成的轮次。预期:新子会话回放正常,排除文件损坏。
- 确认父会话能正常打开并继续。预期:父会话不受影响。
- 记录报错里的 seq 号。预期:与子会话日志里的位置对得上。
| 现象 | seed 未闭合 | 会话文件损坏 |
|---|---|---|
| 父会话 | 正常 | 可能打不开 |
| 子会话 | 回放报越界 | 加载即失败 |
| 重新 fork | 恢复正常 | 仍然失败 |
据讨论里的源码核对,core/session/src/fork.ts:21-29 的 buildForkSeed 复用了 repair.ts:53 的 openTurnClosers,但没有强制调用;core/session/src/index.ts 只逐事件校验形状,不校验尾闭合;报错最终来自 token-meter/src/index.ts:268-271(#10114)。
根因:DeepSeek Harness fork 为什么切在 step 中间
fork 复制的是「当前已有的父会话事件」,而进行中的 step 还没有结束事件,复制点自然落在半截。
- 父会话正在执行某一步,事件已写入
step/start和部分增量。预期:事件列表尾部是开放的。 - 用户触发 fork,复制逻辑读取当前事件列表。预期:拿到一份快照。
- 列表末尾没有
turn/step/end,seed 原样带走。预期:中间态进入子会话。 - 子会话继续追加新的
step/start。预期:两个 start 之间没有 end。 - 回放器按顺序校验。预期:判定越界并报错。
即使 fork 时父会话刚好结束,复制与写入之间的竞态也可能拿到未闭合快照。压缩过的会话更容易踩中,因为事件被折叠,闭合边界不明显。
这也是为什么「父会话看起来已经停了」不等于安全。复制读的是事件列表,不是界面状态。
修法一:等 step 完成再 fork DeepSeek Harness 会话
不改代码时,最稳的做法是等当前回合结束再 fork,避开中间态。
- 观察父会话状态栏,确认没有正在运行的工具或思考动画。预期:界面处于空闲。
- 等本轮
turn/end落盘,可看日志或状态栏。预期:闭合事件已经写入。 - 再执行 fork。预期:子会话从闭合轮次开始。
- 打开子会话,发一条消息。预期:回放正常,回合能继续。
- 如果仍失败,换一个更早的已完成轮次作为 fork 点。预期:重试能复现成功。
- 多等两秒再 fork 一次。预期:结果与上一次一致,不是竞态造成的偶发。
这条修法只要求你改操作节奏,但团队里每个人都要遵守。批量 fork 尤其容易忘,最好在流程里写明「本轮结束后再切分支」。
修法二:让 DeepSeek Harness 在 seed 生成时补齐闭合事件
根治点在 buildForkSeed:复制后调用 openTurnClosers,把未闭合的 turn/step 补上结束事件,或直接拒绝这种 fork。
- 在
fork.ts复制事件后,扫描最后一个 turn/step 是否有对应 end。预期:闭合状态可知。 - 没有就调用
openTurnClosers生成闭合事件,追加到 seed 末尾。预期:seed 以匹配的 end 收尾。 - 如果补齐会改变语义,例如工具结果尚未返回,改为返回明确错误。预期:用户看到「请等本轮结束」。
- 在 seed 元数据里记录是否发生过补齐。预期:诊断时能区分原始 seed 和修补过的 seed。
- 补测试:已完成、进行中、刚好结束三种复制点各一条。预期:三条都符合设计。
- 在 PR 里附上触发时的 seq。预期:维护者能对照 0.2.1-rc.2 复现。
- 复查压缩会话的 fork。预期:折叠后的边界同样能被识别。
补齐还是拒绝,要先定语义。补齐对用户无感,但子会话可能看到一个并未真正完成的 step;拒绝更干净,代价是 UI 必须给出提示。
无论选哪种,错误信息都要说清是第几轮第几步未闭合。只报一个 seq,排查还得自己去翻日志。
修法三:重建 DeepSeek Harness 子会话,不用坏 seed
已经拿到坏 seed 时,最省事的是删掉子会话,按修法一重新 fork。
- 备份子会话目录,确认没有需要保留的独有内容。预期:安全副本存在。
- 删除或归档该子会话。预期:坏 seed 不会被再次打开。
- 回到父会话,等本轮结束。预期:父会话空闲。
- 重新 fork,确认新子会话回放正常。预期:不再出现顺序错误。
- 如果子会话里有独有工具结果,先复制到父会话再删。预期:没有丢有用信息。
- 确认回收站或归档目录里还能找回。预期:误删时有一次后悔的机会。
删之前一定先看子会话里有没有只存在于那里的输出。工具结果不会因为重新 fork 而自动回来。
验证与边界:DeepSeek Harness fork 后如何复查
完整的修复要能拒绝或闭合中间态 fork,同时不影响正常 fork 的回放。
- 在父会话执行一个长工具调用,进行中尝试 fork。预期:被拒绝或自动补齐。
- 等本轮结束再 fork。预期:子会话能正常回放与继续。
- 检查子会话日志。预期:没有孤立的
step/start。 - 用 TokenMeter 重建一次统计。预期:不再报越界。
- 连续 fork 三次。预期:三次都能打开。
- 用 DSH插件 做批量 fork 时抽一条检查。预期:seed 元数据里能看到闭合处理。
复查时优先看子会话的第一屏,而不是最后一条消息。越界发生在开头,后面往往还有正常内容,容易误判成已经好了。
边界有四条:不要手工编辑 seq,回放器对连续性要求严格;fork 进行中的会话本来就有语义风险;压缩后的会话 fork 更容易出问题;讨论里没有官方修复版本,0.2.1-rc.2 仍可复现。补齐只补结构不补 usage,子会话的 token 统计以它自己的事件为准。日志层面的同类问题见 会话日志 seq gap 修复。
常见问题
DeepSeek Harness 的 fork 把未闭合的 step 原样复制进了 seed。上一个 step 没有 turn/step/end,下一个 step/start 就先到了,回放器按顺序校验时判定越界。需要在 seed 生成时补齐结束事件。
fork seed 是 DeepSeek Harness 创建子会话时复制的初始事件集合,决定子会话从哪一轮、哪一步开始。复制点落在 step 执行中时,父会话还没写结束事件,seed 就停在中间态。
DeepSeek Harness 的 seed 问题只影响 fork 出来的子会话,父会话仍能正常打开,报错稳定指向某个 seq 与 step。检查子会话日志开头是否缺少对应 step 的 end 事件即可确认。
DeepSeek Harness 的事件可以手工补,但风险高。必须保证顺序、seq 连续、字段完整,否则会引入新的回放错误。更稳的是重新 fork 已完成的 step,或让 buildForkSeed 自动补齐。
相关术语
- fork seed
- fork seed 是 DeepSeek Harness 创建子会话时复制的初始事件集合,决定子会话从哪一轮、哪一步开始。它必须是一个闭合的事件序列,否则回放会失败。— https://github.com/deepseek-ai/deepseek-harness/discussions/10114
- openTurnClosers
- openTurnClosers 是 DeepSeek Harness 用于补齐未闭合 turn/step 的辅助函数,能把中间态事件补成可回放的闭合序列。buildForkSeed 已引用它,但没有强制执行。— https://github.com/deepseek-ai/deepseek-harness/discussions/10114
- TokenMeter replay
- TokenMeter replay 是 DeepSeek Harness 重放会话事件以重建 token 统计的过程,按 turn/step 的严格顺序校验事件。遇到越界的 step/start 会直接报错,而不是跳过。— https://github.com/deepseek-ai/deepseek-harness/discussions/10114
来源
- #10114 — 中途截断的 seed 通过 agents.create,TokenMeter 回放报错· deepseek-ai(GitHub Discussions)
- DeepSeek Harness 官方仓库· deepseek-ai(GitHub)