Skip to main content

nvidia-oo-agents

Build AI agents using NVIDIA Object-Oriented Agents framework with Python classes, typed methods, and LLM-driven generation

Ir a la instalación

Datos de origen

Repositorio
reason-machines/ai-agent-skills
Última actividad en el origen
4 de agosto de 2026 a las 13:11
Idioma detectado de SKILL.md
inglés
Estrellas
1
Forks
1

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
nvidia-oo-agents
description
Build AI agents using NVIDIA Object-Oriented Agents framework with Python classes, typed methods, and LLM-driven generation
triggers
["create an AI agent with NVIDIA OO Agents","build a nooa agent with typed methods","use NVIDIA Object-Oriented Agents framework","implement generation methods in nooa","setup nooa agent with tools and state","add LLM-driven methods to Python agent","trace and debug nooa agent execution","create typed agent workflows with NVIDIA OO Agents"]
# NVIDIA Object-Oriented Agents (NOOA) > Skill by [ara.so](https://ara.so) — AI Agent Skills collection. NVIDIA Object-Oriented Agents (NOOA) is a model-agnostic Python framework for building reliable AI agents using standard object-oriented programming. Unlike traditional agent frameworks that separate prompts, tools, and workflows, NOOA unifies these concepts into Python classes where: - **Agents are Python objects** with typed fields (state) and methods (capabilities) - **Methods with `...` bodies** become LLM-driven generation methods - **Regular methods** remain deterministic Python code - **Type annotations** define contracts with automatic validation - **Docstrings** serve as prompts - **The LLM acts by writing Python code** in a REPL with access to `self` and imports ## Installation ### Core Framework ```bash # Using uv (recommended) uv add nooa # Using pip pip install nooa ``` ### Optional Packages ```bash # CLI tools and trace viewer uv add nooa-cli # or as extra: uv add "nooa[cli]" # Long-term memory subsystem uv add nooa-memory # or as extra: uv add "nooa[memory]" # Benchmarking tools uv add nooa-bench # or as extra: uv add "nooa[bench]" # Multiple extras at once uv add "nooa[cli,memory,bench]" ``` ### From Source ```bash # Latest development uv add "nooa @ git+https://github.com/NVIDIA-NeMo/labs-OO-Agents.git@main" # Pinned release uv add "nooa @ git+https://github.com/NVIDIA-NeMo/labs-OO-Agents.git@v0.0.7" ``` ## Safety Note **NOOA agents can execute LLM-generated code.** Always run in a sandboxed environment (container, VM, or [NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell)). Built-in AST validation and module deny-lists are defense-in-depth, not containment boundaries. ## Quick Start ### 1. Configure an LLM Client ```python from nooa.unifiedllm.registry import get_llm_client # Anthropic (requires ANTHROPIC_API_KEY env var) llm = get_llm_client("claude-haiku-4-5") # OpenAI (requires OPENAI_API_KEY env var) llm = get_llm_client("gpt-5-mini") # Local Ollama (no key required) llm = get_llm_client( "ollama_chat/qwen3:1.7b", api_base="http://localhost:11434" ) # Local vLLM (no key required) llm = get_llm_client( "hosted_vllm/Qwen/Qwen3-1.7B", api_base="http://localhost:8000/v1" ) ``` ### 2. Create Your First Agent ```python import asyncio from nooa import Agent class FeedbackAgent(Agent, llm=llm): """You are an agent specializing in analyzing customer feedback.""" async def analyze_feedback(self, text: str) -> str: """Analyze customer feedback for sentiment and key topics in one sentence.""" ... async def main(): agent = FeedbackAgent() result = await agent.analyze_feedback("Great product, but shipping was slow") print(result) asyncio.run(main()) ``` ## Core Concepts ### Generation Methods (LLM-Driven) Methods with `...` bodies are implemented by the LLM at runtime: ```python class SupportAgent(Agent, llm=llm): """You are a customer support agent.""" async def triage(self, message: str) -> str: """Classify this support message and suggest next steps.""" ... ``` The method name, parameters, return type, and docstring all contribute to the prompt. ### Deterministic Methods (Regular Python) Regular Python methods provide tools and logic: ```python from datetime import datetime, timedelta class OrderAgent(Agent, llm=llm): """You help manage customer orders.""" def is_refund_eligible(self, order_date: datetime) -> bool: """Check if order is within 30-day refund window.""" days_since = (datetime.now() - order_date).days return days_since <= 30 async def process_refund_request(self, order_id: str, order_date: datetime) -> str: """Decide whether to approve refund and explain why.""" ... ``` The LLM can call `self.is_refund_eligible()` when implementing `process_refund_request()`. ### Typed State Fields on the agent class hold state: ```python from dataclasses import dataclass from typing import List @dataclass class Order: id: str total: float delivered: bool days_since_delivery: int class SupportAgent(Agent, llm=llm): """You are a support agent with access to order database.""" order_db: dict[str, Order] # Typed state def get_order(self, order_id: str) -> Order | None: return self.order_db.get(order_id) async def handle_inquiry(self, order_id: str, question: str) -> str: """Answer customer question about their order.""" ... ``` ### Structured Output with Pydantic Use Pydantic models for typed, validated returns: ```python from pydantic import BaseModel, Field class Ticket(BaseModel): category: str = Field(description="Support category: refund, shipping, technical") priority: int = Field(ge=1, le=5, description="Priority from 1 (low) to 5 (critical)") summary: str = Field(description="One-sentence summary") class SupportAgent(Agent, llm=llm): """You create support tickets from customer messages.""" async def create_ticket(self, message: str) -> Ticket: """Create a structured support ticket.""" ... # Usage async def main(): agent = SupportAgent() ticket = await agent.create_ticket("My order never arrived and I need it urgently!") print(f"Category: {ticket.category}, Priority: {ticket.priority}") print(f"Summary: {ticket.summary}") ``` ## Advanced Patterns ### Context Blocks for Runtime Information Use `Context` to provide runtime information without cluttering the agent class: ```python from nooa import Agent, Context class ResearchAgent(Agent, llm=llm): """You are a research assistant.""" async def answer_question(self, question: str) -> str: """Answer the question using available context.""" ... async def main(): agent = ResearchAgent() with Context.user_message("The meeting is scheduled for 3 PM today."): result = await agent.answer_question("When is the meeting?") print(result) # Will use the context provided ``` ### Multiple Generation Strategies Agents can use different orchestration strategies: ```python from nooa import Agent # ReAct strategy (default): iterative think-act loops class ReactAgent(Agent, llm=llm, strategy="react"): """You solve problems step by step.""" async def solve(self, problem: str) -> str: """Solve this problem.""" ... # Code-first strategy: generates Python code to execute class CodeAgent(Agent, llm=llm, strategy="code"): """You solve problems by writing Python code.""" async def calculate(self, expression: str) -> float: """Calculate the result.""" ... ``` ### Progressive Disclosure with doc() Use `doc()` to provide detailed information only when the LLM requests it: ```python from nooa import Agent, doc class AnalyticsAgent(Agent, llm=llm): """You analyze sales data.""" def get_sales_schema(self) -> str: return doc(""" Sales database schema: - orders table: id, customer_id, total, date - customers table: id, name, email, segment - products table: id, name, category, price """) async def query_sales(self, question: str) -> str: """Answer questions about sales data. Use get_sales_schema() if you need schema details.""" ... ``` The documentation in `doc()` is only shown to the LLM when it calls `get_sales_schema()`. ### Agent Composition Agents can delegate to other agents: ```python class EmailAgent(Agent, llm=llm): """You write professional emails.""" async def compose(self, topic: str, recipient: str) -> str: """Write an email.""" ... class CommunicationAgent(Agent, llm=llm): """You manage customer communications.""" email_agent: EmailAgent async def send_update(self, customer_name: str, order_status: str) -> str: """Compose and send an order status update.""" email = await self.email_agent.compose( topic=f"Order Status Update: {order_status}", recipient=customer_name ) # Send email logic here return email # Usage async def main(): agent = CommunicationAgent(email_agent=EmailAgent()) result = await agent.send_update("John Doe", "Shipped") ``` ### Event System Agents can emit and respond to events: ```python from nooa import Agent class MonitorAgent(Agent, llm=llm): """You monitor system health.""" async def on_error(self, error_message: str) -> str: """Handle an error event.""" ... async def main(): agent = MonitorAgent() # Emit an event await agent.emit("error", error_message="Database connection failed") ``` ### Long-Term Memory With `nooa-memory` installed: ```python from nooa import Agent from nooa_memory import MemoryManager class AssistantAgent(Agent, llm=llm): """You are a helpful assistant with memory.""" memory: MemoryManager async def chat(self, message: str) -> str: """Chat with the user, remembering previous conversations.""" # Memory is automatically managed ... # Usage async def main(): memory = MemoryManager(llm=llm) agent = AssistantAgent(memory=memory) response1 = await agent.chat("My name is Alice") response2 = await agent.chat("What's my name?") # Will remember "Alice" ``` ## CLI Tools ### Start Trace Viewer ```bash # Start development trace viewer (http://localhost:5001) uv run nooa start-dev # Or with custom port uv run nooa start-dev --port 8080 ``` ### View Traces All agent execution is automatically traced (LLM calls, code execution, method invocations) when the viewer is running. Open `http://localhost:5001` to browse traces with parent-child span relationships. ## Configuration ### Environment Variables ```bash # For Anthropic models export ANTHROPIC_API_KEY=your_key_here # For OpenAI models export OPENAI_API_KEY=your_key_here # For custom API endpoints (Ollama, vLLM) # Pass api_base directly to get_llm_client() ``` ### LLM Client Options ```python from nooa.unifiedllm.registry import get_llm_client llm = get_llm_client( "claude-haiku-4-5", temperature=0.7, # Control randomness max_tokens=4096, # Maximum response length timeout=60.0, # Request timeout in seconds ) ``` ## Real-World Example: Research Assistant ```python import asyncio from typing import List from pydantic import BaseModel, Field from nooa import Agent, Context, doc class Source(BaseModel): title: str summary: str relevance: int = Field(ge=1, le=5, description="Relevance score 1-5") class ResearchReport(BaseModel): topic: str key_findings: List[str] sources: List[Source] conclusion: str class ResearchAgent(Agent, llm=llm): """You are a research assistant who gathers and synthesizes information.""" search_history: List[str] = [] def record_search(self, query: str) -> None: """Record a search query in history.""" self.search_history.append(query) print(f"Searching: {query}") def get_research_guidelines(self) -> str: return doc(""" Research best practices: 1. Use multiple diverse sources 2. Verify claims across sources 3. Note conflicting information 4. Prioritize recent, authoritative sources 5. Clearly distinguish facts from opinions """) async def research_topic(self, topic: str, depth: str = "comprehensive") -> ResearchReport: """ Research a topic and produce a structured report. Args: topic: The research topic depth: "quick" for overview, "comprehensive" for detailed analysis """ ... async def main(): agent = ResearchAgent() with Context.user_message("Focus on developments from the last 6 months."): report = await agent.research_topic( topic="Recent advances in multimodal AI models", depth="comprehensive" ) print(f"\n=== Research Report: {report.topic} ===") print(f"\nKey Findings:") for finding in report.key_findings: print(f" - {finding}") print(f"\nSources ({len(report.sources)}):") for source in report.sources: print(f" - {source.title} (relevance: {source.relevance}/5)") print(f" {source.summary}") print(f"\nConclusion:\n{report.conclusion}")
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub