还在手写 Agent 框架?NVIDIA NOOA 把 Agent 写成 Python 类:记忆=字段、工具=方法、指令=docstring

还在手写 Agent 框架?NVIDIA NOOA 把 Agent 写成 Python 类:记忆=字段、工具=方法、指令=docstring 封面

如果你写过 AI Agent,一定经历过这种崩溃:

提示词在一个 YAML 文件里,工具定义在另一个 JSON schema 里,流程图在第三个文件里画成有向图,回调函数散落在第四处。改一个字段名,你得在三种文件格式里做全局替换。想设个断点?对不起,YAML 的边上打不了断点。

NVIDIA 昨天开源的 NOOA,一句话干掉了这一切:

一个 Agent,就是一个 Python 类。

方法就是它能做的动作,字段就是它的状态,文档字符串就是提示词,类型注解就是运行时强制执行的契约。没有单独的工具注册,没有提示词模板字典,没有 schema 声明。类定义本身,就是 Agent 规格说明书。

Apache 2.0 协议,pip install nooa 一行装完。这篇我带你从装到跑通,把这个思路彻底讲明白。

第一章 核心思想:你的 Agent 本来就该是个类

NOOA 全称 NVIDIA Object-Oriented Agents(对象导向智能体)。它的中心论点很朴素但很扎心:Agent 的每一个组成部分,Python 类里本来就有对应物。

对照表长这样:

  • Agent 能做什么 → 类的方法
  • Agent 的记忆和状态 → 实例字段
  • 给模型的指令 → docstring 文档字符串
  • 输入输出契约 → 类型注解(运行时真校验,不是摆设)

这不只是审美问题,是实打实的工程收益。当你的 Agent 就是一个普通 Python 对象,你就能用 pytest 测它、用 mypy 检查它、用 git blame 追责、用 IDE 跳转定义。整套 Python 工具链原封不动全能用。

对比一下图式框架:在 LangGraph 这类框架里,Agent 是”数据”——节点、边、穿针引线的状态对象,加上另外存放的提示词模板和工具 schema。当控制流本身很复杂、你想可视化时,这确实有价值。但代价是你的 Agent 不再是代码,于是你所有的程序员直觉都失效了。

第二章 两种方法:让模型写的,和你自己写的

这是 NOOA 最妙的设计,也是你必须一次记牢的规则。

生成式方法(GENERATION):函数体只写三个点 ...。运行时由 LLM 驱动的循环来实现它。它的签名 + docstring 就是提示词,返回类型会被自动校验。

确定性方法(DETERMINISTIC):正常的 Python 代码,你自己写。用来放那些绝对不能交给模型决定的逻辑——花钱上限、资格校验、数据库写入。

看一段真实代码你就懂了:

from nooa import Agent

class CodeReviewer(Agent):
  """你是资深 Python 代码审查员。关注正确性、性能、安全、可读性。
  永远解释为什么这是问题,而不只是说它是问题。"""

  recent_files: list[str] = []
  severity_threshold: str = "medium"

  def review_file(self, path: str, content: str) -> str:
    """审查单个 Python 文件,返回结构化反馈。"""
    ...

  def check_security(self, code: str) -> list[str]:
    """扫描常见安全漏洞,返回问题列表。"""
    ...

看明白了吗?类的 docstring 变成系统提示词,方法的 docstring 变成工具描述,类型注解变成运行时校验,实例字段变成跨调用持久的状态。整个 Agent 规格,就这一段。

第三章 三分钟跑起来:安装到第一次 run

环境要求先说清楚:Python 3.12–3.13,版本不对直接装不上。

第一步 安装pip install nooa(或 uv add nooa)。当前版本 v0.0.8,PyPI 上标注为 alpha,NVIDIA 自己定位是研究预览版

第二步 写类:继承 Agent,写生成式方法(... 体)和确定性方法(正常代码体)。

第三步 跑:它是异步的,用 asyncio。

import asyncio
from nooa import Agent

class ResearchAgent(Agent):
  """你是技术研究 Agent。被问到某个话题时,搜索最新信息、批判性分析、给出关键发现和你自己的判断。"""
  sources_consulted: list[str] = []

  def search_web(self, query: str) -> str:
    """搜索某个话题的最新信息。"""
    ...

async def main():
  agent = ResearchAgent(model="claude-opus-5")
  result = await agent.run("NOOA 和 LangGraph 的核心差异是什么?")
  print(result)

asyncio.run(main())

模型随便换:通过 LiteLLM 接入,Claude、GPT、Gemini、本地 Ollama、自托管 vLLM,同一套代码全都能跑。名字带 NVIDIA,但它不绑 GPU、不绑任何厂商。

两种执行策略:Sync 同步调度像函数调用,Async 异步并发像生产流水线
两种执行策略:Sync 同步调度像函数调用,Async 异步并发像生产流水线

