为什么需要 Harness
- 大模型在本质上缺什么;
- Harness 补的到底是什么;
- 为什么 DeepSeek 会选择"一切皆插件"作为架构立场;
- 学界到工业界的 Agent 范式是怎么演进的。
0. 一个反直觉的起点
大多数人第一次接触 dsh,会认为它是一个"更强的 ChatGPT 客户端",或者"一个能写代码的 AI 工具"。
**这两个理解都是错的,而且错得关键。**真正值得研究的东西是这样的一个事实:
DeepSeek 花了大量算力训练出的模型,本身并不能读写文件、不能执行命令、不能记住上一句话、不能拒绝你的请求。
所有这些能力,一行都不是模型提供的。
模型交付到你手上时,它是一个纯函数。把这句话理解透,后面所有的架构设计都会变得顺理成章。
1. 第一性问题:模型在本质上是什么
严格地说,一个大语言模型是一个函数:
M : C → Δ(V)
C(Context,上下文):一串 tokenV(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/------ 架构决策记录
学术
- ReAct: https://arxiv.org/abs/2210.03629
- Toolformer: https://arxiv.org/abs/2302.04761
- Reflexion: https://arxiv.org/abs/2303.11366
- Cordis / 时空可组合性: https://arxiv.org/abs/2608.25512
延伸
- Anthropic《Building Effective Agents》------ 区分 workflow 与 agent 的经典论述
- Simon Willison 的 LLM 工具调用与 agent 相关博文