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

Aller à l'installation

Informations de source

Dépôt
reason-machines/ai-agent-skills
Dernière activité de la source
4 août 2026 à 13:11
Langue détectée de SKILL.md
anglais
Étoiles
1
Forks
1

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
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}")
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub