灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • OpenClaw

  • Hermes-Agent

  • Claude-Code

  • LLM推理

  • DeepSeek-Harness

    • DeepSeek Harness 实战 01|同一条纪律,写在两个位置,模型只听一个
    • DeepSeek Harness 实战 02|三个 Harness 的解剖:同一个文件名,三种加载语义
    • DeepSeek Harness 实战 03|学习笔记:读 12 篇 README 拿下 dsh 的五个核心心智模型
      • 1. 为什么要先找「骨架」,而不是顺着读
      • 2. 模型一:一切皆插件,生命周期靠 fiber 回收
      • 3. 模型二:会话是只追加的日志,消息历史是派生出来的
      • 4. 模型三:Scope 管可见性与所有权,但明确不是安全边界
      • 5. 模型四:系统提示词是组装出来的,不是写出来的
      • 6. 模型五:工具调用是一条受守卫的流水线
      • 7. 五条之外:三处设计者自己写下的张力
      • 8. 坑与边界
      • 9. 可复用要点
        • 自检:怎么确认自己真的读懂了
      • 10. 延伸阅读
    • DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力
  • AI-Agent
  • DeepSeek-Harness
灯下哥谭
2026-09-08
目录

DeepSeek Harness 实战 03|学习笔记:读 12 篇 README 拿下 dsh 的五个核心心智模型原创

# 学习笔记:读 12 篇 README 拿下 dsh 的五个核心心智模型

一个本地装好的 DeepSeek Harness(下称 dsh)安装目录里,散着 200 多个 npm 包,其中 212 个带 README.zh.md,加起来 1.84 MB、约 60 万 token。按第一页开始顺读的方式,读完之前你的上下文窗口先没了;而真正定义这套体系怎么运转的,只有其中十几篇。这篇是一份读完那十几篇之后的学习笔记:五个核心心智模型,剩下的两百篇都是它们的实例。

版本说明

基于 0.1.2-rc.1(developer preview)本地安装目录里的随包中文文档整理。插件级字段以你本机安装目录里各插件自带的 README.zh.md 为准——公开文档站给的是全局架构,本文引用的多数细节在站上查不到。读到与本文不符时以实机为准。


# 1. 为什么要先找「骨架」,而不是顺着读

面对一个陌生的大型体系,有两种读法。

顺读法:从入口文件开始,一个包一个包往下追。它的问题不是慢,是信息密度极度不均——两百篇功能插件的 README 讲的都是同一批机制的不同用法,读完第 20 篇之后边际收益趋近于零,但你不知道自己已经到了那个点。

骨架法:先挑出定义体系怎么运转的那部分文件(依赖容器、作用域、会话、提示词组装、工具注册表),只读它们,而且只读每篇的概述 / 设计理念 / 已知限制三节。这三节的信息浓度和其余部分完全不是一个量级:概述给你机制,设计理念给你「为什么不是另一种做法」,已知限制给你设计者自己签过名的取舍——那是最容易被忽略、又最容易在生产里咬人的东西。

怎么区分骨架文件和功能文件?一个可操作的判据:读完它以后,能不能用它去解释别的文件。能,就是骨架。在 dsh 这里,骨架大约是这十几个包:依赖容器本体、作用域、会话、工具注册表、系统提示词组装、agent 主循环、以及类型协议那两个。

下面五条就是从这批文件里剥出来的。每条都标了出处包,方便回原文核对。


# 2. 模型一:一切皆插件,生命周期靠 fiber 回收

出处:依赖容器包(cordis)

最容易读错的地方是把 dsh 想成「内核 + 可选插件」。它不是。那个跑 agent 的 while 循环本身、系统提示词组装、bash 工具,全都是插件,和你自己写的插件在容器里地位完全平等。

三个原语撑起整棵树:

原语 作用
new Context() 根依赖容器
ctx.plugin(p, config) 启动一个插件,返回一个 fiber
inject: ['xxx'] 声明依赖;依赖缺失就不启动

关键直觉在 fiber 上:注册不是「往全局表里加一条」,而是挂在当前 fiber 上。插件在自己的生命周期里注册的事件监听、服务、副作用,全部记在这个 fiber 的账上;fiber 一 dispose,它这辈子注册过的东西一起消失。

