NVIDIA NOOA开源:Agent不是图不是链,是一个Python类
NVIDIA NOOA 开源:Agent 不是图不是链,是一个 Python 类
看完你会发现,你对「Agent 框架」的理解可能要更新了。
NVIDIA Labs 开源了 NOOA(NVIDIA Object-Oriented Agents)。核心宣言只有一句:Agent 不是图,不是链,也不是 YAML 流水线,而是一个 Python 类。
项目以 Apache 2.0 协议发布在 NVIDIA-NeMo/labs-OO-Agents,1,832 Stars,251 Forks,Python 实现。论文同步发布在 arXiv(2607.20709),并随 NVIDIA 牵头的 37 成员 Open Secure AI Alliance 一同亮相。
本文提纲
- 核心哲学:一切皆是 Python 对象
- 一个类搞定状态、能力和提示词
- MCP 支持:和 Claude Code 用同一套配置
- Skills 支持:SKILL.md 格式原生兼容
- 安全模型:OS 级隔离是唯一边界
- 内置 13 个 Skills 的完整生态
- 这件事的结构性意义
核心哲学:一切皆是 Python 对象
当前 Agent 框架的普遍做法:把 prompt、tool、callback、workflow 拆成不同的抽象层。LangChain 有 Chain、Agent、Tool、Memory 四层。LangGraph 有图节点和边。AutoGen 有对话代理。到处是配置文件、YAML 流水线、装饰器栈。
NOOA 砍掉了所有这些。一个 Agent 就是一个 Python 类:
from nooa import Agent
class SupportAgent(Agent):
"""You are a support agent."""
# State lives on the object. Fields are typed.
order_db: OrderDB
# Ordinary method. Just Python.
def is_refund_eligible(self, order: Order) -> bool:
return order.delivered and order.days_since_delivery <= 30
# Agentic method: the runtime hands this to an LLM.
async def triage(self, message: str, order: Order) -> Ticket:
"""Create a typed support ticket."""
...三个设计决策一图看懂:
| 元素 | 传统框架 | NOOA |
|---|---|---|
| 状态 | Memory 对象 / 配置 | 类的字段,带类型注解 |
| 能力 | Tool 定义 / 函数注册 | 类的方法,有真实函数体的是确定性逻辑 |
| 提示词 | Prompt template / 字符串拼接 | 方法的 docstring |
| 接口契约 | JSON Schema / Pydantic | Python 类型注解 |
| 工作流 | DAG / State machine / YAML | 方法调用链,就是 Python 控制流 |
关键细节:方法体是 ...(三个点)的方法变成 generation method——运行时由 LLM 驱动实现。有真实函数体的方法保持确定性 Python。你不用学一套新的 DSL,... 就是「这个方法交给模型」的信号。
一个类搞定状态、能力和提示词
再看那个 SupportAgent 的设计:
order_db: OrderDB——状态存在对象上,类型安全is_refund_eligible(self, order: Order) -> bool——确定性逻辑,纯 Python,不需要模型triage(self, message: str, order: Order) -> Ticket——...方法体,LLM 驱动的 agentic loop
模型通过 CodeAct 方式行动——在 Jupyter 风格的 REPL 中写 Python 代码,可以访问 self、import 和辅助函数。Python 方法和类型注解提供了可调用的接口,减少了对独立 tool-schema 定义的需求。
把方法名从 triage 改成 triage_urgently,输出就变了——方法名、参数、docstring 就是 prompt。
这意味着:你的代码结构就是你的 Agent 架构。不需要在代码和 Agent 配置之间来回切换,不需要维护两套真理。测试、tracing、重构、版本控制——全部复用 Python 工程师已有的工作流。
MCP 支持:和 Claude Code 用同一套配置
NOOA 原生支持 MCP(Model Context Protocol),而且配置格式和 Claude Code / VS Code 完全一致。
from nooa.mcp import MCPManager
class WikiAgent(Agent, llm=llm):
"""Agent with MCP tool access to an internal wiki."""
wiki = MCPManager.create_from_server("wiki", mcp_file=MCP_CONFIG)
async def respond(self, prompt: str) -> str:
"""Answer the user's question using the wiki search tool."""
...MCP 配置文件 .mcp.json:
{
"mcpServers": {
"wiki": {
"command": "python",
"args": ["examples/assets/wiki_mcp_server.py"],
"transport": "stdio"
}
}
}这个格式和 Claude Code 的 MCP 配置一模一样。这意味着:
- 已有的 MCP 生态可以直接用。 所有为 Claude Code 写的 MCP server,不需要改任何配置就能在 NOOA 里跑。
- MCP 工具变成 Python 对象属性。
self.wiki就是一个 MCP server 的代理——模型在 CodeAct 执行时可以直接调用self.wiki.search(...)。 - NOOA 的 MCP 实现很完整。 源码里
src/nooa/mcp/有四个核心文件:client.py(12KB)—— MCP 客户端连接管理tool.py(36KB)—— MCP 工具到 Agent 方法的映射oauth.py(41KB)—— 远程 MCP server 的 OAuth 认证- 完整的测试套件(7 个测试文件,包括 OAuth 发现、浏览器检测、工具刷新)
OAuth 支持意味着 NOOA 不仅能连本地 stdio MCP server,还能连需要认证的远程 MCP server——这是企业级部署的前提。
Skills 支持:SKILL.md 格式原生兼容
NOOA 的 Skills 系统使用和 Claude Code 完全一致的 SKILL.md 格式。
from nooa import TextSkill
class FrontendAgent(Agent, llm=llm):
"""Agent with a single file-based skill."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.frontend_design = TextSkill(path=ASSETS / "frontend-design")
async def respond(self, prompt: str) -> str:
"""Respond to a user message."""
...一个 Skill 就是一个目录 + 一个 SKILL.md 文件。TextSkill(path=...) 加载它,变成 Agent 的一个属性。模型在执行时可以访问这个属性,读取其中的知识。
还支持目录扫描自动加载:
class GenericAgent(Agent, llm=llm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for entry in sorted(ASSETS.iterdir()):
if entry.is_dir() and (entry / "SKILL.md").exists():
setattr(self, entry.name.replace("-", "_"), TextSkill(path=entry))扫一个目录下所有含 SKILL.md 的子目录,全部作为 Skill 加载。这意味着你可以维护一个 Skills 库,不同 Agent 按需加载不同的 Skill 组合。
源码里的 Skill 系统相当重——skill_registry.py 有 54KB,这是一个完整的 Skill 注册、路由和生命周期管理系统。配套的测试包括 test_skill_frontmatter.py、test_skill_registry.py(10KB)、test_skill_registry_extended.py(31KB),覆盖面很广。
安全模型:OS 级隔离是唯一边界
NOOA 对安全的态度非常明确,README 里用粗体标注:
The containment boundary is OS-level isolation.
NOOA 的 Agent 可以执行 LLM 生成的代码——通过 CodeAct 在 REPL 中写 Python。这意味着 Agent 可以 open() 任意文件、importlib 加载任意模块、通过反射访问系统的一切。NOOA 做了 AST 检查和模块黑名单,但明确说这只是 defense-in-depth,不是隔离边界。
真正的隔离边界是操作系统级——容器、VM 或 NVIDIA 自己的开源沙箱 OpenShell。这和 Docker Sandboxes 的思路完全一致:不要信任进程内的检查器,要信任 OS 级的隔离。
这个安全模型也是 NOOA 随 NVIDIA Open Secure AI Alliance 亮相的原因——安全是设计约束,不是事后补丁。
内置 13 个 Skills 的完整生态
NOOA 在 skills/ 目录里自带了 13 个 Skills,全部使用 SKILL.md 格式:
| Skill | 大小 | 用途 |
|---|---|---|
| nooa-agent-authoring | 14KB | 如何用 NOOA 编写 Agent |
| nooa-codeact-advanced | 15KB | CodeAct 高级用法 |
| nooa-agentdoc | 10KB | Agent 文档生成 |
| refine-agent-prompt | 10KB | 提示词优化 |
| nooa-middleware-hooks | 8KB | 中间件钩子 |
| nooa-capturing-traces | 7KB | 追踪捕获 |
| nooa-self-extending | 7KB | 自扩展 Agent |
| nooa-tools-and-skills | 7KB | 工具和技能指南 |
| nooa-trace-viewer | 7KB | 追踪查看器 |
| nooa-trace-explorer | 7KB | 追踪探索器 |
| nooa-channels | 6KB | 通道系统 |
| nooa-context-and-state | 6KB | 上下文与状态 |
| context-blocks | 6KB | 上下文块 |
这些 Skills 覆盖了 Agent 开发的全生命周期:从编写(authoring)、到调试(tracing)、到优化(refine-prompt)、到扩展(self-extending)。它们不仅是文档——它们是可被 Agent 自动加载和使用的知识包。
另外还有示例项目中的 Skills:grid-game-solver(ARC AGI 网格解题)、interactive-game-solver(交互式游戏解题)、frontend-design(前端设计),以及 memory 子系统里的 memory_skill。
这件事的结构性意义
第一,OOP 范式回归 Agent 领域。 过去两年,Agent 框架走了两条路:声明式(LangChain/LangGraph 的图和链)和配置式(YAML/JSON 定义的流水线)。NOOA 走了第三条路:面向对象。Agent 是类,状态是字段,能力是方法,提示词是 docstring。这不只是语法糖——它意味着 Agent 代码和业务代码共享同一套工程实践。
第二,MCP 和 Skills 的跨平台标准正在成型。 NOOA 的 MCP 配置格式和 Claude Code 一致,Skills 用同样的 SKILL.md 格式。加上 NOOA 同时支持 Anthropic、OpenAI、Ollama、vLLM 等所有 LiteLLM 支持的模型后端。这说明:MCP + SKILL.md 正在成为 Agent 生态的跨平台标准,就像 HTTP 之于 Web,npm 之于 JavaScript。
第三,NVIDIA 在 Agent 基础设施层的布局。 NOOA 不只是一个框架,是 NVIDIA 整个 AI 战略的一环:NeMo(训练)→ NeMo Deploy(部署)→ NOOA(Agent 编排)→ OpenShell(沙箱)→ Open Secure AI Alliance(安全标准)。从模型训练到 Agent 执行到安全隔离,全栈覆盖。
第四,「Agent 是 Python 类」降低了门槛。 不需要学 DSL、不需要理解图论、不需要写 YAML。如果你会写 Python 类,你就会写 Agent。这比 LangChain 的学习曲线低一个数量级。NVIDIA 的判断是:Agent 开发的民主化不靠降低模型能力,靠降低框架复杂度。
安装
uv init my-agent-project
cd my-agent-project
uv add nooa
# 可选子包
uv add nooa[cli,memory,bench]模型后端一行搞定:
from nooa.unifiedllm.registry import get_llm_client
llm = get_llm_client("claude-haiku-4-5") # Anthropic
llm = get_llm_client("gpt-5-mini") # OpenAI
llm = get_llm_client("ollama_chat/qwen3:1.7b") # Ollama 本地
llm = get_llm_client("hosted_vllm/Qwen/Qwen3-1.7B") # vLLM参考文档与链接
- GitHub: NVIDIA-NeMo/labs-OO-Agents - 1,832 stars,Python,Apache 2.0
- arXiv 论文 2607.20709 - 设计原理、harness 细节、SWE-bench / Terminal-Bench 2.0 结果
- NVIDIA 博客: Six Agent Harness Capabilities - 官方博文
- NVIDIA OpenShell - NVIDIA 开源沙箱,NOOA 的推荐隔离方案
- MCP 配置示例 - 与 Claude Code 格式一致
- 内置 Skills 目录 - 13 个 SKILL.md,覆盖 Agent 开发全生命周期
你用什么框架写 Agent?LangChain、LangGraph 还是 NOOA?评论区聊聊。觉得有用点个赞让更多人看到。
作者: itech001 来源: 公众号:AI人工智能时代 网站: https://www.theaiera.cn/ 每日分享最前沿的AI新闻资讯和技术研究。
本文首发于 AI人工智能时代,转载请注明出处。