前言¶
给 Agent 工作流写测试,通常要同时应付两类不稳定因素:模型输出和外部工具。官方的 dsh-llm-replay 已经能回放模型流;但 HTTP、MCP、数据库这类工具在测试中仍可能真的访问网络、修改数据,或者依赖一台刚好没开机的服务,第三方接口在 CI 里偶尔还会返回 429。
dsh-tool-cassette 是 DeepSeek Harness(下称 DSH)的社区插件,做法很直接:第一次让被选工具真实执行,把规范化结果录进 cassette 文件;之后切到回放模式,真实工具正文调用为 0,录好的结果按精确匹配递回工具链。和手写 mock 相比,它录的是 DSH 规范化后的 value/error,回放时还要重新通过当前的输出契约。下面介绍它的能力、安装方法和使用边界。
这是什么¶
DSH 的理念是「一切皆插件」,dsh-tool-cassette 就是这个机制下的一个社区插件。它的定位写在 package 描述里:DeepSeek Harness 叶子工具正文边界的确定性录制、完整性校验与离线回放插件。
几项基本信息需要先说清楚:
- 由社区成员 Lem0nTea2002 独立开发和维护,是非官方社区插件,与 DeepSeek 官方无隶属关系,未获官方审核或背书;
- 许可证为 MIT;
- 当前版本 0.1.0,固定兼容 DeepSeek Harness
0.1.0-rc.8(该版本当前位于 npmnext标签),安装与运行需持续使用同一 rc.8 CLI; - Node 引擎要求
^22.19.0 || >=24.0.0;peerDependencies 为@deepseek-ai/cordis4.0.1、@deepseek-ai/dsh-tools0.1.0-rc.8、@deepseek-ai/schemastery3.18.1。
录制与回放怎样工作¶
Record:先真实跑一遍¶
Record 模式下,include 选中的工具(HTTP、MCP、数据库、本地程序)会真实执行,插件把 DSH 规范的 value/error 写入版本化 NDJSON cassette,内容包含 additionalContexts 和取消结果。未选中的工具按原有流程执行,录像机不抢戏。
录制流程是固定的:
1、独占创建 <file>.partial;
2、串行追加 header、call/start、call/result 帧;
3、每帧同步到磁盘;
4、全部调用完成后写入 complete 尾帧;
5、关闭文件,以 create-only 方式原子发布正式文件,再删除 partial。
制品自带完整性协议:每帧包含连续 seq、前一帧哈希和本帧 SHA-256,最后一帧为 complete。截断、帧重复、哈希篡改、协议版本错误和缺少尾帧,都会在 Replay 激活前被拦下。正式文件或 partial 已存在时录制器拒绝启动;录制存在未完成调用时保留 .partial 并拒绝发布正式文件。
需要注意,哈希链不含数字签名:它能发现传输损坏、截断和普通篡改,但面对能重写全部帧与哈希的攻击者,应由制品库补充签名、WORM 或不可变存储。
Replay:四项身份精确匹配¶
Replay 时,插件按四项身份判断是不是同一次调用:
1、工具在调用树中的结构路径;
2、工具名称;
3、递归排序对象键后的无损 JSON 参数;
4、按调用开始顺序分配的 ordinal。
匹配是精确的:参数对象键顺序无关,{ "city": "武汉", "unit": "c" } 换成 { "unit": "c", "city": "武汉" } 仍能命中;但数组顺序、参数值、调用顺序或结构路径一变,回放器立即返回 CASSETTE_MISMATCH。并发调用按开始顺序分配 ordinal,支持倒序完成,先开始后结束的调用不会错配。
Replay 命中后,真实工具正文调用为 0,保存的成功 value 会重新经过当前的输出 schema、renderer、presentation meta 和后置策略。所以回放时仍需注册同名工具,并保持输出契约兼容:录像带只负责保存结果,安检规则仍由当前的 DSH 执行。
对不上就失败关闭¶
第一次轨迹偏差会让回放器进入 poisoned 状态,后续被选工具持续失败,真实正文不执行,避免一半读录像、一半碰真实服务的混合局面。其余几种情况也有明确处置:
- 参数、路径、顺序或工具名不一致:返回
CASSETTE_MISMATCH; - 回放存在额外调用或未消费记录:headless/CI 进程退出码为 1;
- 更高优先级插件短路
tools/execute与tools/post-execute:Record 失效、Replay poison; - 被选调用在
pre-execute或 guard 阶段被拒绝:按未进入 cassette 的轨迹失败关闭。
错误诊断只显示工具、路径、ordinal 和参数指纹,不回显原始参数、结果、原始行或绝对路径。
配置与 CLI¶
配置只有三项¶
interface Config {
mode: 'record' | 'replay'
file: string
include: string[]
}
mode:record执行真实工具并写制品;replay精确命中并跳过正文;file:正式 cassette 文件路径,录制期间使用同路径加.partial后缀;include:显式选择叶子工具,支持精确名称与*通配符;必须非空,空范围、空路径和重复模式在插件启动时直接失败。
先验带,再放带¶
dsh-tool-cassette verify .dsh-cassettes/weather.tool-cassette.jsonl
dsh-tool-cassette inspect .dsh-cassettes/weather.tool-cassette.jsonl
verify 完整校验协议、帧配对、连续 ordinal、哈希链与完成尾帧,用退出码表达结果;inspect 显示协议版本、工具数、调用数与消费说明。校验失败只输出结构性原因,不回显原始行、工具正文或绝对路径。
安装与启用¶
前置条件:已安装 pnpm,Node 版本满足 ^22.19.0 || >=24.0.0。插件固定兼容 DSH 0.1.0-rc.8,安装与运行 profile 请使用同一 rc.8 CLI。
安装命令:
pnpm dlx --package @deepseek-ai/dsh@0.1.0-rc.8 dsh plugin --profile headless add dsh-tool-cassette
安装包会通过 cordis.patch.yml 注入一个默认禁用的 tool-cassette 条目。先做录制:在 profile 的 cordis.patch.yml 中覆盖它,填写模式、文件和叶子工具范围。
- id: tool-cassette
name: dsh-tool-cassette
disabled: false
config:
mode: record
file: .dsh-cassettes/weather.tool-cassette.jsonl
include:
- weather_lookup
- mcp_*_read
跑完一次真实调用后,把 mode 改成 replay,其余轨迹保持一致:
config:
mode: replay
file: .dsh-cassettes/weather.tool-cassette.jsonl
include:
- weather_lookup
- mcp_*_read
经过上面的步骤,再调用 weather_lookup 时,cassette 会递出录制结果,真实工具正文不再执行。
如果想从源码构建并安装本地包:
pnpm install
pnpm run demo
pnpm pack
pnpm dlx --package @deepseek-ai/dsh@0.1.0-rc.8 dsh plugin --profile headless add .\dsh-tool-cassette-0.1.0.tgz
相对路径基于 DSH 进程工作目录解析。
一次离线回放演示¶
项目自带的演示(pnpm run demo)可以完整跑一遍这个流程:
1、启动一个纯本地 HTTP 天气工具;
2、Record 一次,工具正文与网络请求各发生 1 次;
3、关闭 HTTP 服务;
4、Replay 同一条调用,工具正文与网络请求都变成 0;
5、返回结果保持一致,cassette 中的记录全部消费。
整个演示不调用模型,也不产生付费 API 请求。
另外,模型流回放由官方 dsh-llm-replay 负责,本插件只管被选工具正文边界。两者组合,可以搭出模型流与工具流均可回放的无密钥测试。
适用场景与边界¶
它适合这些情况:
- 给 Agent 工作流做离线回归测试;
- 在 CI 中复现一次昂贵或偶发的工具响应;
- 验证插件升级后,当前 schema、renderer 和后置策略仍能处理旧结果;
- 调试 HTTP、MCP、数据库或本地程序工具,不想反复触碰真实服务。
V1 的能力范围是:单 Agent、单场景;显式选择的叶子工具;成功、结构化失败、additionalContexts;并发开始顺序与倒序完成;调用前取消不消费记录。以下明确不支持或留待后续版本:
- 多 Agent 与并发 subagent;
- 同时选择复合工具及其子工具;
concludesTurn: true;- 模糊匹配、参数忽略、自动更新 fixture;
- 延迟与流式取消时序仿真;
- UI、云端制品库、benchmark DSL、模型 judge。
还有两点行为要知道:回放命中后会消费对应记录,随后的 post 阶段取消不会回滚消费位置;回放消费状态只存在于当前进程,全部消费完毕时卸载成功,poison、额外调用或未消费记录会让 headless/CI 进程退出码变为 1。它不充当缓存、模型回放器或生产幂等层。
安全与使用注意¶
V1 为了精确回放,会原样保存规范化后的参数、成功 value、失败信息、渲染内容和附加上下文。cassette 应按密钥文件或测试数据库快照对待:
- 默认
.gitignore已排除 cassette 与 partial; - 只在隔离的本地或 CI 工作目录录制;
- 分享前人工检查全部内容;
- 录制结束后关闭不再需要的真实凭据;
- 参数指纹没有盐,低熵参数仍可能被猜测。
V1 不提供自动脱敏、加密、签名或远端制品库。
最后是通用提醒:作为社区插件,dsh-tool-cassette 以当前 dsh 进程的权限运行,安装前应先检查源码与许可证(MIT),确认兼容的 DSH 版本后再接入。
结尾¶
dsh-tool-cassette 解决的问题很具体:把一次真实的工具执行变成可校验、可离线复用的测试制品,用精确匹配和失败关闭保住对轨迹漂移的敏感度。它和官方 dsh-llm-replay 各守一边,合起来能覆盖模型流与工具流的离线回归。
- GitHub:https://github.com/Lem0nTea2002/dsh-tool-cassette
- 社区插件目录收录页:https://www.skillhub.cn/plugins/Lem0nTea2002/dsh-tool-cassette (目录为独立站点,与 DeepSeek、幻方无官方从属关系)