Build Your Own Agent

Practical guidance drawn from all 8 frameworks.

Start with TypeScript or Python. Build the agent loop first, then add 3-4 tools, session persistence, system prompt, and a channel adapter. Memory search comes last. Use files for state -- add a database only when you actually need one. For studying codebases: HermitClaw first (smallest), then PicoClaw, pi, Spacebot, IronClaw, OpenClaw.

Core Architecture Decisions

Language Choice

LanguageProsConsFrameworks
TypeScriptFast iteration, rich npm ecosystem, same language for web UIHigher memory, slower startup, no static binaryOpenClaw, pi
RustMemory safety, single binary, excellent concurrencySteep learning curve, slower developmentIronClaw, Spacebot
GoSingle binary, fast compilation, low memory, easy concurrencyLess expressive type systemPicoClaw
PythonFastest to prototype, best ML/AI library ecosystemSlowest runtime, GIL, dependency managementHermitClaw

My take: start with TypeScript or Python for prototyping. Move to Go or Rust if you need deployment efficiency or you're targeting constrained environments.

Loop Style

This depends on what you're building:

  • Request-response (most frameworks): User sends message, agent processes, returns response. Best for assistants, coding agents, chatbots.
  • Continuous (HermitClaw): Agent thinks on its own schedule. Best for research agents, monitoring, autonomous systems.
  • Delegation (Spacebot): Orchestrator dispatches to specialized workers. Best for multi-user, high-concurrency, team environments.

State Management

Every framework here stores state as files or SQLite. None require an external database -- IronClaw supports PostgreSQL but also works with libSQL.

Start with files. JSON for structured data, markdown for human-readable content. You can always add a database later, but files are debuggable, portable, and simple.

Essential Components Checklist

Build these roughly in this order:

1. LLM Client

  • Call an LLM API with messages and tools
  • Parse tool call responses
  • Handle streaming (or buffer for simplicity)
  • Support at least 2 providers (for fallback)

2. Agent Loop

  • Send messages + tool definitions to LLM
  • Execute tool calls and append results
  • Loop until LLM returns text (no tool calls)
  • Set a max iteration limit (10-20)

3. Basic Tools

  • Shell command execution
  • File read/write
  • Web search (Brave API or similar)
  • 3-4 tools is plenty to start. Add more as you need them.

4. Session Persistence

  • Save conversation history to disk (JSON/JSONL)
  • Load history on session resume
  • Session key routing (channel + chat ID)

5. System Prompt

  • Load identity files (AGENTS.md, SOUL.md)
  • Inject tool descriptions
  • Add runtime context (date, model, capabilities)

6. Context Window Management

  • Estimate token count (chars/4 is fine to start)
  • Implement basic compaction (LLM summarization of old messages)
  • Emergency fallback: drop oldest messages

7. Channel Adapter

  • Define a channel interface (receive messages, send responses)
  • Implement one channel (Telegram or Discord are easiest)
  • Route messages to correct session

8. Memory

  • Workspace files (MEMORY.md pattern)
  • Optional: embeddings + vector search for semantic retrieval
  • Optional: daily note logging

Memory System Design

Decision Tree

  1. Do you need cross-session memory?

    • No → Session history + AGENTS.md is enough (pi approach)
    • Yes → Continue
  2. How much memory?

    • Small (fits in system prompt) → File injection (PicoClaw approach: MEMORY.md + daily notes)
    • Large → You need search. Continue.
  3. What kind of search?

    • Keyword only → BM25/FTS is fast and good enough
    • Semantic → Add embeddings + vector search
    • Both → Hybrid with RRF (OpenClaw/IronClaw/Spacebot approach)
  4. Real-time or pre-computed?

    • Real-time → Search on every query (most frameworks)
    • Pre-computed → Background bulletin synthesis (Spacebot Cortex approach, better for high-traffic)

Embedding Setup

If you go the vector route, here's what I'd pick:

  • Model: all-MiniLM-L6-v2 (384 dims, fast, local) or text-embedding-3-small (OpenAI, better quality)
  • Storage: SQLite + sqlite-vec (simplest), LanceDB (Spacebot), or PostgreSQL + pgvector (IronClaw)
  • Chunk size: 500-1000 tokens per chunk
  • Search: Always combine with FTS via RRF for best results

