返回博客列表

NVIDIA NOOA开源:Agent不是图不是链,是一个Python类

2026-08-15T03:00:00+08:00
NVIDIANOOAAgentPythonMCPSkillsOOPNeMo

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 一同亮相。

本文提纲

  1. 核心哲学:一切皆是 Python 对象
  2. 一个类搞定状态、能力和提示词
  3. MCP 支持:和 Claude Code 用同一套配置
  4. Skills 支持:SKILL.md 格式原生兼容
  5. 安全模型:OS 级隔离是唯一边界
  6. 内置 13 个 Skills 的完整生态
  7. 这件事的结构性意义

核心哲学:一切皆是 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 配置一模一样。这意味着:

  1. 已有的 MCP 生态可以直接用。 所有为 Claude Code 写的 MCP server,不需要改任何配置就能在 NOOA 里跑。
  2. MCP 工具变成 Python 对象属性。 self.wiki 就是一个 MCP server 的代理——模型在 CodeAct 执行时可以直接调用 self.wiki.search(...)
  3. 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.pytest_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

参考文档与链接

你用什么框架写 Agent?LangChain、LangGraph 还是 NOOA?评论区聊聊。觉得有用点个赞让更多人看到。


作者: itech001 来源: 公众号:AI人工智能时代 网站: https://www.theaiera.cn/ 每日分享最前沿的AI新闻资讯和技术研究。

本文首发于 AI人工智能时代,转载请注明出处。

分享给朋友