第四章 两种执行策略与那个”扔掉压缩”的记忆

NOOA 内置两种执行策略,用途完全不同。

PredictStrategy:单次带类型的 LLM 调用,校验失败就本地重试。适合结构化抽取、分类这类”一问一答”的活。

CodeActStrategy:跑一个迭代式的 Python REPL,模型不断调用 execute_python(...),直到提交 return_result(...),返回值按注解校验。适合需要多步探索的复杂任务。

但真正让长任务 Agent 开发者眼前一亮的,是 nooa[memory] 这个扩展。

它给 Agent 一个带类型的关系型 SQLite 存储,并且按引用传递活对象——运行时递给模型的是一个”句柄”,而不是把整个上下文重新序列化一遍。

这意味着什么?大部分长时运行 Agent 都得外挂的那套”上下文压缩 / 摘要”流水线,NOOA 声称可以直接扔掉。如果你被 context 爆炸折磨过,这一条的分量你懂。

跑分要看
跑分要看”相对增益”而非绝对排名:NOOA 强在让小模型组队逼近大模型

第五章 跑分怎么看:强,但别当排行榜

NVIDIA 公布的数字确实好看:

  • SWE-bench Verified:82.2%
  • CyberGym L1:86.8%
  • ARC-AGI-3 平均 RHAE:85.1%
  • 而且据称只用了对比开源框架约一半的 token

对一个 alpha 阶段的框架来说,这成绩很能打。NVIDIA 还把 LangGraph、Google ADK、PydanticAI、smolagents、Claude Agent SDK、OpenAI Codex、OpenHands 等 14 个框架放在同一套维度上打了分。

但请务必冷静。NOOA 是”外壳”(harness),不是模型。Agent 跑分永远是外壳和底层模型纠缠在一起的结果——换个模型,数字就变。SWE-bench Verified 尤其有个老毛病:任务来自热门开源项目,模型很可能见过。

更诚实的读法是:NOOA 靠 docstring 和类型注解把工具定义、提示词构造标准化了,减少了提示词的不一致性,所以结构化任务上更稳。它不是让模型变聪明了,是让你少犯错了。

真正该决定你选不选的,是你拿自己的任务、自己的模型跑出来的那个数。好在它就是普通 Python,这个测量成本低得离谱。

第六章 安全红线:这句话请抄十遍

NVIDIA 在 README 里写得非常直白,我原样搬给你:

AST 检查和模块黑名单,是纵深防御的护栏,不是隔离边界。

翻译成人话:NOOA 会执行 LLM 生成的代码。它内置的静态检查能挡住误伤,但挡不住一段主动想逃逸沙箱的代码。真正的隔离边界只有三个:容器、虚拟机,或者 NVIDIA OpenShell。

还有个更隐蔽的点:模型生成的代码跑在能触达 Agent 字段和方法的 REPL 上下文里。这既是它强大的原因(模型可以调用你写好的确定性方法,而不是自己蹩脚地重造一遍),也意味着爆炸半径 = 这个对象能碰到的一切。一个持有活数据库连接的类,就是一个连接随时可能被循环用掉的类。

实操建议,三条:

  1. 把对象暴露面收窄,别什么都往字段上挂。
  2. 不可逆操作全部放进确定性方法,写真实代码体,别让模型决定。
  3. 读 trace 再放宽权限。NOOA 内置追踪,每次模型调用、每次代码执行都默认记录——这是它比很多框架厚道的地方。

第七章 该不该现在上:一份取舍清单

适合现在就试的:

  • AI 原生创业团队、中型平台团队做内部 Agent
  • 企业 AI 平台组、应用研究组做评估和试点
  • 典型场景:代码仓库 issue 分诊与修补、终端与基础设施自动化、漏洞验证流水线、大批量分类抽取、带类型的多 Agent 编排

建议再等等的:

  • 受监管的生产负载——等稳定版,v0.0.x 就是 v0.0.x
  • 真正复杂的分支多步工作流——这种场景图式框架仍然更合适,类继承结构反而是劣势,NOOA 没有让这个问题消失
  • 只想最快出个 Demo——那用编排框架更快,NOOA 的价值在”能测、能追、能辩护”

最后说个我很在意的信号:NVIDIA 把这个项目贡献给了开放安全 AI 联盟(Open Secure AI Alliance),源码在 GitHub 上的 NVIDIA-NeMo/labs-OO-Agents,Apache 2.0。至少姿态上,它不想只做一个 NVIDIA 家的框架。

Agent 框架这两年出了太多,每一个都说自己解决了复杂度问题,然后每一个都变成新的调试摩擦源。NOOA 换了个思路:不在 Python 之上再造一层框架,而是让 Python 类本身成为框架。

这个赌注对不对,一年后看提交记录。但今天这个想法本身,值得每一个写过 Agent 的人认真想十分钟。

© 版权声明
THE END
喜欢就支持一下吧
点赞133 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容