【DSH】为什么需要-Harness

为什么需要 Harness

  1. 大模型在本质上缺什么;
  2. Harness 补的到底是什么;
  3. 为什么 DeepSeek 会选择"一切皆插件"作为架构立场;
  4. 学界到工业界的 Agent 范式是怎么演进的。

0. 一个反直觉的起点

大多数人第一次接触 dsh,会认为它是一个"更强的 ChatGPT 客户端",或者"一个能写代码的 AI 工具"。

**这两个理解都是错的,而且错得关键。**真正值得研究的东西是这样的一个事实:

DeepSeek 花了大量算力训练出的模型,本身并不能读写文件、不能执行命令、不能记住上一句话、不能拒绝你的请求。

所有这些能力,一行都不是模型提供的。

模型交付到你手上时,它是一个纯函数。把这句话理解透,后面所有的架构设计都会变得顺理成章。


1. 第一性问题:模型在本质上是什么

严格地说,一个大语言模型是一个函数:

复制代码
M : C  →  Δ(V)
  • C(Context,上下文):一串 token
  • V(Vocab,词表):所有可能的下一个 token
  • Δ(V):词表上的一个概率分布(softmax 之后)

它做的事只有一件:给定前面的 token,预测下一个 token 的分布。

1.1 三个被忽视的推论

推论一:模型是纯函数,因此没有记忆。

M(C) 的输出只依赖 C。这意味着你今天早上和它说的第一句话,它在今天下午"想起来"的方式,仅仅是有人把那句话重新放进了 C 里。

所谓"对话记忆",在工程上是一个谎言------真实发生的是:
#mermaid-svg-3sSKuTNa79gvif1U{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3sSKuTNa79gvif1U .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3sSKuTNa79gvif1U .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3sSKuTNa79gvif1U .error-icon{fill:#552222;}#mermaid-svg-3sSKuTNa79gvif1U .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3sSKuTNa79gvif1U .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3sSKuTNa79gvif1U .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3sSKuTNa79gvif1U .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3sSKuTNa79gvif1U .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3sSKuTNa79gvif1U .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3sSKuTNa79gvif1U .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3sSKuTNa79gvif1U .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3sSKuTNa79gvif1U .marker.cross{stroke:#333333;}#mermaid-svg-3sSKuTNa79gvif1U svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3sSKuTNa79gvif1U p{margin:0;}#mermaid-svg-3sSKuTNa79gvif1U .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3sSKuTNa79gvif1U .cluster-label text{fill:#333;}#mermaid-svg-3sSKuTNa79gvif1U .cluster-label span{color:#333;}#mermaid-svg-3sSKuTNa79gvif1U .cluster-label span p{background-color:transparent;}#mermaid-svg-3sSKuTNa79gvif1U .label text,#mermaid-svg-3sSKuTNa79gvif1U span{fill:#333;color:#333;}#mermaid-svg-3sSKuTNa79gvif1U .node rect,#mermaid-svg-3sSKuTNa79gvif1U .node circle,#mermaid-svg-3sSKuTNa79gvif1U .node ellipse,#mermaid-svg-3sSKuTNa79gvif1U .node polygon,#mermaid-svg-3sSKuTNa79gvif1U .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3sSKuTNa79gvif1U .rough-node .label text,#mermaid-svg-3sSKuTNa79gvif1U .node .label text,#mermaid-svg-3sSKuTNa79gvif1U .image-shape .label,#mermaid-svg-3sSKuTNa79gvif1U .icon-shape .label{text-anchor:middle;}#mermaid-svg-3sSKuTNa79gvif1U .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3sSKuTNa79gvif1U .rough-node .label,#mermaid-svg-3sSKuTNa79gvif1U .node .label,#mermaid-svg-3sSKuTNa79gvif1U .image-shape .label,#mermaid-svg-3sSKuTNa79gvif1U .icon-shape .label{text-align:center;}#mermaid-svg-3sSKuTNa79gvif1U .node.clickable{cursor:pointer;}#mermaid-svg-3sSKuTNa79gvif1U .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3sSKuTNa79gvif1U .arrowheadPath{fill:#333333;}#mermaid-svg-3sSKuTNa79gvif1U .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3sSKuTNa79gvif1U .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3sSKuTNa79gvif1U .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3sSKuTNa79gvif1U .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3sSKuTNa79gvif1U .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3sSKuTNa79gvif1U .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3sSKuTNa79gvif1U .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3sSKuTNa79gvif1U .cluster text{fill:#333;}#mermaid-svg-3sSKuTNa79gvif1U .cluster span{color:#333;}#mermaid-svg-3sSKuTNa79gvif1U div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3sSKuTNa79gvif1U .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3sSKuTNa79gvif1U rect.text{fill:none;stroke-width:0;}#mermaid-svg-3sSKuTNa79gvif1U .icon-shape,#mermaid-svg-3sSKuTNa79gvif1U .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3sSKuTNa79gvif1U .icon-shape p,#mermaid-svg-3sSKuTNa79gvif1U .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3sSKuTNa79gvif1U .icon-shape .label rect,#mermaid-svg-3sSKuTNa79gvif1U .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3sSKuTNa79gvif1U .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3sSKuTNa79gvif1U .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3sSKuTNa79gvif1U :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 真实情况
第1轮: C = 系统, 用户A
第2轮: C = 系统, 用户A, 助手, 用户B
第3轮: C = 系统, 用户A, 助手, 用户B, 助手, 用户C

