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()
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
)
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
-
AST Validation: Blocks risky patterns (e.g.,
import subprocess).
from nooa.sandbox import DENY_LIST
DENY_LIST.extend(["subprocess", "socket", "os.system"])
- 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
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]
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
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"))
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-heavy |
When 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]"
2. Verify Installation
nooa --version # Should output >= 0.1.0
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
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;"
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
Top comments (0)