DeepSeek Harness:一次 Prompt 如何变成 Turn、Step 与工具事件
发布时间:2026/8/22 2:38:49 作者:尧图编辑部 阅读量:1,286

一次 Prompt 如何变成 Turn、Step 与工具事件用户输入一句“检查这个项目并修复测试”系统什么时候算接收什么时候算开始什么时候算完成如果把一次 Prompt 直接等同于一次模型请求工具一出现边界马上崩掉模型先请求读文件工具返回以后还要再调用模型中途可能插入 steering也可能取消一个请求失败后策略还可能决定重试。最后 SDK 看见 Agent 回到 idle却不一定能把这次 idle 唯一归因给最早那条消息。DeepSeek Harness 的固定源码没有用一个笼统的run()掩盖这些阶段而是把 Inbox、Turn、Step、Session Event 和 Agent Status 分开。本文只回答一个问题一条进入 Agent 的消息如何沿着 Turn、Step、模型流和工具批次变成可观测事实核心结论是Turn 是 Agent 对一批待处理输入建立的执行边界Step 是一次模型请求及其工具执行Session Event 保存可重放事实agent/*负责实时协调。只有把这几层分开失败、取消、重试和“完成”才不会被压成一个含糊状态。先看一个最容易误判的案例假设客户端调用followup(检查项目并修复测试)它并不会立即拿到一个“这条消息对应的最终回答句柄”。固定文档指出followup()只把带身份的消息放入 Inbox 并唤醒 Driver消息 ID 能追踪插入、认领和丢弃但不能天然指向后续某条 assistant 输出或某个 Turn end。Agent 可能在这一活动中连续处理用户 Prompt模型要求读取文件工具结果进入日志模型要求修改文件又有 steering 在下一个 Step 边界被认领最后模型停止调用工具Agent 继续清空已排队工作后才回到 idle。因此客户端至少面对五种不同“完成”消息已入队、Turn 已结束、某个 Step 已结束、工具批次已结算、整个 Agent 已静止。把它们合成一个布尔值会让 UI、SDK、评测与恢复逻辑互相误解。Inbox输入先成为待处理事实DeepSeek Harness 的 Agent 拥有两个有序输入边界next-turn和next-step。普通 followup 进入next-turn准备打开独立 Turnsteering 和 injected context 面向最近的后续 Step但是否唤醒 Agent、何时被认领并不相同。输入先记录插入事实。Driver 被唤醒后才从 Inbox 认领当前批次所有可用的next-step输入加上 Turn 边界的一条next-turn消息。认领与进入模型上下文仍不是同一步agent/pre-step可以重写批次也可以拒绝进入。这个拆分解决了一个常见误区消息“发送成功”只证明它进入待处理边界不证明模型已经看见更不证明它会得到独占的一条回答。Turn先打开边界再决定是否真的发生 Step固定 Session 文档对 Turn 的顺序非常严格turn/start在 Driver 认领队列和执行 pre-step 之前就写入日志。因此Turn 可以合法地没有 Steppre-step 拒绝当前批次输入被改写为空在进入模型请求前发生取消或失败。这类 Turn 仍有turn/start与turn/end却没有step/start。它记录的是“系统确实建立过这次执行边界并以某种原因结束”而不是伪造一次没有发生的模型调用。Turn 也不是 HTTP request。Web、Headless 和 Python SDK 可以通过不同传输驱动同一 Agent 语义一个 Driver 的running状态还可能连续覆盖多个排队 Turn。传输请求返回、Turn 结束和 Agent idle 属于三个层次。Step一次模型请求加上它要求的工具执行Step 在 pre-step 决定enter(messages)后开始。固定事件时序大致是step/start - user/message进入本 Step 的消息 - system prompt 与 tool schemas 装配 - agent/request - llm/stream - assistant/chunk* - assistant/message - tool/call* / tool/result* step/end如果模型只返回文本并自然停止一个 Turn 可能只有一个 Step。如果模型发出工具调用工具结果写入后Loop 可能再开一个 Step让模型看到新事实并继续推理。只要工具仍要求下一轮请求或者next-step又有输入同一个 Turn 就可以继续。所以Step 的计数更接近“模型往返次数”Turn 的计数更接近“Agent 为一批工作建立了多少执行边界”。把两者混用会让成本、延迟、失败率和工具使用统计全部失真。durable Event 与 live event 不能混为一类固定架构把事件分为不同职责。Session 中的turn/*、step/*、user/message、assistant/*、tool/*是可重放事实。它们回答当时发生了什么、模型看到了什么、工具调用与结果如何配对。agent/*则承担实时控制和协调例如状态变化、pre-step 拦截、请求构造、取消和错误恢复。它们适合 UI、Hook 或运行中策略观察但不应被默认当作可重建对话的持久事实。官方生命周期图因此给出一个清楚建议需要可重放 transcript 的 SDK 消费者应读取session/event需要队列、状态、steering 和错误协调的消费者使用agent/*。这不是“所有事件都应该持久化”。恰恰相反只有影响恢复、审计或模型可见面的事实才需要进入 Session进程内控制信号可以保留为 live event。正确的边界比日志越多越好更重要。流式输出不是最终模型事实模型 Adapter 产生一串StreamChunk。Surface 可以即时渲染这些 chunkSession 也保存assistant/chunk以维持回放精度但下一 Step 使用的是组装后的assistant/message。固定生命周期文档还指出每次成功 Provider 调用都会记录assistant/message即使内容为空或以 max-tokens 结束。它会带上精确来源 chunk 的序号以及 Provider 提供时的 usage。因此UI 看见 token 不代表 Step 已经形成最终事实。Adapter 还必须处理工具调用增量、结束原因、空内容、取消和流错误。只转发文本 token 的“兼容层”无法满足完整 Loop 契约。工具调用是一个批次不是一个函数模型输出工具调用后Loop 先记录tool/call再进入工具注册表。固定工具管线依次包含tools/pre-executewaterfallmonotonic guardstools/executewaterfall 与工具 bodytools/post-executewaterfall结果规范化与finalizeContenttools/result观察Session 中唯一的模型可见tool/result。同一 assistant message 可以包含多个工具调用。固定 Agent Lifecycle 图显示Loop 会按 barrier 与有界滚动池调度开始但结果仍按模型顺序写回。这是一个重要区别执行可以并发模型可见结果的记录顺序仍要稳定。工具被拒绝也不等于 Runtime 崩溃。拒绝、审批失败、工具 body 错误或 post 阶段替换最终都需要形成权威 outcome并在适用时成为模型可见结果。具体 Sandbox、权限和副作用策略属于本系列第 5 篇本篇只保留执行边界。一个 Turn 为什么会继续又为什么会结束模型请求和工具批次完成后Loop 判断是否还欠下一轮有工具结果需要交回模型next-step有新的 steering 或 injected context策略在结束检查点要求继续。如果没有 continuationLoop 在自然停止时进入agent/turn-stopping终止检查点然后结束 Turn。随后Driver 还可能处理已经排队的下一个 Turn只有整个活动真正静止Agent Status 才回到idle。这解释了为什么whenIdle()不能被误写成“等待这一条消息的回答”。固定 Core 文档明确说它观察整个 Agent 的静止状态并跟随后续替换工作与 maintenance task。只有调用者明确拥有从某次收件到下一次全 Agent idle 的区间才可以把这个区间称为一次 run。失败与取消必须按发生位置分类一条error无法支撑恢复和评测。至少应区分以下位置失败位置事实边界不应该误写成什么Inbox 插入后、认领前消息仍是待处理或被丢弃的输入事实模型请求失败pre-step rejectTurn 可以零 Step 结束Runtime 崩溃Provider 路由或凭据模型请求无法完成研究材料的MISSING_CREDENTIAL属此边界真实模型 E2E 失败样本流式请求中断已有 chunk 可能存在但 Step 没有成功结果完整 assistant messagetool deny / approval refused策略正常执行并阻止 body系统异常或 Sandbox 崩溃tool body / wrapper / post 失败由工具管线规范化为权威 outcome一定需要终止整个 AgentAgent cancel活动 signal 被终止durableturn/end.reason保存 aborted 及 user/parent/hook/disposed 原因原因类别等于具体操作者身份或完整审计轨迹Agent idle当前没有活跃 Driver 或 maintenance task某个 MessageId 的因果完成证明固定 Commit 的源码类型在这里比概述文档更精确一张可执行的观测合同团队接入 DeepSeek Harness 或设计类似 Runtime 时可以用下表明确每项指标与状态到底绑定什么读者想知道应观察的对象能得出的结论Prompt 是否进入系统Inbox inserted / MessageId已入队不代表模型已见输入是否进入一次执行inbox claimed turn/start已建立 Turn 边界仍可能零 Step模型调用了几次step/start/step/end模型往返次数与每步边界模型流是否形成稳定输出chunks assistant/message区分实时渲染与最终模型事实工具是否真正执行tool/call、管线 outcome、tool/result区分调用意图、策略拒绝与执行结果本 Turn 为什么结束turn/end.reason本次 Turn 的粗粒度终点整个 Agent 是否静止agent/status/whenIdle()全 Agent 当前无活动不是单消息回执这张表是本文的主要产物。它把“发送成功”“模型完成”“工具完成”“Turn 完成”和“Agent idle”拆成不同合同避免指标和 API 名称制造虚假的因果关系。结论DeepSeek Harness 的 Agent Loop 可以概括成一条迭代链从 Inbox 认领输入打开 Turn通过 pre-step 决定是否进入 Step装配请求并流式调用模型把模型与工具的可见结果写成 Session 事实再决定继续下一 Step、结束 Turn或处理下一个 Turn。它值得借鉴的不是循环代码有多复杂而是边界足够明确Turn 可以零 StepStep 才对应模型往返工具调用是受控批次Session Event 与 live event 职责不同Agent idle 也不是单条消息的完成证明。这套边界让失败和取消能够被准确命名但不自动证明真实模型、工具副作用和长任务恢复已经可靠。那些结论仍需要凭据、故障注入和生产观测。参考资料固定 Commit Architecturehttps://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/architecture.md固定 Commit Agent Lifecyclehttps://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/agent-lifecycle.md固定 Commit Core Subsystemhttps://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/subsystems/core.md固定 Commit Session Subsystemhttps://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/subsystems/session.md固定 Commit Tool Execution Pipelinehttps://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/tool-execution-pipeline.md固定 Commit LLM Streaminghttps://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/subsystems/llm-streaming.md证据与推导边界Turn、Step、Inbox、事件顺序与 whenIdle固定 Commit 官方文档事实取消持久字段以固定源码session/src/types.ts为准。工具管线的阶段和结果记录顺序固定生成文档事实不等于所有工具安全性已验证。“五种完成”和观测合同基于固定事件边界的作者工程归纳。MISSING_CREDENTIAL只证明研究环境触发凭据门禁不是一次真实模型任务失败样本。真实模型 E2E、长任务恢复、工具幂等与生产稳定性未验证不作结论。