Tool System Design

Minimum Viable Tool Set

Every framework ends up with these:

  1. Shell execution -- exec/bash/shell
  2. File read -- Read file contents
  3. File write -- Create/overwrite files
  4. File edit -- Surgical find-and-replace (better than full rewrites)

Add as needed: web search, web fetch, message sending, browser automation.

Tool Definition Pattern

All of them use the same shape (it matches the LLM APIs):

typescriptinterface Tool { name: string; description: string; parameters: JSONSchema; execute(args: unknown): Promise<ToolResult>; }

Operations Pattern (from pi)

A clean way to make tool I/O pluggable:

typescriptinterface FileOperations { read(path: string): Promise<string>; write(path: string, content: string): Promise<void>; } function createReadTool(ops: FileOperations): Tool { return { name: 'read', execute: (args) => ops.read(args.path), }; }

Now you can redirect tools to SSH, Docker, or any other backend without touching the tool logic itself.

Security Considerations

Threat Model

Your agent has tools, and the LLM decides which ones to call. The LLM can be manipulated by:

  1. Prompt injection -- Malicious content in web pages, emails, or user input that instructs the LLM to take harmful actions
  2. Data exfiltration -- The LLM sends private data to external services via tool calls
  3. Privilege escalation -- The LLM runs commands that exceed intended permissions

Minimum Security (Do This)

  • Restrict exec tool to a working directory
  • Block obviously dangerous commands (rm -rf /, sudo, etc.)
  • Wrap untrusted content with markers (OpenClaw pattern)
  • Log all tool calls for audit

Better Security (If You Care)

  • Run tools in a container/sandbox
  • Implement tool allowlists per context (Spacebot's process separation)
  • Add approval workflow for destructive operations (IronClaw pattern)
  • Scan for credential leaks in tool output (IronClaw leak detector)

Best Security (IronClaw's Approach)

  • WASM sandbox for untrusted tools
  • Capability-based permissions (deny by default)
  • Credential injection at the host boundary (tools never see secrets)
  • Endpoint allowlisting for HTTP requests
  • Prompt injection detection (Aho-Corasick + regex)

If you're reading these codebases to learn agent architecture, here's the order I'd suggest:

  1. Start with HermitClaw -- Smallest codebase (~3K lines, 14 files). You can read the whole thing in an afternoon. The Generative Agents memory system and continuous thinking loop are worth understanding even if you end up building something different.

  2. Then PicoClaw -- Clean Go code (~20K lines). Shows how to build a complete agent with tools, channels, and sessions while staying resource-efficient. A good model for "the minimum viable agent framework."

  3. Then pi -- The extension system and pluggable operations pattern are beautifully designed. Worth studying if you want to build something extensible.

  4. Then Spacebot -- The delegation model (Channel/Branch/Worker) is the most creative architecture in this group. Go here for multi-user or high-concurrency designs.

  5. Then IronClaw -- Deep security architecture. Go here if security is a priority or you want to understand WASM sandboxing.

  6. Finally OpenClaw -- The most complete framework. Save it for last -- it's the most complex, but also the most production-hardened.

"If You Want X, Study Y"

If you want...Study...Specifically...
Simplest possible agentHermitClawbrain.py -- the entire loop in one file
Best tool interface designpicore/tools/*.ts -- operations pattern
Best memory systemSpacebotmemory/ -- typed graph + bulletin synthesis
Best security modelIronClawsafety/ + tools/wasm/ -- 5 security layers
Best channel abstractionOpenClawchannels/plugins/ -- most mature multi-channel system
Best extension systempicore/extensions/ -- 20+ event types, full lifecycle
Smallest footprintPicoClawThe whole codebase -- every design decision is about efficiency
Multi-user concurrencySpacebotagent/channel.rs -- event loop + delegation
Context window managementSpacebotagent/compactor.rs -- tiered compaction
Autonomous agent behaviorHermitClawbrain.py -- continuous thinking + reflection
Hardware/IoT integrationPicoClawtools/i2c_linux.go -- direct syscall tools
Cross-provider LLM supportpipackages/ai/ -- unified API with context handoff