我核了 31 个 AI 编程客户端的权限接口,能真正替你点「允许」的只有少数

给 AI 编程客户端做外部审批面板,做到第三个月才想明白一件事:难点根本不在 UI。

同样是「代理要写文件了」,有的客户端允许你在终端之外回一个「允许 / 拒绝」,有的只能让你看见它想干什么,你照样得切回去点。这两类混在一起做,产品就会变成「看起来什么都能干,一用全是割裂」。

我把接入拆成三层,只有第一层是普遍能做到的。

一、能观察 / 能应答 / 能审批

层级 需要什么 典型实现方式 覆盖面
能观察 单向事件推送 hooks、日志 tail、状态查询接口 几乎全部
能应答 双向通道 提问事件 + 回写答案 一部分
能审批 原生批准结果回写 PermissionRequest + 把 decision 交回客户端 很少

分水岭在第三条。「我收到了一个通知」和「我能替用户批准」是两件事,中间差一个语义层级。 前者只需要读;后者要求你交回的结果被客户端当成「用户按了允许」原生接受。

做不到这一点的后果不是「少一个功能」,是用户点了没反应------然后他怀疑整个软件是坏的。

二、六个真实的坑

坑 1:通知通道不是批准通道

现象:Gemini CLI 的按钮点了「允许」,客户端那边依旧在等它自己的确认。

原因:它有通知通道,但通知本身不是批准接口。你把按钮接在通知上,等于对着一个只读的日志喊话。

做法:先确认这个通知后面有没有对应的回写接口。没有,就只显示状态,不放按钮。

坑 2:没有 PermissionRequest 事件,就不要放按钮

现象:Factory Droid 只核到观察类事件。

做法:不显示任何审批按钮。提前放一个假的「允许」,等于让用户对着一个不会生效的开关点。

这条后来成了整个项目的底线:UI 上没有的按钮,比点了没反应的按钮更诚实。

坑 3:「阻断」不等于「批准」

现象:Windsurf / Cascade 的前置 hook 可以拦住一次调用。

原因:拦住的语义是「我阻止了」,不是「我允许了」。用阻断冒充批准,结果通常是工具直接跑不起来,用户以为软件坏了。

做法:阻断只能拿来做「危险操作拦截」,不能当审批通道。

坑 4:没有安全回写通道,就不做应答

现象:Roo Code 固定在 3.54.0 的任务事件 API,能读任务状态。

做法:只显示状态,审批留在编辑器里。缺一条安全回写路径的时候,「只读」是唯一不会骗人的选择。

坑 5:配置写对 ≠ 被加载 ≠ 被信任

这是第二件反直觉的事。生成一份 hooks 配置,跟它真的被加载、真的被信任,是三件事。

各家普遍还有一层信任确认:你写了配置,它还要用户手动进去点一次「允许这些 hooks」。这层不做,文件写得再对,一个事件都进不来。

反过来也有一个坑:别替用户批量信任。 用户可能有自己的 hooks 在跑,你替他勾上「全部信任」,是在改他的安全边界。

做法:只写自己那一条,只读别人的信任状态,不改。

坑 6:同一个品牌,不等于同一套协议

这条吃过亏。

客户端 真实情况 后果
Trae CN 版与国际版是两套协议 CN 的验收结果不能挪给国际版
Cline VS Code 扩展与 SDK CLI 是两条路径 扩展通了不代表 CLI 通
Zed / JetBrains 内置 AI 拿不到外部通道 能接的只是显式启动的外部 ACP Agent,权限仍留在编辑器里
Continue 只能靠 serve /state 轮询快照 能用,但会漏掉短暂状态,得老实说不精确

所以接入矩阵是按「客户端 × 形态」逐格填的:CLI、IDE 插件、桌面端分开记,一个格子验过不能代表隔壁。

三、「接入了吗」不该是一个布尔值

大多数工具把接入状态做成 connected / disconnected。这个模型在真实世界里会持续给出错误答案。

我把状态做成六档:

ts 复制代码
type AgentState =
  | 'needs_config'      // 配置不完整
  | 'needs_trust'       // 客户端明确报告尚未信任
  | 'needs_setup'       // 需要导入插件 / 选启动入口 / 连外部服务
  | 'awaiting_activity' // 配置已就绪,但还没收到真实事件
  | 'connected'         // 收到过有效活动
  | 'check_failed';     // 读不到授权状态

关键在两条规则:

规则一:没有「等待活动」到「已接入」的自动推定。

配置文件存在、进程起来了、开关打开了,全都只到 awaiting_activity。必须收到一条真实任务产生的事件 ,才允许显示 connected。

