1889 字
9 分钟
- 次浏览
本地助手操作电脑前的动作分级设计
读前导览

让助手操作电脑之前,先明确哪些动作可以直接执行、哪些必须确认、哪些禁止。

正文
1889 字
阅读
9 分钟
结构
8 节
来源线索

windows-bot-memory/action-layer

windows-bot-memory:action-layer windows-bot-memory:capabilities windows-bot-memory:computer-use-roadmap

这篇不是 computer-use 教程,只记录为本地助手设计权限时的一些判断。

很多本地助手做到一半,都会走到同一个诱惑面前:既然模型能理解用户意图,为什么不直接让它操作电脑?

可以让它操作电脑,但前提是动作不能从一条临时命令开始。

codex-windows-bot 的动作层后来选择了一条更慢但更稳的路:所有能力先进入 action registry,再按风险分级,再决定是否需要确认,最后只调用固定 handler。通用 shell 不进入这张表。

动作注册表不是命令菜单#

动作注册表看起来像一份功能清单:

{
"id": "projects.brief",
"category": "projects",
"risk": "R0_READ",
"enabled": true,
"confirm": false,
"handler": "projects_brief",
"args_schema": {
"project": "string",
"mode": "string"
},
"max_output_chars": 10000,
"redact_args": ["project"]
}

但它不该被当成“命令菜单”。它更像一份动作说明:这个动作叫什么、属于哪类、能不能启用、是否要确认、参数长什么样、输出最多多长、哪些参数不能进审计明文。

它要解决的是:每个动作先登记清楚,再进入执行。用户说“帮我看看项目状态”,模型不能临时编一个命令;它只能选择注册过的动作,比如生成项目 brief、列出固定检查、读取允许的入口文件。

风险等级要比功能名称更早出现#

动作层里应先看 risk,再看 handler

风险可以分成五层:

R0_READ 只读本地状态
R1_LOCAL_LOW 低风险本地副作用
R2_LOCAL_STATE 本地状态改变,需要确认
R3_EXTERNAL 外部发送、上传、日历、权限等,需要确认
R4_FORBIDDEN 通用 shell、宽泛删除、敏感信息提取等,拒绝

这样讨论一个能力时,会先问它会碰到什么。截图当然有用,但它会捕获当前屏幕,所以应归到需要确认的一类:固定目录保存,只返回尺寸和文件名。再比如上传文件是常见需求,但它跨出了本机范围,就应该落到外部动作层,不应混在本地修改步骤里。

风险等级把“能做什么”改成了“在什么约束下能做”。

R0 先读,R2/R3 再确认#

本地助手最适合先开放只读观察,控制类动作可以晚一点。

  • 读取健康状态。
  • 列出能力目录。
  • 生成项目 handoff。
  • 查看插件开关。
  • 列出近期审计摘要。
  • 读取本地页面快照。
  • 查看窗口是否存在标题。
  • 列出本地截图元数据。

这些动作仍然要限流、脱敏、审计,但它们不改变机器状态,也不向外发送内容。

一旦动作会改本地状态,就应该进入确认门。比如重启本地私聊机器人、删除过期成果、打开已知应用、清理任务文件,都不应由一句自然语言直接执行。

一旦动作会触达外部系统,就更要和本地步骤拆开。创建日历、发送提醒、上传结果文件,这些动作需要独立确认。不能因为前一步“生成文件”已经被确认,就顺手把文件发出去。

确认门要和动作执行分离#

确认不能只靠一句“确定吗”。

更稳的做法是:先生成一个待确认请求,记录动作 id、风险等级、参数摘要、过期时间和确认码摘要;确认时只允许用这个请求 id 继续执行。

这样至少有三个好处:

  • 用户确认的是一个已冻结的计划,而不是重新解析一遍自然语言。
  • 确认码过期后,旧请求不能被再次利用。
  • 审计里能看到“计划”和“执行”是两个阶段。

这也能避免一个常见漏洞:模型在确认后重新理解用户输入,把原本只读的任务变成写入或外部发送。

文件、项目、应用、桌面要走不同窄门#

“操作电脑”听起来是一个能力,实际应该拆成几类窄门。

文件动作只负责本地助手根内的普通文本读取。项目动作必须通过注册项目 id,只能读相对路径,只能运行枚举好的检查。应用动作只看静态 app registry 和聚合运行状态,启动应用要另走确认。桌面动作只读窗口的安全摘要,不返回进程号、命令行、原始标题、截图或控件树。

这几个门不能互相借权限。

知道某个应用存在,不代表能读它的安装目录。知道某个项目存在,不代表能运行它的任意脚本。能看到当前窗口存在标题,也不代表能把标题明文发回聊天。

把门拆开,系统会少一点“全能感”,但风险范围清楚得多。

输出也要限流和脱敏#

很多安全设计只盯输入,其实输出更容易泄漏。

动作层里每个动作都应该有输出长度上限。返回健康状态时,别带完整路径、进程命令行、配置文件位置、运行参数、消息原文或账号标识。返回审计时,只给摘要、计数、动作 id 和风险,不给原始参数正文。

这会牺牲一些调试便利,但对聊天入口很必要。维护者要看原始日志,可以回到本机高信任环境;远程聊天只应该拿到被裁剪过的事实。

一个简单判断是:如果这段输出被截图转发出去,会不会暴露本机结构、账号线索、私有消息或凭据类内容。会的话,它就不该从动作层原样出来。

health 和 selftest 是发布检查门#

动作注册表写完不代表安全。

长期能兜住这套系统的,是 health 和 selftest。每新增一个动作,都应该至少验证三类事情:

  • 正常路径能返回预期摘要。
  • 禁止路径要明确拒绝,别悄悄换成别的行为。
  • 聊天输出里没有本地路径、进程细节、私有标识、凭据类内容或原始消息。

这类检查听起来繁琐,但它能防止“今天为了方便临时加一个参数”慢慢把窄门拓宽。

尤其是本地助手一旦接入聊天入口,安全范围就不能只靠开发者记着,新增动作时这些检查都得跑一遍。

现在的判断#

本地助手接管电脑前,应先做动作分级,再考虑 UI 控制或通用命令。

一个可长期维护的动作层至少要回答这些问题:

  • 这个动作是否在注册表里。
  • 它属于只读、本地副作用、本地状态改变、外部动作,还是禁止项。
  • 它是否需要确认。
  • 它的参数能不能被 schema 限住。
  • 它是否只调用固定 handler。
  • 它的输出能不能被裁剪和脱敏。
  • 它有没有 health 或 selftest 覆盖。

当这些问题都答得清楚,助手才适合逐步增加能力。

真正容易出问题的地方,是把一次本机操作包装成普通聊天回复。更稳妥的做法是让每个动作先登记清楚,需要确认的就停下来等确认,不该做的直接拒绝。

本地助手操作电脑前的动作分级设计
https://blog.sunmmyapi.xyz/posts/windows-action-risk-gates-before-computer-use/
作者
Sun
发布于
2026-05-29
许可协议
CC BY-NC-SA 4.0

继续读

相关内容