第 9 章 架构全景:轮次流程、会话日志与能力 Seam
本章把视角拉高,梳理 dsh 的整体架构,对应官方 Architecture 页面的后半部分。
9.1 三个事件域
事件就是扩展点,选对事件域是大多数改动的第一个决定:
| 域 | 特征 | 适用场景 |
|---|---|---|
| 会话事件 | 追加到日志并通过 session/event 广播的持久事实 | 事实必须在重新加载后仍然存在时 |
Agent 事件(agent/*) | 携带活跃 Agent:inbox、步骤、状态、请求、验证、续跑 | 观察或拦截进行中的工作 |
| 能力事件 | fs/*、tools/*、telemetry/* 等 | 无需导入循环即可向某个 seam 附加策略和适配器 |
官方的事件映射文档(docs/event-producer-consumer.zh.md)列出每个事件的生产方与消费方。
9.2 轮次流程(Turn Flow)
一个步骤(step)= 一次模型请求 + 它调用的工具;一个轮次(turn)包含零或多个步骤——它在领取首条输入前打开,在不再欠下任何工作时关闭:
理解要点:
持久 vs 实时:
turn/*、step/*、system/message、user/message、assistant/message、assistant/attempt、tool/*是持久会话事件;其余是三个事件域的实时扩展点。waterfall 事件:
agent/pre-step、agent/request、llm/stream和三个tools/*是瀑布式事件,监听器必须调用next()才能委托下去;agent/turn-stopping是 serial 事件,没有next()。输入统一走 inbox:有些消息立即唤醒驱动器;注入的上下文留在 inbox,直到另一条消息将其唤醒。
agent/pre-step决定接纳的输入,监听器可改写或拒绝;首次领取被拒绝或为空时,关闭不含步骤的持久轮次。取消语义:
agent/request与prepareCall()先解析实际路由,再提交系统提示词与已接纳的用户消息;在任一异步阶段取消,这两者都不会被提交。重试不重复组装或agent/pre-step。循环发送不可变请求,同时保留实时取消能力;只有已由该循环完整冻结的消息对象身份才能复用冻结证明。
9.3 会话日志:"模型可见即已记录"
会话日志是模型所见上下文的来源——deriveMessages() 从中投影出模型历史。核心不变量:
抵达模型请求的一切,都必须能从日志重建,并由一项运行时不变量断言这一点。因此新增一项模型可见输入 = 新增一个会话事件(扩展
SessionEventMap并从日志渲染)。
每个
assistant/message嵌入产生其组装内容的精确紧凑带时间 stream;assistant/attempt保留已到达 settlement 的失败、重试、取消与 stream error attempt,不添加模型历史;fork、恢复、transcript、遥测与持久化都从持久 settlement 派生;实时 UI 增量来自
agent/assistant-stream;进程在 settlement 前硬中断则不会留下持久 attempt stream。
格式与迁移
JSONL v0 使用
session.jsonl[.zstd],v1 起使用session.vN.jsonl[.zstd];已提交 generation 路径绝不重命名、替换或删除;
stat/list重扫会话目录、选择数值最高的规范 generation;open拒绝未来版本,或经构建时静态确定的相邻迁移链(每个迁移包只负责一个vN → vN+1步骤)转换到当前逻辑事件;写 open 会在未改变源旁边排他发布最终版本命名的后继。
投影 Seam
dsh-session-projection 提供 ctx.sessionProjections:已注册单元增量折叠已提交事件;消费方通过 stateOf() 读取单个类型化状态,载体通过 snapshot() 批量取得裁剪后的客户端视图。host 读取方要么在激活时要求该服务,要么在必需 key 缺席时明确失败——不能为缺失的 host 值静默提供默认值。agent loop 为读取方注册共享的 turnBoundary 状态。
9.4 能力 Seam:Service Definition Provider Consumer
一个 seam 是一项可替换能力,包含三种角色:
Service Definition:声明接口;
Service Provider:实现它;
Consumer:使用它(通常是面向模型的工具)。
一个包可以合并承担多个角色,但单一角色本身不是 seam;添加一项能力意味着把三者一并设计。
Seam 正是"替换一个提供方就能改变整个产品"的原因:
文件系统与进程提供方共享同一个执行世界——把它们指向远程沙箱,就把 Bash、PTY 和 LSP 一并搬了过去,无需提供方专用 fork;
subagent 提供方在同一接口之后千差万别:从新建一个子 agent,到把一个轮次委派给另一个产品;
实验性 Agent Teams 是
ctx.agentTeams上公开发布、显式启用的协作 seam,在可继续 subagent 之上提供持久 roster、任务板和 mailbox。
9.5 桌面应用补充
Electron 桌面应用持有保留的 $DSH_HOME/profiles/desktop npm 项目,每个签名发行版绑定确切 dsh 版本并携带离线 seed;RPC 经带版本的分帧字节管道传输,Node IPC 只保留生命周期控制;桌面组合不开放 Web server 或 loopback 端口。
依据官方 Architecture 整理;时序图、工具流水线与取消恢复的细节见官方 agent-lifecycle、tool-execution-pipeline 页面。