Harness 不是又一个 Agent 框架,而是一套让模型 真正能干完事 的执行系统。

过去两年,大模型工程的关注点基本是这条线:模型 → Prompt → RAG → Agent。但凡真正跑过复杂任务就会发现一件事——模型能力只是 Agent 能力的一部分。一个模型再聪明,如果没有工具调用、没有环境管理、没有状态管理、没有执行循环、没有错误恢复、没有日志追踪,它照样很难稳定地把一件复杂事情干完。

DeepSeek 前几天开源了一个叫 Harness 的项目,代号 dsh。第一眼看容易划走——又一个 Agent 框架。但把它的架构文档、生命周期文档、子系统文档翻了一遍之后,我改变了想法。这个项目值得聊的地方,不是它接了几个模型、封了几个工具,而是它把“模型如何完成任务”这件事,做到了一个少见的工程精细程度。

官方文档里有句话我印象很深:

这也是从 Prompt Engineering 到 Context Engineering 再到 Harness Engineering 的一个典型体现。这篇文章想顺着源码和文档,把几个具体机制拆开给你看。

「模型是 Agent 的灵魂,Harness 给它理解环境、使用工具、在真实场景里持续工作的能力。』

📌 本文看点

01

一个被低估的公式:Agent = Model + Harness

02

从源码看架构:任务是怎么一层层走下来的

03

最核心的部分:执行 Loop 到底怎么转

01

FORMULA

一个被低估的公式:Agent = Model + Harness

先建立一个认知框架。

模型负责的东西很纯粹:理解、推理、生成、决策。Harness 负责其余所有事:给模型看什么上下文、什么时候轮到它执行、它能调用什么工具、工具在哪跑、怎么保存状态、出错了怎么办、怎么判断任务完成。

最简单的 Agent 应用长这样:

…text

User → Prompt → LLM → Answer

加一层工具调用之后:

…text

User → LLM → Tool → Observation → LLM → Tool → … → Final Answer

到这一步大部分团队都能做出来。真正复杂的 Agent,其实是这样一条链路:

…text

Task → Context → Model → Decision → Tool/Environment → Observation

→ State Update → Verification → Retry/Continue → Final Result

真正复杂的是后面这套控制系统,而不是前面的 Prompt。这句话可以当成贯穿全文的线:Context 决定模型知道什么,Tool 决定模型能做什么,Harness 决定模型能不能把事情真正做完。

02

ARCHITECTURE

从源码看架构:任务是怎么一层层走下来的

一个任务从进入 dsh,到模型执行,到最终产出结果,中间经过了哪些层?

按官方架构文档的说法,答案不是“Context / Model / Tool / Environment / State / Evaluation” 这几个并列模块拼出来的——dsh 的真实组织方式更彻底:没有一个模块是特权的,模型适配器、工具注册表、会话日志、连 Agent 循环本身,全都是插件,通过配置组装起来。

这套组装机制有两层:

1

Bundle(组合包):Cordis 配置项加它挂载的代码,是一种分发格式,它插入的内容始终可以被上层 patch 覆盖

2

Profile(配置):存放在 Harness home 里的具名组装,列出自己叠放了哪些 bundle,还保存用户自己的 cordis.patch.yml

层与层的应用顺序很讲究:先按 profile 列出的顺序应用每个 bundle,再应用 profile 自己的 patch,再应用 home 级别的 patch,最后才是命令行传入的 --patch。dsh-base 是每个 profile 的第一层,包含模型适配器、工具、持久化、沙箱与审批策略;dsh-web-app 在此基础上加浏览器应用;dsh-headless 加一个完全不带服务器的一次性运行器。

想直观感受这套组装结果,跑一条命令就够了:

…bash

dsh --profile web --dump-config

