Lesson 5: DeepAgents Technical Deep Dive
Understanding DeepAgents architecture, NemoClaw configurations, and how to choose between OpenClaw vs DeepAgents
Part 1: The Two NemoClaw Configurations
NemoClaw is NOT tied to a single agent. The Blueprint specifies which agent runs inside the OpenShell sandbox.
NemoClaw Agent Layer is Swappable
(Orchestration)"] OS["OpenShell
(Sandbox)"] end subgraph OPTION_A["OPTION A: OpenClaw"] OC["OpenClaw Agent
NVIDIA's bundled agent"] OC_FEATURES["• General-purpose
• Fixed harness
• Basic memory
• CLI only"] end subgraph OPTION_B["OPTION B: DeepAgents"] DA["DeepAgents (dcode)
LangChain's coding agent"] DA_FEATURES["• Coding-focused
• Tunable harness
• Persistent memory
• Python SDK
• Subagents
• LangSmith tracing"] end NC --> OS OS --> OC OS --> DA style SHARED fill:#f5f5f5,stroke:#666,stroke-width:2px style OPTION_A fill:#e3f2fd,stroke:#1a5fb4,stroke-width:2px style OPTION_B fill:#e8f5e9,stroke:#76b900,stroke-width:2px
NemoClaw + OpenClaw
- Source: NVIDIA (bundled)
- Focus: General AI assistant
- Harness: Fixed
- Memory: Session-only
- Skills: Limited
- Subagents: No
- SDK: CLI only
- Tracing: None
Best for: Quick setup, general tasks, NVIDIA-managed experience
NemoClaw + DeepAgents
- Source: LangChain (separate)
- Focus: Coding agent
- Harness: Tunable per model
- Memory: Persistent + compaction
- Skills: AGENTS.md + skills/
- Subagents: Full delegation
- SDK: Python API
- Tracing: Native LangSmith
Best for: Coding tasks, complex workflows, enterprise observability
Part 2: Blueprint Configuration Differences
The Blueprint YAML specifies which agent runs inside OpenShell:
Blueprint for OpenClaw (NVIDIA Default)
# blueprint-openclaw.yaml apiVersion: nemoclaw/v1 kind: Blueprint metadata: name: openclaw-default version: "1.0.0" digest: sha256:a1b2c3d4... spec: # Agent configuration agent: type: openclaw version: "latest" config: model: nvidia/nemotron-3-ultra # Sandbox image image: base: nvcr.io/nvidia/openclaw:latest tools: - python3.14 - node22 - git - gh # Policy tier policy: tier: balanced # Inference routing inference: provider: nvidia endpoint: inference.local
Blueprint for DeepAgents (LangChain)
# blueprint-deepagents.yaml apiVersion: nemoclaw/v1 kind: Blueprint metadata: name: deepagents-code version: "1.0.0" digest: sha256:e5f6g7h8... spec: # Agent configuration - DeepAgents agent: type: deepagents version: "latest" config: model: nvidia/nemotron-3-ultra memory: backend: sqlite compaction: true threshold: 50000 # tokens skills_path: /sandbox/.deepagents/skills agents_path: /sandbox/.deepagents/agents # Sandbox image with DeepAgents pre-installed image: base: langchain/deepagents-code:latest tools: - python3.14 - node22 - git - gh - dcode # DeepAgents CLI # Policy tier policy: tier: balanced # DeepAgents needs LangSmith access network: allow: - api.smith.langchain.com # Inference routing inference: provider: nvidia endpoint: inference.local # LangSmith tracing (DeepAgents feature) tracing: enabled: true provider: langsmith project: nemoclaw-deepagents
Part 3: DeepAgents Architecture Deep Dive
DeepAgents SDK Internal Architecture
provider:model"] TOOLS["Tool Registry
built-in + custom + MCP"] MW["Middleware Stack
approval, logging, errors"] end subgraph CORE["Core Agent Loop"] PLAN["PLANNING
write_todos()"] EXEC["EXECUTION
Tool calls"] CTX["CONTEXT
Memory + Compaction"] DEL["DELEGATION
Subagents"] SYN["SYNTHESIS
Response"] end subgraph STATE["State Management"] MEM["Memory System
SQLite + Retrieval"] SKILL["Skills Framework
AGENTS.md"] SUB["Subagent Pool
Isolated contexts"] end CREATE --> MODEL CREATE --> TOOLS CREATE --> MW MODEL --> PLAN TOOLS --> EXEC MW --> EXEC PLAN --> EXEC EXEC --> CTX CTX --> DEL DEL --> SYN SYN -.->|"If more work"| PLAN CTX <--> MEM PLAN <--> SKILL DEL <--> SUB style ENTRY fill:#76b900,stroke:#5a8f00,color:#fff style CONFIG fill:#e8f5e9,stroke:#76b900 style CORE fill:#fff3e0,stroke:#f57c00 style STATE fill:#e3f2fd,stroke:#1a5fb4
3.1 Creating a Deep Agent (Python SDK)
from deepagents import create_deep_agent from deepagents.tools import read_file, write_file, execute, web_search # Basic agent creation agent = create_deep_agent( # Model: provider:model format - works with ANY LLM model="nvidia:nemotron-3-ultra", # Tools the agent can use tools=[read_file, write_file, execute, web_search], # System prompt for behavior system_prompt="""You are a senior software engineer. For complex tasks, use write_todos to decompose into steps. Always run tests after making changes. Follow the coding standards in AGENTS.md.""" ) # Invoke the agent response = agent.invoke("Add comprehensive unit tests for the auth module") # Stream responses for chunk in agent.stream("Refactor the database layer"): print(chunk, end="")
Source: LangChain DeepAgents Quickstart
3.2 Model Provider Support
DeepAgents works with any LLM via the provider:model format:
# NVIDIA (recommended for NemoClaw) agent = create_deep_agent(model="nvidia:nemotron-3-ultra") # OpenAI agent = create_deep_agent(model="openai:gpt-4o") # Anthropic agent = create_deep_agent(model="anthropic:claude-sonnet-4-20250514") # Google agent = create_deep_agent(model="google_genai:gemini-2.5-flash") # Local inference (Ollama) agent = create_deep_agent(model="ollama:llama3.3:70b") # OpenRouter (access to many models) agent = create_deep_agent(model="openrouter:meta-llama/llama-3-70b") # Fireworks agent = create_deep_agent(model="fireworks:accounts/fireworks/models/llama-v3-70b")
Source: LangChain DeepAgents Configuration
3.3 The Planning System (write_todos)
DeepAgents uses write_todos for automatic task decomposition:
Planning System Flow
1. Read structure
2. Identify issues
3. Create new structure
4. Move functions
5. Update imports
6. Run tests loop For each todo A->>T: Execute tool calls T-->>A: Results A->>P: Update todo status A->>M: Store context end A->>M: Store completion summary A-->>U: Final response
# The agent automatically calls write_todos for complex tasks # Internal todo structure: todos = [ { "id": 1, "task": "Read current database.py structure", "status": "pending", "dependencies": [] }, { "id": 2, "task": "Identify code smells and duplication", "status": "pending", "dependencies": [1] }, { "id": 3, "task": "Create new modular structure", "status": "pending", "dependencies": [2] }, { "id": 4, "task": "Move functions to appropriate modules", "status": "pending", "dependencies": [3] }, { "id": 5, "task": "Update imports across codebase", "status": "pending", "dependencies": [4] }, { "id": 6, "task": "Run tests to verify", "status": "pending", "dependencies": [5] } ] # Agent updates status as it progresses: todos[0]["status"] = "completed" todos[0]["result"] = "Found 3 main classes: Connection, Query, Migration"
Source: LangChain DeepAgents Quickstart
3.4 Memory System
Memory Architecture
(in context window)"] SUMMARY["Compacted Summaries
(older conversations)"] end subgraph STORAGE["Persistent Storage"] SQLITE["SQLite Database
~/.deepagents/.state/sessions.db"] RETRIEVAL["Retrieval Index
(semantic search)"] end subgraph PROCESS["Processing"] COMPACT["Compaction
(when threshold reached)"] RETRIEVE["Retrieval
(relevant context)"] end end RECENT -->|"Exceeds threshold"| COMPACT COMPACT -->|"Summaries"| SUMMARY COMPACT -->|"Full messages"| SQLITE RETRIEVE -->|"Query"| SQLITE RETRIEVE -->|"Query"| RETRIEVAL RETRIEVE -->|"Inject"| RECENT style ACTIVE fill:#fff3e0,stroke:#f57c00 style STORAGE fill:#e3f2fd,stroke:#1a5fb4 style PROCESS fill:#e8f5e9,stroke:#76b900
# Memory configuration in config.toml [memory] backend = "sqlite" compaction_threshold = 50000 # tokens before compaction kicks in retrieval_top_k = 10 # number of relevant memories to retrieve # Memory is stored at: # ~/.deepagents/.state/sessions.db # Programmatic memory access: from deepagents.memory import MemoryStore memory = MemoryStore(agent_name="code") # Store important context memory.store( key="project_context", value="FastAPI project with SQLAlchemy ORM, using Alembic for migrations", metadata={"type": "project_info", "importance": "high"} ) # Retrieve relevant memories relevant = memory.retrieve( query="database configuration", top_k=5 ) # Memories persist across sessions # Next session can access previous learnings
Source: LangChain DeepAgents Configuration
3.5 Human-in-the-Loop Approval
HITL Approval Flow
[A]pprove / [D]eny / [E]dit / [S]kip U-->>M: User decision alt Approved M->>T: Execute tool T-->>A: Result else Denied M-->>A: ToolDenied error else Edit U->>M: Modified content M->>T: Execute with edits T-->>A: Result end end
from deepagents import create_deep_agent from deepagents.middleware import HumanApprovalMiddleware # Configure approval middleware approval = HumanApprovalMiddleware( # Tools that ALWAYS require approval require_approval_for=[ "write_file", "execute", "delete_file", "git_push", "git_commit" ], # Patterns that are AUTO-APPROVED (skip prompt) auto_approve_patterns=[ "read_file:*", # All file reads "write_file:*.test.py", # Test files "write_file:tests/*", # Tests directory "execute:pytest *", # Running tests "execute:git status", # Git status "execute:git diff *", # Git diff "execute:python -m mypy *", # Type checking ], # Timeout for user response (seconds) timeout_seconds=300, # What to do on timeout timeout_action="deny", # or "approve" for trusted environments ) # Create agent with approval middleware agent = create_deep_agent( model="nvidia:nemotron-3-ultra", tools=[read_file, write_file, execute], middleware=[approval] ) # Custom approval callback for complex logic def custom_approver(tool_name, tool_input, context): """ Returns: True - Auto-approve False - Auto-deny "ask" - Prompt user """ # Auto-approve in test environment if context.get("environment") == "test": return True # Auto-deny dangerous patterns if "rm -rf" in str(tool_input): return False if "DROP TABLE" in str(tool_input).upper(): return False # Ask user for everything else return "ask" approval = HumanApprovalMiddleware( require_approval_for=["write_file", "execute"], approval_callback=custom_approver )
Source: LangChain DeepAgents Overview
3.6 Subagent Delegation
Subagent Architecture
Coordinates work"] end subgraph SUBS["Subagent Pool"] R["Researcher
web_search, read_file"] V["Reviewer
read_file only"] T["Tester
read_file, execute"] W["Writer
read_file, write_file"] end MA -->|"Research best practices"| R MA -->|"Review this code"| V MA -->|"Write and run tests"| T MA -->|"Implement the feature"| W R -->|"Findings"| MA V -->|"Review comments"| MA T -->|"Test results"| MA W -->|"Implementation"| MA style MAIN fill:#76b900,stroke:#5a8f00,color:#fff style SUBS fill:#e8f5e9,stroke:#76b900
from deepagents import create_deep_agent from deepagents.subagents import SubagentConfig # Define subagent configurations agent = create_deep_agent( model="nvidia:nemotron-3-ultra", tools=[read_file, write_file, execute], subagent_configs={ # Research subagent - for gathering information "researcher": SubagentConfig( model="nvidia:nemotron-3-ultra", tools=[web_search, read_file], system_prompt="You research topics and summarize findings concisely.", max_tokens=2000 ), # Code reviewer - read-only, focuses on quality "reviewer": SubagentConfig( model="nvidia:nemotron-3-ultra", tools=[read_file], # Read-only! system_prompt="You review code for bugs, security issues, and improvements.", max_tokens=1500 ), # Test writer - can execute tests "tester": SubagentConfig( model="nvidia:nemotron-3-ultra", tools=[read_file, write_file, execute], system_prompt="You write comprehensive tests and run them.", max_tokens=2000 ), # Documentation writer "documenter": SubagentConfig( model="nvidia:nemotron-3-ultra", tools=[read_file, write_file], system_prompt="You write clear, comprehensive documentation.", max_tokens=3000 ) } ) # The main agent can now delegate: # "I'll have the reviewer check this code..." # "Let me delegate the test writing to the tester subagent..." # "I'll ask the researcher to look into best practices..."
Source: LangChain DeepAgents Overview
3.7 Skills Framework (AGENTS.md)
# ~/.deepagents/code/AGENTS.md (User-level - applies to all projects) ## About Me I'm a senior Python developer specializing in microservices. I prefer functional programming patterns where appropriate. ## Coding Standards - Always use type hints for function parameters and returns - Use dataclasses for DTOs, Pydantic for validation - Prefer composition over inheritance - Maximum function length: 30 lines - Maximum file length: 300 lines ## Testing Philosophy - Use pytest (never unittest) - Aim for 80%+ coverage on business logic - Use pytest-asyncio for async tests - Mock external services, don't mock internal code ## Tools I Use - FastAPI for APIs - SQLAlchemy with async sessions - Alembic for migrations - structlog for logging (never print()) - mypy for type checking - ruff for linting ## Things to Avoid - Don't use global mutable state - Don't commit .env files - Don't use bare except clauses - Don't ignore type errors
# {project}/.deepagents/AGENTS.md (Project-level - specific to this repo) ## Project: Payment Service ## Architecture This is a domain-driven design project with: - Event sourcing for transaction history - CQRS pattern (separate read/write models) - Saga pattern for distributed transactions ## Critical Files (Handle with Care) - src/domain/payment.py - Core payment aggregate - src/events/handlers.py - Event processing (changes here affect all downstream) - src/sagas/payment_saga.py - Distributed transaction coordinator - alembic/versions/ - Database migrations (never modify existing) ## Environment Setup ```bash # Start dependencies docker-compose up -d postgres redis # Run migrations alembic upgrade head # Run tests pytest -v --cov=src ``` ## Domain Rules - Payments must be idempotent (use idempotency_key) - All money calculations use Decimal, never float - Timestamps are always UTC - Event handlers must be idempotent
Source: LangChain DeepAgents Configuration
Part 4: OpenShell Integration (Sandbox-as-Tool)
When DeepAgents runs inside NemoClaw/OpenShell, it uses the sandbox-as-tool pattern:
Sandbox-as-Tool Pattern
• LLM loop
• Memory
• Tool dispatch
• Planning"] end subgraph REMOTE["REMOTE (OpenShell Sandbox)"] FS["Filesystem
read_file
write_file"] EXEC["Execution
shell commands"] TEST["Testing
pytest, etc."] REPO["Source Code
/sandbox/project"] end subgraph INFERENCE["INFERENCE"] MODEL["Nemotron 3 Ultra
(via inference.local)"] end DCODE -->|"Tool calls
over network"| FS DCODE -->|"Tool calls"| EXEC DCODE -->|"Tool calls"| TEST DCODE <-->|"LLM requests"| MODEL FS <--> REPO EXEC <--> REPO TEST <--> REPO style LOCAL fill:#e8f5e9,stroke:#76b900,stroke-width:2px style REMOTE fill:#e3f2fd,stroke:#1a5fb4,stroke-width:2px style INFERENCE fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
from deepagents import create_deep_agent from deepagents.sandboxes import OpenShellSandbox # Configure OpenShell as the sandbox provider sandbox = OpenShellSandbox( # Blueprint to use blueprint="nemoclaw/deep-agents-code:latest", # Security policy tier policy_tier="balanced", # Inference provider inference_provider="nvidia", # Mount project directory into sandbox mount_project=True, project_path="/sandbox/project" ) # Create agent with OpenShell sandbox agent = create_deep_agent( model="nvidia:nemotron-3-ultra", sandbox=sandbox, # Tools execute in OpenShell! tools=[read_file, write_file, execute] ) # Now when agent calls read_file("/src/main.py"): # 1. dcode process runs LOCALLY (your machine) # 2. read_file call goes to REMOTE OpenShell sandbox # 3. File content returned from sandbox # 4. Agent processes locally, makes decisions # 5. Repeat...
Source: LangChain Remote Sandboxes
Part 5: Multi-Agent System Benefits
How does NemoClaw + DeepAgents help with multi-agent systems?
Multi-Agent Isolation with OpenShell
Coordinator"] end subgraph NEMOCLAW["NemoClaw Infrastructure"] subgraph SANDBOX1["OpenShell Sandbox 1"] A1["Agent: Frontend Dev
• React tools
• npm access
• /sandbox/frontend"] end subgraph SANDBOX2["OpenShell Sandbox 2"] A2["Agent: Backend Dev
• Python tools
• DB access
• /sandbox/backend"] end subgraph SANDBOX3["OpenShell Sandbox 3"] A3["Agent: DevOps
• kubectl
• terraform
• /sandbox/infra"] end end subgraph SHARED["Shared Resources"] GIT["Git Repository
(read-only mount)"] DOCS["Documentation
(shared volume)"] end ORCH --> A1 ORCH --> A2 ORCH --> A3 A1 <-.->|"Isolated"| A2 A2 <-.->|"Isolated"| A3 A1 --> GIT A2 --> GIT A3 --> GIT A1 --> DOCS A2 --> DOCS A3 --> DOCS style ORCHESTRATOR fill:#76b900,stroke:#5a8f00,color:#fff style SANDBOX1 fill:#e3f2fd,stroke:#1a5fb4 style SANDBOX2 fill:#e8f5e9,stroke:#76b900 style SANDBOX3 fill:#fff3e0,stroke:#f57c00
Benefits for Multi-Agent Systems
| Benefit | How NemoClaw + DeepAgents Provides It |
|---|---|
| Isolation | Each agent runs in its own OpenShell sandbox - one agent's mistakes can't affect others |
| Credential Separation | Different agents can have different API access without sharing credentials |
| Policy Per Agent | Frontend agent gets npm access; Backend agent gets database access; neither gets the other's permissions |
| Resource Limits | Each sandbox has CPU/memory limits - runaway agent can't starve others |
| Audit Trails | Each sandbox has its own logs - easy to trace which agent did what |
| Safe Communication | Agents communicate through controlled channels, not direct access |
# Multi-agent orchestration with isolated sandboxes from deepagents import create_deep_agent from deepagents.sandboxes import OpenShellSandbox # Each agent gets its own isolated sandbox frontend_agent = create_deep_agent( model="nvidia:nemotron-3-ultra", sandbox=OpenShellSandbox( blueprint="nemoclaw/frontend-dev:latest", policy_tier="balanced", # Network: npm registry access only network_allow=["registry.npmjs.org"] ), system_prompt="You are a frontend developer specializing in React." ) backend_agent = create_deep_agent( model="nvidia:nemotron-3-ultra", sandbox=OpenShellSandbox( blueprint="nemoclaw/backend-dev:latest", policy_tier="balanced", # Network: PyPI + internal database network_allow=["pypi.org", "db.internal:5432"] ), system_prompt="You are a backend developer specializing in Python APIs." ) # Orchestrate: frontend agent can't access database, backend can't access npm async def build_feature(feature_spec): # Backend builds API api_result = await backend_agent.invoke( f"Build API endpoint for: {feature_spec}" ) # Frontend builds UI (can see API spec, can't access backend DB) ui_result = await frontend_agent.invoke( f"Build React component for: {feature_spec}\nAPI spec: {api_result}" ) return {"api": api_result, "ui": ui_result}
Part 6: Complete Configuration Reference
# ~/.deepagents/config.toml - Complete DeepAgents configuration [default] # Default model for all agents model = "nvidia:nemotron-3-ultra" # Default sandbox provider sandbox_provider = "openshell" [memory] # Memory backend (sqlite or redis) backend = "sqlite" # Token count before compaction kicks in compaction_threshold = 50000 # Number of relevant memories to retrieve retrieval_top_k = 10 # Memory database path db_path = "~/.deepagents/.state/sessions.db" [approval] # Tools requiring human approval require_for = ["write_file", "execute", "delete_file", "git_push"] # Auto-approve all read operations auto_approve_reads = true # Patterns to auto-approve auto_approve_patterns = [ "write_file:*.test.py", "write_file:tests/*", "execute:pytest *", "execute:git status", "execute:git diff *" ] # Timeout for approval prompt (seconds) timeout_seconds = 300 # Action on timeout: "deny" or "approve" timeout_action = "deny" [tracing] # LangSmith project name langsmith_project = "my-coding-agent" # Log level: DEBUG, INFO, WARNING, ERROR log_level = "INFO" # Enable detailed tool tracing trace_tools = true [sandbox.openshell] # OpenShell sandbox configuration blueprint = "nemoclaw/deep-agents-code:latest" policy_tier = "balanced" inference_provider = "nvidia" # Mount local project into sandbox mount_project = true project_mount_path = "/sandbox/project" [sandbox.langsmith] # Alternative: LangSmith sandbox api_key_env = "LANGSMITH_API_KEY" [subagents] # Default configuration for subagents max_concurrent = 3 default_max_tokens = 2000 inherit_memory = false
Knowledge Check
Primary Source Reading
Recommended Reading
-
LangChain DeepAgents Code Overview
https://docs.langchain.com/oss/python/deepagents/code/overview
Complete dcode architecture and features -
DeepAgents Configuration Reference
https://docs.langchain.com/oss/python/deepagents/code/configuration
All configuration options with examples -
Remote Sandboxes Guide
https://docs.langchain.com/oss/python/deepagents/code/remote-sandboxes
Sandbox-as-tool pattern explained -
Harness Tuning Playbook
LangChain Blog
How to tune DeepAgents harness for different models