DeepSeek Harness 注册了几个工具:README 五个、源码七个

2026-08-16

如果你打算在 DeepSeek Harness 上做二次开发,packages/extensions/ 这个包组大概是最容易先翻到的一处。它的定位写在 packages/extensions/README.md:5:面向模型的一组工具,作用对象是 agent 自己正跑在其中的那个 cordis 运行时——查看已加载的插件与服务 API、定义并运行模型写出来的动态包、再把它们撤回。听起来很有意思,于是你打开 packages/extensions/tool-cordis/README.md 想抄工具名,麻烦就从这里开始。

先把限定条件说在前面:本文对应的仓库快照是 47f9438,我们核对日为 2026-08-16。这个仓库建立于 2026-08-13,我们采集时距建仓只有三天;版本号是 0.1.0-rc.5,GitHub 上没有任何 Release,README 自述处于开发者预览阶段并明写未来会出现破坏兼容性的变更。所以下面提到的每一个工具名、字段名、默认值都可能随时变动,请以仓库最新内容为准。我们没有安装、也没有运行过这个项目,下文所有内容都是读文件所得。

差异一:README 说「五个」,源码里 name: 出现七个

packages/extensions/tool-cordis/README.md:5 写的是「five model-facing tools」,也就是五个面向模型的工具。

packages/extensions/tool-cordis/src/index.ts 里,name: 字段实际给出了七个工具名:

工具名源码行
cordis_inspect_list:42
cordis_inspect_query:61
cordis_inspect_self:97
cordis_define:149
cordis_run:241
cordis_stop:330
cordis_undefine:352

两处不一致:README 的口径是五个,源码里注册的是七个。以我们实读的仓库状态为准。差异说到这里为止,我们不去推断哪一份是「对的」,也不去猜是谁没同步——这不是本文能回答的问题,也不该由读者去脑补。

差异二:README 里那个 cordis_inspect,源码里搜不到

第一条差异往下追一层,会落到工具名上。packages/extensions/tool-cordis/README.md:11 的要点列表里,那份只读报告是用一个叫 cordis_inspect 的工具名来描述的。

我们对 packages/ 下的全量 TypeScript 文件搜索 cordis_inspect'(带上右引号,避免把三个 cordis_inspect_* 也匹配进来),结果没有命中。源码侧是拆开的三个:cordis_inspect_listcordis_inspect_querycordis_inspect_self,行号见上表。

这一条比「五个还是七个」更值得单独拎出来,因为数量差异顶多让你数错,而一个在源码里不存在的工具名会直接影响你写出来的东西——你按 README 的字面去拼调用、去写 allowlist、去做工具名匹配,都会落空。判定动作很简单:在仓库根目录对 packages/ 做一次带引号的精确搜索,看有没有 cordis_inspect' 这一串;再对同一个 src/index.tsname:,把行号抄下来。这两步不需要装任何东西,clone 下来就能做。

差异三:服务键是 ctx.dynamic 还是 ctx.dynamicCordisRunner

同一份 packages/extensions/tool-cordis/README.md:5(以及它的中文版 README.zh.md:5)在提到 runner 时,写的是它提供 ctx.dynamic

而另外三处写的是另一个键:

  • packages/extensions/tool-cordis/src/index.ts:27inject 数组里是 ['tools', 'systemPrompt', 'dynamicCordisRunner', 'cordisInspect']
  • docs/subsystems/extensions.md:69 的生成目录里,服务键写作 ctx.dynamicCordisRunner,对应的服务类是 DynamicCordisRunnerService,源码位置 packages/extensions/cordis-host-runner/src/index.ts:124
  • packages/extensions/cordis-host-runner/README.md:44 同样写「service key dynamicCordisRunner」。

顺带说一句关于 docs/subsystems/extensions.md 这份文档的读法:它全文 364 行,其中第 7 行到第 364 行是生成区块,标记是 <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) -->,由 scripts/gen-cordis-catalog.ts 从源码生成,仓库里有一条 pnpm run verify-cordis-catalog 用来在 doc-sync 里校验新鲜度(:13)。这个包组还暴露了另一个服务键 ctx.cordisInspect,对应 CordisInspectRegistryService,源码在 packages/extensions/cordis-host-runner/src/inspect-registry.ts:46

差异四:ackTimeoutMs 只在一处 README 里存在

packages/extensions/tool-cordis/README.md:27 的「Config」小节说,这个工具集自己没有配置项,vm 求值边界(vmTimeoutMs)与浏览器确认窗口(ackTimeoutMs)属于拥有沙箱与广播的 runner 服务。

