核心摘要

DeepSeek Harness 将一次 Agent 会话建模为类型化的追加式事件流。模型可见对话由该事件流推导,因此运行时可以从同一份证据重建聊天记录、检查轨迹、恢复或 Fork 会话,并驱动界面和遥测。它提供强大的可观测性,但不是外部系统的事务日志:绝不能通过 Replay 盲目重复邮件、部署、支付或文件写入。

目录

为什么会话需要事件模型

一次 Agent 运行不只是聊天文本。它可能包含用户请求、注入的仓库说明、模型消息、工具调用、工具结果、子 Agent 行为、取消事件,以及改变模型可见内容的设置。可变的纯文本历史会丢失这些事实之间的区别,使后续诊断变得含糊。

DeepSeek Harness 将 Session 定义为类型化 SessionEvent 的追加日志。LLM 消息历史从日志推导,而不是保存为另一份可变来源。这为重建、界面更新、遥测、持久化和评测提供同一份有序证据流。

flowchart LR I["输入与注入上下文"] --> E["追加式 Session Event"] M["模型流式输出"] --> E T["工具调用与结果"] --> E E --> H["推导的模型历史"] E --> U["Trajectory 界面"] E --> R["Resume 或 Fork"] E --> O["遥测与评测"]

关键不变量比“记录一切”更窄: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 版本都会产生完全相同的字段:

json
[
  { "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 对模型可见、模型收到了哪个工具结果、一次运行从哪个边界开始偏离。

sequenceDiagram participant L as Session Log participant D as 推导历史 participant A as Agent 实例 participant X as 外部系统 L->>D: 投影有序的模型可见事件 D->>A: Resume 或 Fork 上下文 A->>X: 提议新的动作 X-->>A: 独立对账后的结果 A->>L: 追加新的事件证据

这些术语容易混淆:

操作 安全解释
Resume 从保留的会话状态创建或继续运行时,仍受当前策略和兼容检查约束
Fork 从源 Session 或边界初始化子 Session,以探索不同路径
Replay 从记录事件重新推导状态、历史、展示或评测输入
Re-execution 再次调用工具或外部系统;这是新的副作用,必须重新授权

重放一个 Tool Result 可以复现模型当时看到什么,但不能证明外部系统是否在超时前接受了写操作。因此,Agent 轨迹 与业务审计账本不是同一概念。

Trace 与副作用账本的边界

事件溯源的 Session Log 很有价值,但其持久化和顺序不自动使其成为 Exactly-once 事务协调器。最难处理的是外部结果未知:

  1. Agent 提议 create_ticket
  2. 工具向外部服务发送请求。
  3. 返回结果前网络失败。
  4. 外部服务可能已经创建工单。

盲目 Replay 会创建重复工单。安全设计需要应用拥有的副作用账本:

记录 目的
稳定操作 ID 使下游能够去重或查询请求
意图与授权快照 绑定主体、资源、参数、策略和过期时间
派发尝试 记录何时向哪个下游发送请求
对账结果 确认下游副作用是否已提交
补偿或升级状态 处理不可逆或结果未知的情况

Session 可以引用操作 ID 与最终结果,但不应把回放得到的 tool/result 静默视为完成证明。检查点与外部副作用对账的分离,可参阅 Agent Harness 架构

如何安全扩展会话事件

插件新增模型可见输入时,DeepSeek Harness 要求存在相应 Session Event,以保证未来可以完整重建。实际实现中应遵循以下原则:

  1. 先定义事件,再写界面:说明该事实是否持久化、模型可见、可回放以及是否适合展示。
  2. 保持 JSON 安全并做版本设计:Session 模型会校验事件数据是否为 JSON;存入新结构前要定义兼容策略。
  3. 将敏感数据与广泛可见性分离:完整内容对回放并非必要时,保存受保护引用或脱敏摘要。
  4. 保持工具调用与结果成组:只有结果没有调用,会丢失关键因果上下文。
  5. 遇到未知的必要事件时失败关闭:若静默跳过会改变重建结果的事件,就会产生伪造的历史。

最后一点在升级时尤其重要。官方 Session 文档区分可忽略的信息事件和必要未知事件。任何持久化桥接都应保留这种区分;看似成功的部分回放比显式兼容错误更危险。

评测与运维

Trajectory 数据只有在评测集定义成功标准时才有价值。它可用于衡量有依据的工具选择、拒绝动作、参数校验、预算使用、恢复决定和结果质量;不能因为轨迹很长或模型解释流畅就证明事实正确。

建议包含成功、拒绝、中断、延迟、畸形和对抗场景:

场景 应检查的证据
只读任务 有序上下文、工具调用和最终答案
被拒绝的写操作 派发前的策略决定,以及不存在外部请求
工具超时 操作 ID、对账查询,以及不存在盲目重试
上下文注入 来源记录与其变为模型可见的请求边界
版本升级 事件投影和必要事件处理是否仍兼容

还必须制定数据保留策略。Session 可能含有源码、用户文本、文件路径、工具参数、结果和系统提示词。应限制访问、在正确存储边界加密、尽可能脱敏、设置保存期限并测试删除;没有数据治理的可观测性会变成新的敏感数据系统。

常见问题 (FAQ)

DSH Session 等同于聊天历史吗?

不等同。聊天历史通常是渲染出来的对话;DSH Session 是从中推导模型历史和界面展示的类型化事件流。它可以包含边界、工具活动、请求元数据等聊天文本没有的事实。

模型或插件升级后可以回放旧 Trajectory 吗?

只有事件词表和读取器保持兼容时才可以尝试重新推导。应锁定版本并测试旧 Session Fixture;遇到必要未知事件时,应显式报告兼容失败,而不是静默忽略。

记录 assistant chunk 会暴露隐藏思维链吗?

不能假设会,也不能假设应该。只记录和展示 Provider 及策略允许的事件类型和模型字段;生产调试应从可观察的动作和结果评测,而不是依赖隐藏推理。

Session Log 应该如何存储?

应按会话敏感度选择具有访问控制、加密、保留、删除、备份和 Schema 迁移能力的持久化后端。事件日志是运行时真相来源,但合规和租户规则仍由应用负责。

Fork 会继承授权吗?

不应静默继承不同资源、参数或时间范围的审批。Fork 可复用探索上下文,但产生重要副作用前必须重新检查当前身份、策略和授权。

相关资源