我们做好准备迎接AGI的诞生了么
从 2024 年开始,各类 AI Agent 如雨后春笋般大量涌现。在架构层面来看各类 AI Agent 差别并不算大,都是让一个挂载了几十个工具定义的 LLM 进程连接到用户的各类数字资产中参与到生产当。安全策略依赖 system prompt 中的几句限制性指令,成本控制也寄托在模型”自觉”以减少 Token 消耗。
虽然大家都知道 LLM 还不够安全,但这一切行为背后都事实上的指向了一个前提:LLM 是可信的,或者至少是可控的。
直到今年 OpenClaw 的爆火。最早接触 OpenClaw 的时候,我兴奋地在本地也部署了一套。运行一段时间之后却对它有一点小失望,它并没有给我带来传说中贾维斯般的惊艳感,可能是我自己的期望值太高了。不过不是因为出现了安全问题,而是几个简单的命令就耗光了我的测试 API 余额。简单算了一下 Token 的消耗构成,其中相当一部分成本来自重复注入那些实际上并不会被使用的工具定义。仅工具 schema 每条消息就消耗约 8000 Token,加上 SOUL.md、AGENTS.md 这些配置文件的重复注入,单条消息的固定开销可以超过 4 万 Token,还没算任何实际对话内容。几十个工具,每一轮对话都完整注入,不论当前任务是否相关。
这让我开始重新思考问题的起点。于是我决定自己新建一个文件夹,尝试从结构上而不是用提示词来解决这些问题。
我做的第一件事是对资产进行分类。SSH 服务器归为一类,GitHub 仓库是一类,数据库是一类。每一类有自己的凭据格式和访问规则。Agent 如果需要使用某一类资产,必须有一条明确的绑定关系;如果没有绑定,这类工具就不会出现在它的上下文中。一个没有被授权使用 SSH 的 Agent,不是在调用时收到一条”权限不足”的报错,而是从始至终不知道 SSH 这个工具的存在。
这里的关键不在于”拒绝访问”,而在于”不可见”。不是告诉它”你没有权限”,而是它的世界里根本没有这个对象。到此为止,安全问题和 Token 浪费似乎同时得到了缓解——不是两个目标分别被解决,而是同一个结构性选择自然带来的两个面向。
这个选择本身并不复杂,真正有意思的是它之后发生的事情。
当”谁能看到什么”解决之后,下一个问题立刻浮现:看到之后能做什么?
一个 Agent 被授权访问 GitHub 仓库,但它应该只能读取特定组织下的几个仓库而不是所有仓库。一个 Agent 被授权使用 SSH,但它只应该连接开发环境的机器、只能执行查看日志的命令而不能执行部署脚本。
工具可见性只是第一层,第二层是参数级的约束。这意味着不仅需要控制 Agent 能调用哪些工具,还要控制它传入的参数是否在允许范围之内。
最初的做法是为每种资源类型编写专门的权限检查代码。SSH 有 SSH 的检查逻辑,GitHub 有 GitHub 的,MCP 有 MCP 的。但当到第五种资源类型的时候我就意识到这条路走不通,每增加一种集成就需要写一套新的检查代码并确保它与核心逻辑保持一致。安全逻辑散落在各处,任何一处遗漏都是一个漏洞。
但是我注意到一件事:所有这些检查,抽象到底层,都在从工具调用的参数中提取某个值与授权范围进行匹配。SSH 检查的是主机名,GitHub 检查的是仓库名,MCP 检查的是工具名,形式不同但结构完全一样。
所以权限的声明与执行被分离了。插件开发者不再需要写权限检查代码,只需要声明”哪个参数需要检查,怎么匹配”。一个通用的权限引擎负责执行:提取参数、匹配约束、允许或拒绝。每一种集成无论是 GitLab、Notion 还是 Slack 都只需要在声明中增加几行,不需要动任何核心代码。
工具可见性和参数校验这两层在架构中成为两道独立的防线:第一层在 LLM 调用之前过滤工具列表,第二层在 LLM 返回工具调用之后检查参数。任何一层都足以阻止越权,即便其中一层被绕过另一层仍然完整。理论上两层同时失效很难发生,但安全设计的意义恰恰在于不依赖”很难”。
两层都遵循同一个原则:出错时关闭而不是放行。工具解析失败就返回空列表,参数校验失败就拒绝请求,事件投递前权限复检失败就阻止投递。系统在任何异常情况下的默认行为是停止。
LLM 会产生幻觉、会受到 prompt injection、也可能在复杂语境下做出越权调用。在 system prompt 中写”不要泄露 API Key”跟提醒一个人”不要偷看保险柜密码”在结构上没有区别。问题从来不在提醒是否真诚,而在结构是否允许。
如果越权在结构上不可能发生,它就不再是信任问题,而是物理问题。
管理 Agent 访问资源的逻辑,到这里已经和管理员工访问公司资产的逻辑几乎同构——身份、授权、凭据、审计,一样都不少。
而当我开始推演 Agent 之间的协作时,一个经典的安全问题以几乎原样的形式出现了。
当 Agent A 委托 Agent B 执行一个任务,而 Agent B 碰巧拥有 Agent A 没有的某项权限比如访问生产数据库,Agent A 是否可以通过委托来间接获得这个能力?
这是 Confused Deputy 问题的一个变体。它在操作系统的权限模型中被研究了几十年,现在以几乎相同的形式出现在 Agent 协作场景中。
解决方案也遵循同样的逻辑:Agent A 在委托 Agent B 时,必须声明一组约束——允许 Agent B 使用哪些工具、在什么参数范围内。Agent B 的有效权限是这组约束与 Agent B 自身权限的交集。权限只能在传递过程中收窄,不可能放大。
这组约束同样在两层生效:LLM 调用之前过滤工具列表让 Agent B 只能看到委派范围内的工具,工具调用之后校验参数时取委派约束与自身权限的交集。无论调用链多长,A 委托 B 再委托 C,权限在每一个节点都只会收窄,不存在通过委托链泄漏权限的可能。
在处理工具权限的过程中还有一个发现,花了我一些时间才想清楚:Agent 使用的工具其实分为两类,治理逻辑完全不同。
一类是操作外部系统的,比如通过 SSH 连接服务器、通过 GitHub API 操作仓库、通过 MCP 调用第三方工具。这些工具涉及外部资源,需要凭据、需要权限校验、需要审计日志,也是前面一直在讨论的。
但还有一类工具,是 Agent 操作自己的数据——写自己的记忆、设置自己的定时任务、上报自己的进度。
这两类工具的治理需求本质上不同。一个员工用公司账号登录 GitHub,需要公司的授权;但一个员工在自己的笔记本上写备忘录,不需要任何人批准。
如果不做这个区分就会陷入两难:要么所有工具都走权限校验,连 Agent 写自己的记忆也需要审批,既慢又不合理;要么放松校验,外部资源操作失去保护。
判断标准其实很简单:数据归谁所有? 操作 Agent 自己的数据,所有权就是权限,不需要额外校验。操作外部系统或其他 Agent,走完整的权限链路。
两类工具在架构上走不同的路径,外部资源工具经过完整的权限校验和执行链路,自有能力工具则直接路由到内部处理逻辑,跳过整个权限检查。
这个区分看起来是一个实现细节,但它反映的是一个更根本的判断:治理不是越多越好。过度治理和缺乏治理一样有害——它会让系统变慢、变脆弱,最终让人想绕过它。正确的治理是精确的:在需要的地方严格,在不需要的地方不添麻烦。
记忆是另一个在实践中暴露出来的问题。标准的 LLM Agent 每次对话都从零开始,上一轮交互中学到的所有信息在会话结束后全部消失。如果 Agent 是一个长期运转的行为主体,它需要记忆——但不是无差别的全量记忆。
一个 Agent 在运维频道里学到”这台服务器每周四凌晨会有计划维护”,这条信息不应该出现在它帮另一个团队写代码的会话中。一个 Agent 在执行部署任务时获取的环境变量,不应该泄漏到其他任务的上下文中。
记忆因此被分区管理。全局记忆在所有场景中可见,相当于通用经验;频道记忆只在对应的 IM 频道中可见,是特定团队的协作上下文;任务记忆只在该任务执行期间可见;资源记忆与特定外部系统绑定,记录的是”使用这个工具时的注意事项”。
分区不仅是效率优化,也是安全的延伸。记忆的边界就是信息的边界,一个 Agent 不应该因为被分配了一个新任务就自动获得它在其他上下文中积累的所有信息。
当 Agent 确实需要跨分区访问记忆,比如处理一个跨团队协作任务,它可以动态加载只读副本,任务结束后自动卸载。权限收窄的原则在记忆层面同样成立:跨分区加载的是只读的不能修改,卸载是自动的不依赖 Agent 自己”记得”清理。
会话结束时 Agent 的对话历史会被 LLM 分析,自动提取值得保留的记忆条目。这个提取是原子性的,属于自动提取的旧记忆被整体替换,用户手动写入的记忆永远不受影响。
当多个 Agent 在同一个组织中工作,它们之间需要通信。一个 Agent 完成了部署任务,运维 Agent 需要知道。一个定时调度触发了,对应的 Agent 需要被唤醒。一个工作流中的某个步骤完成了,下一步需要启动。
事件系统因此产生。但事件系统同样需要治理。
一个 Agent 订阅了某个事件。之后,它的某项资源绑定被管理员撤销了。下一次事件触发时,投递是否应该继续?
答案是不应该。每次投递前重新检查绑定权限,投递时的权限状态才是决策依据,而不是订阅时的。事件只投递给同一个工作区的订阅者,复检失败则阻止投递——宁可漏发,不可错发。出错时关闭的原则在异步通信中同样成立。
如果把以上这些放在一起看,会发现它们不是一组零散的功能:资源分类、工具可见性、参数校验、声明式权限、委派约束、工具分类、记忆分区、事件治理——每一个都是从同一个起点自然推导出来的。
起点是一个判断:安全不应当依赖 AI 自身的克制,而应当在结构上强制实现。
从这个判断出发,工具可见性和参数校验构成了两道防线,声明式权限让它们能够规模化,委派约束让多 Agent 协作不泄漏权限,工具分类避免了过度治理,记忆分区把信息隔离延伸到上下文层面,事件治理确保异步通信不绕过安全边界。每一个问题的解决都自然暴露了下一个问题,而下一个问题的解决方式又总是回到同一个原则。
凭据是一个还没有提到的例子。在大多数 Agent 方案中 API Key 和 Token 被直接放在 system prompt 或环境变量中,LLM 可以在对话中接触到明文。我从一开始就做了不同的选择:凭据以加密形式存储,执行时在执行层解密注入,LLM 在整个生命周期中接触不到任何明文。模型只发出意图,实际的鉴权在模型看不到的地方完成。即使模型被完全攻破它也没有任何可以泄露的密钥,因为密钥从未进入过它的世界。
从用户的视角看,事情很简单:我拥有哪些资源,我给 Agent 什么权限,Agent 就能做什么。
但如果换一个视角,站在 Agent 的位置上:我是承担什么职责的主体?我的边界在哪里?我的预算还有多少?我能访问哪些记忆?
| 自然人 | Agent |
|---|---|
| 身份证 | Agent ID + 名称 + 描述 |
| 法律约束 | 权限策略 |
| 工作授权 | 资源绑定 |
| 密钥 / 钥匙 | 加密凭据(自己看不到明文) |
| 薪资预算 | Token 预算 |
| 行为记录 | 审计日志 |
| 经验 / 记忆 | 分区记忆 |
此时此刻,两个不同位面的抽象就像镜子的两面在此重合。
当用户说:“把生产服务器的只读权限给运维 Agent。“Agent 所看到的是:“我拥有一个 SSH 工具,只能连接 10.0.1.* 的机器,只能执行 cat 和 tail。”
同一组数据,从两个方向展开,都能自洽。
所以,我慢慢开始不再使用 Agent 这个称呼,转而开始称其为 Bot。并不是刻意做区分,而是这两个词指向的东西确实不同。Agent 强调的是能力,自主决策、工具调用、循环推理;Bot 强调的是身份,一个被管理的、有边界的、可追溯的行为主体。LLM 是 Bot 的大脑,Agent 是 Bot 执行任务的方式,但 Bot 不等于 LLM,就像一个人不等于他的大脑。
这并不意味着我就认为 AGI 在概念上已经实现了,我深知当前的技术发展还远未及此。
当前的 Agent 不会学习。一个人做了十次同样的工作会越来越熟练,但 Agent 每次对话仍然依赖上下文注入。记忆系统部分缓解了这个问题,这离真正的”学习”还很远。更深层的张力在于:如果 Agent 真的开始通过经验改变行为模式,它的权限边界是否还有效?它学到的”经验”中是否包含了不该跨越的信息边界?
多 Agent 协作的治理复杂度也在上升。当调用链变长、协作关系变复杂,权限的动态撤销、调用链的实时审计、多 Bot 之间的资源竞争,都还没有优雅的解决方案。委派约束的交集模型是一个起点,但不是终点。工具生态同样如此——现在有八种内置资源类型和一个插件机制,当集成数量从十几种增长到上百种,声明式权限的设计是否还能保持一致性和可维护性,我还不确定。
但有一件事比较确定:这些问题的解决方式,最终都会回到同一个起点,同一个问题。
如果在明天或者后天,AGI 就此诞生了,我们真的做好迎接他的到来的准备了吗?
2025 年底,OWASP 发布 Agentic Applications Top 10,开篇写道:“Once AI began taking actions, the nature of security changed forever.”只是现实比”安全”更复杂。当我们真正把一群 Bot 放进生产系统会发现安全只是其中一项,成本、记忆、协作、可观测性这些方方面面同样紧迫。
AGI 不是治理的前提。只要一个东西能自己做决定、操作外部系统、安排别人干活——你就必须管它。
身份证、合同、门禁卡、审批流程、操作日志——不是限制人,而是让组织能够放心运转。
Bot 也一样。
没有清晰权限的 Bot,你不敢让它碰生产。 没有预算边界的 Bot,你不敢月底看账单。
反过来,当这些都存在,你才敢放手。
安全和效率从来都不冲突。它们的敌人只有同一件事——过度授权。而治理的目的,从来不是控制。
是让你有资格放手。