dsh 是什么
DeepSeek 开源的 Agent 运行时,MIT 协议。官方定位:Agent = Model + Harness,模型负责想,Harness 负责模型之外的一切:工具、文件系统、会话、日志、界面。
更关键的是架构口号:"一切皆插件"。底层内核叫 Cordis,模型适配器是插件,会话日志是插件,连 Agent 主循环本身都是插件,官方原话 "no privileged core to patch"。想改什么,就挂一个插件在旁边,不用 clone 源码、不用改内核。
插件解决什么问题
我用 dsh 之前,用着多个 Agent 工具,各有各的约束规则和记忆文档,散在不同目录;还有一套知识库仓库,里面存着规则、文档、知识。这些都是跨会话全局记忆的雏形——但 dsh 不知道它们存在。
dsh 本身没有内置全局记忆。它的全局自动加载只加载 ~/.dsh/AGENTS.md,工作区级只管项目目录链,其他工具的全局文档它完全不读。
社区有别的记忆插件,但都是奔着"记忆引擎"做的:自动吸收、蒸馏、检索,还要配服务和数据库,比较重。
所以我写这个插件轻量化:文档不动、原地注入。把文档路径列进配置,dsh 每次会话装配系统提示词时全文注入,跨工作区生效。零依赖、单向只读、不写回文件。
看看代码
核心就是一个函数。apply 是 Cordis 插件的入口,config 是它的第二参数——注意不是从 ctx.plugin.config 上取。
export function apply(ctx, config) {const cfg = { ...DEFAULTS, ...(config ?? {}) }ctx.systemPrompt.section({name: 'memory-snapshot',order: cfg.order,// text 是函数:每次装配系统提示词时重新读文件,改完文档不用重启就生效text: () => [`${cfg.marker}-MARKER: 用户记忆快照已注入。`,'以下是用户的长期记忆文件(持久化,跨会话持续有效,回答用户问题时优先参考):','---',loadSnapshot(cfg.files, cfg.maxBytes),'---','记忆快照结束。请勿复述以上内容,只需在相关问题时使用它。',].join('\n'),})}
loadSnapshot 就是逐个读文件、按 maxBytes 截断,读不到的文件把原因标出来,不崩会话。配置校验直接手写 ~standard 接口(zod 底层实现的也是这个),所以一个依赖都不用引。
装好后,安装脚本会往 cordis.patch.yml 里写入这么一段配置,之后想换记忆源,改 files 列表重启 dsh 即可:
# ~/.dsh/cordis.patch.yml(install.mjs 自动写入)- insert:- id: memory-snapshotname: 'file:///~/.dsh/plugins/dsh-memory-snapshot/index.js'config:files:- '~/MEMORY.md'- '~/notes/context.md'maxBytes: 3000 # 单文件注入上限,防系统提示词撑爆
这个插件怎么做出来的:Spec Coding + 多 Agent 协作
插件基本是 AI 完成,工作流:
- 写 Spec
先把需求、接口约定、验收标准写成文档,明确插件形态(函数式 Cordis 插件、 ~standard配置校验、系统提示词注入) - 委派编码
按 Spec 分派编码任务,产出 TypeScript 源码 + 零依赖构建 - 对抗验证
另一个 Agent 扮演挑刺角色做 code review,专找接口误用、边界条件;再由我人工 code review - 实机跑通
真实 dsh 会话验证,自动化测试(含实机会话)全通过
对抗验证那轮真抓出问题:比如 Cordis 插件的 config 是 apply(ctx, config) 的第二参数,不是 ctx.plugin.config——这种坑文档不写明、单靠一个 Agent 很容易踩。两轮 review 加实机验证,才算跑通。
验收是基于dsh的Trajectory功能
我把带特征词的记忆快照注入系统提示词,然后解码会话日志——能看到 dsh 每次会话都写一个 zstd 压缩的 JSONL 事件流(~/.dsh/sessions/<工作区>/<会话id>/session.jsonl.zstd),特征词在系统提示词的注入段里,测试通过。

这就是 dsh 的 Trajectory:模型给你的是自我报告,日志给你的才是它真正收到的东西。调试 Agent,后者才是证据。
安装验证
写完当然要真跑一遍。安装就一行:
nodeinstall.mjs
装完 ~/.dsh/cordis.patch.yml 里多出一条配置,默认指向当前目录下的 ./MEMORY.md:

直接起 dsh 会话。默认路径下没有这个文件,插件把读取失败的原因原样报进系统提示词,就是明确告诉你没读到:
把 files 改成指向我的知识库里的 git 提交规则文档,重新问一次,这次内容真的进去了:


在 dsh web 的轨迹视图里,还能直接看到模型收到的完整系统提示词: 
全文完。
📮
👋 还没关注?别划走,这里有个名片等你收下。
往期精选
记:从Claude Code迁移到OpenCode,我做了什么工作?
Ollama vs LM Studio vs llama.cpp:本地大模型方案怎么选?
Hermes 和 Claude Code 协作踩坑 & 如何编写对应委派 Agent Skill
解决 Unity InputSystem 微信小游戏在鸿蒙版的触摸异常
Godot Ollama 角色人格注入:三张角色卡让 AI 第一次有性格
夜雨聆风