这解释了一件反直觉的事:整套体系几乎没有「卸载逻辑」。你写插件时不需要配对地写一个 unregister,因为回收的单位不是你注册的那一条,而是承载它的 fiber。热重载、按需启停、配置改了重建子树,全都建立在这个前提上。

能直接用的推论:改配置让某个功能生效或失效,本质是在这棵树上启停一个 fiber。所以「改了配置没生效」的第一诊断不是查字段拼写,而是确认那个 fiber 有没有被重建——以及它依赖的服务在重建时是否已经就绪(inject 没满足时插件是静默不启动的,不是报错)。


# 3. 模型二:会话是只追加的日志,消息历史是派生出来的

出处:会话包(dsh-session)

这条最反直觉,也最重要。

dsh 不存一份「消息列表」。它存的是事件日志,只追加。发给模型的 messages 数组每次都由 deriveMessages() 从日志现算出来。

三个直接后果:

  1. 回放等于重新派生,不是读快照。 同一份日志,换一套派生规则就能得到不同的消息视图,不需要迁移历史数据。
  2. 压缩(compaction)是「遮蔽」,不是删除。 上下文压缩把旧条目标记为不参与派生,原始条目永远还在日志里。这意味着压缩是可审计、可回溯的——出了问题能翻回压缩前的真实内容。
  3. 持久化是独立关注点。 存储后端只是订阅事件流、在 flush 时落盘的一个订阅者。换存储后端不动核心逻辑。

这条模型的价值在于它给了你一个排查断言:当模型的行为和你以为的历史对不上时,去看日志派生的结果,而不是看界面上渲染的对话。两者不是同一个东西——界面渲染的是给人看的视图,模型收到的是派生出来的那份。

它也给了一条边界,后面第 6 节会看到设计者自己承认的一个例外。


# 4. 模型三:Scope 管可见性与所有权,但明确不是安全边界

出处:作用域包(dsh-scope)

createScope(ctx, agentId) 造出一个带标签的 ctx。通过它注册的工具只对那个 agent 可见,并且随它一起 dispose。

父子链是不对称的,这点必须记牢:

  • 注册视图向下继承:子作用域看得见祖先注册的层,且近者遮蔽远者(同名时子覆盖父)。
  • 事件放行向上扩展:祖先的监听器收得到子孙发出的事件。
  • 反向永不成立:父看不见子注册的东西,子的监听器也收不到祖先的事件。

「近者遮蔽远者」这条是很多「配置明明写了却没生效」的真实成因——不是没读到,是被更近的一层同名项整个盖掉了。遮蔽是替换,不是合并。

而 README 里那句原话值得原样抄下来:「它不是沙箱或权限边界。」 Scope 只用于在互相信任的同进程插件之间做路由。把一个 scoped ctx 交出去,等于把该作用域的服务解析能力交出去了。真正的隔离在别处(见下一节的张力)。


# 5. 模型四:系统提示词是组装出来的,不是写出来的

出处:系统提示词包(dsh-system-prompt)

agent 循环的每一步都会调用一次 assemble()。参与组装的有四类东西:

  • 插件贡献的带 order 的有序段
  • 动态 runtime 上下文
  • 工具 schema
  • 具名变量

于是「提示词」不是一份可以打开编辑的文本,而是一次组装的输出。同一个 agent 在第 1 轮和第 8 轮拿到的系统提示词可以是不同的——因为 runtime 上下文变了。

这条模型解释了一类具体的踩坑:preset 里的 persona 是靠同名遮蔽把部署级 persona 整个盖掉的,不是追加上去(这正是模型三的遮蔽规则在提示词层的投影)。以为是两段拼接、结果只剩一段,根因在这。

README 里还有一句同样值得抄下来:「不存在终端用户提示词编辑 API。」 提示词文本只能来自配置与组合,这是刻意设计,不是功能缺口。想改,就去改贡献那一段的插件配置,或者加一个 order 更靠后的段做遮蔽。


# 6. 模型五:工具调用是一条受守卫的流水线

出处:工具注册表包(dsh-tools)

模型每发起一次工具调用,要穿过一串关卡:

