Preset:同一套 Harness 如何运行不同 Agent?
为什么同一个Harness系统里,可以同时运行工具和提示词完全不同的 Agent?
什么是Preset?
上面那个问题的答案就在关键词Preset上。
Preset 的字面意思是“预设”。放在 DeepSeek Harness 里,可以先把它理解成 Agent 的一种工作模式:选择不同的 Preset,就等于为 Agent 预先选好不同的提示词、工具和工作方式。
DeepSeek Harness 内置了四种工作模式:标准模式、PTC 模式、极简模式和创造模式。标准模式适合日常编码,PTC 模式让模型通过代码组合多步工具操作,极简模式只保留少量核心工具,而创造模式比较特别——它专门用来帮助我们检查插件、调整组装,并创建新的 Preset。
多说两句这个创造模式,我们可以先启动“创造模式”,再让 Agent 协助设计一种新的工作模式。这个新 Preset 可以拥有自己的系统提示词、工具和 Skills,最终就形成了一个面向特定业务的自定义 Agent。
理解到这里,Preset 的核心作用就很清楚了:它解决的是“某一类 Agent 应该怎样组成”。Host 启动以后,公共服务已经准备就绪;至于接下来创建的是编码 Agent、内容 Agent,还是我们自己设计的业务 Agent,则由 Preset 决定。
为什么有 Profile 还需要 Preset
Profile 选择的是整套程序的运行形态。一个 Web Host 启动后,可能同时服务几十个 Session。
其中一个 Session 是代码助手,需要终端、文件编辑、LSP 和代码规范;另一个是内容助手,只需要网页搜索、文档读取和写作提示词。
如果每创建一种 Agent 都重新启动一套 Host,会浪费公共资源,也很难统一管理。更好的办法是:
- Host 共享模型连接、Session 基础设施、API 和 Agent Loop;
- 每个 Agent 按 Preset 获得自己的工具、提示词和扩展能力。
所以 Profile 与 Preset 不在同一层竞争。一个负责“开哪家公司”,一个负责“组哪种项目小组”。
Preset 目录里有两份不同文件
一个 Preset 目录至少包含真正的组装文件 agent.cordis.yml,还可以包含用于界面展示的 preset.yml。
my-agent/
preset.yml
agent.cordis.yml
preset.yml 主要保存名称、简介、排序等信息。它像招聘页面上的岗位说明,方便用户在界面里选择。
agent.cordis.yml 才是实际组装清单。它列出 Persona、Tools、Skills、Plan 等插件,以及这些插件的具体配置。
不要因为 preset.yml 名字更像“配置”,就以为它决定 Agent 能力。真正被 Cordis 挂载的是 agent.cordis.yml。
先看看系统自带的几种 Preset
源码中的预置组合位于 apps/cli/config/agent-presets。打开目录,会看到 standard、code、minimal 和 cordis 四个子目录。它们不是四套 Host,而是同一套 Host 上的四种 Agent 组合。

图 7-1:WebUI 会把系统提供的 Preset 展示成可选择的工作模式。
菜单里的“标准模式”“PTC 模式”等名称,以及每个名称下面的灰色说明,分别对应各个 Preset 目录中 preset.yml 的 name 和 description;order 则决定它们的排列顺序。例如标准模式的配置位于 apps/cli/config/agent-presets/standard/preset.yml:
name: 标准模式
description: 功能完整的编码 Agent,支持文件编辑、Shell、文件与网页检索、Skills、计划、目标、子代理和工作流。
order: 1
因此,preset.yml 管的是“这个 Preset 在选择界面里怎样介绍自己”,不是 Agent 实际加载哪些能力。系统自带的四种 Preset 为了支持中英文界面,还准备了与这些配置对应的内置翻译。
| Preset id | 界面名称 | 主要差别 |
|---|---|---|
| standard | 标准模式 | 文件、Shell、搜索、Skills、Plan、子 Agent 等能力较完整 |
| code | PTC 模式 | 具备标准能力,但通过 Code Mode SDK 把工具呈现给模型 |
| minimal | 极简模式 | 只保留持久 bash 与 str_replace_editor 两个核心工具 |
| cordis | 创造模式 | 在标准能力上增加运行时检查、插件实验和 Preset 创作指导 |
Preset可以同时改变提示词、工具数量、工具呈现方式、Skills、工作流和某些只属于该类 Agent 的服务。
Preset 是第二次插件装配
当 Session 选择 standard Preset 后,AgentPresets 会读取对应组装,并让这个 Agent 的作用域能够看到其中注册的工具和提示词。