核心洞察 :上下文工程(context engineering)不是 Agent 的一个子功能,它就是 Agent 的记忆系统本身。

谁来决定 C 里放什么、去掉什么、按什么顺序放------谁就拥有了这个 Agent 的"记忆"。

推论二:模型不产生副作用。

模型输出的是 token,不修改文件、不发网络请求、不改数据库。它是一个纯粹的、无副作用的计算过程。

因此,"让 Agent 做一件事"这个命题,在工程上等价于"构造一段上下文 C,使得 M© 的输出恰好表达了做这件事的意图,然后由外部系统去执行这个意图"。

后半句(外部系统去执行)就是 Harness。

推论三:模型无法自我约束。

模型没有内建的权限概念。它可以"说出"任何东西,包括危险的命令。它能"生成"一个 rm -rf 的调用,但它不能真的执行------因为它没有手。

有没有手、能不能伸、伸出去之前要不要审批,全是 Harness 的事。


2. Harness 补齐的六项能力

把上面三个推论展开,Harness 的职责可以精确地分解为六块。这不是分类学游戏,而是理解 dsh 目录结构的钥匙:
#mermaid-svg-B5VyI24uVI08M1Hs{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-B5VyI24uVI08M1Hs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-B5VyI24uVI08M1Hs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-B5VyI24uVI08M1Hs .error-icon{fill:#552222;}#mermaid-svg-B5VyI24uVI08M1Hs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-B5VyI24uVI08M1Hs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-B5VyI24uVI08M1Hs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-B5VyI24uVI08M1Hs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-B5VyI24uVI08M1Hs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-B5VyI24uVI08M1Hs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-B5VyI24uVI08M1Hs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-B5VyI24uVI08M1Hs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-B5VyI24uVI08M1Hs .marker.cross{stroke:#333333;}#mermaid-svg-B5VyI24uVI08M1Hs svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-B5VyI24uVI08M1Hs p{margin:0;}#mermaid-svg-B5VyI24uVI08M1Hs .edge{stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .section--1 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section--1 path,#mermaid-svg-B5VyI24uVI08M1Hs .section--1 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section--1 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section--1 text{fill:#ffffff;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth--1{stroke-width:17;}#mermaid-svg-B5VyI24uVI08M1Hs .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-0 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-0 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-0 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-0 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-0 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-0{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-0{stroke-width:14;}#mermaid-svg-B5VyI24uVI08M1Hs .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-1 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-1 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-1 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-1 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-1 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-1{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-1{stroke-width:11;}#mermaid-svg-B5VyI24uVI08M1Hs .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-2 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-2 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-2 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-2 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-2 text{fill:#ffffff;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-2{stroke-width:8;}#mermaid-svg-B5VyI24uVI08M1Hs .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-3 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-3 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-3 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-3 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-3 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-3{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-3{stroke-width:5;}#mermaid-svg-B5VyI24uVI08M1Hs .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-4 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-4 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-4 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-4 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-4 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-4{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-4{stroke-width:2;}#mermaid-svg-B5VyI24uVI08M1Hs .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-5 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-5 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-5 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-5 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-5 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-5{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-5{stroke-width:-1;}#mermaid-svg-B5VyI24uVI08M1Hs .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-6 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-6 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-6 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-6 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-6 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-6{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-6{stroke-width:-4;}#mermaid-svg-B5VyI24uVI08M1Hs .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-7 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-7 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-7 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-7 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-7 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-7{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-7{stroke-width:-7;}#mermaid-svg-B5VyI24uVI08M1Hs .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-8 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-8 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-8 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-8 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-8 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-8{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-8{stroke-width:-10;}#mermaid-svg-B5VyI24uVI08M1Hs .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-9 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-9 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-9 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-9 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-9 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-9{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-9{stroke-width:-13;}#mermaid-svg-B5VyI24uVI08M1Hs .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-10 rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-10 path,#mermaid-svg-B5VyI24uVI08M1Hs .section-10 circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-10 polygon,#mermaid-svg-B5VyI24uVI08M1Hs .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-10 text{fill:black;}#mermaid-svg-B5VyI24uVI08M1Hs .node-icon-10{font-size:40px;color:black;}#mermaid-svg-B5VyI24uVI08M1Hs .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .edge-depth-10{stroke-width:-16;}#mermaid-svg-B5VyI24uVI08M1Hs .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled,#mermaid-svg-B5VyI24uVI08M1Hs .disabled circle,#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:lightgray;}#mermaid-svg-B5VyI24uVI08M1Hs .disabled text{fill:#efefef;}#mermaid-svg-B5VyI24uVI08M1Hs .section-root rect,#mermaid-svg-B5VyI24uVI08M1Hs .section-root path,#mermaid-svg-B5VyI24uVI08M1Hs .section-root circle,#mermaid-svg-B5VyI24uVI08M1Hs .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-B5VyI24uVI08M1Hs .section-root text{fill:#ffffff;}#mermaid-svg-B5VyI24uVI08M1Hs .section-root span{color:#ffffff;}#mermaid-svg-B5VyI24uVI08M1Hs .section-2 span{color:#ffffff;}#mermaid-svg-B5VyI24uVI08M1Hs .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-B5VyI24uVI08M1Hs .edge{fill:none;}#mermaid-svg-B5VyI24uVI08M1Hs .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-B5VyI24uVI08M1Hs :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Harness 的