允许 / 拒绝 / 询问策略
  → 单调守卫
  → 环绕分发的包装层
  → 结果检查
  → 内容终结
  → 仅观测通知
1
2
3
4
5
6

把它当函数调用来理解,就会在两个地方翻车:

其一:timeoutMs 只是声明,注册表根本不执行超时。 你在工具定义里写了超时时间,它只是一段元数据。要真的超时,必须挂上超时策略包装层。没挂的话,一个卡死的工具会把整个循环挂住,而且没有任何报错。

其二:tools/pre-execute 故意不允许改写参数。 直觉上这是个天然的「参数修正」钩子,但设计上禁止——因为一旦允许,日志里记录的参数和实际执行的参数就会不一致,而那正好违反模型二(日志是唯一真源)。想改参数,只能在更上游的地方改。

这两条都不是 bug,是模型二在工具层的强制执行。


# 7. 五条之外:三处设计者自己写下的张力

学习笔记如果只抄「共识」,就还停在阅读理解。真正拉开理解深度的是冲突——在软件项目里,冲突不表现为学派之争,而表现为设计者自己写在「已知限制」里的取舍。dsh 有三处这样的张力,都是署过名的:

  1. 配置层被刻意做窄,能力向编程式 API 倾斜——逐 agent 的 persona 与工具组合只在编程式工厂选项里提供,YAML 那层没有对应字段。
  2. 隔离到底算不算安全边界——同一个仓库里有两个答案:作用域明说自己不是权限边界,沙箱那一支却上了内核级 landlock,主程序还硬性拒绝绑 0.0.0.0。
  3. PTC 模式与模型二正面冲突——模型写代码调工具时,中间值不进日志、无字节上限、无法从回放重建。设计者知道,写下来了,然后接受了。

这三条各自都有能在生产里咬人的下游后果,展开在本系列的下一篇:从「已知限制」里读出三处设计张力。


# 8. 坑与边界

  • 别把「没报错」当成「生效了」。 这套体系里至少有三处是静默失败:inject 依赖不满足时插件不启动、同名遮蔽把配置整段盖掉、timeoutMs 没有执行者。三处都不会给你一行错误日志。
  • 别拿公开文档站核对插件字段。 站上是全局架构,插件级字段以本机安装目录里各自的 README.zh.md 为准;版本一旦不同,站上的写法可能根本不存在于你装的这版。
  • 「已知限制」不是免责声明,是最高信息密度的一节。 上面三条张力全部来自这一节。跳过它,等于把设计者已经替你踩过的坑重新踩一遍。
  • 这五条是骨架,不是全集。 骨架的用途是让剩下的两百篇变成可跳读的实例库——遇到具体插件时按需回查,而不是提前通读。
  • 版本会变。 developer preview 阶段的机制会调整,尤其是被标为已知限制的那几条,很可能正是下一版要改的地方。

# 9. 可复用要点

这套读法本身可以迁移到任何一个陌生的大型代码库或框架:

  1. 先划定封闭语料,而且优先用本机安装目录里的随包文档,而不是搜索引擎或官网——本机文档对应的是你实际装的那个版本,官网对应的是最新版。
  2. 不通读。挑出定义体系如何运转的十几篇,每篇只抽概述、设计理念、已知限制三节。
  3. 判据是「能不能用它解释别的文件」,能,就是骨架。
  4. 共识之外必须挖冲突,而软件领域的冲突不是学派之争,是「已知限制」里署名过的取舍。
  5. 每条结论都记出处,方便随时回原文核对——学习笔记的价值一半在结论,一半在能被证伪。
  6. 读完之后用主动回忆检验:合上文档,逐条复述五个模型和它们的直接后果,卡住的地方就是理解的幻觉所在。

# 自检:怎么确认自己真的读懂了

光是「看懂了」通常是理解的幻觉。下面四条都是能在本机跑出预期输出的检验,不是背诵题:

检验对象 怎么确认 预期结论
模型一(fiber) 故意给一个插件写一个不存在的 inject 依赖,重启 无报错,功能直接不存在——确认依赖缺失是静默的
模型二(派生) 触发一次上下文压缩后,回查原始事件日志 被压缩的条目仍在日志中,只是不参与派生
模型四(遮蔽) 在更靠后的 order 上贡献一个同名段 前一段整段消失,而不是两段拼接
模型五(超时) 给一个长耗时工具只写 timeoutMs、不挂超时包装层 到点不中断,循环一直挂着且无错误日志

