Skip to content
learnspace
Go back

omp Approval 模式:安全与效率的开关

TL;DR:omp 的 approval 系统用三种模式(always-ask/write/yolo)+ 三层工具分级(read/write/exec)+ 逐工具覆盖,让你按任务类型精细控制 agent 的自主权。默认 yolo 最省心,项目里建议用 writebash: prompt 做安全兜底。


omp 的记忆系统解决了「agent 怎么记住经验」。但经验要落地,agent 就得动手:改文件、执行命令、删除旧代码。这就引出了所有 AI 编程工具的共同问题——agent 有多大自主权? 每改一个文件都弹确认框?你会疯。完全不确认?万一 rm -rf / 呢。

approval 系统就是在这两端之间找平衡。

问题的本质

假设你让 agent「把 config.ts 里所有硬编码端口改成环境变量」。这个任务涉及:

agent 跟人不一样:它能一秒改 20 个文件,也能一秒删 20 个文件。你得有个机制精确控制每一步的自主权。

omp 的解法是三层结构:模式 × 分级 × 逐工具覆盖。先讲每一层,再讲怎么组合。

三种模式

配置项:tools.approvalMode,默认 yolo

模式自动通过弹确认框
always-askreadwriteexec
writereadwriteexec
yoloreadwriteexec

always-ask——最保守。 读取操作自动放行,写文件和执行命令都要你点头。适合你不确定 agent 会做什么的场景,比如第一次让它碰核心代码。

write——最常用。 读和写都放行,只在执行命令时弹框。这是大多数项目的 sweet spot:agent 能自由读代码、改文件,但跑 bash 命令要你确认。改 50 个文件不用点 50 次,但要执行部署脚本时你会看到。

yolo——完全自主。 所有操作自动放行,包括执行命令。适合你完全信任 agent(或者看都不想看)的场景。这也是 omp 的默认模式——它假设你知道自己在做什么。

三种模式可以随时切换,不用重启 session:

Terminal window
# 在 session 里改,对当前 session 生效
/settings set tools.approvalMode write
# 或启动时指定
omp --approval-mode always-ask
omp --auto-approve # 等价于 approvalMode: yolo(注意:也是 yolo,不是 write!)
omp --yolo # 等价于 approvalMode: yolo

三层工具分级

每种工具都有一个 approval 声明,告诉系统它属于哪个风险等级:

等级语义典型工具
read只读数据,不改变任何状态readgrepgloblsp
write改变工作区/会话状态,但不执行任意代码editwritetodo
exec执行代码、shell 命令、浏览器操作、spawn agentbashevalbrowsertask

没有声明 approval 的工具默认当 exec 处理——宁可多确认,不能漏掉。MCP 服务端的工具默认声明为 write

在逐工具覆盖(per-tool 覆盖,即 tools.approval 配置,见下一节)中引用 MCP 工具时,命名格式为 mcp__<server>__<tool>(双下划线分隔),例如 mcp__filesystem__deletemcp__github__create_pr。不知道工具名?在 session 里问 agent “list available tools” 或用 /tools 命令查看完整列表。

这意味着:你用 write 模式时,bashexec 级)会弹框,但 editwrite 级)不会。想要更精细?用逐工具覆盖。

逐工具覆盖(per-tool)

逐工具覆盖就是在全局模式之外,给每个工具单独设规则。比如全局用 write(读写自动、exec 弹框),但对 bash 单独设 prompt,或者对某个 MCP 工具设 deny。配置项是 tools.approval,跟 tools.approvalMode 平级:

tools:
approvalMode: write
approval:
bash: prompt # 执行命令必须确认
read: allow # 读取总是放行(在 always-ask 下也没事)
edit: allow # 编辑总是放行
mcp__filesystem__delete: deny # 禁止某个 MCP 工具

每项的值:

这个覆盖在所有模式下都生效。即使在 yolo 模式,设了 bash: prompt 也会弹框。

实际用法:全局设 write,对高频安全工具设 allow,对高危工具设 promptdeny

知道三种模式和逐工具覆盖后,理解到底谁说了算比记忆配置项更重要。源码中的 resolveApproval() 函数按这个顺序判断:

resolveApproval(tool, args, mode, userConfig)
├─ 1. 获取工具的 approval 声明(可能是函数,动态计算)
│ └─ 没声明 → 默认 tier = "exec"
├─ 2. 如果是 yolo 模式?
│ └─ YES → 有 user policy 就用它,没有就 "allow"
│ ★ 即使工具标记了 override: true,yolo 也忽略
├─ 3. 工具标记了 override: true(比如 bash 检测到 rm -rf /)?
│ └─ YES → user policy = "deny" → 拒绝
│ → 其他情况 → 弹框(哪怕 mode 说放行)
├─ 4. 有 user policy(per-tool 覆盖)?
│ └─ YES → 用它(allow/deny/prompt)
└─ 5. 模式的 tier 上限 >= 工具的 tier?
└─ YES → allow
└─ NO → prompt

这个顺序有几个反直觉的点:

动态 approval:不是所有工具都是静态等级

有意思的是,approval 声明可以是函数bash 工具就用了这个机制——它不是固定 exec 等级,而是检查命令参数:

// bash.ts 源码逻辑
approval: (args) => {
const cmd = args.command;
// 匹配 critical patterns → { tier: "exec", override: true, reason: "Critical pattern detected" }
if (matchesCriticalPattern(cmd)) return { tier: "exec", override: true, reason: "..." };
// 普通命令 → "exec"(但不 override)
return "exec";
}