图 7-2:Host 已经在第一阶段启动;Preset 在第二阶段决定 Agent 的岗位能力。
图中“挂到 Agent 身上”是方便理解的说法。当前实现会为一个 Preset 建立常驻挂载,相同 Preset 的多个 Agent 通过作用域父链加入它,而不是每个 Session 都重复创建一整套插件实例。
这样既复用了同一份 Preset 注册,又让工具和状态可以按 Agent 或 Session 区分。
第一次有人选择某个 Preset 时,系统会真正读取并挂载它;后续 Session 再选择同一个 Preset,通常只需要加入已经存在的常驻作用域。可以把它理解成:公司第一次成立“标准开发组”时要准备制度、工具和资料,以后新员工只需加入这个组,不必再复制一整套部门。
作用域像一副分层眼镜
一个 Agent 查找工具或提示词时,不只看一个全局列表。它会沿着自己的作用域链向上查找:
Agent 作用域 → Preset 作用域 → Host 公共作用域
因此它既能看到 Host 提供的公共能力,也能看到自己 Preset 增加的专属能力。
另一个 Agent 加入不同 Preset,就会看到另一组注册。两者在同一进程里工作,却不需要共享完全相同的工具列表。
这就是作用域的意义:不是复制一套世界,而是规定“站在这里能够看到哪些注册”。
为什么某些服务需要 isolate
有些 Cordis 服务默认是进程级单例。如果在 Preset 中直接再提供一次,可能与 Host 或另一个 Preset 的同名服务冲突。
需要由 Preset 自己拥有的服务,应放进独立 realm,也就是配置 isolate。可以把它理解成给项目组安排独立会议室:名字可以相同,但门牌所在的区域不同,不会和公司公共会议室抢占同一位置。
工具和提示词等按作用域注册的贡献,通常可以自然区分;真正提供服务实例的插件,则要认真判断它属于 Host 还是 Preset。
Preset 不是把任何插件都随手塞进去。它应该放“随 Agent 类型变化的能力”,公共基础设施仍然留在 Host。
用一份极简清单看懂 agent.cordis.yml
真实的 standard 配置很长,因为编码 Agent 的能力很多。第一次阅读时,可以先看下面这份概念化的极简版本:
- id: persona
name: '@deepseek-ai/dsh-persona'
config:
text: 你是一名只负责分析仓库的代码审查助手。
- id: file-reader
name: '@company/tool-file-reader'
- id: review-skill
name: '@deepseek-ai/dsh-skill-filesystem'
每个顶层条目都可以理解成一位被安排进组里的成员:id 是这行配置的稳定称呼,name 指向真正的插件实现,config 是交给这位成员的工作参数。
Cordis 加载这份清单后,persona 插件向系统提示词贡献身份说明,文件插件向工具注册表增加读取能力,Skill 插件让该 Agent 找到审查方法。Preset 自己并不执行任务,它只负责把这些贡献放进同一个可见范围。
上面的包名与内容用于解释结构,不是可以直接运行的完整配置。真实编写时,应从系统自带 Preset 复制并逐项删改。
修改 Preset 会影响谁
同一个 Preset 会以常驻方式挂载并供多个 Agent 加入。组装文件变化后,新创建的 Session 可以进入新的 Preset 代际;已经运行的 Session 继续留在原来那一代,避免工具和提示词在任务中途突然变化。
这说明 Preset 不只是一个静态标签,而是一份真实的运行组装。它与 Session 历史存在对应关系:恢复旧 Session 时,应继续采用产生这段历史的 Preset。
这里还有一个重要限制:已经产生历史的 Session 不适合随意切换 Preset。假设旧日志里记录过 validate_article 工具调用,新 Preset 却根本没有这个工具,那么恢复上下文时就会出现“历史里做过,但现在不会做”的断裂。
因此,默认 Preset 的变化只影响以后新建的 Session;空白 Session 可以重新选择组合,已经开始工作的 Session 则应该保持原来的能力世界。
Preset 不能替代什么
Preset 很灵活,但不是所有定制都应该塞进去:
- 它不能代替 Profile。没有 Web Server、Session 服务和 Agent Loop,Preset 自己无法启动一套程序;
- 它不能凭空创造底层 Provider。Preset 可以放入模型可见的网页工具,但 Host 仍要先提供网页服务和可用 Provider;
- 它不是 Session 数据。Preset 记录“怎样组装”,SessionEvent 记录“实际发生了什么”;
- 它也不是安全边界。配置里列出了某个工具,不代表该工具可以绕过 Host 的沙箱、审批和凭据规则。
最稳妥的理解是:Host 先建好办公楼和公共系统,Preset 再决定某类项目组能够使用哪些工位、制度和专业工具。
Preset 最适合承载什么
适合放进 Preset 的通常包括:
- Agent 的 Persona 与系统提示词;
- 这一类 Agent 专用的工具;
- Skills、Plan Mode 或工作流程;
- 只服务这类 Agent 的投影和策略;
- 针对该 Agent 类型的默认模型选择。
下一课,我们沿着真实创建路径继续向前:用户点击“新建会话”以后,Session、Preset 和 Agent Loop 怎样合作,让一个 Agent 正式出生?
一个 Agent 是怎样被创建出来的?
从创建 Session 到 Agent Ready,中间到底发生了什么?