第22讲 · 自指涉开发——用 dsh 开发 dsh

《DeepSeek Harness 从上手到精通》系列 · 第七阶 深度定制篇

🎯 目标:体验运行时自我扩展——用 dsh 开发 dsh 难度 ★★★ ⏱ 约 45 分钟 前置:第 20、21 讲 · 了解 dsh 源码结构

如果你看到过"用 AI 写 AI"、"agent 写 agent"这类说法但觉得只是 PPT 上的修辞——本讲要把它落到代码上。dsh 自己就是它的第一个用户:它的内部有一组 cordis_* 工具,让模型在 vm 沙箱里动态定义新插件,即写即用。


一、什么是"自指涉开发"

所谓自指涉(self-referential)开发,是指 运行时的 dsh 进程能够修改自己——在不开新仓库、不重启的前提下,给当前进程动态注册新的插件和工具,让模型当场就能调用。

自指涉:递归与镜像
图 1 自指涉开发:系统把"自己"也当作可改造的对象。

这不是炫技。它意味着你可以让 dsh 长出你没预先设计过的能力,并且修改过程可审计、可回滚(还记得 effect 吗)。

二、cordis_* 工具组

这一组工具是 dsh 的"元能力",把插件生命周期包装成模型可调用的函数。常见四条:

工具作用
cordis_define把一段 TS 源码当成一个插件包定义,返回 plugin_id
cordis_run激活指定 plugin_id(执行 apply)
cordis_stop停掉插件(执行 dispose,自动撤销所有 effect)
cordis_inspect_*查看当前已注册的插件树、服务、事件(dump / graph)

这些工具默认不在生产 profile 里,需要走 dsh dev 或显式授权才暴露。

三、在 vm 沙箱里"写一个工具当场用"

最有戏剧感的剧本:让模型给自己写一个"查询今日 K 线"的工具,写完立刻就能用。在 Web UI 里直接对它说:

用 cordis_define 写一个新工具叫 today_kline,参数是 symbol, 调用一个本地 mock 服务(不联网),返回 { open, close, change_pct }。 写完后用 cordis_run 激活,再用这个工具查一下 "AAPL"。

模型底层做的事情大致是:

// cordis_define 的源码参数里,模型提交的就是这段 TS: import { Context, Service } from '@deepseek-ai/dsh-core' class TodayKline extends Service<Context> { static name = 'today_kline' async invoke(args: { symbol: string }) { // mock 数据:返回固定结构 return { symbol: args.symbol, open: 100 + args.symbol.length, close: 101 + args.symbol.length, change_pct: 1.0, } } } export function apply(ctx: Context) { ctx.plugin(TodayKline) ctx.on('dispose', () => ctx.unregister(TodayKline)) }

dsh 在 vm 沙箱里 compile → 注入到运行时 → 注册到 ctx.tools → 工具立刻对模型可见。一次会话内完成"定义 → 激活 → 调用 → 销毁"全链路。

沙箱的边界:vm 里 禁用了 require()、文件系统、网络裸调用。能用的只有 dsh 显式注入的 API——这是安全前提。

四、协作约定:AGENTS.md / CLAUDE.md

dsh 项目自身用一份"给模型读的 README"——AGENTS.md(兼容 CLAUDE.md,两者同义),告诉将来参与开发 dsh 的 agent 该怎么做:

  • 项目结构、命名约定、不要碰哪些"保留目录";
  • 每改一个子包就要跑 .agents/notes/ 里的标准测试矩阵;
  • 文档用"生成式"流水线维护:跑 pnpm docs:check 自动校验。

这个约定可以被你"借走":在自己团队的仓库里也放一份 AGENTS.md,让 dsh(或其他 agent)按你们的规矩干改代码的活。

五、参与开源:测试矩阵与文档校验

想给 dsh 提 PR?CONTRIBUTING.md 里列了六套必跑测试矩阵

  1. pnpm test:单元测试;
  2. pnpm test:e2e:端到端(Playwright + dsh dev);
  3. pnpm test:browser:浏览器形态;
  4. pnpm test:tui:终端形态;
  5. pnpm test:python:Python SDK 冒烟;
  6. pnpm docs:check:生成式文档一致性(重要:防止 cordis 注释过时)。

这套矩阵就是为什么 dsh 在高速迭代里仍然稳:每个 PR 都得跑完 6 项。提 PR 时建议先在本地跑一遍,CI 一次过的概率会高很多。

六、动手练习:一次完整的"运行时定义 + 即时调用"

  1. 以 dev 模式启动 dsh:npx @deepseek-ai/dsh dev --enable-cordis-tools
  2. 让 agent 用 cordis_define 写一个工具 now_beijing(),返回当前 +08:00 时间字符串;
  3. cordis_run 激活;用 cordis_inspect_tools 看到新工具出现在列表里;
  4. 直接在对话里调用 now_beijing(),观察返回值;
  5. cordis_stop 撤销,验证下次调用该工具会报"未注册"。

七、常见坑

  • 生产 profile 默认禁用:别在正式环境挂 --enable-cordis-tools,它是给开发者/调试用的;
  • vm 沙箱的 import 限制:写插件代码只能用注入的 API,import fs from 'node:fs' 会被编译报错;
  • 没写 dispose 回调:动态插件也遵循 effect 原则,否则会在 dev 热重载中累积泄漏;
  • AGENTS.md 与 README 冲突:把 AGENTS.md 写成 README 的子集或补充,避免给模型互相打架的指引;
  • PR 没跑 docs:check:生成式文档会自动从源码注释生成,没跑校验容易出现"代码改了但文档没改"的不一致。

八、官方文档对应章节

  • docs/self-development.mddocs/cordis-vm.md
  • 仓库根 AGENTS.mdCONTRIBUTING.md.agents/notes/
  • GitHub Actions 配置文件 .github/workflows/ci.yml 里的六套 job。

本讲内容基于 DeepSeek Harness 官方文档与项目源码整理,仅供学习参考,具体命令与配置请以官方最新版本为准。源码仓库:https://github.com/deepseek-ai/deepseek-harness

咨询 DeepSeek Harness 相关问题,请加微信:A0qingfengyuan_01

个人观点,仅供参考,如有不对之处,请多包涵,欢迎指出。本文由 AI 协助完成!