Skip to main content
An Agent uses a Large Language Model to orchestrate a cycle of reasoning and action. It thinks about what to do, acts by calling tools, and observes the results to inform its next step.

Install

pip install -U dreadnode

Authenticate

Authenticate with the Dreadnode platform to enable tracing and metrics:
dreadnode login
This opens your browser to complete authentication. For self-hosted platforms:
dreadnode login --server https://your-server.com
Platform features are optional. Agents run locally without authentication.

Create an Agent

Create a file called agent.py:
import dreadnode as dn

agent = dn.Agent(
    name="hello",
    model="gpt-4o-mini",
    instructions="You are a helpful assistant.",
)

Run with the CLI

The CLI discovers agents defined in your files:
# See available agents
dn agent ls

# Run with a prompt
dn agent run hello "What is the capital of France?"
The CLI searches agent.py, main.py, and other common filenames by default. See CLI Reference for configuration options and overrides.

Add Tools

Agents become powerful with tools. Add filesystem access:
import dreadnode as dn

agent = dn.Agent(
    name="file-reader",
    model="gpt-4o-mini",
    instructions="You explore and summarize files.",
    tools=[
        dn.agent.tools.fs.Filesystem(path=".", variant="read"),
    ],
)
dn agent run file-reader "Summarize the README.md"
The variant parameter controls permissions—"read" for read-only, "write" for full access. See Tools for built-in toolsets, custom tools, and variants.

Key Concepts

Before diving into the lifecycle, understand these core concepts:
  • Threads - Maintain conversation history across multiple interactions. Pass a Thread to agent.run() to preserve context between calls.
  • Tools - Enable agents to take actions (read files, execute code, call APIs). Agents autonomously choose which tools to use based on the task.
  • Hooks - Functions that observe or intervene during execution. Use them for logging, metrics, error handling, or modifying agent behavior in real-time.
  • Stop Conditions - Define when an agent should finish. Control execution based on steps, tokens, cost, time, or custom logic.
  • max_steps - Limits the number of think-act cycles. Prevents infinite loops and controls execution time.
See Threads, Hooks, and Stop Conditions for details.

How Agents Work

Every agent run follows a predictable lifecycle. For each step (up to max_steps), the agent thinks, acts, then checks if it should stop:
  [ Start Run ]

┌──── Step 1 ───┐
│       ↓       │
│   [ Think ]   │  →  LLM generates response
│       ↓       │
│    [ Act ]    │  →  Execute tool calls
│       ↓       │
└───( Stop? )───┘

  [  End Run  ]
The agent, thread, and your components fit together like this:
            ┌──────────────────┐
            │      Thread      │  ← Conversation state
            └────────┬─────────┘

┌────────────────────┼────────────────────┐
│   Agent            │                    │
│                    ↓                    │
│    ┌───────────────────────────────┐    │
│    │        Lifecycle Loop         │    │
│    │   Think  →  Act  →  Stop?     │    │
│    └───────────────┬───────────────┘    │
│                    │                    │
│ ┌──────────────────┴──────────────────┐ │
│ │           Your Components           │ │
│ │                                     │ │
│ │  • Tools           (for acting)     │ │
│ │  • Hooks           (for reacting)   │ │
│ │  • Stop Conditions (for finishing)  │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘

TaskAgent

For goal-oriented work, use TaskAgent. It includes planning tools and continues until the agent explicitly finishes:
import dreadnode as dn
from dreadnode.agent import TaskAgent

researcher = TaskAgent(
    name="researcher",
    model="gpt-4o",
    tools=[dn.agent.tools.fs.Filesystem(path=".", variant="read")],
    max_steps=50,  # Safety limit to prevent infinite loops
)
TaskAgent adds finish_task, give_up_on_task, and update_todo tools. It keeps working until the agent calls one of the completion tools.
When to use each:Use Agent for:
  • Simple, bounded tasks with clear completion
  • Fixed workflows or pipelines
  • Quick scripts where you control the flow
Use TaskAgent for:
  • Open-ended goals requiring planning
  • Complex tasks needing multiple steps
  • Scenarios where the agent decides when it’s done

Running Programmatically

For notebooks, scripts, or CI, run agents directly:
import asyncio
import dreadnode as dn

agent = dn.Agent(
    name="hello",
    model="gpt-4o-mini",
    tools=[dn.agent.tools.fs.Filesystem(path=".", variant="read")]
)

async def main():
    # Run and get the result
    result = await agent.run("What is the capital of France?")
    print(result.messages[-1].content)

asyncio.run(main())

Streaming Events

Stream events for real-time progress updates:
from dreadnode.agent.events import StepStart, ToolStart, GenerationEnd

async def main():
    async with agent.stream("Analyze the README file") as events:
        async for event in events:
            if isinstance(event, StepStart):
                print(f"Step {event.step}...")
            elif isinstance(event, ToolStart):
                print(f"  Using tool: {event.tool_call.name}")
            elif isinstance(event, GenerationEnd):
                print(f"  Tokens used: {event.usage.total_tokens}")

asyncio.run(main())
Two execution methods:
  • run() - Returns AgentResult when complete. Best for most use cases.
  • stream() - Yields events as they occur. Use for progress bars, logging, or real-time UIs.
See Results for working with AgentResult.

Next Steps