NVIDIA's NOOA turns an AI agent into one Python class
NVIDIA’s NOOA turns an AI agent into one Python class
NVIDIA 的 NOOA 将 AI Agent 简化为一个 Python 类
NVIDIA Labs open-sourced NOOA (NVIDIA Object-Oriented Agents) this week, and the pitch is unusually simple: an agent is a Python class. Not a graph, not a chain, not a YAML pipeline. A class. I cloned it and got it running the same day. Here’s what it actually looks like, what broke, and why I think the core idea matters more than the framework itself.
NVIDIA Labs 本周开源了 NOOA (NVIDIA Object-Oriented Agents),其核心理念异常简洁:一个 Agent 就是一个 Python 类。不是图(Graph),不是链(Chain),也不是 YAML 流水线。就是一个类。我克隆了代码并在当天就运行了起来。以下是它的实际样貌、我遇到的问题,以及为什么我认为这个核心理念比框架本身更重要。
The whole idea in one code block: 整个理念可以用一个代码块概括:
from nooa import Agent
class InventoryAgent(Agent, llm=llm):
"""You are an agent that checks inventory using deterministic helper methods."""
# Plain Python — automatically available as a tool for the LLM
def get_stock(self, item: str) -> int:
"""Get current stock for an item."""
return self.inventory.get(item, {}).get("stock", 0)
# `...` body — the LLM implements this at runtime, calling the methods above
async def can_fulfill_order(self, items: list[str], budget: float) -> Result:
"""Check if order can be fulfilled within budget."""
...
That’s from the repo’s quickstart, lightly trimmed. The mapping is: Fields are agent state Methods with real bodies are deterministic tools Methods with … bodies are implemented by an LLM loop at runtime Docstrings are the prompts Type annotations are contracts the runtime enforces, with auto-retry on mismatch
以上代码摘自仓库的快速入门指南,经过了精简。其映射关系如下:
字段(Fields)即 Agent 的状态;
带有具体实现的方法是确定性的工具;
带有 ... 的方法在运行时由 LLM 循环实现;
文档字符串(Docstrings)即提示词(Prompts);
类型注解(Type annotations)是运行时强制执行的契约,若不匹配会自动重试。
No separate tool-schema JSON. No registration step. The model acts by writing Python in a REPL with access to self, so your method signatures are the tool definitions.
没有单独的工具模式 JSON,也没有注册步骤。模型通过在 REPL 中编写 Python 代码来执行操作,并能访问 self,因此你的方法签名就是工具定义。
Two install gotchas before you try it
在尝试之前,有两个安装上的坑
The README says pip install nooa. Two things I hit on a clean machine:
- It’s not on PyPI yet. As of today,
pip install nooareturns “No matching distribution found.” Install from source instead:git clone https://github.com/NVIDIA-NeMo/labs-OO-Agents.gituv venv --python 3.13 && uv pip install ./labs-OO-Agents - No Python 3.14 support. The package pins
>=3.12,<3.14. My default interpreter is 3.14, and the install fails with a version error. Use 3.12 or 3.13.
README 中写着 pip install nooa。但在干净的机器上我遇到了两个问题:
- 它尚未发布到 PyPI。截至今日,
pip install nooa会返回“找不到匹配的发行版”。请改为从源码安装:git clone https://github.com/NVIDIA-NeMo/labs-OO-Agents.gituv venv --python 3.13 && uv pip install ./labs-OO-Agents - 不支持 Python 3.14。该包限制版本为
>=3.12,<3.14。我的默认解释器是 3.14,安装会因版本错误而失败。请使用 3.12 或 3.13。
After that, everything imported cleanly and defining an Agent subclass with a generation method worked first try (version installed: 0.0.1.dev1 — this is early software, and it behaves like it).
之后,一切导入正常,定义一个带有生成方法的 Agent 子类也一次成功(安装版本为 0.0.1.dev1 —— 这是早期软件,表现也确实如此)。
What’s genuinely different here
这里真正与众不同的地方
Most agent frameworks make you maintain two parallel worlds: your code, and a shadow copy of your code described in schemas, prompt templates, and callback wiring. Every refactor has to happen twice. NOOA’s bet is that the language already has all the metadata an LLM needs — signatures, types, docstrings — so the shadow world can be deleted. Your agent diffs like code, tests like code, and refactors like code. mypy and your IDE understand it because there’s nothing else to understand.
大多数 Agent 框架让你维护两个平行的世界:你的代码,以及用模式、提示词模板和回调连线描述的代码影子副本。每次重构都得做两次。NOOA 的赌注是:编程语言本身已经包含了 LLM 所需的所有元数据(签名、类型、文档字符串),因此那个影子世界可以被删除。你的 Agent 像代码一样进行差异对比(diff)、测试和重构。mypy 和你的 IDE 都能理解它,因为没有其他复杂的东西需要理解。
There’s also a strategy layer worth knowing about: PredictStrategy (single completion) vs CodeActStrategy (iterative code execution, capped by max_iterations), swappable per method via a decorator. That’s a clean answer to “some steps need one LLM call, some need a loop” without restructuring the agent.
还有一个值得了解的策略层:PredictStrategy(单次补全)与 CodeActStrategy(迭代代码执行,受最大迭代次数限制),可以通过装饰器在每个方法上进行切换。这为“有些步骤需要一次 LLM 调用,有些需要循环”的问题提供了一个简洁的答案,而无需重构 Agent。
NVIDIA’s paper claims a 253-line NOOA agent hits 82.2% on SWE-bench Verified and 86.8% on CyberGym L1. I haven’t reproduced those numbers, and you shouldn’t take vendor benchmarks at face value — but the interesting claim isn’t the score, it’s the line count.
NVIDIA 的论文声称一个 253 行的 NOOA Agent 在 SWE-bench Verified 上达到了 82.2%,在 CyberGym L1 上达到了 86.8%。我没有复现这些数字,你也不应该盲目相信厂商的基准测试——但真正有趣的不是分数,而是代码行数。
The part that should make you nervous
让你感到不安的部分
A NOOA agent acts by executing LLM-generated Python. With access to self, imports, and whatever your process can reach. NVIDIA’s own docs tell you to run agents in a sandbox, and they mean it — this is exec() with extra steps, by design. If you wouldn’t run curl | sh from a model, don’t run NOOA agents outside a container either.
NOOA Agent 通过执行 LLM 生成的 Python 代码来运作。它拥有对 self、导入项以及你进程所能触及的一切的访问权限。NVIDIA 自己的文档也建议在沙箱中运行 Agent,他们是认真的——从设计上讲,这就是带有额外步骤的 exec()。如果你不会让模型运行 curl | sh,那么也请不要在容器外运行 NOOA Agent。
My own bias here: I build AI products, and the biggest lesson from my last one was that quality came from composing many small, checkable steps — not from trusting one big end-to-end model call. Most agent frameworks fight that instinct: they want the composition described in their vocabulary of chains and graphs instead of the language I already work in. NOOA is the first design I’ve seen where the composition just is Python. Which is also why the sandbox warning matters double — when wiring agents into real systems gets this frictionless, you’ll ship one faster than you audit it.
我个人的偏见是:我构建 AI 产品,从上一个产品中学到的最大教训是,质量来自于组合许多小的、可检查的步骤,而不是信任一个巨大的端到端模型调用。大多数 Agent 框架违背了这种直觉:它们希望用自己的链和图的词汇来描述组合,而不是用我已经在使用的语言。NOOA 是我见过的第一个将组合直接等同于 Python 的设计。这也是为什么沙箱警告加倍重要的原因——当将 Agent 接入真实系统的过程变得如此顺滑时,你发布它的速度会快过你审计它的速度。
Should you use it?
你应该使用它吗?
Today: probably not in production. It’s a 0.0.1.dev1 that isn’t on PyPI yet. But I’d bet on the direction. We spent two years building agent frameworks that look like workflow engines, and the results are brittle in ways every practitioner knows. “The programming language is the agent definition language” is the first framing I’ve seen that gets simpler as your agent gets bigger. Worst case, NOOA becomes the CoffeeScript of agents: the thing itself fades, but every framework after it steals the idea.
目前:可能不适合生产环境。它还是 0.0.1.dev1 版本,甚至还没上 PyPI。但我看好这个方向。我们花了两年时间构建看起来像工作流引擎的 Agent 框架,结果是每个从业者都知道的那种脆弱。这是我见过的第一个将“编程语言即 Agent 定义语言”作为核心框架的设计,它让 Agent 随着规模扩大反而变得更简单。最坏的情况是,NOOA 成为 Agent 界的 CoffeeScript:它本身可能会消失,但后续的每个框架都会借鉴它的理念。
The examples directory is a genuinely good progressive tutorial — 11 numbered files from first generation method to MCP tools. Start with 03_codeact_tools.py; it’s the one that made the design click for me.
示例目录是一个非常好的渐进式教程——从第一个生成方法到 MCP 工具,共有 11 个编号文件。从 03_codeact_tools.py 开始看吧;正是这一篇让我彻底理解了它的设计。
Have you tried collapsing your agent stack into plain code? I’d like to hear where it broke.
你尝试过将你的 Agent 栈简化为纯代码吗?我很想听听你在哪里遇到了问题。