Author: TrixSec
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.
NOOA (pronounced "no-ah") treats AI agents as Python objects, eliminating the need for:
Instead, an agent is a single class where:
...
)pdb
or pytest
like normal Python.
“NOOA is to AI agents what PyTorch was to deep learning: a simple interface for complex systems.”—NVIDIA Labs
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"]) |
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()
NOOA’s memory subsystem stores typed, relational knowledge in a SQLite database. Key features:
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"
).Relevant memories surface into the agent’s context during execution.
Multiple agents can access the same store with separate ownership.
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"]}
)
critical_cves = self.memory.query(
tags=["cve", "critical"],
limit=5
)
A background process:
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% |
...
) methods reduce round-trips.
“Harness design alone can account for double-digit swings in benchmark results—with the same underlying model.”—NVIDIA
...
methods.os.system
).
docker run -it --rm nvcr.io/nvidia/openshell:latest nooa run agent.py
import subprocess
).
from nooa.sandbox import DENY_LIST
DENY_LIST.extend(["subprocess", "socket", "os.system"])
“NOOA’s centralized design makes audits easier—but also concentrates risk. Sandboxing isn’t optional.”—Karthik Karunanithi, IBM
Let’s build a vulnerability scanner agent with NOOA.
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
php
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]
php
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
scanner = VulnScannerAgent()
scanner.set_api_key("your_api_key_here")
results = scanner.full_scan(["192.168.1.1", "192.168.1.2"])
print(results)
print(scanner.get_patch_suggestions("CVE-2026-1234"))
scan_host
(LLM-driven) + query_cve_db
(deterministic).List[str]
for hosts).| 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 |
pip install nooa
pip install "nooa[memory,cli]"
nooa --version # Should output >= 0.1.0
scanner.py
.
docker run -it --rm -v $(pwd):/app nvcr.io/nvidia/openshell:latest
python /app/scanner.py
nooa trace
.
sqlite3 agent_memory.db "SELECT * FROM memories LIMIT 5;"
mypy
, pytest
).
“NOOA proves that the harness around a model matters as much as the model itself.”—NVIDIA Research
pdb
or test with pytest
.NOOA is a paradigm shift in AI agent development:
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