Vault

让智能体可以被信任:Palantir Orchestrator 的持久化、挂起与隔离

cover

摘要

DevCon 6 上,Palantir 发布基础设施层新品 Orchestrator,专治「DemoWare」病:那些演示里惊艳、一进生产就崩的智能体。演讲者用一个患者出院智能体完整走了一遍失败路径——进程死亡、节点升级、内存溢出、模型故障、供应商宕机,以及最隐蔽的:重启后上下文变量(如「今天」)解析出不同值导致非确定性、副作用重复执行、无法等待人类审批、无法重放调试。

核心洞见是:「今天智能体有用性的瓶颈往往不是智能,而是信任。」所有 AI 公司都在烧钱让模型更聪明,但智能体能否真正干活的分水岭,是你能不能信任它安全地完成工作——重复送药、重复计费、数据库写入重复这些真实世界的后果不可撤销。

Orchestrator 用两个方法化解全部问题:orchestrator.run 把每一步执行结果写入持久账本,重跑时短路重放、以幂等键保证「恰好一次执行」;orchestrator.signal 让智能体可以完全挂起——进程彻底拆除、零内存零 CPU、只活在账本里,等医生批准或化验结果这类信号到来时,再唤起微 VM 从原处继续。等待从此几乎免费。

正文

一、DemoWare 之死:生产环境里智能体的五种死法

演讲者(John)接着 Ankit 的话题,谈基础设施层的规模化智能体构建。在座各位大概都见过十几个「DemoWare」智能体——演示里漂亮地解决某个业务问题或工作流,但放进生产环境几乎全部失败。他带着大家从零构建一个智能体,逐一审视所有可能失败的方式。

这个智能体是「患者出院智能体」:接收患者标识,从当前日期取一些上下文,交给智能体循环调用工具、起草出院计划,等待医生签字,然后执行真实世界的效应——把处方发给药房、向保险公司计费。看似简单,却已经暗藏大量不明显的大问题:进程死亡、节点升级、内存溢出、模型失败、模型供应商宕机——「你的智能体有一百万种理由会失败,而且它终究会失败」。

第一个问题:你得先发现它失败了——当组织里有成千上万个智能体并行运行时,这本身就不容易。假设发现了失败,也不能就此放任:病人必须拿到处方、保险必须被计费,事情终究要办成。于是做软件工程师最直觉的事——重启进程。重启后的第一道坎:智能体没有记忆,本地数据全没了。朴素解法是把对话历史存到磁盘或 S3——但这不够:即使存了模型的对话历史,重新执行时上下文变量(contextual variables)的已存结果也拿不回来。以「since」变量为例:周二 23:58 首次运行,崩溃后周三 00:02 重跑——这个变量会传播进工具调用并解析出不同值:第一次 fetch labs 拿到周二的化验,第二次拿到周三的——智能体出现难以推理的非确定性行为。

第二道坎:重启会导致真实世界的副作用重复——药方不能发给药房两次、病人的保险不能被重复计费;不只是屏幕上这些函数,工具调用里的函数也可能双重执行。第三道坎:智能体不能「等」,但你恰恰需要它会等——真实智能体工作流里有大量人类交互,本例必须等医生签字才能发处方;而保持一个长生命周期进程常开(朴素的「让它一直跑着」),又会撞上内存溢出、节点重启、升级等前面所有问题;上千个智能体常驻更是持续烧计算成本。第四道坎:无法轻易重放——服务或 API 出了 bug,直觉是「用同样的输入再打一次」复现调试;智能体做不到——世界已经前进了:时间流逝、副作用已发生、这个人可能有了新过敏史,check allergies 的解析结果与第一次不同——变量太多,根本无法定位问题。

二、关键洞见:瓶颈不是智能,是信任

这一串失败暴露了构建智能体的核心张力:智能体的能力越强,越强大、商业价值越高,但失败模式也越复杂、越危险。由此得到一个关于智能体本身的洞见:今天限制智能体有用性的瓶颈,往往不是智能——而是信任。「全世界每一家 AI 公司都在花令人瞠目的钱让模型更聪明,也确实见效了。但当前世界与『智能体真正完成工作』的世界之间的差别不是智能,而是我们是否信任智能体能够安全地完成工作。」智能体失败会有真实世界的后果——病人重复拿到药物、重复的数据库写入导致损坏、购买被双重计费——这些行为作用于真实世界,且无法撤销。

