DeepSeek Harness 新建会话出现旧内容与子 Agent 设置失效:空壳会话清理

故障排查发布于 2026-10-30作者: DeepSeek Plugin 插件市场
DeepSeek HarnessDSH新建会话blank会话复用子 Agentsession
DeepSeek Harness 点新建会话、发第一条消息,却冒出几天前的图片或命令记录;创建时间还是旧的,子 Agent 模型选择也悄悄失效。原因是 blank 判定只数 turn,先识别三类空壳会话再清理。

点「新建会话」,界面是空白输入页,看起来一切正常;输入「哈哈」发出去,屏幕上却先冒出一条 10 月 20 日用 /image 生成的图片卡片,你的新消息被追加在它后面。 这不是界面渲染错乱——新建会话根本没新建,它把一条旧会话当成「空白会话」复用并 seed 了(#10889)。先分清三种空壳会话,再决定怎么清。

DeepSeek Harness 判据一:新会话里出现旧内容

只要旧事件出现在 session/end-seed 之前,就是复用;真正的空白会话不会有这个事件落在中间。

  1. 找到会话日志 ~/.dsh/sessions/<workspace>/<session-id>/session.v4.jsonl.zstd。
  2. 解压后看事件序:社区案例里 seq 3 是 10-20 的 command/run,seq 4 是 command/done。
  3. seq 5 是 10-24 20:33 的 session/end-seed——这就是「把旧日志当 seed 收尾」。
  4. seq 6 才是新消息 agent/inbox/spliced "哈哈",seq 7 起才是 turn/start。
  5. 事件时间跨度就是证据:同一份日志里出现两个相隔四天的时间段。

DSH插件 判据二:创建时间不对

会话头的 createdAt 保留旧值,所以「新会话」显示的是几天前的创建时间;这是复用最直观的一条线索。

  1. 看会话列表里的创建时间,和你刚才点「新建」的时刻比。
  2. 社区另一个案例里,新会话显示的是 10-17 的时间,实际当天是 10-24。
  3. 这类会话的日志通常只有三条 seed 事件:permission/preset、sandbox/mode、approval/policy,没有 turn/start,也没有 end-seed。
  4. 也就是说,上一次创建过程没走完,留下一条半初始化记录,被判成 blank 后又被复用。

DeepSeek Harness 三类空壳会话:为什么会永久算 blank

blank 的定义是「折叠后不含任何 turn」,与「有没有内容」无关,所以下面三类都会长期留在候选池里。

类型日志里有什么怎么来的
命令型command/run + command/done只跑斜杠命令(如 /image),没有形成 turn
半初始化型只有 permission/preset、sandbox/mode、approval/policy创建过程没有收尾,缺 end-seed
单条消息型只有一条 user/message首条消息被打断或失败

社区实测:/image 会话与「只有一条 user/message」的会话,在 sessionListMetadata 里都是 blank: true。判定逻辑就写在 schema 里:「Whether the folded prefix contains no turn.」

DeepSeek插件 判据三:子 Agent 模型选择静默失效

这类会话里没有 subagent/model-selection-policy 事件,subagent 工具不带 provider/model,设置页却还写着「仅影响新会话」,用户无从察觉。

  1. 打开工作区配置,确认 subagent-model-selection-settings 是 enabled: true 且有 allowedModels。
  2. 在被复用的会话里搜 subagent/model-selection-policy,没有这条事件。
  3. 看 request/header 的 tools 数组:subagent 只有 cwd、description、prompt,没有 provider、model、reasoning_effort,也没有 list_subagent_models。
  4. 对照同工作区里真正新建的会话:seq 3 就有该策略事件,subagent 带三个参数,list_subagent_models 也在。
  5. 根因是 tool-subagent 用 firstLiveSeq === 0 判新会话;复用会话从磁盘恢复后首个存活序号是 3(补完 end-seed 后是 4),永远不等于 0,策略就不会被读取和写入。
  6. 这种策略是每会话一次性快照:那条正常会话快照的是当时的 2 条路由,而当前配置已是 4 条。

DeepSeek Harness 清理:找出空壳会话并移走

判断标准只有一个:日志里没有 turn/start,但有命令或用户消息。

  1. 完全退出 DSH,避免边清边写。
  2. 备份整个 ~/.dsh/sessions 目录。
  3. 逐个会话目录解压 session.v4.jsonl.zstd(zstd 多帧格式,需要逐帧解)。
  4. 统计 turn/start 出现次数:0 次且存在 command/run 或 user/message 的,就是空壳。
  5. 把这些目录移到 sessions 根之外(不要直接删,先移出观察)。
  6. 重启后新建会话,确认输入页是真正空白、创建时间是当前时间。

还有一点必须一起查:如果被复用的 blank 会话日志校验不过,新建会直接失败而不是跳过。社区遇到的报错是 SessionQueryError: stored session ... is corrupt ... session event at seq 4 lacks an identified message,原因是旧版本的 user/message 事件没有 data.id,而当前版本要求每条 message 必须带 id。这时只能手工修日志或删掉那条会话。

DSH插件 修复方向与今天的规避

核心要改的是 blank 的判定:只把「header 加默认初始化事件」算空白,并在复用前重新读一遍日志。

  1. blank 改成「日志为空」:只有 header 与 permission/preset、sandbox/mode、approval/policy 时才算。
  2. 或者至少把含 user/message、command/run 的会话排除在候选之外。
  3. 复用前重新读日志再判(refreshProjections() 目前只在 restoreBlank 分支调用,普通新建用的是可能过期的缓存提示)。
  4. 命中「有内容的 blank」时改为新建,而不是 seed 旧日志。
  5. create 路径对单条坏会话容错:跳过并提示,不要让一条坏日志卡死整个新建流程。
  6. 子 Agent 侧把新鲜度判据改成「没有 turn/start」,或在 blank 复用路径上补写一次策略事件。

一分钟自检清单

每次新建会话后花一分钟核对三项,能在串台变严重之前发现空壳会话。

  1. 列表里的创建时间是不是刚才点新建的那一刻。
  2. 输入页是不是完全空白,没有历史卡片、没有残留的滚动位置。
  3. 发出第一条消息后,日志里不应出现「session/end-seed 排在你的消息之前」这种顺序。

三项里有任意一项不对,就按上面的清理步骤把候选会话移出去,再新建一次。

注意事项

  1. 别以为「界面空白」就是新会话。真正的判断在日志里,不在 UI。
  2. 别只删最后一条。空壳会话可能有多个,清一个之后下次会复用另一个。
  3. 别忽略创建时间。它是零成本的自检信号。
  4. 清理前先备份。会话日志里有历史消息,误删不可恢复。
  5. 升级后复查。rc.3 上社区仍能复现,别以为换版本就好了。

如果你的新会话内容正常、只是偶尔某天出现旧图片,那也属于这一类,只是候选池里恰好只有一条空壳。相关排查见 DeepSeek Harness 新会话草稿丢失:handOffDraft、localStorage 与复用。

常见问题

DeepSeek Harness 新建会话后第一条消息,为什么冒出几天前的 /image 结果?

因为那条旧会话被 DeepSeek Harness 判定成 blank 并复用了。新建会话时会找同工作区里一条 blank 会话,把它的日志当成 seed 继续写,于是 session/end-seed 落在旧事件之后,旧内容就出现在「新」会话里。

DeepSeek Harness 的 blank 到底怎么判,为什么只有一条命令也算空白?

DeepSeek Harness 的判定是「折叠后没有 turn」,不是「没有任何内容」。所以斜杠命令会话(只有 command/run 和 command/done)、被打断的首条消息、命令失败留下的记录,都会永久算 blank。

DeepSeek Harness 新建会话的创建时间显示成七天前,这正常吗?

不正常,这同样是被 DeepSeek Harness 复用旧会话导致的。会话头里的 createdAt 保留旧值,所以「新会话」显示的是旧会话的创建时间;只要工作区里还有一条空壳会话,就可能反复出现。

子 Agent 模型选择设置写着仅影响新会话,为什么在 DeepSeek Harness 复用会话里不生效?

因为 DeepSeek Harness 的 tool-subagent 判「新会话」用的是 firstLiveSeq === 0。被复用的 blank 从磁盘恢复,首个存活序号等于已有事件数,永远不等于 0,于是策略事件不写入,subagent 工具也就不带 provider/model 参数。

怎么找出 DeepSeek Harness 中这些空壳会话,并安全清理?

在 DeepSeek Harness 里解压 session.v4.jsonl.zstd 后看有没有 turn/start:没有但存在 command 或 user/message 的会话就是空壳。把它们归档或删除,新建会话就能恢复真正的空白。

相关术语

blank 会话
blank 会话是 DeepSeek Harness 里折叠后不含任何 turn 的会话。判定只数 turn,不看是否存在 command 或 user/message,因此半初始化的记录也会被当成空白会话复用。— https://github.com/deepseek-ai/deepseek-harness/discussions/10889
session/end-seed
session/end-seed 是会话日志中的种子收尾事件,标记某份已有日志被当作新会话的初始内容。它出现在旧事件之后,就是「旧会话被复用」的直接证据。— https://github.com/deepseek-ai/deepseek-harness/discussions/10889
firstLiveSeq
firstLiveSeq 是会话中第一条存活事件的序号。tool-subagent 用它判断是否新会话:等于 0 才算新,因此复用过的会话永远拿不到新的子 Agent 策略。— https://github.com/deepseek-ai/deepseek-harness/discussions/10889
subagent/model-selection-policy
subagent/model-selection-policy 是会话内一次性快照子 Agent 可用模型设置的事件。它只在新建会话时写入,缺这条事件时 subagent 工具不会带 provider/model 参数。— https://github.com/deepseek-ai/deepseek-harness/discussions/10889

来源