六项职责
A · 状态

State
会话日志

session
上下文裁剪

compaction
记忆检索

spill / session-query
B · 动作

Action Space
工具定义与 schema
执行与结果回填
技能 / MCP / LSP
C · 执行世界

Execution World
文件系统
进程与 shell
沙箱与权限
D · 控制流

Control Flow
agent loop
终止条件
重试与取消
E · 可观测

Observability
事件流与轨迹
遥测与埋点
崩溃恢复
F · 扩展

Extensibility
插件系统
能力 seam
配置组合

2.1 A · 状态 ------ 构造 C

问题 没有 Harness 时 dsh 的做法
上文哪来的? 手工拼字符串 deriveMessages() 从会话日志投影出模型历史
太长了怎么办? 截断 / 报错 compaction 子系统按策略压缩
崩了怎么恢复? 全部重来 仅追加日志,重放即可恢复
怎么审计? 无从下手 每一行都有来源标记

dsh 的一条设计原则值得单独记住:

模型可见即已记录。(What the model sees is already logged.)

每个模型请求都必须能从日志重建出来。

这句话的分量极重。它意味着不存在"只有运行时才知道的秘密" ------你可以对着一条 session.jsonl 完整复现任意一次模型调用。这是后面所有可观测性的基础。

2.2 B · 动作空间 ------ 让模型能"做事"

模型输出工具调用时,输出的是一段结构化的文本。把它变成真实的系统调用,中间需要一整条流水线:
#mermaid-svg-cvBeT6H3iLT7wcVK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cvBeT6H3iLT7wcVK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cvBeT6H3iLT7wcVK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cvBeT6H3iLT7wcVK .error-icon{fill:#552222;}#mermaid-svg-cvBeT6H3iLT7wcVK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cvBeT6H3iLT7wcVK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cvBeT6H3iLT7wcVK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cvBeT6H3iLT7wcVK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cvBeT6H3iLT7wcVK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cvBeT6H3iLT7wcVK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cvBeT6H3iLT7wcVK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cvBeT6H3iLT7wcVK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cvBeT6H3iLT7wcVK .marker.cross{stroke:#333333;}#mermaid-svg-cvBeT6H3iLT7wcVK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cvBeT6H3iLT7wcVK p{margin:0;}#mermaid-svg-cvBeT6H3iLT7wcVK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-cvBeT6H3iLT7wcVK .cluster-label text{fill:#333;}#mermaid-svg-cvBeT6H3iLT7wcVK .cluster-label span{color:#333;}#mermaid-svg-cvBeT6H3iLT7wcVK .cluster-label span p{background-color:transparent;}#mermaid-svg-cvBeT6H3iLT7wcVK .label text,#mermaid-svg-cvBeT6H3iLT7wcVK span{fill:#333;color:#333;}#mermaid-svg-cvBeT6H3iLT7wcVK .node rect,#mermaid-svg-cvBeT6H3iLT7wcVK .node circle,#mermaid-svg-cvBeT6H3iLT7wcVK .node ellipse,#mermaid-svg-cvBeT6H3iLT7wcVK .node polygon,#mermaid-svg-cvBeT6H3iLT7wcVK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cvBeT6H3iLT7wcVK .rough-node .label text,#mermaid-svg-cvBeT6H3iLT7wcVK .node .label text,#mermaid-svg-cvBeT6H3iLT7wcVK .image-shape .label,#mermaid-svg-cvBeT6H3iLT7wcVK .icon-shape .label{text-anchor:middle;}#mermaid-svg-cvBeT6H3iLT7wcVK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cvBeT6H3iLT7wcVK .rough-node .label,#mermaid-svg-cvBeT6H3iLT7wcVK .node .label,#mermaid-svg-cvBeT6H3iLT7wcVK .image-shape .label,#mermaid-svg-cvBeT6H3iLT7wcVK .icon-shape .label{text-align:center;}#mermaid-svg-cvBeT6H3iLT7wcVK .node.clickable{cursor:pointer;}#mermaid-svg-cvBeT6H3iLT7wcVK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cvBeT6H3iLT7wcVK .arrowheadPath{fill:#333333;}#mermaid-svg-cvBeT6H3iLT7wcVK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cvBeT6H3iLT7wcVK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cvBeT6H3iLT7wcVK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cvBeT6H3iLT7wcVK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cvBeT6H3iLT7wcVK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cvBeT6H3iLT7wcVK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cvBeT6H3iLT7wcVK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cvBeT6H3iLT7wcVK .cluster text{fill:#333;}#mermaid-svg-cvBeT6H3iLT7wcVK .cluster span{color:#333;}#mermaid-svg-cvBeT6H3iLT7wcVK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cvBeT6H3iLT7wcVK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cvBeT6H3iLT7wcVK rect.text{fill:none;stroke-width:0;}#mermaid-svg-cvBeT6H3iLT7wcVK .icon-shape,#mermaid-svg-cvBeT6H3iLT7wcVK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cvBeT6H3iLT7wcVK .icon-shape p,#mermaid-svg-cvBeT6H3iLT7wcVK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cvBeT6H3iLT7wcVK .icon-shape .label rect,#mermaid-svg-cvBeT6H3iLT7wcVK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cvBeT6H3iLT7wcVK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cvBeT6H3iLT7wcVK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cvBeT6H3iLT7wcVK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 模型输出