让智能体足够可信、能上生产,是 Palantir 多年来在许多智能体与客户用例中反复解决的问题。现在他们把大量经验固化成了新产品 Orchestrator:同一个出院智能体,包上 Orchestrator SDK 后,只需引入两个方法——orchestrator.run 与 orchestrator.signal——前面所有问题加上几个新问题全部解决。

三、Orchestrator:账本、重放与恰好一次执行

原理是这样:用 orchestrator.run 包住每一步,操作执行一次后被记录进 Orchestrator 服务的账本(ledger)。账本持久存储,智能体失败或重启也不怕;之后的每次重新调用,从账本重放已记录的结果,而不是重新执行代码。账本的简化视图很直观:第一条记录是「day」变量,解析为具体日期;第二、三条是智能体实际发出的工具调用;第四条是智能体循环产出的出院计划结果;第五、六条是智能体采取的副作用——给药房发药、向保险计费。

有了账本,失败或挂起后可以靠「从账本重水化执行状态」恢复:再次调用时函数从头到尾重跑,但每一个已完成的 orchestrator.run 调用都会短路——返回账本里记录的结果、把变量与代码重水化为那个值。日期重放为与第一次完全相同的日子;崩溃前已完成的智能体循环可以直接跳过、不重复计算——省下模型 Token 与时间。最关键的是:无论崩溃发生在何时,药单都不会第二次触发——账本里同时存储了执行尝试与幂等键(idempotency key),保证「恰好一次执行」(exactly-once execution)。

一旦意识到「重启智能体是安全的」,你就能意识到可以构建「会停止」的智能体:orchestrator.signal 让进程检查某个信号是否已完成,未完成就让智能体挂起——进程被彻底拆除:没有内存、没有 CPU、没有磁盘,除了账本里的一行记录哪里都不存在,因此成本为零。当医生批准到来——无论几分钟、几小时还是几天后——信号被写进账本,Orchestrator 唤起一个新的微 VM(micro VM)、重新调用智能体,用既有状态加信号完成的信息把它重水化,从上次停下的地方继续。「这让等待几乎免费:你可以有数千个智能体无限期挂起,不产生任何成本,也不用管理它们的生命周期,更不用处理内存溢出、节点重启、故障——前面说的所有事。」

四、挂起即免费:等待、隔离与微 VM 架构

四个问题都解决了,但生产环境的水面下还有更多:隔离——智能体执行代码天生危险又极其强大,微 VM 提供内核级隔离、阻止恶意代码执行,因此所有智能体都跑在微 VM 里;子智能体编排——智能体调用智能体形成几十上百层深的执行图时,失败、重试、取消必须能传播穿透整张图,把生命周期作为一个集体管理;安全——Foundry 的原则之一,为智能体配备精细的安全控制与权限模型;规模化的可观测性——由同事 Chris 稍后讲解。

架构示意:智能体执行请求进入 Orchestrator 后被放进队列——队列支持背压(back pressure):模型供应商宕机或触及 Token 上限时,把工作暂存在队列里等资源恢复;资源就绪后事件循环取出请求,调用管理微 VM 的 Cordite 服务,拉起一个新的微 VM 开始运行智能体。智能体自由调用工具、执行代码、调用子智能体,直到命中挂起点——然后彻底关闭、只存在于账本中,等待某个信号服务完成信号(LLM 调用完成、用户批准、本体对象增删、定时器、Webhook——任何你想触发动作的真实世界事件都可以建模成信号)。信号完成后,用账本加信号数据重水化智能体、继续执行。这一整张复杂架构最终蒸馏成两个方法:orchestrator.run(持久化执行)与 orchestrator.signal(可挂起的智能体)——这正体现了 Foundry 的关键设计目标:把复杂的基础设施顾虑抽走,让开发者专注于业务结果。

演示中,TypeScript 代码里只需在「fetch external records」这个外部数据库操作工具前加一个 orchestrator.signal 调用与几个字段,就能让工具执行等待用户签字——此刻进程处于挂起状态,没有任何 VM 与之关联;点击「授予访问」,新的微 VM 即刻拉起、从头重水化并继续生成出院计划;计划生成后对应代码中的 signal 等待临床医生对最终计划签字,点批准,执行继续推进到副作用阶段——向药房派发、向保险公司发账单,智能体循环完成。

回到开头的论断:这个智能体的瓶颈不是智能——今天有大量模型聪明到足以起草出院计划;是信任。「挂起、持久化、隔离这三个基础原语,可以用来把任何高风险的智能体,变成你能放心托付真实数据、真实客户与真实后果的东西。」

觉得有用?分享给一个需要的朋友 🙏