lsp 工具更灵活——根据操作类型返回不同等级:diagnostics 返回 readrename 返回 write。在 write 模式下两者都自动放行(write 级已自动通过);在 always-ask 模式下诊断自动通过,重命名需要确认(除非设了 lsp: allow)。

自定义工具或扩展也可以利用这个机制——一个工具可以在不同参数下表现为不同风险等级。

弹框长什么样?标准审批提示会显示工具名、风险等级和操作上下文——比如 bash 会显示完整命令,edit 会显示目标文件和修改范围。自定义工具可以通过 formatApprovalDetails(args) 钩子追加额外的提示行(比如文件路径、预计影响的代码量)。你看到的信息足够判断”这个操作我放不放心”。

安全护盾:bash 的 critical pattern 检测

bash 工具内置了 CRITICAL_BASH_PATTERNS 正则列表。匹配任一模式时,approval 返回 { tier: "exec", override: true },触发上一步解析顺序中的第 3 条——非 yolo 下强制弹框。源码中精确的检测范围:

类别匹配的模式
递归删除rm -rf / / rm -fr /sudo rm
权限破坏chmod -R ... /chown -R ... /
Fork bomb:(){ :|:& };:
磁盘/文件系统> /dev/sd*mkfsdd ... of=/dev/...shred /dev/cryptsetup
系统配置> /etc/passwd / /etc/shadow / /etc/sudoerstee ... /etc/...
远程代码执行curl ... | bashbash <(curl ...)eval "$(curl ...)"
主机控制shutdownreboothaltpoweroffinit 0kill -9 1
网络 shellnc -e ...

如前所述(解析顺序第 2 步),yolo 模式下 override 不生效——这些命令直接执行。保护策略同上:设 bash: prompt

(历史细节:2026 年 5 月的一个版本曾让 override 在 yolo 下也弹框,但很快回退了——大量用户抱怨 yolo 模式下被”误杀”。现在 yolo 就是字面意思的 yolo。)

怎么选模式:决策框架

没有”万能模式”,按任务类型选:

任务类型推荐模式理由
探索代码、问问题always-ask不需要改文件,安全最优先
日常开发、重构write + bash: prompt自动改文件,命令要确认
跑测试、格式化write + bash: allow测试命令安全且频繁
批量自动化脚本yolo你看了脚本逻辑,信任它跑
部署write + bash: prompt部署脚本要确认,别手滑
初学 ompalways-ask先看懂它在干什么

我的日常配置(这个博客项目):

.omp/config.yml
tools:
approvalMode: write
approval:
bash: prompt
read: allow
edit: allow
write: allow

readeditwriteallowwrite 模式下其实是冗余的——这些 tier 已经自动放行。写出来是为了切到 always-ask 时也能正常工作,也方便一眼看懂配置意图。

逻辑:agent 能自由读写文件(写博客文章、改组件、调样式),但跑 bash 命令必须我确认。日常开发 90% 的操作不需要我点确认,但 npm run buildrsync 部署等命令我能看到。

当我明确要批量操作时——比如重命名 10 个文件、统一改 frontmatter——我会临时切到 yolo

Terminal window
/settings set tools.approvalMode yolo

干完活切回来。会话不中断,零摩擦。

常见陷阱

1. 用 always-ask 做日常开发

改一行代码弹一次框,改 20 行弹 20 次。你会习惯性点”允许”,变成人肉 yolo——既没安全也没效率。write 模式才是日常开发的正确默认。

2. yolo 下忘设 per-tool 保护

全局 yolo + 没设 bash: prompt = agent 可以无确认执行任何命令。如果你不 100% 信任 agent(或者不 100% 信任自己给 agent 的指令),至少设 bash: prompt

3. 以为 deny 能挡住一切

deny 只在 approval 层面生效。如果 agent 用别的方式绕过(比如通过子 agent、通过 MCP 工具),需要对应的 per-tool 覆盖也配上。不过 omp 的子 agent 会继承 per-tool 配置,所以 deny 配置会穿透。

4. 混淆 CLI 标志和配置文件模式

--auto-approve--yolo 是等价的——都强制 yolo 模式。想用 write 模式?必须用 --approval-mode write

常见的踩坑姿势:配了 tools.approvalMode: write,但启动时加了 --auto-approve,以为在 write 模式——实际已经是 yolo 了。CLI 标志优先级最高,会覆盖配置文件。

跟前面系统的协作

approval 模式跟你已经配好的 Rules、Skills、Memory 形成完整的安全网:

四条线各司其职:Rules 防错,Skills 提效,Memory 省心,Approval 兜底。

还有一个跨系统的交互值得注意——子 agent(task 工具 spawn)始终以 yolo 运行,per-tool 配置会穿透,审批边界在 parent agent 的 task 调用上。所以多 agent 协作时,你只需确认”要不要 spawn”,不需要盯着子 agent 每一步操作。

下一步

approval 系统解决了”agent 能不能做”的问题。到这里,omp 的核心机制——Session、Rules、TTSR、Skill、多 Agent、Memory、Approval——已经全部讲完了。

最后一篇,我们回到最初的问题:把这些机制放进真实开发流程,omp 跟 Cursor / Windsurf 比到底谁更好? 不是参数对比,是用这个博客项目 5 个月的实战数据说话。


本文是「omp 编程工具使用探讨」专栏第 8 篇。查看专栏目录浏览全部文章。文中的配置示例来自 omp 官方文档和本博客项目的实际使用。


Share this post:

Previous Post
AI Agent 总是忘事?omp 记忆系统让它记住所有踩过的坑