tool_call JSON
schema 校验
权限检查

approval
实际执行
结果序列化

回填上下文
下一轮

其中第 C 步是安全边界,也是 Harness 区别于"裸调 API 写个 for 循环"的核心价值。

dsh 把这一段做成了可插拔的流水线:tools/pre-execute → tools/execute → tools/post-execute,全部是 waterfall 事件,任意插件可以包裹、拦截或替换。

2.3 C · 执行世界 ------ 让手伸得到东西

工具调用想真正生效,必须有真实的文件系统、真实的进程、真实的网络。以及对它们的约束:哪些目录可写、哪些命令可执行、哪些网络可访问。

dsh 里对应 fs / shell / subprocess / sandbox 四个子系统。

2.4 D · 控制流 ------ 决定什么时候停

单轮问答很简单,但 Agent 任务是多轮的:调用工具 → 看到结果 → 再思考 → 可能再调用 → ......什么时候停?

这需要:终止条件、步数上限、重试策略、取消语义、超时处理、超限降级。

dsh 的答案写得很清晰:

一个**步骤(step)是一次模型请求加上它调用的工具。一个轮次(turn)**包含零个或多个步骤:它在领取首条输入之前打开,并在不再欠下任何工作时关闭。

这个定义之所以值得反复读,是因为它把"turn / step"这两个在日志里反复出现的词一次讲清了,后面读 session.jsonl 时就不会混乱。

2.5 E · 可观测 ------ 让过程可被检查

对研究来说这是 dsh 最有价值的部分。一次运行中发生的所有事:

  • 系统提示词是怎么组装出来的
  • 模型看到了什么上下文
  • 每一轮调用了哪些工具、参数是什么、返回了什么
  • 有没有失败、重试、取消
  • 子 Agent 是怎么被调度的

全部写入**仅追加(append-only)**的会话日志。Trajectory 视图可以按来源分层查看。

2.6 F · 扩展 ------ 让上面五项可以被替换

这是 dsh 最独特的立场,也是下一节的主题。


3. Agent 范式演进史:从 ReAct 到 PTC

要理解 DeepSeek Harness 为什么长这样,得先看它站在哪条演进线上。

3.1 时间线

