多年来,我一直在探索一个问题:如何让大语言模型真正脱离聊天窗口的局限。观察了众多方案后,我渐渐看清哪些方法可行、哪些行不通,并形成了一些成熟的观点。下面分享这些思考以及我近期开展的实际项目。
什么是真正有效的安全约束
- 第一,对智能体而言,安全机制应当自然直观,无需额外学习成本。
- 第二,整个过程必须完全透明,便于智能体自主修复、持续进化,也方便事后审计追溯。
- 第三,设计必须极其精简灵活,避免冗余臃肿。
- 第四,系统要能容忍错误、适应更新,内存不会随时间推移而损坏或退化。
随着大语言模型智能水平的不断提升,安全约束最终会变得可靠。但眼下的核心挑战是:如何降低你施加给机器人的认知负载——用代币来衡量。
初步的经验真相
这些年我体会到的最重要结论:
- 尽可能保持确定性。大语言模型可以自主选择目标,但实现路径应该是明确界定的,或至少由一系列清晰的步骤组成。
- 核心提示词应尽量精简,让大语言模型在运行时自行决定加载哪些技能模块。
- 一旦接近上下文窗口的容量上限,大语言模型的行为会变得不可靠。
别调概率参数,操控智能体
一个好的工具必须利用大语言模型已有的先验知识。编码和系统管理在训练数据中占比极高,所以为模型提供一个它已熟悉的环境——例如通过小说文本与它沟通,最终只会浪费代币。同样,宝贵的上下文不应浪费在文件查找、目录遍历等琐事上——优秀的工具能让委派变得简单高效。对大语言模型而言,安全约束应该极为轻量,但后台实际承担了大量工作:日志记录、健全性检查、故障安全、清理等等。
可审计性、日志记录与自我修复
一切都很脆弱,所有智能体最终都会失败。失败分为两种类型:
LLM级别的故障无法直接修复,但可以通过安全措施降低风险。由于LLM的回合制特性,线束级别的故障能在运行时恢复,并且应该具备可修复能力。
要修复缺陷,智能体需要两样东西:完善的日志记录和清晰的错误信息。
通用的数据统一层
这些要求其实大多是老生常谈的问题,只是主语从“用户”换成了“智能体”。因此值得思考:当人们实际编写代码时,我们能从前人的经验中学到什么?
我的假设:Unix/Linux环境是一个天然的候选,稍加改造即可成为智能体工具的基础。
我绝非Unix或其任何变体的专家,但过去十年我一直在学习它的历史、设计理念和用法。其中很多理念完美映射了我们当前的困境,也有不少并不匹配。我们把U/L当作一种激励性的类比,而非直接照搬。
新旧概念的映射与Unix哲学
如果你忘了,或者以前没见过,这是里奇和汤普森的信条:
- 编写只做一件事并且把这件事做好的程序。要完成新工作,就重新构建,而不是通过添加新功能让旧程序变复杂。
- 编写能协同工作的程序。每个程序的输出都应该是另一个程序的输入。
- 编写处理文本流的程序,因为这是一个通用接口。
这些理念完美概括了当前安全约束的问题:过于复杂,试图包揽过多任务,而且智能体预期采取的路径往往不明确。这些都是同一个问题的症状:智能体无法对自身保持主体性。如今,很多情况下工具会直接加载到上下文中,系统提示里预先塞满了警告和开发人员制定的规则与指南——最终都会逐渐失效。
由此我们可以总结出一套设计安全约束的原则:
- 编写模块化、透明的工具,只做一件事并且做好;确保它们会大声失败。
- 编写能协同工作的工具、技能和连接器。技能决定工作流,工具是执行工作流的手段,连接器是智能体操作的数据。
- 文本流是通用接口,语言模型在主场上具有优势。一切都应该是平面文本文件。
一切都是文件
你曾经手动处理过JSON问题吗?构建一堆curl命令来查询端点?写复杂的正则表达式?我没有,因为那些太痛苦了。大语言模型可能比你更擅长处理这些,但请放心,它们也更喜欢纯文本。所以,每当处理外部数据源时,你的工具应该做任何必要的清理,让数据在到达大语言模型之前就变得干净整洁。
你还需要一个地方来存储所有这些数据。通过把所有内容分类到目录中,你就能为智能体节省大量浪费的代币。
考虑文件系统层次结构标准(FHS)
FHS概述了全新Linux安装应有的样子。大语言模型是Linux文件系统导航的专家,所以战略性地植入外部数据源并路由到虚拟文件系统,会让智能体有宾至如归的感觉——比如日志放进/var,配置文件放进/etc,智能体工作区放在/home等。另一个好处是,你和智能体都可以通过grep、find、which甚至非GNU工具(如rg和fzf)轻松审计、跟踪和搜索内容。
繁重的工作在于让杂乱无章的外部世界融入人工构建的虚拟文件系统。
我一直在使用下面的映射关系。注意,很多场景可以做到1:1转换。
“内核”
现在确定了文件系统该长什么样,接下来考虑智能体如何与环境交互——或者说,何时交互。始终在线智能体的行业标准OpenClaw采用事件驱动消息处理与心跳配对:完整智能体以固定间隔(默认30分钟)启动,检查是否有需要注意的事项。问题在于,所有非推送消息(比如文件变更或外部状态)只能在心跳粒度上被注意到。缩短间隔,每次空检查都会消耗一次完整的大语言模型调用;拉长间隔,智能体就会比世界慢一个小时。
因此,我决定围绕事件总线构建Ambiance,我错误地把它称为“内核”。它通过文本文件上的光标监视文件系统的变化,然后相应地调用LLM(采用一些合并策略处理高吞吐量)。这样就能确保智能体不会错过任何通知。而且,你还可以连接不同的“用户”(LLM实例)来响应不同事件。
内核承担繁重工作
真正的内核充当软件和硬件之间的中间层。Ambiance内核则充当大语言模型与外界之间的中间层。它检查并确保大语言模型所做的一切都是安全的,没有明显危害。
“用户”
到目前为止,我已经开发了三个默认用户:
- root,处理所有系统级事务,特别是编码新驱动、二进制文件和修复旧驱动。
- pai,面向人类的LLM,负责与外界交互。
- librarian,记录pai擅长什么、不擅长什么,以及系统当天做了什么。
三个用户通过事件总线和发送消息的二进制文件不断相互通信。
Ambiance背后的想法很简单:模型的先验知识是你拥有的最廉价资源,所以用模型已知的东西(文件、用户、日志、文档)构建的工具,总是会击败它必须从头学习的东西。其余的一切都是为此服务的。
Ambiance目前仍在开发中,但你今天就可以试用。另外,如果你对这类项目感兴趣,或者自己也在做类似的事,不妨去了解一下递归中心——我最初就是在那儿开始构建这个系统的。
