适用版本:ChengOS v0.1.0+ | 最后核对:2026-08-12 | 来源:
deploy/config/presets.yaml、deploy/config/shortcuts.yaml、crates/cheng-core/src/domain/preset.rs、crates/cheng-core/src/domain/shortcut.rs、crates/cheng-api/src/services/presets.rs、crates/cheng-api/src/services/shortcuts.rs
有两份 YAML 目录,让你不改工作流也能改变它的行为:
| 预设 | 快捷指令 | |
|---|---|---|
| 改变什么 | 某个节点的配置 | 下一回合的路由 |
| 文件 | presets.yaml |
shortcuts.yaml |
| 作用范围 | 直到再次更改 | 一回合,或直到被清除 |
| 消费者 | 目标节点 | ai/llm_branch |
两者都由全局文件和工作区文件合并而成,也都以文件 mtime 作为缓存失效信号——改完 YAML 无需重启即可生效。
<global_dir>/presets.yaml ← 所有工作区共享
<workspace-root>/<workspace-id>/config/presets.yaml ← 按工作区,id 冲突时它胜出
与全局条目 id 相同的工作区条目会替换全局条目(不区分大小写);其余按文件顺序追加。
预设
预设是针对某个节点类型的、具名且经过校验的配置补丁。选择是两级的:先选预设类型,再选预设。
preset_types:
- id: tool_nodes
label: Tool nodes
description: Presets for tool nodes
presets:
- id: code-safe-mode
preset_type: tool_nodes
node_type: tools/code
label: Code execution safe mode
description: Restrict file and shell behavior
llm_visible: true
risk_level: high
config_patch:
allow_write: false
sandbox: strict
| 字段 | 含义 |
|---|---|
id |
稳定、文件内唯一的身份,用于命令和审批载荷 |
preset_type |
所属分类 id |
node_type |
该补丁适用的节点类型——应用到别处会被拒绝 |
label |
选择列表中显示的名字 |
description |
面向人和 LLM 的说明:它改什么、何时用 |
llm_visible |
受限的 LLM 发现是否可以看到它——默认 false |
risk_level |
low、medium 或 high |
config_patch |
浅合并进目标节点配置的 JSON 对象 |
补丁经由与普通节点更新相同的校验路径应用,因此预设写不出属性面板本来会拒绝的配置。
唯一真相
presets.yaml 在所有界面上都是唯一的存储。编辑器属性面板的「保存为预设」写入它,而对话的预设选择器、CLI 和外部渠道都从它读回。系统刻意没有第二份浏览器本地预设存储需要对账。
用户保存但未指定分类的预设会落进 user_presets(「已保存的预设」),该分类按需创建,且默认 llm_visible: false——你为自己保存的预设不会自动提供给智能体,因为那会在无人评审的情况下扩大智能体可改动的范围。
由于持久化一个预设意味着重写整个文件,保存操作在一把进程内锁后串行化;否则两次并发保存会竞争,后者会把前者丢掉。
LLM 发现被刻意收窄
智能体看不到整个工作区目录。一个预设只有在同时满足 llm_visible 且其 node_type 属于「从请求方节点可作为工具触达的节点类型」时,才是可发现的。
而且 LLM 只能请求切换预设,绝不能自行应用。请求会变成一次审批,携带工作区、工作流、请求方节点、目标节点、预设 id 与标签、一份 change_summary 差异,以及可选的理由。它走常规审批基础设施——~~y / ~~n、CLI、网页卡片——动作名为 preset_switch,因此各界面都能把它与工具执行审批区分开。见人工审批与评审。
失败行为
列举是软失败:presets.yaml 缺失或格式错误只会记一条警告并给出空目录,因此对话摄取绝不会因为一个坏掉的工作区文件而崩溃。
应用和保存则是硬失败,返回带类型的错误:一次没有发生的保存,绝不能看起来像发生了。
快捷指令
快捷指令给某一回合附加结构化路由数据:
shortcuts:
- name: Need Tools
description: Route to the tool-capable branch
route_mode: always
value:
need_tools: true
- name: Search
description: Route to the search action
value:
action:
name: search
- name: Deep Think
description: Enable extended reasoning mode
route_mode: always
value:
reasoning:
mode: deep
max_steps: 20
| 字段 | 含义 |
|---|---|
name |
显示名与稳定身份;非空,且在文件内唯一 |
description |
选择列表中显示的一行说明 |
route_mode |
once(默认,仅下一回合)或 always(直到被清除) |
value |
合并进该回合路由载荷的 JSON 对象 |
value 必须是对象,因为消费者是 ai/llm_branch,它按嵌套路径查找来路由。请用嵌套 map(action: { name: search }),不要用扁平的点号键(action.name: search)——后者解析不出来。
为什么不直接写进消息里
快捷指令把路由数据附加在消息旁边,而不是把 JSON 注入消息文本。带来两个后果:对话历史保持干净,模型也绝不会把路由控制 JSON 当成自然语言来读。
生命周期
活动的快捷指令保存在会话上下文的 active_shortcut_v1 键下,并在每一回合被序列化进该回合的 route_shortcut 输入。once 在一回合后清除;always 会保持到用户取消选择为止——选择器是一个开关。
它与「待决的数字选择」不同,后者只是某个列表的瞬时快照。
在哪里使用
| 界面 | 预设 | 快捷指令 |
|---|---|---|
| 编辑器 | 属性面板选择器;「保存为预设」 | 对话工具条 |
| 对话 | 输入框上方的预设选择器 | 输入框上方的快捷指令选择器 |
| CLI | /presets |
/shortcuts |
| 外部渠道 | ~~presets 后回数字 |
~~shortcuts 后回数字 |
实用建议
- 快捷指令按意图命名,不要按实现命名:
Deep Think优于set reasoning.mode=deep。 always要省着用。 它会一直生效到被取消,而一个被遗忘的常驻快捷指令很难被注意到。- 默认保持
llm_visible: false,只为那些让智能体去请求也安全的预设打开它——注意即便如此,请求仍然需要审批。 - 给任何扩大权限的预设设置
risk_level;它决定审批如何呈现。 - 共享条目放全局文件,工作区文件只用于真正的覆盖。

暂无评论内容