#mermaid-svg-RPjmnoY2mMzyUDgb{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RPjmnoY2mMzyUDgb .error-icon{fill:#552222;}#mermaid-svg-RPjmnoY2mMzyUDgb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RPjmnoY2mMzyUDgb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RPjmnoY2mMzyUDgb .marker.cross{stroke:#333333;}#mermaid-svg-RPjmnoY2mMzyUDgb svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RPjmnoY2mMzyUDgb p{margin:0;}#mermaid-svg-RPjmnoY2mMzyUDgb .edge{stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .section--1 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section--1 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section--1 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section--1 text{fill:#ffffff;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth--1{stroke-width:17;}#mermaid-svg-RPjmnoY2mMzyUDgb .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:#ffffff;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-0 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-0 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-0 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-0 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-0{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-0{stroke-width:14;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-1 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-1 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-1 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-1 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-1{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-1{stroke-width:11;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-2 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-2 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-2 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-2 text{fill:#ffffff;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-2{stroke-width:8;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:#ffffff;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-3 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-3 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-3 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-3 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-3{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-3{stroke-width:5;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-4 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-4 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-4 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-4 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-4{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-4{stroke-width:2;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-5 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-5 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-5 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-5 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-5{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-5{stroke-width:-1;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-6 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-6 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-6 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-6 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-6{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-6{stroke-width:-4;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-7 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-7 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-7 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-7 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-7{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-7{stroke-width:-7;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-8 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-8 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-8 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-8 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-8{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-8{stroke-width:-10;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-9 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-9 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-9 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-9 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-9{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-9{stroke-width:-13;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-10 rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-10 path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-10 circle,#mermaid-svg-RPjmnoY2mMzyUDgb .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-10 text{fill:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .node-icon-10{font-size:40px;color:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .edge-depth-10{stroke-width:-16;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-RPjmnoY2mMzyUDgb .lineWrapper line{stroke:black;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled circle,#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:lightgray;}#mermaid-svg-RPjmnoY2mMzyUDgb .disabled text{fill:#efefef;}#mermaid-svg-RPjmnoY2mMzyUDgb .section-root rect,#mermaid-svg-RPjmnoY2mMzyUDgb .section-root path,#mermaid-svg-RPjmnoY2mMzyUDgb .section-root circle{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-RPjmnoY2mMzyUDgb .section-root text{fill:#ffffff;}#mermaid-svg-RPjmnoY2mMzyUDgb .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-RPjmnoY2mMzyUDgb .edge{fill:none;}#mermaid-svg-RPjmnoY2mMzyUDgb .eventWrapper{filter:brightness(120%);}#mermaid-svg-RPjmnoY2mMzyUDgb :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 学术奠基 2022-10 ReAct 提出 推理与行动 交替 arXiv 2210.03629 2023-02 Toolformer 证明 模型可自己学会调工具 arXiv 2302.04761 2023-03 Reflexion 引入 自我反思 机制 arXiv 2303.11366 2023-04 AutoGPT 工程化 自主循环 引发热潮 框架时代 2023 LangChain 组件化 工具链 编排 2023-10 各类 Agent 框架涌现 AutoGen / CrewAI 2024 多 Agent 协作成为主流 子代理 工作流 范式反思 2024-2025 上下文工程兴起 KV cache 提示缓存 成本优化 2025 MCP 协议 工具接入 标准化 工程化 2026-08 DeepSeek Harness 开源 一切皆插件 可组合 2026 轨迹可观测 成为研究刚需 Agent 范式演进

3.2 五个关键转折

转折一:ReAct(Yao et al., 2022)------ 让"思考"和"行动"交替

把单纯的思维链扩展为「thought → action → observation」的循环。这是所有现代 Agent 的骨架。

意义:Agent 从"一次性输出"变成了"可迭代的过程"。

转折二:Toolformer(Hou et al., 2023)------ 证明模型自己能学会调工具

用自监督的方式让模型学会何时插入 API 调用。这解决了"工具怎么暴露给模型"的问题:靠训练,不靠人工 prompt。

意义:工具调用成为模型的一种表达方式,而不是外围胶水。

转折三:Reflexion(Shinn et al., 2023)------ 失败信息也是有价值的

让 Agent 把失败原因写进上下文再重试。隐含了一个重要认识:Harness 负责决定"什么信息进入下一轮上下文"。

这正是第 2.1 节说的"上下文工程即记忆"。

转折四:框架化(LangChain 时代)------ 组件化,但代价是抽象泄漏

把 Agent 拆成 Chain / Agent / Tool / Memory / OutputParser 几类。好处是快,坏处是这些抽象边界并不对应真实系统的边界,遇到边界情况时必须"逃逸"到原生代码。

转折五:DeepSeek Harness ------ 把"框架"降级,把"内核"提升

它的做法是:不给出一套固定的抽象(Chain/Agent/...),而是给出一个极小的内核(插件容器 + 事件),让所有能力以插件形式自行涌现。


4. 为什么必须是「一切皆插件」

这是本章最需要想清楚的一节。

4.1 反问:如果不用插件架构,会怎样?

假设我们做一个普通的 Agent 框架。最自然的写法是:

复制代码
class Agent:
    def __init__(self):
        self.llm = LLMClient()
        self.tools = [ReadFile(), Shell(), Grep()]
        self.memory = ConversationMemory()

问题在第一次需求变更时爆发:

需求 传统写法要改什么
换成远程沙箱执行 改 Shell 的实现 → 但 ReadFile 也要改,因为它们共享执行世界
加一个新的工具类型 改 Agent 主循环,加 if-else
想在工具执行前加个审计 改每个工具,或者改主循环
想给不同会话不同能力集 又一套 if-else