ts 复制代码
function resolveState(s: ProbeResult): AgentState {
  if (!s.configComplete) return 'needs_config';
  if (s.trust === 'denied') return 'needs_trust';
  if (s.setupPending) return 'needs_setup';
  if (s.lastEventAt === null) return 'awaiting_activity';
  return 'connected';
}

规则二:能查就问,查不到就说查不到。

客户端有只读的授权查询接口就去查真实状态,别猜。比如 Codex 可以读它的 hooks 列表,拿到启用状态、信任状态和当前定义指纹------查得到就查,查不到就写 check_failed。

不要写「未授权」,也不要写「已授权」。猜错的方向刚好相反的两个错误,都会让用户做错决定。

四、会话身份是另一个坑

把事件收上来只是开始,还得知道这条事件属于哪个会话。

各家给的身份线索都不一样:

客户端 身份线索 需要注意
Windsurf trajectory_id 与窗口不一一对应
Kimi 任务树 一个任务下有多个子节点
Qoder 会话 ID 要区分原生会话与子任务
GitHub Copilot CLI 并发 ID 并发时要消歧,不能只看时间
Roo Code 窗口来源 多个窗口会同时产生事件
Amazon Q(旧 CLI 包装器) 无稳定 ID 拿不到调用标识和回复正文,只能进程级观察,不碰内容

认错会话的后果很难看:代理 A 的问题显示在代理 B 的卡片上,你点了一个允许,批的是另一件事。

这类问题不会在单客户端测试里暴露,只在「三个代理同时跑」的时候暴露。

五、现在到哪一步了(不美化)

31 个接入目标,全部都有通过项目契约测试的基础通道;完整的端到端验收,一个都还没做完。

差别只在深度:

  • Claude Code 走得最远:2.1.234 的隔离真实读取、以及「在终端之外拒绝写入」已经实机验过;完整审批、并发权限、子代理和 TUI 还在验
  • Codex / Cursor / Gemini CLI / Copilot CLI / CodeBuddy 到「契约测试通过 + 事件类型核对」,真实客户端加载待验
  • Aider / Cody / Amazon Q / Zed / JetBrains 只能包一层显式启动器做观察,交互不覆盖

矩阵和每个版本的实际验证记录都公开在仓库里(docs/compatibility/agent-matrix.json 和 release-verification 系列),每一格写的是「验到哪一步」,不是「支持 / 不支持」。

我宁可这份表看起来难看,也不想让人装完发现某一行是假的。

六、小结

  1. 「能观察」「能应答」「能审批」是三层能力,别用一层的说法描述三层
  2. 通知不是批准,阻断不是批准,两者都只能用来做更弱的那件事
  3. 配置写对、被加载、被信任是三件事,缺一层就没有事件
  4. 接入状态不要做成布尔值,没有「自动推定已接入」这条捷径
  5. 品牌相同不代表协议相同,矩阵要按「客户端 × 形态」逐格填
  6. 会话 ID 不稳的时候,只做进程级观察,别碰内容

这套东西最后落成了一个小工具,跑在 Mac 的刘海上:XIsland (客户端闭源,接入矩阵和验收记录开源,GitHub 上搜 Meteorkid/XIsland)。

想听两件具体的事:

  1. 你主力用哪几个 AI 编程客户端?我按使用量排验收优先级,现在这张表是按「能不能接」排的,不是按「多少人用」排的
  2. 有没有人清楚某家客户端其实有对外审批接口、但这里标成了「只能观察」------那说明我漏了,比我自己测出来更值钱
相关推荐
爱勇宝1 小时前
《道德经》第 13 章:别让评价系统控制你的心
前端·后端·产品
茶底世界之下2 小时前
山间站台不必转暖:用 Awaking 留住冷光与红箱
ios·app·产品
SL_staff17 小时前
从‘连得上’到‘管得好’:JVS-IOT双引擎驱动设备运维闭环
java·物联网·产品
GrowingIO技术社区20 小时前
SaaS与私有化部署怎么比较?责任、集成与成本
大数据·数据挖掘·产品
AMASENSYS艾马斯1 天前
矿山变频设备全生命周期管理与配件备件方案
产品·资讯
京东云开发者1 天前
从“会生成”到“能生产”:萤火虫 AIGC 平台的 AI Infra 实践
算法·aigc·产品
茶底世界之下1 天前
阴天花摊不必变暖:用 Awaking 留住花色与湿街
ios·app·产品
SL_staff2 天前
制造业订单交付崩盘?用四层协同框架重建交付可信度(技术实践)
java·产品·全栈
SL_staff2 天前
打破风控迭代死循环:用决策编排重构业务与技术协作链路
java·产品·全栈