Agent = Model + Harness
如果把Agent当成一名数字员工,模型相当于员工的脑子。
Harness则是电脑、办公软件、文件柜、操作手册、权限制度、项目经理和工作记录。
![[Pasted image 20260912210610.png]]
同一个人坐进两间配置不同的办公室,工作结果会差很多。一个人只能口头回答问题。 而另一个人能查数据库、运行程序、分派任务,还能再第二天接着昨天的进度继续干。
DeepSeek Harness研究的就是这间办公室,它把办公室里的主要设施拆成可替换组件,并记录AI工作时看到和做过的事情。 一套完整 Harness 通常包含下面这些部分:
- System Prompt : 告诉模型身份、规则和环境信息
- Tool Registry: 管理模型当前能看到和调用的工具
- Agent Loop:驱动模型和工具反复交互
- Session: 保存任务历史和当前状态
- Sandbox/Approval: 限制危险操作,必要时询问用户
- Model Adapter: 把统一请求转换成不同模型接口
- Storage / UI: 保存数据并展示运行过程
![[Pasted image 20260912211137.png]]DeepSeek Harness的口号是Everything is a Plugun,所有能力都是插件。
模型适配器、工具注册表、Session Log、Agent Loop、存储、沙箱、调度和UI都由插件提供。
Profile: 一整套Agent配方。 Profile决定了这次启动用哪一种Agent,把Agent想成一名刚入职的数字员工。Profile是公司在他上班前准备好的整套工位:
- 给他配哪个模型
- 能用哪些工具
- 把工作记录存在哪
- 有没有浏览器界面
- 采用什么安全规则
Bundle: 可以服用的一组插件
Profile管整台机器,Bundle管一组经常一起出现的能力。
它把一批Cordis配置和对应代码装进同一个功能包。
例如,团队可以准备一个“研究 Bundle”,一次装入网页搜索、文件处理、引用检查和研究提示词。另一个“代码审查 Bundle”可以装入代码读取、测试和审查规则。以后创建新的 Agent,配置里引用 Bundle 就行,不必把十几个插件重新接一遍。
Patch: 在现有配方上做局部修改
Patch 解决的是“小改动”。假设 Profile 已经写了几百行配置,你只想换一个模型、关闭某个工具,或者给文件插件增加一条路径限制。复制整份 Profile 再修改,会得到一份难以跟随上游更新的副本。Patch 只记录那几个变化。
它像贴在装机单旁边的一张便签:其他配置照旧,只把便签上写到的项目换掉。Patch 也可以插入新插件,因此你既能修改现有设置,也能给当前 Agent 临时加一项能力。
![[Pasted image 20260912211731.png]]
读取 Profile
↓
按顺序叠加 Bundles
↓
应用用户 Patch
↓
得到最终插件清单和配置
↓
Cordis 根据依赖关系加载插件
↓
模型、工具、Session、Loop、UI 共同组成可运行 Agent
三个动作:
- Profile 选择整套 Agent
- Bundle 安装一组能力
- Patch 修改几个局部设置。
Cordis 接过最终清单,按照依赖关系把这些零件组装成一套能运行、也能安全拆卸的系统。
插件卸载后,系统要恢复干净。
DeepSeek Harness使用Cordis管理插件。Cordis论文提出了一个术语:
Spatiotemporal Composability,时空可组合性
空间可组合性:谁依赖谁,由系统管理
一个网页研究插件需要模型服务、搜索服务和工具注册表。它只声明这些依赖,不必把某一家模型或某一个搜索实现写死。
依赖关系像办公室里的标准插座。台灯只要求有电,不关心电来自哪座发电厂。
时间可组合性:插件离开时,撤销它留下的改变
插件运行时可能做很多事:
-
注册一个工具;
-
增加一段 System Prompt;
-
监听工具执行事件;
-
打开定时器、文件监听器或网络连接;
-
挂载子插件。
普通插件系统常见的麻烦,是界面上已经关闭插件,旧监听器或旧状态还留在进程里。开发者热更新几次后,同一个回调可能执行多次,或者旧版提示词继续影响模型。
Cordis 把插件实例放进一个名为 Fiber 的生命周期容器。Fiber 会经历:
PENDING → LOADING → ACTIVE → UNLOADING → DISPOSED
↘ FAILED
术语解释:Fiber 是什么?
这里的 Fiber 不是操作系统线程。它是 Cordis 对一个插件实例的运行记录,负责追踪依赖、状态和清理动作。
插件通过 ctx.on() 注册事件、通过 ctx. tools .register() 注册工具,Cordis 会把这些注册记在所属 Fiber 下。插件卸载时,Cordis 自动移除它们。插件自己创建的定时器或连接,可以通过 ctx.effect() 返回一个清理函数;Cordis 在卸载阶段调用这个函数。
术语解释:Effect 是什么?
Effect 指程序对外部环境造成的改变。注册工具、订阅事件和打开连接都属于 Effect。
一场临时展览结束后,工作人员需要拆掉展台、灯光和电线。Cordis 希望插件也按这种方式撤场,而不是只从菜单里消失。
插件拥有的子插件会一起递归卸载。异步清理完成后,dispose() 才结束。这个设计也支撑热模块替换:系统先卸载旧插件并清理注册,再加载新代码。
Cordis 只干三件事:
- 加载/卸载插件:插件注册服务、事件、工具、配置;卸载时回收
- 解依赖:插件声明“我需要 ctx.llm / ctx.tools / ctx.sessions”,内核等依赖齐了再启动,缺依赖就排队不崩
- 发事件/做注入:插件间不直接硬调,通过事件总线和 Service 名取能力
两个高级特性决定它适合 Agent 热扩展:
- 空间可组合:插件依赖变化,自动重排启动顺序。比如新装一个沙箱插件提供
ctx.sandbox,原来等它的审批插件自动就位。 - 时间可组合(可逆副作用):插件注册的服务/事件/文件/环境变量,卸载时按注册反操作撤销;理想情况下不残留。这让它支持运行时试装插件、自扩展 preset。
对开发者通俗理解:Cordis 像“插件操作系统”,dsh 各功能像“APP”;写新能力=写一个 APP 注册进去,不改系统。
DeepSeek Harness的Agent Loop驱动整个执行过程。
理解两个词就能看懂这个循环。
- Turn: 用户交给Agent的一轮任务 你说读取销售数据并生成报告,这句话会开启一个Turn。 Agent完成任务、停止或失败时,Turn结束。
- Step:一次模型请求,加上它出发的工具执行 模型第一次查看目录,这是一个Step,读取文件后再次请求模型,让它判断下一步,这是第二个Step。一个Turn经常包含多个Step。