每一次改动都要动核心代码。这就是"特权内核"(privileged kernel)的原罪。

4.2 插件架构怎么解决

dsh 的答案是三个设计:

设计一:能力用接口声明,用 Provider 实现。

工具不直接用 fs,而是声明"我需要一个 ctx.fs 提供方"。把本地文件系统的 Provider 换成远程的,工具代码一行不改。

设计二:注册是可逆的副作用。

工具、监听器、提示词片段都不是"永久注册",而是 ctx.effect() 安装的副作用,插件卸载时自动撤销。

这一条解决了插件系统的经典难题:热重载(HMR)时的状态污染。没有可逆性,热重载就无从谈起。

设计三:配置即组合。

产品形态(Web / headless / SDK / Desktop)不是四个代码库,而是四组配置树。

4.3 关键论证:seam 让"换 Provider"变成"换产品"

dsh 架构文档里有句话值得抄下来:

文件系统与进程提供方共享同一个执行世界,因此把它们指向远程沙箱,也就把 Bash、PTY 和 LSP 一并搬了过去,无需提供方专用 fork。

这句话是插件架构价值的最好证明。它意味着:
#mermaid-svg-irH4T08Uq67U10lx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-irH4T08Uq67U10lx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-irH4T08Uq67U10lx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-irH4T08Uq67U10lx .error-icon{fill:#552222;}#mermaid-svg-irH4T08Uq67U10lx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-irH4T08Uq67U10lx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-irH4T08Uq67U10lx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-irH4T08Uq67U10lx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-irH4T08Uq67U10lx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-irH4T08Uq67U10lx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-irH4T08Uq67U10lx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-irH4T08Uq67U10lx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-irH4T08Uq67U10lx .marker.cross{stroke:#333333;}#mermaid-svg-irH4T08Uq67U10lx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-irH4T08Uq67U10lx p{margin:0;}#mermaid-svg-irH4T08Uq67U10lx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-irH4T08Uq67U10lx .cluster-label text{fill:#333;}#mermaid-svg-irH4T08Uq67U10lx .cluster-label span{color:#333;}#mermaid-svg-irH4T08Uq67U10lx .cluster-label span p{background-color:transparent;}#mermaid-svg-irH4T08Uq67U10lx .label text,#mermaid-svg-irH4T08Uq67U10lx span{fill:#333;color:#333;}#mermaid-svg-irH4T08Uq67U10lx .node rect,#mermaid-svg-irH4T08Uq67U10lx .node circle,#mermaid-svg-irH4T08Uq67U10lx .node ellipse,#mermaid-svg-irH4T08Uq67U10lx .node polygon,#mermaid-svg-irH4T08Uq67U10lx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-irH4T08Uq67U10lx .rough-node .label text,#mermaid-svg-irH4T08Uq67U10lx .node .label text,#mermaid-svg-irH4T08Uq67U10lx .image-shape .label,#mermaid-svg-irH4T08Uq67U10lx .icon-shape .label{text-anchor:middle;}#mermaid-svg-irH4T08Uq67U10lx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-irH4T08Uq67U10lx .rough-node .label,#mermaid-svg-irH4T08Uq67U10lx .node .label,#mermaid-svg-irH4T08Uq67U10lx .image-shape .label,#mermaid-svg-irH4T08Uq67U10lx .icon-shape .label{text-align:center;}#mermaid-svg-irH4T08Uq67U10lx .node.clickable{cursor:pointer;}#mermaid-svg-irH4T08Uq67U10lx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-irH4T08Uq67U10lx .arrowheadPath{fill:#333333;}#mermaid-svg-irH4T08Uq67U10lx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-irH4T08Uq67U10lx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-irH4T08Uq67U10lx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-irH4T08Uq67U10lx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-irH4T08Uq67U10lx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-irH4T08Uq67U10lx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-irH4T08Uq67U10lx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-irH4T08Uq67U10lx .cluster text{fill:#333;}#mermaid-svg-irH4T08Uq67U10lx .cluster span{color:#333;}#mermaid-svg-irH4T08Uq67U10lx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-irH4T08Uq67U10lx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-irH4T08Uq67U10lx rect.text{fill:none;stroke-width:0;}#mermaid-svg-irH4T08Uq67U10lx .icon-shape,#mermaid-svg-irH4T08Uq67U10lx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-irH4T08Uq67U10lx .icon-shape p,#mermaid-svg-irH4T08Uq67U10lx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-irH4T08Uq67U10lx .icon-shape .label rect,#mermaid-svg-irH4T08Uq67U10lx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-irH4T08Uq67U10lx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-irH4T08Uq67U10lx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-irH4T08Uq67U10lx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} seam 架构
Bash 工具
ctx.subprocess

