Build 带来 AI Agent 新信号
Build real agentic apps using CUGA: two dozen working examples on a lightweight harness: Most agentic apps start with a week of plumbing before the agent does anything useful. You pick a framework, wire up a model client

正文
大多数 agentic 应用一开始都要先花一周时间搭管道,智能体才会真正做出有用的事。你要先选框架,接上模型客户端,编写工具适配器,搭建把状态流式传到 UI 的方式,而在这一切之中,你还得决定这个智能体到底是用来做什么的。最有意思的部分总是最后才到来。
CUGA 把这个顺序反了过来。它是 IBM 推出的开源智能体 harness,负责替你处理规划、执行循环、工具调用和状态管道。剩下的,才是真正属于你的部分:智能体可以访问哪些工具,以及你要让它做什么。为了展示这种体验在实践中是什么样子,我们构建了 cuga-apps:二十多个小型、可运行的应用,每个都是一个封装了单个 CugaAgent 的 FastAPI 文件,从电影推荐器到 IBM Cloud 架构顾问都有。它们的存在,就是为了被阅读和复制。你可以点击查看在线 gallery。
这篇文章会带你看其中一个,说明这个 harness 帮你卸掉了哪些工作,并展示当你需要把它纳入生产治理时,同一份代码会走向哪里。不需要先学一个新的框架。如果你写过 FastAPI 路由,就能读懂每一行。
对于这个领域里的任何东西,一个公平的问题都是:它替你省去了哪些要写的东西。CUGA 的答案是:模型周围那一层编排逻辑,而这正是你原本每次都得重新搭一遍的部分。
它会先规划,再行动,然后结合工具调用和生成代码(CodeAct)来执行。对于一个要跑二十步的长任务来说,最容易让大多数 agent 出问题的,是丢失中间结果,并在下一轮重新推导它们(而且往往是错的);CUGA 会保留这些状态,并运行一个反思步骤,既能发现错误调用,也能在继续向前冲之前重新规划。正是这套机制,让它在 AppWorld 和 WebArena 这类 agent 基准测试中登顶,而不是靠你手工调参。
你还可以通过配置而不是代码来设定成本/延迟的权衡:Fast、Balanced 和 Accurate 三种推理模式,代码则在你信任的任意沙箱执行环境里运行(本地、Docker/Podman,或 E2B 云端)。同一个 agent 定义,只是拨盘不同。这个拨盘的重要性,比听上去还要大。大多数 harness 默认底层有一个前沿模型,依赖它在计划跑偏时兜底;CUGA 则把这部分工作自己做了。规划、反思步骤、让长流程保持正轨的变量跟踪——这些都是 harness 在承担原本要由模型承担的负载,这也正是它能让更小的开源权重模型在通常撑不住的场景下顶住的原因。也因此,托管应用运行在 gpt-oss-120b 上,而不是某个前沿 API 上。通常的赌法是调用你能用到的最大模型;CUGA 的赌法则是,更小的开源模型就已经够用。
CUGA 的各个单独组件都不新鲜。不同之处在于,它们是预先组装好的,所以你配置它们,而不是把它们一一接线拼起来。你接触到的 API 很小——先用工具列表和提示词构建一个 CugaAgent,然后 await agent.invoke(...)。这条线以下的所有东西,都是 harness。
具体来说,这些都是可互换的工具(OpenAPI、MCP 和 LangChain functions 的绑定方式都一样),以及长周期规划能力——包含变量管理和自我纠正(这是 AppWorld 在 07/25 - 02/26 以及 WebArena 在 02/25 - 09/25 取得第 1 名背后的机制)——、声明式护栏、通过 A2A 进行的多智能体委派、由 Docling 驱动的 RAG,以及只需一个环境变量即可切换提供方(先 `pip install cuga`,然后在 OpenAI、watsonx、Ollama 等之间切换);这些东西要么你本来就得自己搭,要么至少得自己实现。这个名字的第一个词就点明了这一点:Configurable;难点都已经处理好了,所以你的工作就只是做任务本身。
下面是 IBM Cloud advisor —— 一个为架构推荐真实 IBM Cloud 服务的智能体。整个东西只放在一个文件里:一个包含智能体工厂、工具和提示词的 `main.py`,再加一个小型 UI。
四个参数。模型来自一个小型工厂(`create_llm`),它会根据环境变量与 OpenAI、Anthropic、watsonx、LiteLLM 或 Ollama 通信。应用代码里完全不知道背后接的是哪一个模型。`cuga_folder` 是这个应用保存状态和各类策略的地方。承载应用本身的两个参数是 `tools` 和 `special_instructions`。
这些工具把一个本地函数和一个托管函数混在了一起:
这里有一个模式,适用于每一个应用:MCP 工具和内联工具之间的分工。通用、无状态的能力来自共享的 MCP 服务器;`load_tools(["web"])` 会直接引入网络搜索,而不需要你自己托管任何东西。凡是这个应用特有的功能,都以内联方式定义成普通的 Python 函数,比如 `search_ibm_catalog`,它的 docstring 就是 agent 用来判断何时调用它的依据。你写下那个属于你的工具,剩下的就借用现成的。
云顾问的 prompt 会告诉 agent:在命名任何服务之前先搜索目录,推荐三到七个服务,并说明每个服务在设计中的作用,而且绝不能凭空编造服务名称。最后这一条尤其重要:让 agent 推荐根本不存在的 IBM Cloud 服务,比没有 agent 还糟,所以这个 prompt 强制每一次推荐都先经过目录查询。按步骤顺序写、并带有明确“不要瞎编”规则的 prompt 表现稳定;写成角色设定的 prompt 则容易跑偏。
这就是这个应用。一个工具,一个流程,四行构造函数。围绕它的 FastAPI 路由只是普通的 Web 代码:浏览器把问题提交到 `/ask`,实时面板则轮询 `/session/{thread_id}` 端点获取状态。这里没有数据库;状态是一个按 `thread_id` 划分的 Python dict,只能由 agent 通过自己的工具写入。agent 在运行中一旦调用工具,面板就会重新渲染。UI 不是逻辑的第二份副本;它只是 agent 修改后的状态视图。
有一个细节很容易被忽略,但后来证明至关重要:每个内联工具都返回同一个小型封装。成功时是 `{"ok": true, "data": {...}}`;失败时是 `{"ok": false, "code": "...", "error": "..."}`。
这看起来像模板化措辞。其实不是。CUGA 的规划器能优雅地处理已声明的失败(“地理编码没有返回任何结果,跳过这一部分,继续执行”),却会在未声明的失败面前卡住:原始堆栈跟踪会在规划过程中间冒出来,把整个运行带偏。放眼这些应用,真正稳定工作的,都是那些工具从不向 agent 抛出裸异常的。这个约定看似平淡,却决定了一个 agent 是能恢复,还是会直接翻车。
上面的这种拆分之所以有意义,是因为通用那一半本来就在某处运行着。那些应用反复调用的能力——Web 搜索、Wikipedia/arXiv、地理编码和天气、金融报价,以及少量其他工具——都位于 7 个公开的 MCP 服务器中,共 36 个工具,托管在 IBM Code Engine 上,无需认证。一个小型桥接层会自动解析这些服务器的 URL,而在线展示页还提供了一个 MCP Tool Explorer,可以先通过表单调用其中任意工具,再把它接入 agent。
二十多个经过打磨的应用之所以存在,意义甚至大于任何单个应用:读完 cloud advisor 之后,你其实也就读完了它们全部。它们共享同一套骨架——电影推荐器把 IBM catalog 工具换成了 knowledge MCP server,web researcher 则几乎完全依赖 web——所以 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 驱动 headless Chromium,从 Meetup、Luma 和 Eventbrite 抓取结构化事件数据——这些平台都关闭了公开搜索 API;打开它可以看浏览器自动化,这也是 CUGA 的起点,以及它在 WebArena 上表现出色的底层能力。
克隆之前有两个注意事项。真实的目录在内层的 `cuga-apps/cuga-apps/apps/` 目录里,不是在外层那个。并且并不是每个应用都同样精致,所以 UI 把它们标成“showcase”或“additional apps”,并默认显示“showcase”;如果想找一个能直接跑起来的基线,可以从 cloud advisor 或 movie recommender 开始。
一个会搜索目录的演示智能体风险很低。把同样的模式用到会写文件、执行 shell 命令,或者接触生产环境的场景里,问题就变了:你要怎么阻止它做出让你后悔的事?
CUGA 把这个问题解决在运行时,而不是事后再套一层包装。这个开源智能体自带一套策略系统,你可以把策略附加到同一个 agent 对象上:
那就是 Intent Guard,它是六种策略类型之一;每一种都在团队放手让 agent 自主运行之前,回答一个问题:
Intent Guard——它能不能直接拒绝一个请求?
Tool Approval——在高风险工具运行之前,它能不能先暂停,等人类确认?
Tool Guide——我能不能不改写工具本身,就引导某个特定工具的使用方式?
Playbook——我能否为一个重复执行的任务固定一套已知可用的流程?
Output Formatter——我能否强制最终回复呈现为指定格式?
第六种类型是 CustomPolicy,当前面那些都不适用时,它就是兜底方案。把握好生效时机很重要,因为它并不是单一阶段:Intent Guard 会在 agent 选择工具之前检查请求,Tool Approval 会在 agent 生成代码之后运行,并检查这段代码使用了哪些工具,而 Output Formatter 只会在最终消息已经生成后才触发。触发条件也不只是关键词匹配:它们存放在 sqlite-vec 中,并通过语义方式匹配,因此一项 policy 触发的是用户的意图,而不只是某个精确关键词。可以基于语义相似度、agent 状态,或者某个特定工具是否被触发来匹配。policy 本身则存放在构造函数里那个 .cuga 文件夹中,随代码一并版本化,而不是漂移到单独的配置里。
要看一个可运行的示例,可以打开 Ouroboros——一个七 agent 的获客应用,它把三项 policy(intent guard、tool guide 和 output formatter)附加到它的 supervisor 上,因此它是唯一一个在同一个文件里同时演示治理能力和多 agent 形态的应用。
当应用不再能靠单一聊天循环撑住时,就会出现两种重要的扩展方式。若一个 agent 被自己的上下文淹没——工具太多、证据太多,根本理不清——就把工作拆开。CugaSupervisor 会把任务委派给专门的 CugaAgent,每个 agent 都有自己的工具、提示词和隔离上下文,而 supervisor 只需要判断该把子任务交给哪一个专长 agent。无论底下挂着多少工具,它的规划面都保持很小;一个不稳定的工具也只会让一次委派失败,而不会拖垮整个运行。专长 agent 甚至不必是本地的;它也可以是通过 A2A 访问的外部 agent,并以同样的方式被委派。新增一种能力,意味着增加一个专长 agent,而不是重写一个协调器。
另一种扩展方式打包的是经验,而不是工具:Agent Skills。它是一个包含 SKILL.md 作战手册的文件夹,agent 只有在任务需要时才把这份手册拉进上下文,因此一个提示词不必承载 agent 未来可能需要知道的全部内容。两者保留的都是同一套构件——工具、提示词、状态、策略——只是把它们提升到更高一层来组合。
前面提到的 lead-gen 应用 Ouroboros 把这种模式具体化了。它在七个专长 agent 之上设置了一个 supervisor,分别是 scout、site auditor、voice-of-customer、person finder、stack scanner、revenue estimator,以及负责综合生成的 pitch-email writer。每个专长 agent 都是加载进 CugaAgent 的一个 skill,supervisor 则通过自动生成的 delegate_to_ 工具来调用它。再增加第八个,只需要一行 factory 代码,不必重写协调器。如果你想完整看一遍这种多 agent 结构,可以读它的 `main.py` 和 `ARCHITECTURE.md`。
还有第三个扩展方向,而且它指回了这些技能本身。借助 ALTK-Evolve,这套 CUGA 的在岗学习框架,智能体会根据自己的运行结果去打磨技能,让今天完成过的任务在明天变得更快、更准确。某个 specialist 加载的 `SKILL.md`,最终承载的就是智能体在你写入内容之上学到的东西。底层构件还是那些,只不过现在,使用一次就会为下一次铺路。你不再需要对上周已经解决过的问题反复重新提示。
治理放在技术栈里的哪个位置,会决定生产环境的故事怎么展开。一个最小化的 agent 库,只会给你基础原语,把治理——策略、审批、审计、身份——留给你自己去组装。CUGA 走的是另一条路:策略、人类在回路审批、`.cuga` 状态目录,以及自托管,从第一行开始就是 harness 的一部分,而不是后面再补上的一层。
当你把智能体推进生产环境时,这会改变工作的方向。你不是在给一个为开放访问而构建的东西后补控制措施;控制平面本来就已经在那里了。受治理的路径是默认选项,而那些不受治理的捷径,才是你需要主动选择的。剩下的工作就很明确了:把 sandbox 收紧到真正会接触外部世界的那几个工具上,而不是围绕它们重新发明治理机制。
这就是回报,也是这一切之所以这样设计的原因。因为这个 harness 足够小、开源、与模型无关,而且已经能自我治理,所以你在笔记本电脑上写出来的智能体,和运行在受严格锁定部署中的智能体是同一个。你不需要迁移它。你只需要重新部署它。
这正是 IBM Sovereign Core 的基础,也是我们将 CUGA 继续推进的地方。我们已经单独写过这些细节,但简要来说:Sovereign Core 通过我们称为 Boundary Isolation 的方式运行 CUGA agent:数据、控制平面和执行引擎都处于同一个逻辑边界内,而 agent 则运行在租户自身 workspace 中临时、隔离的容器里。模型也在这里运行。部署默认使用在你自己的基础设施内完全 air-gapped 运行的 gpt-oss-120b,工具只能访问私有 VNETs,并且每个工具都需要单独批准。每一步推理都会把 OpenTelemetry traces 发到仍留在租户内的 Grafana Tempo backend,不会有任何 telemetry 回传。没有任何东西会离开这个边界。
agent 的定义本身并没有改变;改变的是围绕它的部署。而之所以能够这样,是因为上面这些内容——能力、策略和模型选择——都运行在一个你可以读懂的 runtime 里。我们在构建它时押注的就是这一点:当 agent 的 runtime 是黑箱时,主权只是一个承诺;但当它是开源代码时,主权就是你可以核查的东西。你克隆下来的 apps 和你编写的 agent,依托的都是同一个开源 runtime,而这正是这种主张成立的基础。
不过,对开发者的启示本身就已经成立。一个 agentic app 可以只是一个你能在脑子里完整记住的单文件。你真正需要写的,只有 tools 和 prompt。这里的 apps 更像是一个可供学习的 library,而不是一个封闭的 demo。并且当风险变高时,治理能力已经内置在 runtime 里——你不需要为了安全而重写 agent。
克隆这个 repo,然后运行一个 app。由于托管的 MCP servers 已经准备好,你不需要第三方密钥,只需要一个 LLM provider。本文中的 apps 运行在开源权重的 gpt-oss-120b 上——这也是托管 gallery 和我们的 Sovereign Core 部署所使用的同一个模型——但由于这个模型只需要一行替换(create_llm 读取一个环境变量),你可以在不改任何代码的情况下,把任何 app 指向 OpenAI、Anthropic、watsonx,或本地的 Ollama 模型;如果使用本地模型,则完全没有 API 成本:
先从这里的《快速开始指南》入手。如果你想把所有应用都搭起来,先确保 Docker 已经运行,然后按照下面的步骤操作。
然后打开 `apps/ibm_cloud_advisor/main.py`,从头到尾读一遍——这是理解“内联工具 + MCP”模式最清晰的示例。改一下 system prompt,新增一个工具,再观察行为如何变化。MCP Tool Explorer 会列出每一个托管工具,并提供一个表单可直接调用它,这是在把工具接入 agent 之前,快速检查整套链路是否正常的好办法。
所以不妨试试。`pip install cuga`,克隆 `cuga-apps`,然后运行一个应用——或者先直接点开在线 gallery 看看。`harness` 在 `cuga-agent`,项目主页是 `cuga.dev`。如果哪里出了问题、某个应用表现异常,或者你有任何想法,我们都希望听到:欢迎提 issue、提交 PR、加入你自己的应用,或者直接联系我——这个仓库本来就是为持续添加内容而设计的,我们会阅读收到的每一条反馈。
`cuga-apps` —— 本文中的应用、MCP servers 和 UI
cuga-apps/apps —— 这两打经过打磨的单文件 agent 应用(内部目录;从这里克隆)
cuga-apps/mcp_servers —— 应用所借用的共享 MCP 服务器(web、knowledge、geo、finance、code、text,等等)
实时应用画廊 + MCP Tool Explorer —— 每个应用都带有一个启动按钮,另有一个表单可直接调用每个托管的 MCP 工具
cuga-agent —— CUGA 运行时和策略系统
cuga.dev —— CUGA 项目主页(`pip install cuga`)
Open by Design:Sovereign Core 中的通用型与预构建智能体——IBM Community 上关于 CUGA 如何在 Sovereign Core 内运行的文章(Srivastava、Marreed、Thomas,2026年4月)
IBM Sovereign Core —— 产品页面
Sovereign、开放、自学习智能体:`https://github.com/cuga-project/cuga-agent`。我们期待与大家合作,也欢迎你的贡献,共同推动开放智能体社区向前发展。
· 注册或登录后发表评论
AI解读
这是一条雷达解读:它可能反映 AI 产品、开发者工具、模型基础设施或研究方向的新变化。
对开发者来说,可以作为后续选题、产品观察或技术调研的线索。
建议打开原文核对细节,并观察是否有同类信号在其他来源重复出现。