description: "面向用户与维护者的默认 agent 驱动器说明,用于选择、配置或调试 agent 的创建方式以及轮次与步骤的运行方式。"
English | 中文
dsh-agent-loop 创建 agent——全新创建或从持久化历史恢复——并运行轮次与步骤生命周期:领取提示词、组装请求、流式接收模型响应、分发工具调用,并把每个结果追加回会话日志。作为默认驱动器,它实现 dsh-agent 的 Agent 接口并在此注册工厂,因此插件通过 ctx.agents 创建与驱动 agent,而不必依赖本包。声明式配置项会在启动时自动启动 agent,maxParallelToolCalls 限制同时运行的并行安全工具调用数量。它是 harness 唯一的具象循环——超出「调用模型、运行工具、重复」的所有内容都属于监听事件分类体系的插件。标准组合请选择它作为驱动器;如需替换,请实现 Agent 并通过 ctx.agents 注册。
在任何应运行 agent 的组合中挂载 dsh-agent-loop。它提供 ctx.agents 背后的驱动器,并启动你在配置中声明的 agent;dsh-base 与 dsh-sdk-minimal 都将它作为显式配置行挂载。
配置中声明的 agent 会在插件加载时自动启动。每个条目需要一个 id 标签;模型调用还同时需要 provider 与 model(agent/request 可以在分发前补齐缺失的这一对值)。
- name: '@deepseek-ai/dsh-agent-loop'
config:
maxParallelToolCalls: 10
agents:
- id: 'main'
provider: deepseek
model: deepseek-chat
reasoningEffort: high
cwd: /workspace
| 字段 | 默认值 | 含义 |
|---|---|---|
maxParallelToolCalls |
10 |
每个步骤同时在途的并行安全工具调用数;1 为串行 |
agents[].id |
必填 | 稳定标签;未设置 sessionId 时,全新会话会生成 ${id}-session-<uuid> |
agents[].provider / agents[].model |
— | 模型路由;分发前两者都必须存在 |
agents[].reasoningEffort |
— | 非空的初始推理等级;agent/request 可以覆盖它 |
agents[].maxTokens |
— | 正数的逐请求输出 token 上限 |
agents[].cwd |
— | 全新会话的工作目录 |
agents[].sessionId |
— | 确切身份:首次使用创建,重新挂载时恢复已实体化的历史 |
agents[].resumeSessionId |
— | 加载这个持久化会话而不是创建新会话;与 sessionId 互斥 |
生成的配置目录是每个受支持字段的穷尽式真源。适配器会校验有效推理等级,循环则把它记录在请求头中。maxParallelToolCalls 也是整个 agent-loop 设置分节,因此叠加在该条目之上的用户层无需重启即可限制下一组工具调用。
插件与宿主通过 ctx.agents.create() 创建 agent,通过 ctx.agents.resume() 恢复持久化会话;两者都返回 AgentHandle,其 dispose() 拥有确切的 teardown 能力。循环会把每个创建的 agent 运行到完成——只有调用方需要自行拆除 agent 时才需要句柄。
const handle = await ctx.agents.create({
sessionId,
agentOptions: { provider: 'deepseek', model: 'deepseek-chat' },
setup: (agentCtx) => { /* scoped tools, prompt sections, listeners */ },
})
每个步骤都会发送该 agent 渲染后的系统提示词、其可见工具 schema 与会话的派生历史;模型的工具调用经过受守卫的工具流水线,每个被接纳的事实都会在下一步据此派生之前追加到会话日志。并行安全调用最多可重叠 maxParallelToolCalls 个;独占调用单独运行并构成排序屏障。取消是协作式的:agent.cancel() 中止当前活动,并在未设置 keepInbox 时清除待处理工作;被取消的流会终结已送达用户的文本。
包级约定对大多数消费方已经足够;需要周边领域与设计原理时再阅读以下页面。
Agent 句柄、注册表与 agent/* 事件。每个步骤中,循环会发送针对该 agent 渲染的系统提示词、可见工具 schema 与会话的派生消息。它提供 provider、model 与 cwd 变量值,但不添加固定文案。
系统文本与 schema 在每个步骤都会再次计入。逐 agent 作用域决定贡献,而权威组装 waterfall 可以改变最终请求,并使其监听器负责保持协议连贯。
只有在同一提供方与模型路由下,且系统文本、schema 与此前历史都保持逐字节一致时,请求才保持仅追加。携带 token 的组装改写或组合变更可能从第一个改变的请求 token 起使复用失效。
已接纳的 user 消息、assistant 消息、工具调用与结果、注入上下文与 steering 都会记录,并在后续步骤中发送。原始流分片、生命周期边界与其他仅写入日志的事件会被排除。
输入会随每条表层消息增长,直到压缩(compaction)替换遮蔽较旧节点;包含多个步骤的工具轮次会在每个步骤重新发送累积的历史。
普通历史增长仅追加,并保留可复用条目。表层替换或压缩会从第一个被遮蔽的历史 token 起使复用失效。
如果后续请求回放一个中止的步骤,取消所阻止分发的每个工具调用都有错误码 ABORTED_BEFORE_DISPATCH,结果文本为 Error: tool call aborted before dispatch。
每个跳过的调用都会在历史中保留一个固定错误结果,直到压缩将其遮蔽。
仅追加;每个合成结果都位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
这些限制说明循环何时需要特别留意。它们是当前包约束,不是任务积压。
sessionId 时,每次启动都会创建新的 ${id}-session-<uuid>;如需确切的恢复或创建行为,必须显式提供稳定的 sessionId,而 resumeSessionId 要求已有持久化历史。ctx.agents.create() / resume() 工厂选项支持带作用域的 persona 与工具组合。agent/turn-stopping)执行取消。