# Agent Builder

> Use when building a new agent harness, designing tool systems, or structuring multi-agent workflows. Provides patterns, templates, and decision trees for harness engineering.

- Skill: `fareedkhan-dev/agent-builder` (Agent Skill)
- Install (CLI): `npx skillmds@latest add fareedkhan-dev/agent-builder`
- Raw SKILL.md: https://api.skillmd.com/api/skills/fareedkhan-dev/agent-builder/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: fareedkhan-dev (https://skillmd.com/u/fareedkhan-dev)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/fareedkhan-dev/agent-builder

---


# Agent Builder Skill

## When to use this skill
Load this skill when the user wants to:
- Build a new agent from scratch
- Design a tool for an agent
- Structure a multi-agent system
- Debug an agent loop that isn't working
- Choose between agent architectures

## Core principle

The agent is always the model. Your job is the harness.

```
Harness = Tools + Knowledge + Observation + Action + Permissions
```

Never try to encode intelligence in your harness code. Give the model
clean tools, clear context, and get out of the way.

## The minimal agent (always start here)

```python
from anthropic import Anthropic
client = Anthropic()

def agent_loop(messages, tools, dispatch, system):
    while True:
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            system=system, messages=messages,
            tools=tools, max_tokens=8000,
        )
        messages.append({"role": "assistant", "content": response.content})
        if response.stop_reason != "tool_use":
            return
        results = []
        for block in response.content:
            if block.type == "tool_use":
                output = dispatch[block.name](block.input)
                results.append({"type": "tool_result",
                                 "tool_use_id": block.id, "content": output})
        messages.append({"role": "user", "content": results})
```

Do not add anything until you need it. Every mechanism should earn its place.

## Tool design checklist

Before writing a tool, ask:
- [ ] Is the name a verb? (bash, read, write — not "file_manager")
- [ ] Does the description say WHEN to use it, not just what it does?
- [ ] Is the input schema minimal? No optional fields unless truly needed.
- [ ] Does it return plain text the model can reason about?
- [ ] Does it have a hard timeout?
- [ ] Is output truncated to a safe length (≤50k chars)?

## Tool description formula

```
"[Action verb] [what it does]. Use when [specific situation].
[What it returns]. [Any important limits]."
```

Example:
```
"Read a file and return numbered lines. Use when you need to inspect
file content or reference specific line numbers. Returns up to 50,000
characters. Use start_line/end_line for large files."
```

## Architecture decision tree

```
One task, one user, no persistence needed?
    → s01: minimal loop + bash

Need file read/write/search?
    → s02: extended tool dispatch

Need the agent to plan before acting?
    → s03: add todo_write tool

Task too big for one context window?
    → s04: subagent isolation

Need domain-specific knowledge?
    → s05: skill loading

Long-running session, context will overflow?
    → s06: compression + memory file

Complex multi-step project spanning sessions?
    → s07: task graph with dependencies

Slow operations (builds, tests)?
    → s08: background tasks

Work that parallelises across specialties?
    → s09+: agent teams with mailboxes

Need isolation between parallel tasks?
    → s12/s23: git worktrees
```

## Common mistakes

**Putting logic in the harness instead of trusting the model**
Bad:  `if "error" in output: retry_with_different_approach()`
Good: return the error to the model and let it decide

**Giant system prompts**
Bad:  5,000-word system prompt covering every scenario
Good: load domain knowledge on-demand via skills (s05)

**Blocking the loop on slow operations**
Bad:  `output = subprocess.run("npm test", timeout=300)`
Good: run in background thread, notify when done (s08)

**Shared mutable state between subagents**
Bad:  subagents writing to the same dict/file without locks
Good: each subagent has its own isolated context (s04, s12)

## Subagent pattern template

```python
def spawn_subagent(prompt: str, tools=EXTENDED_TOOLS, dispatch=EXTENDED_DISPATCH) -> str:
    messages = [{"role": "user", "content": prompt}]
    while True:
        response = client.messages.create(
            model=MODEL, system=SUBAGENT_SYSTEM,
            messages=messages, tools=tools, max_tokens=8000,
        )
        messages.append({"role": "assistant", "content": response.content})
        if response.stop_reason != "tool_use":
            break
        results = dispatch_tools(response.content, dispatch)
        messages.append({"role": "user", "content": results})
    return "".join(b.text for b in messages[-1]["content"] if hasattr(b, "text"))
```