Service
读文件工具
ctx.fs

Service
LSP
ctx.subprocess

Service
换 Provider =

全部搬到远程
传统架构
Bash 工具
本地执行
读文件工具
本地 FS
LSP
本地进程

架构的价值不在于"更容易加功能",而在于"更容易换掉某一个东西而让整个系统跟着变"。


5. Cordis:把插件系统做成时空可组合程序

dsh 的底层框架是 Cordis(以 vendor 方式引入),其设计论文是

A Programming Paradigm for Spatiotemporal Composability。

"Cordis" 在日语中意为"绳结",取"把分散的东西绑在一起"之意。论文标题里的 Spatiotemporal Composability(时空可组合性) 是理解它的钥匙:

  • Spatial(空间):插件在上下文树中的位置 ------ 决定它能看到谁、影响谁
  • Temporal(时间):插件的挂载与卸载时刻 ------ 决定它什么时候生效
  • Composability(可组合性):这两者可以自由嵌套与叠加

5.1 五个核心概念(务必背下来)

来自官方 docs/cordis-primer.zh.md:

# 概念 一句话
1 Plugin 实现 Service 的对象,可以是带 apply(ctx) 的函数,也可以是 Service 子类
2 Context 服务的容器;一个服务占据稳定的 ctx.<key>,其他插件按 key 查找而非 import 实现
3 inject 声明服务依赖;加载顺序由依赖表达,而非手动编排启动序列
4 Event 类型化事件,5 种分发模式
5 effect 注册是可逆副作用,reload / teardown 时撤销

第 3 条是整个系统最精妙的地方:

加载顺序不是一张拓扑排序表,而是从依赖图自然涌现的。

5.2 五种事件分发模式

这张表建议直接背下来,后面读源码时天天用:

模式 是否 await 分发顺序 有返回值
emit 否 按注册顺序观察 否
waterfall 否 按注册顺序观察 是
parallel 是 所有监听器并行 否
serial 是 按注册顺序观察 是
bail 否 按注册顺序,直到某个监听器返回 bail 值 是

waterfall 的语义特别容易搞混,用人话说:

waterfall 是洋葱。 监听器收到 (...args, next)。

调 next() → 交给下游监听器处理;

不调 next() 直接 return → 短路,下游根本不会执行。
#mermaid-svg-XdyDXP0EQg8Ldn8R{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XdyDXP0EQg8Ldn8R .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XdyDXP0EQg8Ldn8R .error-icon{fill:#552222;}#mermaid-svg-XdyDXP0EQg8Ldn8R .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XdyDXP0EQg8Ldn8R .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XdyDXP0EQg8Ldn8R .marker.cross{stroke:#333333;}#mermaid-svg-XdyDXP0EQg8Ldn8R svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XdyDXP0EQg8Ldn8R p{margin:0;}#mermaid-svg-XdyDXP0EQg8Ldn8R .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-XdyDXP0EQg8Ldn8R .cluster-label text{fill:#333;}#mermaid-svg-XdyDXP0EQg8Ldn8R .cluster-label span{color:#333;}#mermaid-svg-XdyDXP0EQg8Ldn8R .cluster-label span p{background-color:transparent;}#mermaid-svg-XdyDXP0EQg8Ldn8R .label text,#mermaid-svg-XdyDXP0EQg8Ldn8R span{fill:#333;color:#333;}#mermaid-svg-XdyDXP0EQg8Ldn8R .node rect,#mermaid-svg-XdyDXP0EQg8Ldn8R .node circle,#mermaid-svg-XdyDXP0EQg8Ldn8R .node ellipse,#mermaid-svg-XdyDXP0EQg8Ldn8R .node polygon,#mermaid-svg-XdyDXP0EQg8Ldn8R .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XdyDXP0EQg8Ldn8R .rough-node .label text,#mermaid-svg-XdyDXP0EQg8Ldn8R .node .label text,#mermaid-svg-XdyDXP0EQg8Ldn8R .image-shape .label,#mermaid-svg-XdyDXP0EQg8Ldn8R .icon-shape .label{text-anchor:middle;}#mermaid-svg-XdyDXP0EQg8Ldn8R .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-XdyDXP0EQg8Ldn8R .rough-node .label,#mermaid-svg-XdyDXP0EQg8Ldn8R .node .label,#mermaid-svg-XdyDXP0EQg8Ldn8R .image-shape .label,#mermaid-svg-XdyDXP0EQg8Ldn8R .icon-shape .label{text-align:center;}#mermaid-svg-XdyDXP0EQg8Ldn8R .node.clickable{cursor:pointer;}#mermaid-svg-XdyDXP0EQg8Ldn8R .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-XdyDXP0EQg8Ldn8R .arrowheadPath{fill:#333333;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XdyDXP0EQg8Ldn8R .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XdyDXP0EQg8Ldn8R .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XdyDXP0EQg8Ldn8R .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XdyDXP0EQg8Ldn8R .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-XdyDXP0EQg8Ldn8R .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XdyDXP0EQg8Ldn8R .cluster text{fill:#333;}#mermaid-svg-XdyDXP0EQg8Ldn8R .cluster span{color:#333;}#mermaid-svg-XdyDXP0EQg8Ldn8R div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XdyDXP0EQg8Ldn8R .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XdyDXP0EQg8Ldn8R rect.text{fill:none;stroke-width:0;}#mermaid-svg-XdyDXP0EQg8Ldn8R .icon-shape,#mermaid-svg-XdyDXP0EQg8Ldn8R .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XdyDXP0EQg8Ldn8R .icon-shape p,#mermaid-svg-XdyDXP0EQg8Ldn8R .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-XdyDXP0EQg8Ldn8R .icon-shape .label rect,#mermaid-svg-XdyDXP0EQg8Ldn8R .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XdyDXP0EQg8Ldn8R .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-XdyDXP0EQg8Ldn8R .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-XdyDXP0EQg8Ldn8R :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} A: pre-execute

