跳到主要内容
路径文档

Agent 预设与 Persona

一个 Agent 不只是"模型 + 几个默认工具":它有一个固定组合:工具、系统提示词段、投影单元,外加它的人格。DSH 用两层机制承担这个:Agent 预设(preset)与 Persona

机制管什么载体
Agent 预设(preset)该 agent 的完整能力组合目录 + 一个 agent.cordis.yml
Persona该 agent 的人格/系统提示词一个可组合的系统提示词行

1. Agent 预设(agent-presets)

一个 preset 是一个目录,里面放一个 agent.cordis.yml@deepseek-ai/dsh-agent-presets 在进程内把它只挂载一次(standing mount),每个命名了它的会话通过 agent scope 的父链加入它。

  • 每个会话各 key 自己状态,但共享同一份挂载:"每个 preset 的组合只存在一次,覆盖所有加入它的 agent"
  • 作用域解析链:agent → preset → global(就近遮蔽最远)
  • 挂载的工具/提示段/投影单元对每个其下 agent 可见,兄弟 preset 对其保持 deaf
ctx.agentPresets.defaultId // 未指名时挂载的 preset id
await ctx.agentPresets.list() // 当前所有 preset(含 broken,带 reason)
await ctx.agentPresets.resolve(id?) // 按 id,缺省 defaultId
await ctx.agentPresets.mount(agentCtx, id?) // 组成一个 agent 的 preset
await ctx.agentPresets.composeFrom(agentCtx, parentCtx) // 加入另一 agent 已在运行的标准组合
await ctx.agentPresets.read(id) / copy(...) / remove(id) // 读原文 / 复制建新 / 删除(本地授权)

发现不缓存:list()/resolve() 每次重读根,运行中新增的 preset 立即可见。损坏的目录会以 broken 列出(带原因),而不是被跳过。

2. Persona

@deepseek-ai/dsh-persona 是一个可组合的人格行。部署人格由 dsh-system-prompt 作为自己的 config 无条件注册(进程恰有一个);这个包就是给单个 agent shadow 部署人格的那一行。

# 在 preset 的 agent.cordis.yml 里
- id: persona
name: '@deepseek-ai/dsh-persona'
config:
text: |
你是一个专注代码审查的助手。语气直接、给出可执行的修改建议。
complete: false # false=shadow; true=成为唯一系统提示词段
includeRuntimeContext: true # false=隐藏此 agent 的全部动态上下文快照
  • text 是模板,支持 {{…}} 组,在渲染时(非组装时)对已注册提示词变量严格解析
  • complete: true 时,组装仍解析上下文/工具/变量/协作监听器,但之后只保留这一个 persona 段:没有其他身份/工具指引能追加
  • includeRuntimeContext: false 时不求值此 scope 的 context provider,并丢弃 assembly listener 追加的 context;它不关闭拥有沙箱、审批、委派状态的服务

只能挂在 agent 作用域内(preset 挂载提供的):在作用域外挂会与 deployment:persona 注册冲突并 loud fail。这不该绕过:部署人格已有主人,这一行的意义就是为单个 agent 遮蔽它。

3. Plan 模式(plan-mode)

@deepseek-ai/dsh-plan-modeper-agent 的规划协作状态 + 部署所有的指导段。它和 persona 一样是一段可组合进系统提示词的文本,区别在于 persona 是持续的人格行,plan 段只在 plan mode 激活时出现在 prompt order 50,未激活贡献零 token。

  • 入口/出口是命令:/plan [message] 选中 plan mode(裸 /plan 直接进;非空参数先选中、再经 agent.steer() 作为下一步普通用户消息提交);/plan off 退出(参数 off 被精确保留)。命令与其终端结果都不进模型历史。
  • exit_plan_mode 是唯一的退出工具:schema 两种状态都稳定注册,execute 只在 plan 激活时接受,且只在用户经 ctx.userQuestions 精确批准后才离开。它声明 plan-review presentation intent,把 Approve 作为批准标签——有能力的 UI 会把它呈现成决策而非通用提问。
  • 状态只写日志:plan/mode 事件({ active: boolean })是 log-only、整值替换;foldPlanMode 从会话日志直接恢复,所以 resume、fork、compaction 都拿回状态。fork 子继承已记录的 plan 状态,新 spawn 从 inactive 开始。
  • section必填非空的 config;未知键 load 时即失败。它不接受任意命名模式、工具过滤、沙箱设置或批准策略。

口径一致:plan mode 是软指导,不是模型路由。它不切换模型、不做 plan/execute 双路由(见 多模型模型路由);沙箱模式与批准策略独立强制、不读也不写 plan 状态。要真正"限制"执行,得单独配 sandbox + approval。默认挂载(base);Web 下 plan-mode 移到 preset 层,standard preset 的 planning group 以 entry-local realm 携带它——plan 状态本就是 per-agent 的,这才是正确生命周期。

一个完整 preset 长什么样

~/.dsh/.agent-presets/reviewer/ # 用户自己作的 preset 根($DSH_HOME/.agent-presets)
└── agent.cordis.yml
# agent.cordis.yml —— 该 preset 的标准组合
- id: persona
name: '@deepseek-ai/dsh-persona'
config:
text: 你是一个代码审查助手。只读重构建议,不实施。
- insert:
- id: tools
name: '@deepseek-ai/dsh-tools'
- id: lsp-tool
name: '@deepseek-ai/dsh-tool-lsp'

会话选择这个 preset → 只挂一次,mount 的组合对每个加入的 agent 有效。

验证

# 看用户 preset 根
ls ~/.dsh/.agent-presets/
dsh web --dump-config | grep agentPresets
# 会话里看 persona/系统提示词段
zstdcat ~/.dsh/sessions/*/*/session.jsonl.zstd | grep -E 'persona|preset' | head

下一步