NVIDIA Labs 将 AI Agent 抽象为普通 Python 类,有实体的方法自动成为 LLM 工具,`...` 空体由运行时 LLM 填充,文档字符串即 prompt,类型注解即契约。
本週 NVIDIA Labs 開源了 NOOA(NVIDIA Object-Oriented Agents),其宣傳點異乎尋常地簡潔:一個 agent 就是一個 Python 類。不是有向圖,不是 chain,不是 YAML 流水線。就是一個類。
我把它 clone 下來並當天就跑起來了。以下是它實際的樣子、哪些地方踩坑了,以及為什麼我認為這個核心理念比框架本身更重要。
一個代碼塊說清整個思路
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."""
...
以上來自倉庫的快速上手,稍作刪減。映射關係如下:
... 的方法在運行時由 LLM 循環實現不需要單獨的 tool-schema JSON,不需要註冊步驟。模型通過在一個可訪問 self 的 REPL 中編寫 Python 來執行操作,所以你的方法簽名就是工具定義。
安裝時的兩個坑
README 說 pip install nooa。我在乾淨機器上遇到了兩個問題:
pip install nooa 返回「No matching distribution found」。改用源碼安裝:git clone https://github.com/NVIDIA-NeMo/labs-OO-Agents.git
uv venv --python 3.13 && uv pip install ./labs-OO-Agents
>=3.12,<3.14。我默認的解釋器是 3.14,安裝會因為版本錯誤失敗。使用 3.12 或 3.13。此後一切導入都順利,定義一個帶生成方法的 Agent 子類也是一次成功(安裝的版本:0.0.1.dev1——這是早期軟件,表現也確實像早期軟件)。
這裡真正與眾不同之處
大多數 agent 框架要求你維護兩個平行世界:你的代碼,和你的代碼在 schema、prompt 模板、回調連線中的影子副本。每次重構都得做兩遍。
NOOA 的賭注是:語言本身已經具備 LLM 需要的所有元數據——簽名、類型、docstring——所以影子世界可以刪掉。你的 agent 像代碼一樣做 diff,像代碼一樣做測試,像代碼一樣做重構。mypy 和你的 IDE 能理解它,因為根本沒有別的東西需要理解。
還有一層策略值得了解:PredictStrategy(單次完成)vs CodeActStrategy(迭代代碼執行,由 max_iterations 控制),可通過裝飾器在每個方法層面切換。這是對「有些步驟需要一次 LLM 調用,有些需要一個循環」這個問題的簡潔回答,無需重構 agent。
NVIDIA 的論文聲稱一個 253 行的 NOOA agent 在 SWE-bench Verified 上達到 82.2%、在 CyberGym L1 上達到 86.8%。我沒有重現這些數字,你也不應該把廠商基準分數當真——但有趣的數字不是分數,而是代碼行數。
讓你神經緊繃的部分
NOOA agent 通過執行 LLM 生成的 Python 來行動。有了 self 的訪問權、import 權,以及你的進程能觸及的一切。NVIDIA 自己的文檔告訴你要在沙箱中運行 agent,他們是認真的——這本質上就是帶了幾步的 exec()。如果你不會從一個模型執行 curl | sh,那麼也不要在一個容器之外運行 NOOA agent。
我自己的偏見:我做 AI 產品,上一個產品最大的教訓是:質量來自於組合許多小的、可檢查的步驟——而不是信任一個大的端到端模型調用。多數 agent 框架都在對抗這種直覺:它們希望用 chain 和 graph 的詞彙來描述組合,而不是用你已經在用的語言。NOOA 是我見過的第一個組合就是 Python 的設計。這也是為什麼沙箱警告要加倍重視——當把 agent 接入真實系統變得如此無摩擦時,你交付一個的速度會比你審計它的速度更快。
今天:生產環境大概還不行。這是一個还没上 PyPI 的 0.0.1.dev1。
但我願意押注這個方向。我們花了兩年時間構建看起來像工作流引擎的 agent 框架,結果在每個實踐者都知道的方式上很脆弱。「編程語言就是 agent 定義語言」是我見過的第一個隨著 agent 變大而變得更簡單的框架。最壞的情況,NOOA 成為 agent 界的 CoffeeScript:東西本身消亡,但此後每個框架都抄走了這個想法。
examples 目錄是一個真正好的漸進式教程——從第一個生成方法到 MCP tools 的 11 個編號文件。從 03_codeact_tools.py 開始;這個文件讓我真正理解了這個設計。
你嘗試過把你的 agent 棧壓成純代碼嗎?我想聽聽它在哪裡失敗了。