Author: TrixSec
NOOA Deep Dive: NVIDIA’s Pythonic AI Agents Framework with Practical Implementations
In July 2026, NVIDIA unveiled NOOA (NVIDIA Object-Oriented Agents), an open-source framework that redefines AI agents as single Python classes. By unifying capabilities, state, prompts, and memory into a cohesive interface, NOOA addresses the fragmentation in agent development while delivering performance, inspectability, and security.
This guide explores NOOA’s architecture, benchmarks, and practical implementations—including a full code walkthrough of a cybersecurity agent.
Table of Contents
- NOOA’s Core Philosophy
- Six Key Capabilities with Examples
- Memory System: SQLite Knowledge Graphs
- Performance: Benchmarks and Optimizations
- Security: Sandboxing and Validation
- Building a Cybersecurity Agent: Step-by-Step
- Comparison with LangGraph, AutoGen, and CrewAI
- Getting Started: Installation and Setup
- The Future of NOOA
NOOA’s Core Philosophy
NOOA (pronounced “no-ah”) treats AI agents as Python objects, eliminating the need for:
- Separate prompt templates (e.g., Jinja)
- JSON tool schemas
- Custom workflow graphs
Instead, an agent is a single class where:
-
Methods = Capabilities (LLM-driven if body is
...) - Fields = State (typed and persistent)
- Docstrings = Prompts (natural language instructions)
- Type annotations = Contracts (enforced I/O)
Why This Matters
-
Inspectability: Debug with
pdborpytestlike normal Python. - Testability: Mock methods for unit testing.
- Performance: Fewer LLM calls → lower latency/cost.
- Memory: SQLite-backed knowledge graphs (not just chat history).
“NOOA is to AI agents what PyTorch was to deep learning: a simple interface for complex systems.” — NVIDIA Labs
Six Key Capabilities with Examples
NOOA’s design centers on six model-facing interfaces:
Capability Description Example Typed I/O Methods enforce input/output types (no free text).def scan_port(host: str, port: int) -> dict:
Pass by Reference
Agents manipulate live Python objects (e.g., self.state).
self.vulnerabilities.append(issue)
Code as Action
Agents execute Python (e.g., import socket).
socket.connect((host, port))
Programmable Loops
Orchestration uses standard Python (for, while).
for ip in subnet: self.scan(ip)
Explicit Object State
State persists as fields (not just in conversation history).
self.last_scan = datetime.now()
Harness APIs
Context/memory are Python APIs (e.g., self.memory.query()).
matches = self.memory.search(tags=["exploit"])
Example: Typed I/O and State
from nooa import Agent
from typing import Dict, List
from datetime import datetime
class SecurityAgent(Agent):
"""A cybersecurity assistant for vulnerability scanning."""
def __init__(self):
self.scanned_hosts: List[str] = [] # Persistent state
self.last_scan: datetime = None
def scan_host(self, host: str) -> Dict[str, str]:
"""
Scan a host for open ports and vulnerabilities.
Args:
host (str): Target hostname/IP.
Returns:
Dict[str, str]: Report with findings.
"""
... # LLM implements this at runtime
def add_to_history(self, host: str) -> None:
"""Record a scanned host deterministically."""
self.scanned_hosts.append(host)
self.last_scan = datetime.now()
Enter fullscreen mode Exit fullscreen mode
Memory System: SQLite Knowledge Graphs
NOOA’s memory subsystem stores typed, relational knowledge in a SQLite database. Key features:
1. Structured Records
Each memory has:
-
content(str): The knowledge (e.g., “CVE-2026-1234 affects OpenSSH 9.0”). -
tags(List[str]): Categorization (e.g.,["vulnerability", "critical"]). -
importance(float): Priority (0.0–1.0). -
relationships: Links to other records (e.g.,"supports","contradicts").
2. Automatic Context
Relevant memories surface into the agent’s context during execution.
3. Multi-Agent Sharing
Multiple agents can access the same store with separate ownership.
Example: Storing and Querying Memories
# Add a vulnerability to memory
self.memory.add(
content="CVE-2026-1234: RCE in OpenSSH 9.0. Patch immediately.",
tags=["cve", "critical", "openssh"],
importance=0.9,
relationships={"affects": ["openssh-9.0"]}
)
# Query memories later
critical_cves = self.memory.query(
tags=["cve", "critical"],
limit=5
)
Enter fullscreen mode Exit fullscreen mode
4. Reflection and Pruning
A background process:
- Merges duplicate records.
- Links related knowledge (e.g., “exploit” → “patch”).
- Prunes outdated information.
Performance: Benchmarks and Optimizations
NOOA’s July 2026 benchmarks show efficiency gains over traditional frameworks:
Benchmark NOOA (GPT-5.5) Comparison Harnesses Token Savings SWE-bench Verified 82.2% (29 calls) 78.2% (66 calls) ~50% CyberGym L1 86.8% N/A N/A ARC-AGI-3 50.2% RHAE Baseline: ~40% ~20%Why NOOA Wins
-
Fewer LLM Calls: Ellipsis (
...) methods reduce round-trips. - Typed Contracts: Prevents invalid inputs/outputs early.
- Memory Efficiency: SQLite avoids redundant context.
“Harness design alone can account for double-digit swings in benchmark results—with the same underlying model.” — NVIDIA
Security: Sandboxing and Validation
Risks
-
Prompt Injection: Malicious inputs could exploit
...methods. -
Arbitrary Code: LLM-generated Python may call dangerous functions (e.g.,
os.system). - State Leaks: Centralized memory could expose sensitive data.
Mitigations
- OpenShell Sandbox: NVIDIA’s secure runtime for untrusted code.
# Run agent in OpenShell container
docker run -it --rm nvcr.io/nvidia/openshell:latest nooa run agent.py
Enter fullscreen mode Exit fullscreen mode
-
AST Validation: Blocks risky patterns (e.g.,
import subprocess).
from nooa.sandbox import DENY_LIST
DENY_LIST.extend(["subprocess", "socket", "os.system"])
Enter fullscreen mode Exit fullscreen mode
- Scoped Credentials: Use restricted API keys/permissions.
- Memory Encryption: SQLite database can be encrypted at rest.
Expert Take
“NOOA’s centralized design makes audits easier—but also concentrates risk. Sandboxing isn’t optional.” — Karthik Karunanithi, IBM
Building a Cybersecurity Agent: Step-by-Step
Let’s build a vulnerability scanner agent with NOOA.
1. Define the Agent Class
from nooa import Agent
from typing import Dict, List, Optional
import requests
class VulnScannerAgent(Agent):
"""Scans hosts for CVEs and suggests patches."""
def __init__(self):
self.scanned_hosts: List[str] = []
self.api_key: str = "" # For vulnerability DBs
def set_api_key(self, key: str) -> None:
"""Securely set the API key."""
self.api_key = key # In production, use a secrets manager
def scan_host(self, host: str) -> Dict[str, List[Dict]]:
"""
Scan a host for CVEs.
Args:
host (str): Target (e.g., "192.168.1.1").
Returns:
Dict[str, List[Dict]]: {"vulnerabilities": [...], "suggestions": [...]}
"""
... # LLM implements scan logic
def query_cve_db(self, cve_id: str) -> Optional[Dict]:
"""Fetch CVE details from a database."""
headers = {"Authorization": f"Bearer {self.api_key}"}
response = requests.get(
f"https://api.cvedb.com/v1/cves/{cve_id}",
headers=headers
)
return response.json() if response.ok else None
Enter fullscreen mode Exit fullscreen mode
2. Add Memory Integration
def record_finding(self, host: str, cve: Dict) -> None:
"""Store a vulnerability in memory."""
self.memory.add(
content=f"{host} affected by {cve['id']}: {cve['description']}",
tags=["vulnerability", "unpatched", host],
importance=0.9,
relationships={"affects": [host], "type": [cve["id"]]}
)
def get_patch_suggestions(self, cve_id: str) -> List[str]:
"""Retrieve patch suggestions from memory."""
results = self.memory.query(
tags=["patch", cve_id],
limit=3
)
return [r["content"] for r in results]
Enter fullscreen mode Exit fullscreen mode
3. Implement a Scan Workflow
def full_scan(self, hosts: List[str]) -> Dict[str, Dict]:
"""Scan multiple hosts and aggregate results."""
report = {}
for host in hosts:
report[host] = self.scan_host(host)
for vuln in report[host]["vulnerabilities"]:
self.record_finding(host, vuln)
return report
Enter fullscreen mode Exit fullscreen mode
4. Test the Agent
# Initialize
scanner = VulnScannerAgent()
scanner.set_api_key("your_api_key_here")
# Scan and record
results = scanner.full_scan(["192.168.1.1", "192.168.1.2"])
print(results)
# Query memory later
print(scanner.get_patch_suggestions("CVE-2026-1234"))
Enter fullscreen mode Exit fullscreen mode
Key Features Demonstrated
-
Hybrid Methods:
scan_host(LLM-driven) +query_cve_db(deterministic). - Memory Integration: Findings persist across sessions.
-
Typed Contracts: Input/output validation (e.g.,
List[str]for hosts).
Comparison with LangGraph, AutoGen, and CrewAI
Feature NOOA LangGraph AutoGen CrewAI Language Python Python Python Python State Management Python fields JSON/YAML Dicts/files JSON Tool Definition Python methods JSON schemas JSON JSON Orchestration Python loops Custom graphs Workflow graphs Sequential/parallel Memory SQLite (typed, relational) External DB File-based Vector DB Sandboxing OpenShell integration Manual Manual Manual Performance ✅ 2x token efficiency ❌ Higher overhead ❌ Moderate ❌ Moderate Inspectability ✅ Single class ❌ Scattered configs ❌ Mixed abstractions ❌ JSON-heavyWhen to Choose NOOA
-
Use NOOA for:
- Python-native projects (e.g., DevOps, cybersecurity).
- High-performance agents (fewer LLM calls).
- Long-term memory (SQLite knowledge graphs).
-
Avoid NOOA if:
- You need non-Python integration (e.g., TypeScript).
- Your workflows require heavy graph orchestration (e.g., LangGraph).
Getting Started: Installation and Setup
1. Install NOOA
# Core framework
pip install nooa
# With memory and CLI tools
pip install "nooa[memory,cli]"
Enter fullscreen mode Exit fullscreen mode
2. Verify Installation
nooa --version # Should output >= 0.1.0
Enter fullscreen mode Exit fullscreen mode
3. Run the Cybersecurity Example
- Save the VulnScannerAgent to
scanner.py. - Test in a sandbox:
docker run -it --rm -v $(pwd):/app nvcr.io/nvidia/openshell:latest
python /app/scanner.py
Enter fullscreen mode Exit fullscreen mode
4. Explore Advanced Features
-
Tracing: Visualize agent runs with
nooa trace. - Benchmarks: Run evaluations from NOOA’s GitHub.
- Memory CLI: Inspect the SQLite store:
sqlite3 agent_memory.db "SELECT * FROM memories LIMIT 5;"
Enter fullscreen mode Exit fullscreen mode
The Future of NOOA
Roadmap (2026–2027)
- Enterprise Features: Fine-tuning support, RBAC for memory stores.
- Security Hardening: Expanded AST validation and OpenShell integration.
- Community Tools: VS Code extension for agent debugging.
Broader Impact
- Open AI Alliance: NOOA is part of NVIDIA’s initiative for transparent AI research.
- Research Catalyst: Standardized benchmarks (e.g., SWE-bench) enable fair comparisons.
-
Python Ecosystem: Bridges AI agents with traditional dev tools (e.g.,
mypy,pytest).
“NOOA proves that the harness around a model matters as much as the model itself.” — NVIDIA Research
Should You Adopt NOOA?
✅ Yes, If You Need
-
Inspectable Agents: Debug with
pdbor test withpytest. - Performance: Cut LLM costs by 50% (fewer tokens/calls).
- Pythonic Workflows: No JSON/YAML—just classes and methods.
- Cybersecurity/DevOps: Ideal for structured tasks (e.g., scanning, coding).
❌ No, If You Require
- Non-Python Stacks: JavaScript/TypeScript integration.
- Mature Enterprise Support: NOOA is research-grade (not yet production-hardened).
- Complex Workflows: Heavy graph-based orchestration (e.g., LangGraph).
Resources
- GitHub Repo: Full documentation and examples.
- ArXiv Paper: Technical deep dive.
- NVIDIA Blog: Official announcement.
- OpenShell: Secure sandbox for deployment.
- Harbor Benchmarks: Reproduce performance tests.
Final Thoughts
NOOA is a paradigm shift in AI agent development:
- Unified Interface: Agents are Python classes—no more fragmented abstractions.
- Performance: Achieves state-of-the-art results with half the tokens.
- Memory: SQLite knowledge graphs enable persistent, queryable state.
- Security: Sandboxing and validation mitigate risks of LLM-generated code.
For developers building cybersecurity tools, DevOps assistants, or research agents, NOOA offers a rare blend of power and simplicity. As the framework matures, expect it to influence how we test, deploy, and trust AI systems.
Have you built a NOOA agent? Share your use case in the comments!
Cover image suggestion: A side-by-side comparison of NOOA’s Python class vs. traditional JSON-based agent configurations, or a diagram of the VulnScannerAgent workflow.
~TrixSec