但翻到 runner 那一侧:packages/extensions/cordis-host-runner/README.md:36-40 的配置表只有 vmTimeoutMs 一项,并在 :40 明写「One field is all there is」;源码 packages/extensions/cordis-host-runner/src/index.ts 里同样只有 vmTimeoutMs,类型在 :90,默认值 5000:128。我们对整个 packages/ 目录搜 ackTimeoutMs,只命中两行:packages/extensions/tool-cordis/README.md:27 与其中文版 README.zh.md:27

这里要提醒一条通用的读法,不只对这个仓库有效:配置里出现 ≠ 功能可用,文档里出现更 ≠ 配置项存在。看到一个字段名,第一件事是回源码 grep 它的定义与默认值;grep 不到就照实记「没找到对应实现」,而不是当成一个能填的配置去写进 cordis.yml。至于 vmTimeoutMs5000 这个数字,它是配置里的默认值,不是对运行表现的任何承诺——该调成多少取决于你的用法,项目没有给出通用值。

把这四条压成一个可复用的核对流程

这四处差异形态各不相同,但核的动作是同一套,四步:

  1. 先定位「文档侧的说法」在哪一行。 上面每一条我们都给了文件路径加行号,包括中文版 README,别只看英文版就下判断。
  2. 再回源码找同名标识符。 工具名去 src/index.tsname:;服务键去 inject 数组和 Service 子类的构造里搜;配置项去 schema 定义和默认值那一段搜。搜索时把引号带上,能避开前缀相同的兄弟标识符——差异二就是靠这一点区分开的。
  3. 看有没有第三方口径。 这个仓库里的 docs/subsystems/ 有相当一部分是生成区块,docs/tool-catalog.mddocs/config-catalog.md 也被多处文档指为「精确工具参数 schema」与「精确配置默认值」的去处。需要说明的是,本文的默认值全部回源码核,我们没有把这两份生成目录逐条比对过,所以不对它们的口径下判断。
  4. 确认差异不是自己搞错了范围。 什么情况说明「不是这个问题」:如果你搜不到某个标识符,先确认搜索路径覆盖了 packages/ 全量而不是单个包,确认没有把 node_modules 一起排除掉了目标文件,也确认你手上的快照与本文一致——我们用的是 47f9438,仓库处于开发者预览阶段,上游一次提交就可能让上面的行号全部失效。

顺便照读 README 里另外两段话

翻这个包的时候,有两段原文值得按原样记住,它们跟上面的差异无关,但比工具名更要紧。

一是动态包的边界(packages/extensions/tool-cordis/README.md:19):动态包只活在共享的 DSH 进程内存里,跨轮次保持活跃,也可能影响同进程内的其它会话;在 cordis_stop / cordis_undefine、工具集卸载或 DSH 重启之后消失。它们不创建任何 Plugin 文件、不安装包、不改 cordis.yml 或个人与项目配置、不跨重启存活,也无法自动提升为正式插件。

二是信任姿态(packages/extensions/tool-cordis/README.md:23),两句关键原文是:「The sandbox isolates globals but is not a security boundary.」以及「Treat this toolset like bash access」。这里就照抄,不加演绎——这个工具集能让模型写的代码在你本机的 DSH 进程里求值,README 自己把它的风险等级对齐到了 bash 访问权限。

这三个包在出厂组合里的位置

最后补一个组合层面的事实,方便你判断这个工具集默认在不在你手上。我们对全仓 *.yml 做了搜索:@deepseek-ai/dsh-cordis-host-runner 出现在 packages/bundle/web-app/cordis.patch.yml:102-103@deepseek-ai/dsh-client-ui-cordis 出现在同一文件的 :206;而 @deepseek-ai/dsh-tool-cordis 只出现在 apps/cli/config/agent-presets/cordis/agent.cordis.yml:245-246 这一处。

再提一个跟本文主题同源的小陷阱:packages/extensions/ 下四个子包里,ui-cordis 这个目录的包名是 @deepseek-ai/dsh-client-ui-cordis——目录名不等于包名。写组合行、写安装命令的时候,要用 package.json 里的 name,不能拿目录名去凑。

延伸阅读


本文依据 DeepSeek Harness 官方仓库(github.com/deepseek-ai/deepseek-harness)的 README、docs/ 下的 架构与子系统文档、以及 packages/ 下的源码整理,核对日 2026-08-16,对应仓库快照 47f9438(版本 0.1.0-rc.5)。 本文内容为仓库源码与文档口径,我们没有安装、也没有运行过这个项目, 因此不涉及界面外观、操作手感与运行速度的任何描述。 该仓库建立于 2026-08-13,README 自述处于开发者预览阶段并明确说明未来会有破坏兼容性的变更, 文中出现的命令、配置与默认值随时可能变动,请以仓库最新内容为准。 安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。