包装
B: 权限检查

包裹
C: 实际执行
D: post-execute

收尾
返回结果
B 收尾
A 收尾

这就是"洋葱模型"(Ko-Ko 的 onion)。每一个包装层都可以决定是否继续传递 ------权限策略层可以拒绝(不调 next()),纯日志层必须调用(否则下游全被阻断)。

官方文档的判断很准确:

对于单决策事件,短路是设计意图。策略监听器在拥有决策权时可以不调用 next(),而仅做标注或观察的监听器则必须委托。


6. DeepSeek Harness 的具体立场

综合上面,梳理 dsh 明确主张的五件事:

立场一:Agent = Model + Harness

模型提供智能,Harness 提供其余的一切。Harness 的质量,而不是模型的参数量,决定了一个 Agent 系统能走多远。

立场二:一切皆插件(Everything is a Plugin)

不存在需要打补丁的特权内核。模型适配器、工具注册表、会话日志,以及 agent loop 本身,都是插件。

连"智能体循环"都是可替换的------这件事的激进程度值得反复体会。

立场三:模型可见即已记录

每个模型请求都必须能从日志重建。新增模型可见输入必须新增会话事件。

立场四:seam 优先于继承

能力由 Definition / Provider / Consumer 三角色构成,而不是基类继承。单一角色本身不是 seam------添加一项能力意味着把三者一并设计。

立场五:配置组合而非代码分支

产品形态 = 配置树。dsh --profile web --dump-config 打印出的任何条目,都可以由你自己的 patch 替换。


9. 参考材料

本仓库

  • docs/architecture.zh.md ------ 架构总纲,本章大部分论断的出处
  • docs/cordis-primer.zh.md ------ 五概念与分发模式
  • docs/capability-seams.zh.md ------ seam 三角色(65KB)
  • docs/tool-execution-pipeline.zh.md ------ 工具流水线
  • .agents/notes/implemented/architecture/ ------ 架构决策记录

学术

延伸

  • Anthropic《Building Effective Agents》------ 区分 workflow 与 agent 的经典论述
  • Simon Willison 的 LLM 工具调用与 agent 相关博文
相关推荐
JackLam3 小时前
AI-安装ChatGpt Codex
人工智能
强哥聊算力3 小时前
《算力江湖·英伟达传奇》第七集:ChatGPT出现前夜,英伟达发生了什么?
服务器·人工智能·算法·ai·chatgpt·gpu算力
吴佳浩4 小时前
Run:ai 开源了,我把 GPU 编排摆回 AI 栈里看了一遍
人工智能
IT_Octopus5 小时前
【零基础入门 LLM 开发 · Day 13】:LangChain 的对话记忆——Message 对象版
人工智能·python·langchain
2603_965148116 小时前
社区与学习资源:从入门到精通的API选品学习路径
数据库·人工智能·python·学习·数据挖掘
LiuPig刘皮哥6 小时前
2026年开源3D陪玩对比:xiaoke.ai、AIRI、Open-LLM-VTuber、Amica 有什么、没有什么
人工智能·3d·开源
西柚小萌新6 小时前
【岗位面试】--成都博维数孪 - 工业 AI 解决方案顾问
人工智能·面试·职场和发展
Luminbox紫创测控6 小时前
车载LiDAR强光测试的实验设计方法与数据分析
人工智能·数据挖掘·数据分析·车载系统·安全性测试·太阳光模拟器
建筑工程企业管理系统7 小时前
工程进度统计管理系统自动化汇总数据,解决施工企业手工对账误差难题
大数据·人工智能·自动化