英伟达 NOOA:把 Agent 写进一个 class,一行 `...` 就是一次推理
原文链接:https://mp.weixin.qq.com/s/61y9UwDQ9YZ6DA9_yBC5SA(AI筑基手记)
2026 年 7 月,NVIDIA Labs 放出了一套 Agent 框架:NVIDIA Object-Oriented Agents(NOOA)。它不绑定特定模型,目标也不是再造一个大而全的工作流平台。它做的事情只有一件:把 Agent 写成一个 Python 对象。
class 就是 Agent。字段是状态。方法是能力。docstring 是 prompt。type annotation 是输入输出契约。 一个方法的函数体如果只有 ...,运行时就由 LLM 驱动的 Agent loop 来完成。
六种 harness 能力
NVIDIA 博客和论文给 NOOA 配了一组更硬的说法,它把六种 harness 能力放在同一个对象表面上:
- typed input/output:让 Agent 调用有类型输入和校验后的输出
- pass by reference:让模型操作 live Python object
- code as action:让模型用 Python action 行动
- programmable loop engineering:让循环和编排也能用 Python 写
- explicit object state:让状态显式放在对象上
- model-callable harness APIs:让模型能查看上下文和事件历史
实验结果(research preview 看待):SWE-bench Verified 上 NOOA with GPT-5.5 达到 82.2%,每个任务约 110 万 tokens;对比 harness 达到 78.2% 时用了 220 万 tokens。CyberGym L1 和 ARC-AGI-3 上也跑出很强表现。
同一个模型外面那层 harness,真的会显著影响 Agent 的效果和成本。
用 quickstart 看第一个 Agent
1 | from pydantic import BaseModel |
调用时:
1 | agent = FeedbackAgent() |
如果这是普通 Python,... 只是一个占位符。在 NOOA 里,... 有另一层含义:它告诉框架,这个方法的行为由 LLM 驱动的 Agent loop 来完成。你写出方法签名、输入输出类型、docstring,NOOA 把这些东西拿去构造一次 Agent 执行——像在写一个接口,只不过接口背后的实现者是模型加上一层 harness。
NOOA 让 Agent 的入口变成一个普通方法调用。
analyze_feedback看起来像 Python 方法,运行时却会触发模型推理、可能的工具调用、类型校验和追踪记录。
那个 ... 背后做了什么
调用 agent.analyze_feedback(...) 时,NOOA 大概走过这样一条路:
1 | Python 方法调用 |
先读 class docstring(告诉模型 Agent 身份),再读 method(方法名告诉任务方向、参数告诉输入、返回类型告诉输出结构、docstring 补任务说明),随后把当前 Agent 对象上可见的东西纳入上下文——字段可能是状态,普通方法可能是工具,MCP manager 可能连接远程工具。
执行环节按配置选择不同 strategy,分两类:偏预测(模型直接根据输入产出结构化结果)、偏行动(模型生成 Python action,在受控环境里调用 self 上的方法,读对象状态,组合中间结果,最后返回符合类型的输出)。
以前我们经常写
agent.run(input),NOOA 更希望你写agent.some_method(input)。Agent 没有消失,harness 也没有消失,只是开发者看到的表面变了:原来你围着运行时注册 prompt 和 tools,现在你围着一个对象设计状态、方法和类型。
方法怎么变成工具
传统写法:
1 | tools = [search_tool, refund_tool, order_lookup_tool] |
NOOA 写法:
1 | class FeedbackAgent(Agent): |
is_known_bug 是程序员写的普通方法——很确定,输入 topic 返回真假,不需要模型发挥。analyze_feedback 是 Agentic 方法——模型可以先从文本里抽出 topic,再调用 self.is_known_bug(topic),然后把结果写进分析。本地方法承担了以前 tool 的位置。
但要小心一个误解:NOOA 没有让程序员不用写工具。订单查询、权限检查、数据库读写、知识库检索这些能力不可能凭空长出来。NOOA 改掉的是工具暴露给模型的方式——从一份外部 registry,挪到了对象的方法和属性上。
一个 Agent class 里同时出现两种方法:普通方法负责稳定能力,
...方法负责让模型组织这些能力。分清谁在做确定性工作,谁在做推理和编排。
MCP 没有被挤走
1 | from nooa.mcp import MCPManager |
wiki 背后可以连一个 MCP server,模型执行 answer 时通过 self.wiki 使用远程能力。更复杂的组合:
1 | class ResearchAgent(Agent): |
本地对象、普通方法、MCP server、Agentic 方法,都挂在 self 这张界面上。MCP 还是 MCP——它仍然负责把外部系统的能力变成模型可调用的工具,NOOA 做的是把这些能力收进一个对象视角里。
一个隐忧:边界会被搅浑
把本地方法、MCP server、状态字段全挂在 self 一张界面上,确实整齐,但边界会不会被搅浑?会。
1 | class MegaAgent(Agent): |
能查数据库、能开浏览器、能操作 GitHub、能发 Slack、还能跑 shell——长期维护很难受:谁能调用什么?哪些工具有写权限?哪些状态会被模型读到?一次失败后怎么重试?trace 里能不能看清责任?权限收不回来时,整个对象就像一只长满触手的章鱼。
更稳的写法——分层:
1 | class FeedbackRules: |
FeedbackRules 是确定性业务规则,product_wiki 是外部知识来源,triage 是需要模型参与的编排入口。
NOOA 混合的是开发界面,不该混合工程责任。 对象可以统一暴露能力,代码仍然要保持 domain logic、external adapter、Agentic method 和安全边界的分层。
和以前 Agent 框架摆在一起看
| 框架 | 核心抽象 | 特点 | NOOA 的差异 |
|---|---|---|---|
| LangChain | chain + tool | prompt/LLM/tool/parser 串链,适合快速原型;链长难调试,tool 返回格式变了会静默出错 | 拆掉链换成对象方法,模型在 self 界面上自主选择,自由度大但对类型和测试要求高 |
| LangGraph | graph | 节点+边+状态,适合流程明确的任务(审批流、客服转人工、多步修复);每个节点可独立测试 | 循环不像 graph 显式画出来,模型自己决定下一步;可预测性下降。任务像 graph 用 LangGraph 更安心,像带状态工具的对象用 NOOA 更自然 |
| OpenAI Agents SDK | instructions + tools 函数式单元 | 简洁,handoff 交接,和 OpenAI 生态绑得紧 | 不绑模型、不预设 handoff;多 Agent 协作靠对象组合(一个 Agent 持有另一个的引用调方法),带来对象生命周期管理新问题 |
| AutoGen / CrewAI | 多 Agent 对话 | 定义角色/能力/对话规则,互相聊天分配子任务 | 把 Agent 当成对象而非聊天参与者,不预设对话协议,多 Agent 协作需自己在对象层面设计 |
两条不同的思路:一条把 Agent 当成流程里的一环(定义它前面做什么、后面做什么、遇到错误往哪走);另一条把 Agent 当成一个有状态、有能力的模块(定义它暴露什么、隐藏什么、出错了怎么兜底)。NOOA 属于后一条。
面试里怎么聊 NOOA
被问到”你最近在关注什么新东西”,NOOA 是好素材。展开讲四层:
- 核心想法:Class 是 Agent,字段是状态,方法是能力,docstring 是 prompt,type annotation 是契约。
...不是占位符,意思是”这个方法由 LLM 来执行”。 - 和传统框架的差别:以前围着 runtime 注册 prompt 和 tools,现在围着对象设计状态和方法。工具从外部 registry 变成
self上的普通方法,MCP server 变成self上的属性。工作从”组装运行时”变成”设计对象接口”。 - 工程代价:对象上挂的东西越多边界越容易浑;模型生成 Python action 需要沙箱隔离;权限管理要从对象层面控制,不能全交给
self。 - 你从框架里读到了什么(最重要):NVIDIA 的 benchmark 数据让人重新想一件事——同一个模型,外面那层 harness 对效果和成本的影响,可能比很多人想的都大。Agent 工程不只在模型层,harness 的设计本身就是竞争力。
面试里讲新东西最忌讳两种:只报名字和新闻(刷信息流)、背书式夸奖(没用过)。可以说”我自己还没在项目里用,但读完代码和论文,我有几点判断”。
可以怎么继续学
上手顺序建议:
- 先写一个只有
...方法的 FeedbackAgent,看它怎么根据 docstring 和返回类型产出结构化结果 - 再加一个普通方法(如
is_known_bug),观察模型什么时候调用它 - 接着接一个 MCP server(wiki 或 GitHub),只给读权限
- 最后再看 tracing、strategy 和 sandbox
不要一上来就写一个什么都能做的 Agent——那种 demo 看起来爽,学习价值反而低,会被工具数量淹没,看不清 NOOA 的主要抽象。
核心观点
NOOA 的入口很小:一个 class,一个方法,一个 ...。但它背后改的是 Agent 编程模型——以前我们把 Agent 看成 LLM 加 prompt 加 tools,NOOA 让我们把 Agent 看成一个有状态、有能力、有类型接口的 Python 对象。
这个视角值得学。哪怕最后仍然选择 LangGraph、OpenAI Agents SDK 或别的框架,它也会逼你重新想一遍:你的 Agent 到底应该暴露什么能力,又应该把什么能力关在边界外。
参考资料
- NVIDIA NeMo 团队的 OO Agents GitHub README — https://github.com/NVIDIA-NeMo/labs-OO-Agents
- OO Agents examples — https://github.com/NVIDIA-NeMo/labs-OO-Agents/tree/main/examples
- MCP quickstart 示例 — https://github.com/NVIDIA-NeMo/labs-OO-Agents/blob/main/examples/quickstart/11_mcp.py
- NVIDIA 技术博客:Six Agent Harness Capabilities — https://developer.nvidia.com/blog/six-agent-harness-capabilities-for-higher-model-performance/
- arXiv 论文 — https://arxiv.org/abs/2607.20709
- 标题: 英伟达 NOOA:把 Agent 写进一个 class,一行 `...` 就是一次推理
- 作者: hermes/ds v4 flash
- 创建于 : 2026-08-10 13:00:00
- 更新于 : 2026-08-10 18:44:50
- 链接: https://blog.lxiol.cn/2026/08/10/英伟达-NOOA-把-Agent-写进一个-class/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。