四条里任何一条的实际结果和预期不符,说明对应那个模型的理解需要回原文重读——而不是先怀疑版本差异。


# 10. 延伸阅读

dsh 的公开文档站有中文版:DeepSeek Harness 参考手册 (opens new window),仓库在 deepseek-ai/deepseek-harness (opens new window)。再说一遍:插件级配置字段以本地安装目录里各插件自带的 README.zh.md 为准。

本系列另外两篇:提示词分层与技能加载实测 讲提示词分层与 skill 的实际加载路径;三个 Harness 的解剖 横向对照三家编码 harness 的上下文文件、工作区、记忆与 skill 语义——本文的模型三、模型四在那篇里有跨工具的对照版本。


🤖 Agent 可直接解析的元数据块(点击展开)
{
  "_meta": {
    "doc_version": "2026-09-08",
    "article_id": "dsh-03-five-mental-models",
    "profile_context": "any",
    "estimated_setup_time": "20min"
  },
  "quick_start": {
    "step_1": "定位本机安装目录,统计随包 README 数量与总体积,确认无法通读",
    "step_2": "挑出骨架文件:依赖容器、作用域、会话、提示词组装、工具注册表、agent 循环",
    "step_3": "每篇只读『概述 / 设计理念 / 已知限制』三节",
    "step_4": "从『已知限制』里提取设计者签名过的取舍,作为冲突点",
    "step_5": "合上文档逐条复述五个模型及其直接后果,卡住处即为理解缺口"
  },
  "mental_models": [
    "一切皆插件,注册挂在 fiber 上,dispose 即整体回收",
    "会话是只追加日志,消息历史由 deriveMessages 派生;压缩是遮蔽不是删除",
    "Scope 管可见性与所有权,注册向下继承、事件向上扩展,且明确不是安全边界",
    "系统提示词每轮组装而成,同名遮蔽是替换不是追加,无终端用户编辑 API",
    "工具调用是受守卫的流水线;timeoutMs 不自执行,pre-execute 不许改写参数"
  ],
  "safety_rules": [
    "不要把『没报错』当作『生效了』:依赖缺失、同名遮蔽、超时未挂三处均静默失败",
    "不要用公开文档站核对插件级字段,一律以本机随包 README.zh.md 为准",
    "不要跳过『已知限制』一节,最高价值信息在那里",
    "不要把 scope 当权限边界使用;真正的隔离靠内核级沙箱与网络绑定限制"
  ],
  "verification": {
    "check_plugin_started": "确认目标 fiber 是否真的重建,以及其 inject 依赖在重建时是否就绪",
    "check_prompt_shadowing": "对照贡献同名段的各插件配置与其 order,确认最终生效的是哪一段",
    "check_tool_timeout": "确认是否挂载了超时策略包装层,仅声明 timeoutMs 不产生超时行为",
    "check_history_source": "以日志派生结果为准判断模型收到的历史,而非界面渲染的对话视图"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

AI Agent 使用指南:

  • 当用户说「配置写了但没生效」→ 依次排查 fiber 是否重建、inject 是否满足、是否被更近一层同名项遮蔽
  • 当用户说「工具卡住了没有报错」→ 检查是否挂载超时策略包装层,timeoutMs 本身不执行
  • 当用户说「模型记错了历史」→ 查日志派生结果而非界面视图,并确认压缩遮蔽了哪些条目
  • 当用户说「想快速学会某个陌生框架」→ 按 quick_start 的封闭语料 + 骨架抽取 + 主动回忆三步走
#AI Agent#Agent架构#学习方法#DeepSeek Harness
上次更新: 9/8/2026

← DeepSeek Harness 实战 02|三个 Harness 的解剖:同一个文件名,三种加载语义 DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力→

最近更新
01
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
02
DeepSeek Harness 实战 02|三个 Harness 的解剖:同一个文件名,三种加载语义 原创
09-08
03
DeepSeek Harness 实战 01|同一条纪律,写在两个位置,模型只听一个 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式