ChatGPTClaudeGrok / X / CursorGemini

DSH plugin 怎么跟 Agent 生命周期?turn/step 时序、状态与两类事件

插件开发发布于 2026-10-21作者: DeepSeek Plugin 插件市场
DSH pluginDeepSeek HarnessAgent 生命周期session/eventturn
DeepSeek Harness 的 Agent 生命周期分成两套事件:agent/* 负责实时队列与状态,session/event 负责持久回放。turn 里先 pre-step,再 request、工具执行、step/end,最后 turn/end。

Agent 生命周期最容易踩的坑,是把两套事件当成一套用:agent/* 是实时协调,session/event 是持久回放。 前者告诉你“现在在队列里、正在跑、该重试”;后者告诉你“历史上到底发生了什么”。写插件前先决定你要观察哪一类,否则会出现“实时能看到、回放却没有”的错觉。

DeepSeek Harness:一轮 turn 的时序

一次用户输入先进入 inbox,再由 driver 认领成 turn;turn 内可以跑多个 step。 主干顺序:(来源)

  1. followup(content) — 用户或上游把消息放进 inbox。预期:出现 agent/inbox/spliced 与 agent/inbox/inserted。
  2. turn/start — driver 被排队工作唤醒,状态变 running。预期:开始认领待处理的下一步输入与一条排队 prompt。
  3. system-prompt/assemble — 组装系统提示词。预期:waterfall 可以在这里改写提示词。
  4. agent/pre-step — 决定是否进入消息批次。预期:返回 reject 或 enter(messages)。
  5. step/start — 进入一个 step。预期:随后发生 agent/request、请求准备与消息准入。
  6. assistant/message 或 assistant/attempt — 记录成功调用或失败尝试。预期:agent/assistant-stream 先实时推送 chunk,再给 committed end。
  7. 工具执行 — 按 executionMode 分类,走 barrier 与有界滚动池。预期:tool/call、工具结果事件、tool/result 按序出现。
  8. step/end → turn/end — 没有下一步输入且自然停止时收尾。预期:状态回到 idle。

如果 pre-step 拒绝、第一批为空或 pre-step 失败,已认领的批次保持移除,打开的 turn 不消耗 step。这不是错误,而是“这一轮暂时没有可执行输入”。

DeepSeek Harness:agent/* 与 session/event 的分工

实时状态与持久事实是两条通道,消费错通道就会得到不完整的历史。 对照:(来源)

通道内容适合谁
agent/*队列、状态、请求构造、steering、错误处理UI、实时协调插件
session/eventturn/step、消息、工具调用与结果SDK transcript、回放、审计

官方明确建议:需要可回放 transcript 的 SDK 用户应消费 session/event。agent/* 不是历史记录,它服务于“现在怎么协调”。

实时 agent/assistant-stream 的 chunk frame 是瞬态数据;回放读取的是 assistant/message 或 assistant/attempt 里的持久 settlement。进程在 settlement 前硬中断,不会留下持久 attempt stream。

DeepSeek Harness:三个可介入点

插件不需要改 driver,只要选对钩子:pre-step 管准入,request-error 管溢出,turn-stopping 管收尾。 三个点:(来源)

  1. agent/pre-step — 在构造请求前拦截或替换消息。预期:可以拒绝一批输入、补充上下文,或保留下游消息。
  2. agent/request-error — 处理规范上下文溢出与重试决策。预期:返回重试动作或保留原始错误;不要拿它做通用异常兜底。
  3. agent/turn-stopping — 自然停止且 inbox 为空时的串行终检。预期:适合做收尾检查,不要在这里启动新的长任务。

包装 next() 时要注意:保留下游消息与 startsRequestSeries,除非你确实想替换整批输入。

DeepSeek Harness:工具并发与 barrier

工具不是一把并发跑完;driver 会按 executionMode 分类,用 barrier 与有界滚动池控制节奏。 关键点:(来源)

  • 先分类再启动 — 每个待处理调用按执行模式归类。预期:只读与写入不会无序混跑。
  • 有序 pre、并发 execute、有序 post — 前置与后置按模型顺序,执行阶段可并发。预期:结果顺序仍与模型请求一致。
  • 工具自有事件 — 工具可以在执行中写自己的事件。预期:这些事件不替代 tool/result。
  • barrier 会重新分类 — 滚动池在启动前会再次检查。预期:不会因为状态变化绕过屏障。

写工具插件时,不要假设“上一个工具一定已经结束”;需要顺序就显式声明,而不是靠时间差。

DeepSeek Harness:三种消费方式

观察生命周期的方式不同,选错会多写很多胶水。 三种:(来源)

  1. UI 实时展示 — 消费 agent/status 与 agent/assistant-stream。预期:状态与流式输出及时。
  2. SDK transcript — 消费 session/event。预期:能回放完整 turn/step 与工具结果。
  3. 插件钩子 — 监听 agent/pre-step、agent/request-error、agent/turn-stopping。预期:在正确阶段介入,不破坏 driver 时序。

如果同一份数据在两套通道里不一致,以 session/event 为准做历史判断,以 agent/* 为准做实时协调。

DeepSeek Harness:一张事件顺序表

排查时序问题时,先把关键事件按顺序列出来,比读整段日志快。 简化顺序:(来源)

阶段关键事件说明
入队agent/inbox/spliced、inserted消息进入 inbox
开始turn/start、agent/status runningdriver 认领输入
准入system-prompt/assemble、agent/pre-step决定是否进入消息批次
请求step/start、agent/request准备并发出模型请求
结果assistant/message 或 assistant/attempt成功消息或失败尝试
工具tool/call、tool/result按 executionMode 调度
收尾step/end、turn/end、agent/status idle轮次结束

如果日志里缺少其中一段,不要先怀疑模型;先确认是不是被 pre-step 拒绝、被取消,或进程在 settlement 前中断。

三个排查判据

时序问题先看“缺哪一段”,比逐行读日志快。 三个判据:

  1. 有 turn/start 没有 step/start — 多半是 pre-step 拒绝、第一批为空或 pre-step 失败。预期:turn 不消耗 step,属于正常拒绝。
  2. 有 step/start 没有 assistant/message — 请求失败或被取消,可能留下 assistant/attempt。预期:按 request-error 与取消原因查。
  3. 有 tool/call 没有 tool/result — 工具还在执行、被 barrier 挡住,或进程中断。预期:看 executionMode 与活跃执行。

三个判据能把问题定位到准入、请求或工具层,而不是笼统地“Agent 不动了”。

DeepSeek Harness 常见问题

Q:为什么实时流里有内容,回放却没有? 实时 chunk 是瞬态的;回放只读 settlement。没有 settlement 的尝试不会留下持久流。

Q:turn/end 之后还会不会有 step? 不会。turn/end 是轮次终点;下一步输入会开新的 turn。

Q:压缩是在哪个阶段发生的? 基础压缩通过 agent/pre-step 处理压力,agent/request-error 只处理规范上下文溢出;先剪枝工具结果,再选择摘要。

一句话收束: 生命周期插件只要记住“实时看 agent/*、历史看 session/event、介入选对钩子”,就不会把协调状态当成审计记录。

ChatGPTClaudeGrok / X / CursorGemini

常见问题

DeepSeek Harness 的 agent/* 和 session/event 有什么区别?

DeepSeek Harness 里,agent/* 是实时控制与状态,例如队列、状态、请求构造、steering 与错误处理;session/event 是持久回放事实,记录 turn、step、消息与工具结果。需要可回放 transcript 的 SDK 应消费 session/event。

一个 turn 里可以有几个 step,在 DeepSeek Harness 中如何处理?

DeepSeek Harness 里,一个 turn 可以包含多个 step。每个 step 对应一次模型请求与随后的工具执行;当 inbox 里还有下一步输入,或工具结果需要继续请求时,会在同一个 turn 里进入下一个 step。

agent/pre-step 拒绝一批输入会发生什么,在 DeepSeek Harness 中如何处理?

DeepSeek Harness 里,被 claim 的批次保持移除,已经打开的 turn 不消耗 step;如果第一批为空或 pre-step 失败,同样不进入 step/start。监听器通过包装 next() 可以保留下游消息与 startsRequestSeries。

agent/request-error 适合做通用错误处理吗?

DeepSeek Harness 里,不适合。它主要用于规范的上下文溢出;压缩会先在 pre-step 处理压力,再在 request-error 触发时做工具结果剪枝与摘要。普通错误应按各自错误路径处理,不要都塞进这个钩子。

实时流式 chunk 能在回放里重新读到吗,在 DeepSeek Harness 中如何处理?

DeepSeek Harness 里,不能。agent/assistant-stream 的 chunk frame 是瞬态数据;回放读取 assistant/message 或 assistant/attempt 里的持久 settlement。进程在 settlement 前硬中断,不会留下持久 attempt stream。

相关术语

turn
turn 是 DeepSeek Harness 中一次用户输入驱动的完整轮次,从 turn/start 开始,到 turn/end 结束;一个 turn 可以包含多个 step。— DeepSeek Harness 官方参考 - Agent 轮次与步骤生命周期
step
step 是 turn 内的一次模型请求与工具执行单元,以 step/start 开始、step/end 结束;模型请求、消息准入与工具结果都在 step 内发生。— DeepSeek Harness 官方参考 - Agent 轮次与步骤生命周期
agent/pre-step
agent/pre-step 是 DeepSeek Harness 的 waterfall 钩子,在构造模型请求前决定是否进入消息批次;它可以拒绝或替换消息,拒绝时该批次不消耗 step。— DeepSeek Harness 官方参考 - Agent 轮次与步骤生命周期
session/event
session/event 是 DeepSeek Harness 的持久会话事件流,记录 turn、step、消息、工具调用与结果,是回放与 SDK transcript 的事实来源。— DeepSeek Harness 官方参考 - Agent 轮次与步骤生命周期

来源