摘要——构建一个智能体主要涉及管道工程:工具、状态、护栏、从单个智能体扩展到多个智能体。CUGA(`pip install cuga`),全称可配置通用智能体(Configurable Generalist Agent),是IBM的企业级智能体框架,它处理了这些管道工作,你只需编写工具列表和提示词即可。我们构建了二十多个单文件应用来证明这一点。在此完整阅读一个案例,然后看看同一个智能体如何在无需重写的情况下,以主权可控的方式在生产环境中运行。
大多数智能体应用在智能体做任何有用的事情之前,都要先花一周时间搭建管道。你选择一个框架,连接模型客户端,编写工具适配器,构建某种将状态流式传输到UI的方式,然后在这个过程中,你还要决定这个智能体到底是用来做什么的。有趣的部分总是最后才到来。
CUGA颠覆了这种模式。它是IBM开源的智能体框架,为你处理规划、执行循环、工具调用和状态管道。剩下的才是真正属于你的部分:智能体可以访问哪些工具,以及你告诉它做什么。为了展示这在实践中是什么感觉,我们构建了cuga-apps:二十多个小巧、可运行的应用,每个都是一个包装了单个CugaAgent的FastAPI文件,从电影推荐器到IBM Cloud架构顾问,应有尽有。它们的存在就是为了被阅读和复制。你可以点击浏览在线演示库。
本文详细讲解其中一个应用,指出该框架为你省去了哪些工作,并展示当你需要为生产环境进行治理时,相同的代码会走向何方。无需先学习新框架。如果你写过FastAPI路由,就能读懂每一行代码。
为什么是框架,而不是另一个框架
对这个领域的任何东西,一个合理的问题是:它能让你少写什么代码?CUGA的答案是:围绕模型的编排工作,否则你每次都得重新构建。
它在行动之前先做规划,然后通过工具调用和生成的代码(CodeAct)混合执行。在一个需要二十步才能完成的长期任务中,大多数智能体失败的原因在于丢失了中间结果,并在下一步中(常常错误地)重新推导它们;而 CUGA 会保存该状态,并运行一个反思步骤,该步骤能够捕捉到错误的调用并重新规划,而不是一味蛮干。正是这套机制,而非手动调优,使其在 AppWorld 和 WebArena 等智能体基准测试中名列前茅。
你还可以通过配置而非代码来设定成本/延迟的权衡:快速、均衡和精确三种推理模式,代码执行则在你信任的任何沙箱(本地、Docker/Podman 或 E2B 云端)中进行。智能体定义相同,但调节旋钮不同。这个旋钮的重要性远超其表面意义。大多数框架都假设底层有一个前沿模型,并在计划偏离轨道时依赖它来恢复;而 CUGA 自己完成了这项工作。规划、反思步骤、确保长程任务不偏离轨道的变量追踪——这些都是框架承担了原本需要模型来承担的负载,这使得一个较小的开源权重模型能够在通常无法胜任的场景下站稳脚跟。这也是为什么托管应用运行在 gpt-oss-120b 上,而非前沿模型 API 上。通常的做法是调用你能调用的最大模型;而 CUGA 的做法是,一个较小的开源模型就足够了。
没有任何一个单独的组件是 CUGA 独有的。不同之处在于,它们被预先组装好了,所以你只需配置它们,而无需将它们连接起来。你接触到的 API 很小——用工具列表和提示词构建一个 `CugaAgent`,然后 `await agent.invoke(...)`。这行代码之下的所有内容都是框架本身。
具体来说,就是可互换的工具(OpenAPI、MCP 和 LangChain 函数都以相同方式绑定)、带变量管理和自我修正的长期规划(这是 2025 年 7 月至 2026 年 2 月 AppWorld 榜单第一、以及 2025 年 2 月至 9 月 WebArena 榜单第一背后的机制)、声明式护栏、基于 A2A 的多智能体委派、由 Docling 驱动的 RAG,以及通过一个环境变量切换提供商(`pip install cuga`,然后就能用 OpenAI、watsonx、Ollama 等)—— 每一样都是你原本需要自己构建的东西。名字的第一个词就说明了它的作用:可配置(Configurable);困难的部分已经处理好了,你的工作就只剩下任务本身。
一个应用,从开始到完成
这是 IBM Cloud 顾问 —— 一个能为架构推荐真实 IBM Cloud 服务的智能体。整个应用只用一个文件:一个包含智能体工厂、工具和提示词的 main.py,外加一个小型 UI。
整个智能体就是这样的:
def make_agent():
from cuga import CugaAgent
from _llm import create_llm
return CugaAgent(
model=create_llm(
provider=os.getenv("LLM_PROVIDER"),
model=os.getenv("LLM_MODEL"),
),
tools=_make_tools(),
special_instructions=_SYSTEM,
cuga_folder=str(_DIR / ".cuga"),
)
四个参数。模型来自一个小型工厂(create_llm),它根据环境变量与 OpenAI、Anthropic、watsonx、LiteLLM 或 Ollama 通信。应用代码中没有任何部分知道背后是哪个模型。cuga_folder 是这个应用保存状态和任何策略的地方。承载应用的两个参数是 tools 和 special_instructions。
这些工具将本地函数与托管函数混合在一起:
def _make_tools():
from langchain_core.tools import tool
@tool
def search_ibm_catalog(query: str) -> str:
"""Search the IBM Cloud Global Catalog for real IBM Cloud services.
Always call this before recommending services to verify they exist."""
...
from _mcp_bridge import load_tools
web_tools = load_tools(["web"])
return [search_ibm_catalog, *web_tools]
这里有一个适用于所有应用的模式:MCP 工具与内联工具之间的划分。通用的、无状态的能力来自共享的 MCP 服务器;`load_tools(["web"])` 会引入网络搜索功能,而你无需托管任何东西。任何特定于该应用的内容都会作为普通的 Python 函数以内联方式定义,比如 `search_ibm_catalog`,它的文档字符串就是智能体读取以决定何时调用它的依据。你只需编写属于你自己的那个工具,其余的工具都可以借用。
云顾问的提示词指示智能体在提及任何服务名称前先搜索目录,推荐三到七项服务并说明每项在设计中的角色,且绝不能编造服务名称。最后这条规则至关重要:推荐不存在的 IBM Cloud 服务的智能体比没有智能体更糟糕,因此提示词强制每次推荐都先经过目录查询。按有序步骤编写并明确包含"不要编造内容"规则的提示词效果良好;而采用角色设定的提示词则容易偏离方向。
这就是整个应用:一个工具、一个流程、四行构造函数。围绕它的 FastAPI 路由只是普通的 Web 代码:浏览器向 /ask 端点提交问题,实时面板轮询 /session/{thread_id} 端点获取状态。没有数据库;状态是按 thread_id 存储的 Python 字典,仅由智能体通过其工具写入。当智能体在运行中途调用工具时,面板会立即重绘。UI 并非逻辑的副本,而是智能体所修改状态的视图。
承担核心工作的约定
有一个容易被忽略的细节实际上至关重要:每个内联工具都返回相同的小型信封结构。成功时返回 `{"ok": true, "data": {...}}`;失败时返回 `{"ok": false, "code": "...", "error": "..."}`。
这看起来像模板代码,实则不然。CUGA 的规划器能优雅地处理已声明的失败("地理编码未返回结果,跳过该部分继续执行"),但遇到未声明的失败时就会卡住——原始堆栈跟踪在规划中途弹出,导致运行偏离轨道。在多个应用中,那些运行可靠的应用,其工具从未向智能体抛出裸异常。这虽然是个乏味的约定,但正是智能体能恢复运行还是直接崩溃的关键区别。
上述分离之所以有效,是因为通用部分已在某处运行。这些应用反复调用的能力——网页搜索、维基百科/arXiv、地理编码与天气、金融行情等——都部署在 7 个公共 MCP 服务器(共 36 个工具)上,托管于 IBM Code Engine,无需认证。一个小型桥接器会自动解析它们的 URL,而实时图库还提供了 MCP 工具浏览器,让你在将工具接入智能体之前,就能通过表单调用其中任意一个。
一个库,而非演示
之所以有二十多个精良的应用,其意义远超任何一个单独的应用:一旦你读懂了云顾问应用,你就读懂了它们全部。它们共享一个骨架——电影推荐器将 IBM 目录工具替换为知识 MCP 服务器,网络研究员则几乎完全依赖网络——因此 cuga-apps 实际上是一个起点目录。你克隆仓库,找到最接近你创意的应用,然后编辑它的工具列表和提示词(`HOW_TO_BUILD_AN_APP_FAST.md` 和 `ADDING_AN_APP.md` 详细说明了这一过程)。有几个应用甚至是通过将一份规范文件和一行的简要说明交给编码助手生成的——这种规律性足以让模型复现,也足以让你学习。在克隆任何东西之前,你可以在实时图库中逐一浏览它们。
它们还横跨多个类别,因此无论你在构建什么,总有一个应用已经用到了你需要的部分。有一个研究集群(Paper Scout 按引用次数对 arXiv 论文进行排序;Wiki Dive 和 Web Researcher 进行引用综合),一组日常效率应用(城市简报、旅行、食谱、路线),一个文档与媒体组,对 PDF、音频和视频进行 RAG 检索,一个监控实时指标的运维角落,以及一个基于真实 IBM 产品文档的企业示例。Ouroboros 是一个七智能体的线索生成系统;打开它可了解多智能体形态。而 Meetup Finder 通过 Playwright 驱动无头 Chromium,从 Meetup、Luma 和 Eventbrite(这些平台都已关闭其公共搜索 API)抓取结构化活动;打开它可了解浏览器自动化,这正是 CUGA 的起点,也是其在 WebArena 上取得强劲成绩背后的实力所在。
在你克隆之前有两点注意事项。真正的目录位于内部的 `cuga-apps/cuga-apps/apps/` 目录中,而非外层的那个。并且,并非每个应用都同样精良,因此 UI 将它们标记为“可发布”、“待完善”或“探索性”,默认显示“可发布”状态;从云顾问或电影推荐器开始,以获得一个可用的基线。
将你的智能体保持在边界之内
一个用于搜索目录的演示智能体风险较低。但如果将同样的模式应用于写入文件、运行 shell 命令或接触生产环境的场景,问题就变了:如何阻止它做出让你后悔的事?
CUGA 在运行时层面解决这个问题,而不是在你事后添加的包装器中。这个开源智能体自带一个策略系统,你可以将策略附加到同一个智能体对象上:
await agent.policies.add_intent_guard(
name="Block force-push",
keywords=["--force", "--no-verify"],
response="Blocked: destructive git flags are not permitted.",
)
这就是意图守卫(Intent Guard),六种策略类型之一,每种策略都回答了团队在允许智能体运行前会提出的一个问题:
- 意图守卫——它能否直接拒绝一个请求?
- 工具审批——在运行有风险的工具之前,它能否暂停并等待人工确认?
- 工具指南——我能否在不重写工具的情况下,引导某个特定工具的使用方式?
- 操作手册——我能否为重复性任务固定一个已知的可靠流程?
- 输出格式化器——我能否强制最终回复符合要求的格式?
第六种类型是自定义策略(CustomPolicy),当上述类型都不适用时,它作为备用方案。时间节点的把握很重要,因为并非所有检查都在同一阶段进行:意图守卫在智能体选择工具之前检查请求,工具审批在智能体生成代码之后运行,并检查该代码使用了哪些工具,而输出格式化器仅在最终消息生成后触发。触发条件也不仅限于关键词匹配:它们存储在一个 sqlite-vec 数据库中,并通过语义进行匹配,因此策略会根据用户的真实意图触发,而不仅仅是精确的关键词。可以基于语义相似度、智能体状态或特定工具的调用来触发匹配。这些策略本身存放在构造函数中指定的 `.cuga` 文件夹里,与代码一起进行版本管理,而不是在独立的配置中漂移。
来看一个实际例子:打开 Ouroboros——一个由七个智能体组成的线索生成应用,它为其监督智能体附加了三个策略(一个意图守卫、一个工具指南和一个输出格式化器),因此它是在同一个文件中同时演示治理机制和多智能体形态的应用。
从单个智能体发展壮大
当一个应用超出单次对话循环的规模时,两种扩展方式就变得重要了。当一个智能体会在自己的上下文中不堪重负(工具太多、需要理清的证据太多)时,你就需要拆分工作。一个 CugaSupervisor 将任务委派给专门的 CugaAgent,每个 CugaAgent 都有自己的工具、提示词和独立的上下文,而 Supervisor 只负责判断将子任务交给哪个专家。无论底层有多少工具,它的规划面始终保持精简,并且一个不稳定的工具只会导致一次委派失败,而不会拖垮整个运行流程。一个专家甚至不必是本地部署的;它可以是经由 A2A 协议访问的外部智能体,以同样的方式接受委派。增加一项能力意味着增加一个专家,而不是重写协调器。
另一种扩展方式封装的是知识而非工具:Agent Skills,即一个包含 SKILL.md 操作手册的文件夹,只有当任务需要时,智能体才会将该手册加载到上下文中,这样单个提示词就不必承载智能体可能需要了解的所有信息。两者都使用相同的构建模块(工具、提示词、状态、策略),只是组合方式提升了一个层级。
之前的潜在客户生成应用 Ouroboros 让这种模式变得具体。它有一个 Supervisor 和七个专家(侦察员、网站审计员、客户之声、人员查找器、技术栈扫描器、收入估算器以及一个负责整合的推销邮件撰写员)。每个专家都是一个加载到 CugaAgent 中的技能,Supervisor 通过一个自动生成的 `delegate_to_<name>` 工具来调用它。增加第八个专家只需一行工厂代码,而不是重写协调器。如果你想了解多智能体架构的完整形态,可以阅读它的 `main.py` 和 `ARCHITECTURE.md` 文件。
还有第三种扩展方式,它指向了技能本身。借助 CUGA 的在岗学习框架 ALTK-Evolve,智能体可以从自身的运行中优化一项技能,从而使今天完成的任务能让明天的工作更快、更准确。专家加载的 SKILL.md 最终会包含智能体在你编写内容的基础上学到的东西。同样的构建模块,只不过现在是用一个技能来教会下一个技能。你不再需要为上周已经解决过的问题反复调整提示词。
通过构建方式实现治理
治理机制在技术栈中的位置,决定了生产落地的故事走向。一个极简的智能体库会提供良好的基础构件,而将治理(策略、审批、审计、身份认证)留给你自行组装。CUGA 则选择了另一条路径:策略、人工介入审批、.cuga 状态文件夹以及自托管,从第一行代码起就是框架的一部分,而非后期添加的附加层。
这改变了将智能体投入生产时的工作方向。你无需为原本面向开放访问构建的系统事后加装管控;控制平面早已就位。受治理的路径是默认选项,而不受治理的快捷方式才是你需要主动选择加入的。因此,剩余的工作范围很窄:收紧少数几个真正接触外部世界的工具的沙箱,而不是围绕它们凭空发明一套治理机制。
同一个智能体的最终归宿
这就是回报,也是这一切如此构建的原因。由于框架小巧、开源、与模型无关且自带治理能力,你在笔记本电脑上编写的智能体,与在严格锁定环境中运行的智能体是同一个。你无需移植它,只需重新部署它。
这正是 IBM Sovereign Core 所依赖的基础,也是我们下一步对 CUGA 的演进方向。我们已另行撰文详述,但简而言之:Sovereign Core 在我们称之为“边界隔离”的架构下运行 CUGA 智能体——数据、控制平面和执行引擎位于同一逻辑边界内,智能体在租户自有工作区的临时隔离容器中运行。模型也在其中运行。部署默认使用完全气隙隔离运行在你基础设施内的 gpt-oss-120b 模型,工具仅通过每个工具单独审批的方式访问私有 VNET。每个推理步骤都会向租户内部的 Grafana Tempo 后端发出 OpenTelemetry 追踪信息,无任何遥测数据回传。没有任何数据离开这个边界。
智能体的定义本身无需改变;改变的是其周围的部署环境。而这一切之所以可能,是因为上述所有要素——能力、策略和模型选择——都存在于一个你可以读取的运行时中。这正是我们构建它时所押注的理念:当智能体的运行时是一个黑箱时,主权只是一句承诺;但当它是一段开放的代码时,主权就成了你可以验证的东西。你克隆的应用和你编写的智能体,都运行在同一个开放的运行时之上,这便是这一主张的根基。
不过,对开发者而言,其核心启示是独立成立的。一个智能体应用可以是一个你完全能掌握在脑海中的单一文件。你真正需要编写的,只有工具和提示词。这些应用是一个可供学习的库,而非一个封闭的演示。当风险升级时,治理机制已经内置于运行时之中——你无需为了安全而重建整个智能体。
后续步骤
克隆仓库并运行一个应用。托管的 MCP 服务器意味着你无需第三方密钥,只需一个 LLM 提供商即可。本文中的应用运行在开源权重的 gpt-oss-120b 模型上——该模型与托管演示画廊及我们的 Sovereign Core 部署所使用的模型相同——但由于模型切换仅需一行代码(`create_llm` 读取单个环境变量),你可以将任何应用指向 OpenAI、Anthropic、watsonx 或本地 Ollama 模型而无需修改代码,并且使用本地模型时完全没有 API 成本:
首先,请在此处查阅我们的快速入门指南。如果你想设置所有应用,请确保 Docker 正在运行,然后按照以下步骤操作。
git clone https://github.com/cuga-project/cuga-apps.git
cd build
cp .env.example .env
docker compose up --build
接着,打开 `apps/ibm_cloud_advisor/main.py` 并从头到尾通读一遍——这是内联工具加 MCP 模式最清晰的示例。修改系统提示词,添加一个工具,然后观察行为的变化。MCP 工具浏览器会列出所有托管工具,并提供一个可直接调用它们的表单,这是在将工具接入智能体之前快速检查底层连接的有效方式。
所以,试试看吧。运行 `pip install cuga`,克隆 `cuga-apps`,然后运行一个应用——或者先直接点击浏览在线演示画廊。该框架位于 `cuga-agent`,项目主页是 `cuga.dev`。如果遇到问题、应用出现异常,或者你有任何想法,我们都期待你的反馈:提交 issue、发起 PR、上传你自己的应用,或者直接联系我们——这个仓库就是为了不断扩充而建的,我们会阅读每一条收到的反馈。
资源
- cuga-apps — 本文中涉及的应用程序、MCP 服务器和用户界面
- cuga-apps/apps — 约二十余个精良的单文件智能体应用(内部目录;请从此处克隆)
- cuga-apps/mcp_servers — 共享的 MCP 服务器(涵盖网络、知识、地理、金融、代码、文本等),供各应用调用
- 实时应用展示 + MCP 工具浏览器 — 每个应用均配有启动按钮,另附表单可直接调用每个托管的 MCP 工具
- cuga-agent — CUGA 运行时与策略系统
- cuga.dev — CUGA 项目主页(pip install cuga)
- 开放设计:主权核心中的通用型与预构建智能体 — IBM 社区文章,阐述 CUGA 如何在 Sovereign Core 内运行(Srivastava、Marreed、Thomas,2026 年 4 月)
- IBM Sovereign Core — 产品页面