核心摘要
DeepSeek Harness 将一次 Agent 会话建模为类型化的追加式事件流。模型可见对话由该事件流推导,因此运行时可以从同一份证据重建聊天记录、检查轨迹、恢复或 Fork 会话,并驱动界面和遥测。它提供强大的可观测性,但不是外部系统的事务日志:绝不能通过 Replay 盲目重复邮件、部署、支付或文件写入。
目录
- 为什么会话需要事件模型
- DeepSeek Harness 记录什么
- Trajectory、Replay、Fork 与 Resume
- Trace 与副作用账本的边界
- 如何安全扩展会话事件
- 评测与运维
- 常见问题 (FAQ)
- 相关资源
为什么会话需要事件模型
一次 Agent 运行不只是聊天文本。它可能包含用户请求、注入的仓库说明、模型消息、工具调用、工具结果、子 Agent 行为、取消事件,以及改变模型可见内容的设置。可变的纯文本历史会丢失这些事实之间的区别,使后续诊断变得含糊。
DeepSeek Harness 将 Session 定义为类型化 SessionEvent 的追加日志。LLM 消息历史从日志推导,而不是保存为另一份可变来源。这为重建、界面更新、遥测、持久化和评测提供同一份有序证据流。
关键不变量比“记录一切”更窄:DSH 架构要求模型可见输入可以从 Session Log 重建,因此上下文组装可被检查。这不代表每个内部细节或敏感 Secret 都应该暴露给每位运维人员。
DeepSeek Harness 记录什么
文档化事件词表包含 Turn 与 Step 边界、用户消息、助手流式 Chunk、完整助手消息、工具调用、工具结果、待办快照和请求元数据。一次 Step 是一次模型请求及该请求产生的工具执行;一次 Turn 可以包含多个 Step。
| 事件族 | 能证明什么 | 不能证明什么 |
|---|---|---|
user/message |
模型可见的用户或注入输入进入了会话 | 输入本身可信或已获授权 |
request/header |
有效请求配置、系统提示词和 Tool Schema | 策略对某个租户一定正确 |
assistant/message |
组装后的模型输出,以及 Provider 报告的用量 | 模型隐藏的内部推理 |
tool/call |
模型请求某个工具及原始参数 | 派发已获授权或一定完成 |
tool/result |
模型可见的结果和可选错误标识 | 外部写入已经永久对账完成 |
turn/* 和 step/* |
运行边界 | 业务事务边界 |
下面是简化后的日志投影,仅用于说明结构,不承诺每个 DSH 版本都会产生完全相同的字段:
[
{ "seq": 18, "type": "turn/start", "data": { "turn": 4 } },
{
"seq": 19,
"type": "user/message",
"data": { "role": "user", "content": [{ "type": "text", "text": "运行测试" }] }
},
{
"seq": 20,
"type": "tool/call",
"data": { "turn": 4, "step": 7, "callId": "call_123", "name": "bash", "arguments": "{\"command\":\"pnpm test\"}" }
},
{
"seq": 21,
"type": "tool/result",
"data": { "turn": 4, "step": 7, "message": { "role": "tool", "content": [] } }
}
]
需要真实事件形状时,应读取锁定项目版本生成的 Session Catalog 或 TypeScript 类型,不能围绕博客示例构建安全或持久化集成。
Trajectory、Replay、Fork 与 Resume
DeepSeek Harness 用同一条事件流支持 Trajectory 检查、Resume、Fork 与 Replay。这让团队可以回答具体问题:哪条说明进入了模型请求、哪个 Tool Schema 对模型可见、模型收到了哪个工具结果、一次运行从哪个边界开始偏离。
这些术语容易混淆:
| 操作 | 安全解释 |
|---|---|
| Resume | 从保留的会话状态创建或继续运行时,仍受当前策略和兼容检查约束 |
| Fork | 从源 Session 或边界初始化子 Session,以探索不同路径 |
| Replay | 从记录事件重新推导状态、历史、展示或评测输入 |
| Re-execution | 再次调用工具或外部系统;这是新的副作用,必须重新授权 |
重放一个 Tool Result 可以复现模型当时看到什么,但不能证明外部系统是否在超时前接受了写操作。因此,Agent 轨迹 与业务审计账本不是同一概念。
Trace 与副作用账本的边界
事件溯源的 Session Log 很有价值,但其持久化和顺序不自动使其成为 Exactly-once 事务协调器。最难处理的是外部结果未知:
- Agent 提议
create_ticket。 - 工具向外部服务发送请求。
- 返回结果前网络失败。
- 外部服务可能已经创建工单。
盲目 Replay 会创建重复工单。安全设计需要应用拥有的副作用账本:
| 记录 | 目的 |
|---|---|
| 稳定操作 ID | 使下游能够去重或查询请求 |
| 意图与授权快照 | 绑定主体、资源、参数、策略和过期时间 |
| 派发尝试 | 记录何时向哪个下游发送请求 |
| 对账结果 | 确认下游副作用是否已提交 |
| 补偿或升级状态 | 处理不可逆或结果未知的情况 |
Session 可以引用操作 ID 与最终结果,但不应把回放得到的 tool/result 静默视为完成证明。检查点与外部副作用对账的分离,可参阅 Agent Harness 架构。
如何安全扩展会话事件
插件新增模型可见输入时,DeepSeek Harness 要求存在相应 Session Event,以保证未来可以完整重建。实际实现中应遵循以下原则:
- 先定义事件,再写界面:说明该事实是否持久化、模型可见、可回放以及是否适合展示。
- 保持 JSON 安全并做版本设计:Session 模型会校验事件数据是否为 JSON;存入新结构前要定义兼容策略。
- 将敏感数据与广泛可见性分离:完整内容对回放并非必要时,保存受保护引用或脱敏摘要。
- 保持工具调用与结果成组:只有结果没有调用,会丢失关键因果上下文。
- 遇到未知的必要事件时失败关闭:若静默跳过会改变重建结果的事件,就会产生伪造的历史。
最后一点在升级时尤其重要。官方 Session 文档区分可忽略的信息事件和必要未知事件。任何持久化桥接都应保留这种区分;看似成功的部分回放比显式兼容错误更危险。
评测与运维
Trajectory 数据只有在评测集定义成功标准时才有价值。它可用于衡量有依据的工具选择、拒绝动作、参数校验、预算使用、恢复决定和结果质量;不能因为轨迹很长或模型解释流畅就证明事实正确。
建议包含成功、拒绝、中断、延迟、畸形和对抗场景:
| 场景 | 应检查的证据 |
|---|---|
| 只读任务 | 有序上下文、工具调用和最终答案 |
| 被拒绝的写操作 | 派发前的策略决定,以及不存在外部请求 |
| 工具超时 | 操作 ID、对账查询,以及不存在盲目重试 |
| 上下文注入 | 来源记录与其变为模型可见的请求边界 |
| 版本升级 | 事件投影和必要事件处理是否仍兼容 |
还必须制定数据保留策略。Session 可能含有源码、用户文本、文件路径、工具参数、结果和系统提示词。应限制访问、在正确存储边界加密、尽可能脱敏、设置保存期限并测试删除;没有数据治理的可观测性会变成新的敏感数据系统。
常见问题 (FAQ)
DSH Session 等同于聊天历史吗?
不等同。聊天历史通常是渲染出来的对话;DSH Session 是从中推导模型历史和界面展示的类型化事件流。它可以包含边界、工具活动、请求元数据等聊天文本没有的事实。
模型或插件升级后可以回放旧 Trajectory 吗?
只有事件词表和读取器保持兼容时才可以尝试重新推导。应锁定版本并测试旧 Session Fixture;遇到必要未知事件时,应显式报告兼容失败,而不是静默忽略。
记录 assistant chunk 会暴露隐藏思维链吗?
不能假设会,也不能假设应该。只记录和展示 Provider 及策略允许的事件类型和模型字段;生产调试应从可观察的动作和结果评测,而不是依赖隐藏推理。
Session Log 应该如何存储?
应按会话敏感度选择具有访问控制、加密、保留、删除、备份和 Schema 迁移能力的持久化后端。事件日志是运行时真相来源,但合规和租户规则仍由应用负责。
Fork 会继承授权吗?
不应静默继承不同资源、参数或时间范围的审批。Fork 可复用探索上下文,但产生重要副作用前必须重新检查当前身份、策略和授权。