这条命令会把当前 profile 实际加载的整棵插件树摊开——从模型适配器到沙箱策略,每一层配置来自哪个 bundle、被哪一层 patch 覆盖过,一目了然。这也是为什么说 dsh 更像一个操作系统内核,而不是一个应用框架——扩展点不是“预留的几个回调”,而是系统默认的组织方式。

03

LOOP

最核心的部分:执行 Loop 到底怎么转

Harness 的核心不是某一个类,而是一条 Loop。这条 Loop 不是通用意义上“while not finished 一直跑”的抽象循环,dsh 把它拆得很具体:

几个值得展开的细节:

事件被明确分成两类。 turn/*、step/*、user/message、assistant/*、tool/* 是持久会话事件,老老实实写进日志构成可回放的历史;agent/* 是实时扩展点,用来做队列管理、状态通知、prompt 拦截,不进日志。不是所有事件都值得永久记录,但所有影响模型看到什么的决策,最终都要落到会被记录的那条日志上。

事件有两种执行模式。 agent/pre-step、agent/request、llm/stream、三个 tools/* 事件都是瀑布式——每个监听器必须显式调用 next() 才能把处理权继续往下传,跟中间件几乎一模一样。而 agent/turn-stopping 是串行事件,没有 next(),谁都可以直接一票终止这个回合。一个用来层层加工,一个用来一锤定音。

agent/pre-step 有个反直觉但很讲道理的限制。 这个钩子不能直接改写消息内容——模型可见的内容必须走已被记录的日志通道。你能在这一步拒绝这批消息,或者替换成另一批已经写进日志的消息,但不能凭空塞一段游离在日志之外的文本让模型看到。这条限制保证了“模型看到的东西必须能从日志里重建”这条硬规则不会被这一个钩子破坏掉。

一次尝试哪怕彻底失败,也会被记下来。 如果消息在 agent/pre-step 被拒绝,或者第一次认领时就是空的,系统依然会关闭一个“没有花费任何 step”的完整 turn——日志里留下“这次尝试发生过”的记录,而不是悄悄丢弃。

04

CONTEXT

Context 是怎么构建出来的

agent/pre-step 这个钩子,本质上就是在回答“模型这一步该看到什么”这个问题。System Prompt、历史消息、工具 schema,全部在这一步组装完成,然后才真正打包成一次模型请求。

这里可以引出一个贯穿全文的观点:Harness 本质上是在控制模型看到什么。这就是 Context Engineering 的工程落地——不是靠精心措辞的提示词模板,而是靠一个可以拦截、可以拒绝、可以替换的钩子,系统性地管住“模型的输入”这件事。

05

TOOL

工具调用:不只是 Function Calling

真正的 Tool System 要解决的问题,远比“模型说要调用一个函数,然后执行它”复杂:注册表、参数解析、权限控制、执行、结果回传、错误处理、超时、日志,每一环都要落地。dsh 把工具执行拆成三段流水线——tools/pre-execute → tools/execute → tools/post-execute,每一段都是瀑布式事件,插件可以在任意一段介入。

更关键的是 Tool 和 Environment 之间的关系。dsh 引入了一个叫 Capability Seam(能力接缝) 的设计单位,每个能力由三个角色拼出来:

1

Service Definition:只声明接口,比如 ctx.llm、ctx.fs

2

Service Provider:真正的实现,比如 llm-deepseek 实现 ctx.llm,fs-local 实现 ctx.fs

3

Consumer:使用这个能力的一方,往往就是模型能调用的一个工具,比如 tool-bash 消费的是 shell 这个能力

三个角色缺一不可。这套设计的直接好处是:想把文件系统从本地换成远程沙箱,只需要换掉 Provider,Definition 和 Consumer 一行代码都不用动,Bash、持久终端、代码检查这些能力会整体跟着搬家。这也是 Agent 与普通 Chatbot 最大的工程区别之一——Chatbot 的“工具”往往是辅助性的,而在 dsh 里,Environment 是核心基础设施,不是可有可无的附加项。

06

STATE

State:一条日志,取代了一整套状态机

如果 Agent 要连续执行几十步,它到底记住了什么?很多框架会分别维护 Task State、Execution State、Tool State、Context State 好几套东西,但 dsh 的做法是把它们统一收敛成一条只能追加、不能修改的 Session Log。

有一条硬规则贯穿始终:任何模型能看到的东西,必须能从这条日志里完整重建出来。这不是文档里写写的约定,是运行时会强制校验的规则——前面提到 agent/pre-step 不能直接改写消息内容,本质上就是这条规则在具体钩子上的体现。

会话要不要 fork、断点要不要恢复、UI 要不要重放某一次流式输出,全部从这一条日志派生,不需要另外维护一套状态系统。就连 assistant/message 这种记录一次成功模型调用的事件,连“内容为空但耗尽了 token 限额”这种边缘情况都会精确记下 usage 和对应的 chunk 序列。

Memory 解决的是“记住什么”,State 解决的是“现在进行到哪里”——这句话在通用 Agent 框架里往往对应两套独立机制,但在 dsh 里,两者被统一成了同一条日志的不同投影,这是比“分开维护两套系统”更干净的做法。

也正因为日志格式本身还在快速迭代,dsh-session 包里的 SESSION_FORMAT_VERSION 现在被钉在 0,官方原话是目前没有向后兼容承诺。这是把地基做对放在稳定性前面的一个坦诚代价。

07

ERROR

错误处理:真正的 Agent 不可能一次成功

Agent 执行中的错误来源很多:模型报错、工具报错、环境报错、解析失败、超时、无效动作、结果错误。这部分很能体现工程水平,因为它决定了系统撑不撑得住长任务。

dsh 有一个具体的补偿机制值得细讲:内置的 dsh-compaction-basic 插件专门处理上下文压力。它挂在两个时机上——一是 agent/pre-step 阶段根据上下文压力提前介入,二是 agent/request-error 阶段专门盯着“上下文溢出”这一类错误。触发之后,它会先尝试裁剪历史工具调用结果,不够的话再进行摘要压缩。

更细一点的是它和重试之间的配合:一次失败的 step 和一次失败的 turn 之间,只有当压缩或摘要动作确实让上下文往前推进了,系统才会开一个新的重试回合;如果没有实质性进展,原始的请求错误依然是最终结论,不会无意义地空转重试。什么情况下值得重试,什么情况下不值得,是被明确写进机制里的,不是一句“我们支持 retry”就能带过的。

08

EVALUATION

Evaluation:dsh 没有直接回答,但留了地基

传统 LLM 应用的评估很简单:Input → Model → Output → Score。但复杂 Agent 的执行链路是 Task → Planning → Tool → Execution → Observation → Retry → Result,真正应该评估的是整个执行轨迹,而不是最终那段文本——Task Success、Tool Success、中间状态、成本、延迟,都是轨迹级别的信号。

这是一个行业层面越来越清晰的判断:Agent Evaluation 的对象,正在从“答案”变成“轨迹”。

不过要坦白说清楚一件事:目前抓取到的 dsh 核心包列表和文档里,并没有一个独立的 evaluation 子系统。Session Log 那条只追加的事件流,客观上为轨迹级评估提供了现成的数据基础——你想统计工具调用成功率、想复盘某一次失败的完整过程,理论上都能从日志里拿到,但这是“日志设计带来的可能性”,不等于“dsh 内置了评估功能”。这一点上,dsh 目前给的是地基,不是答案。

09

CONFIG

配置体系:为什么不把这些东西写死在代码里

回到前面讲的 Bundle/Profile/Patch 机制,本质上是在回答这个工程问题。因为 Harness 的核心目标之一,就是把执行逻辑和实验参数解耦——同一套 Harness,换一层 patch 就能装上不同的模型、不同的工具集、不同的执行环境,不需要碰底层代码一行。

10

PRINCIPLES

从代码设计看几个关键工程思想

把前面几节的具体机制往上收一收,能提炼成几条原则:

插件优先,无特权核心。 不是先设计好一个固定内核再开几个扩展口子,而是从一开始就没有内核,所有子系统按同一套 Cordis 规则组装。

模型是可替换的一个组件,不是系统的中心。 ctx.llm 只是众多 Capability Seam 里的一个,和 ctx.fs、ctx.shell 地位相同。

能力和执行环境彻底解耦。 这是 Capability Seam 设计带来的直接结果——换底座,能力整体搬家。

用一条日志取代一整套状态管理。 Session Log 既是历史记录,也是恢复的依据,也是审计的证据,一件事解决了原本要好几套机制才能覆盖的需求。

评估在闭环之内留了口子,但没有交卷。 这是目前唯一一个“设计上支持、功能上未完成”的部分,值得持续关注它接下来怎么补。

11

COMPARE

和主流框架比,差在哪一句话

不做简单的功能对比表,从架构思想上比会更清楚:

维度ChatbotAgent Framework(LangGraph / CrewAI 等)DeepSeek Harness
核心对话编排器/图引擎作为内核没有内核,一切皆插件
Model 的地位系统核心核心组件众多 Capability Seam 里的一个
Tool辅助功能重要模块基础设施,和文件系统、Shell 平级
State一段对话历史各家自己的 checkpoint 机制统一收敛到一条只追加的 Session Log
Evaluation输出评估Agent 级评估设计上支持轨迹级评估,功能未内置
目标回答问题完成任务稳定完成任务,且全程可审计

Agent Framework 关注“怎么让模型调用工具”,Harness 更关注“怎么让整个任务可靠地跑完”。这是两个不同层次的野心。

12

REALITY

真实世界的另一面

设计上的巧思讲了不少,得讲点真话。

官方自己承认接下来会有破坏性变更。 项目文档里明确写着,现阶段没有外部使用者,团队更愿意选对的基础设施而不是保兼容,该改名改名、该重构重构。这话说得坦诚,但也意味着现在往生产环境接,是要担风险的。

学习成本是双重的。 想真正玩明白 dsh,得先搞懂它底下那套叫 Cordis 的插件框架怎么运作,理解 Service/Event/Scope 这几个基本概念,然后才能理解 dsh 在这套框架上又搭了什么。这不是一层学习曲线,是两层叠在一起的学习曲线。

系统复杂度是实打实提高了的。 更多的 Loop、更多的 State、更细的事件分类,意味着 debug 成本会上升;长任务如果跑得久,Token 消耗、Context 大小、状态复杂度都会跟着涨。这些不是 dsh 独有的毛病,任何走向“插件化操作系统”这条路的项目,都要经历这样一段权衡。

13

ENTERPRISE

如果自己做企业级 Agent,该从这里学什么

不建议照着这个项目抄,更值得抄的是这套分层方法:

五层里前四层,dsh 都给出了具体到能看代码的实现方式;最后一层评估,目前是留白,需要使用者自己在这条日志之上把轨迹级评估搭起来。这也是这套系统目前最诚实的地方——它没有假装什么都做完了。

THE END

写在最后

过去大家拼的是谁能接上最强的大模型。

后来开始拼 RAG、拼 Agent、拼 Tool Calling。

但当所有团队都能调用同一个模型之后,真正拉开差距的,就变成了模型之外的那一层。Context 决定模型知道什么,Tool 决定模型能做什么,而 Harness 决定模型能不能把事情真正做完。

所以 DeepSeek Harness 值得研究的地方,并不是“DeepSeek 又开源了一个项目”,而是它让我们重新看到了一件事:

LLM 时代的核心工程问题,正在从“如何调用模型”,转向“如何围绕模型构建一个可靠、可审计的执行系统”。

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

在这里插入图片描述

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