第一次会话
一句话版:一条用户消息在 DSH 里走完会话 → 轮次 → 步骤三级生命周期:agent 循环驱动模型推理 + 工具执行,每一步都被记录、可回滚、可恢复。
经过 快速上手 你已经能跑。现在跟随第一条消息到底走了什么。
一、生命周期层级
Session(会话) 持久化边界,可恢复 / 可 fork
└── Turn(轮次) 一次用户消息 + agent 完整响应
└── Step(步骤) 一次模型调用 或 一次工具执行
一句:一个会话装一段长期对话;一个轮次从你发一条开始到 agent 应答完;一个步骤是轮次里的每次推进(模型推理或工具执行)。agent-loop 的 README 原话:它"驱动会话/轮次/步骤生命周期"。
二、一次消息的旅程
- 创建/恢复会话:
ctx.agents.create({ sessionId })或resume({ resumeSessionId }):恢复会从持久化日志重建历史,轮次编号继续 - Setup 事务:构造私有会话、agent、带作用域上下文:受回滚保护,失败即回滚
- 发布:
session/created→agent/created→agent/session-start依次宣告 - 驱动循环:模型推理 → 工具调用 → 结果回填 → 下一轮(见 Agent 主循环)
- Teardown:停止并 drain → 撤销作用域 → detach agent → detach 会话
关键特性:
- 创建与恢复属于同一个受回滚保护的事务
sessionId全局唯一;两个并发操作可同时准备,最终enter()裁决发布resumeSessionId与sessionId互斥- 声明式配置把
agents[].id当稳定 label,通常生成${label}-session-<uuid>
三、源码佐证(agent-loop)
// 配置驱动创建:循环 fiber 拥有 agent
ctx.agentLoop.create(id, options, meta)
// 编程式创建:返回 AgentHandle(唯一 teardown 能力)
ctx.agents.create({ sessionId, agentOptions, setup, signal })
// 恢复持久化会话:从日志重建历史
ctx.agents.resume({ resumeSessionId, agentOptions, setup })
signal(AbortSignal)只作用于创建期/加载期,会在 handle 可见前脱离;resume 依赖持久化后端,无后端时明确报错。
四、配置一个 agent
agents 挂在 agent-loop 插件的 config 下(不是顶层段):
- id: agent-loop
name: '@deepseek-ai/dsh-agent-loop'
config:
agents:
- id: main
provider: deepseek-official
model: deepseek-v4-flash
maxTokens: 65536
cwd: /path/to/workspace
- id: resume-demo
resumeSessionId: <已有会话 id>
同级配置还有 maxParallelToolCalls(循环级并行,默认 10,1 = 串行)。
五、端到端:你发一条消息,发生了什么
假设你问"这个仓库有多少行代码":
这一切的持久化记录(默认 zstd、两级目录):
zstdcat ~/.dsh/sessions/*/*/session.jsonl.zstd | tail -30
注意:内容是会话日志(surface);
agent/*是控制面事件(状态、错误、请求),两者见 事件系统。
六、可观测性(扩展点)
每次请求/响应发布一系列 agent/* 事件(控制面),持久化真正落在 session/event:
agent/status、agent/created、agent/disposed、agent/request-error、agent/pre-step- 配合
ctx.tools/session事件,你可以挂策略、压缩、重试、UI 渲染
七、验证
# 跑一个会话后看会话文件(默认 zstd 压缩、两级目录)
ls ~/.dsh/sessions/*/*/session.jsonl.zstd
# 解压后看事件流(3级结构一目了然)
zstdcat ~/.dsh/sessions/*/*/session.jsonl.zstd \
| jq -r 'select(.type | test("turn/|step/|user/message|assistant/message|tool/call|tool/result")) | [.seq, .type] | @tsv'