跳到正文

安全与权限

工具如何声明副作用、只读运行能做什么、输入如何校验与脱敏,以及凭据保存在哪里。

有时用户只想让 Agent 看看图表、讲讲行情,什么都别动;有时又希望它把整个工作区重新排一遍。权限模型同时照顾这两种情况:每个工具都声明自己的副作用,只读运行只会拿到不能改动任何东西的工具,所有输入在执行任何代码之前都要先通过校验。

每个工具都声明副作用

每个 @Tool 都把 safety 设为以下两种之一。

等级含义示例
read-only只读取状态或外部数据,不做任何修改。panes_list、indicators_query、instruments_query_name、market_bars_query、market_timeshare_query、market_timeshare_range_query、drawings_list、comparisons_list、settings_get、web_search、ask_user
destructive会改变图表、设置或外部世界。pane_create、pane_replace_content、panes_clear、drawing_create、drawing_update、drawing_delete、drawings_copy、drawings_clear、comparison_create、comparisons_clear、settings_update、settings_reset、code_interpreter

安全等级是工具冻结元数据的一部分,工具参考 中逐个列出。

只读运行

只读是针对单次运行的策略,不属于图表上下文。Agent 工作区单独保存这个开关,在启动运行时通过 StartRunInput 的 readOnly 传入。它由两道相互独立的检查保证:

  1. 解析工具时。 浏览器 bridge 为本次运行构建工具列表时,BrowserToolRegistry 会去掉所有 safety 不是 read-only 的图表工具,模型根本看不到写入工具。
  2. 执行时。 运行驱动器在执行前会再检查一次。即使写入工具因为某种原因(例如 Provider 行为异常)出现在只读运行里,调用也会以 TOOL_NOT_ALLOWED 失败。

用户还可以在 Agent 设置里单独关闭某些工具。选择会被保存;首次使用时,所有已注册工具默认启用。

当前提交下,浏览器 bridge 不会在每次 destructive 调用前请求确认:confirmTool 会报告没有待确认的调用。只想让 Agent 看、不想让它动时,请使用只读运行。Agent 做出的修改与界面操作走同一套命令,所以它画的线可以像其他画线一样撤销。

方法执行前先校验输入

每次工具调用都经过注册表统一的 execute 入口,用 Value.Check 按工具的 TypeBox schema 校验输入。无效输入永远到不了领域方法。schema 是深度冻结的副本,注册表之外的代码无法放宽它。

校验失败时,模型会收到一段简短且有上限的说明:最多收集 TOOL_INPUT_ERROR_LIMIT(5)条字段错误,每条写成 <path>: <message>,并以数据形式返回:

{
  "success": false,
  "error": {
    "code": "…",
    "message": "The tool input is invalid: /anchors/0/price: …",
    "retryable": true,
    "recommendedAction": "Correct the invalid field and retry the request."
  },
  "stateChanged": false
}

图表的领域错误也以同样方式返回,并附带该错误码对应的恢复提示。drawing_create 还会补充具体指引,例如有效的 pane ID 或已加载的日期范围。由于 stateChanged 为 false,模型知道可以放心重试。

脱敏

用户的提示词在写入会话或发送给模型之前,会先经过 redactString(位于 packages/agent-runtime/src/security)处理:

  • Bearer …、Basic … 鉴权值以及 sk- 形式的 Key 替换为 [REDACTED];
  • /Users/<name>、/home/<name>、C:\Users\<name> 这类用户目录路径替换为 [LOCAL_PATH];
  • 当前 Provider Key 与 Exa 搜索 Key 的原值替换为 [REDACTED]。

脱敏只作用于用户提示词。模型输出、工具结果、错误、运行事件和用量元信息都原样传递,所以工具绝不能把密钥放进返回结果。

凭据保存在哪里

渲染层代码通过 AgentBridgeClient 和 AgentUiEvent 与 Agent 交互;Provider 负载、凭据、Electron 对象和原始工具结果都留在运行时与宿主适配层之后。发给界面的配置视图从不包含 API Key。Key 本身存在哪里取决于宿主:

宿主Key 的存放位置
浏览器(默认)页面 localStorage 中的 Agent 设置;配置了 持久化范围 时按账户和工作区隔离。
Electron注入的 credentials 存储(例如 safeStorage),不写入 localStorage。
托管 Provider浏览器里没有真实 Key:只发送只读占位值,由宿主的 fetch 完成鉴权,托管工作台就是用会话 Cookie 这样做的。

代码解释器的隔离

code_interpreter 是 destructive 且 sequential 的工具,只有导入其入口时才会注册。它的策略始终要求禁用网络,但实际执行力度取决于 Provider:只有 cloud-run-sandbox 报告 enforcesNetworkPolicy: true,而它从未在真实的 Cloud Run 沙箱上运行过;fly-machines 的出站拦截由本项目自己的 runner 镜像完成,而不是 fly.io;LocalProvider 在 macOS、Windows,以及无法使用 unshare -rn 的 Linux 主机上不做任何隔离,切勿用它执行不可信代码。完整对比表见 集成 Agent。

并行与顺序执行

executionMode 告诉运行时,模型在一条消息里发出多个工具调用时该如何调度。运行时默认并行;只要这条消息里有一个调用指向 sequential 工具,整条消息的调用就按顺序逐个执行。读取类工具一般是 parallel;所有图表写入、ask_user 和 code_interpreter 都是 sequential,因此两次写入永远不会交错。无论哪种方式,工具结果都按模型发出调用的顺序返回给它。

本页内容