Back to Blog

Context Engineering for Multi-Agent AI: How to Feed Your Agents the Right Information

Architecture··11 min read·
context engineeringmulti-agentCLAUDE.mdSOUL.mdarchitecture

Your agent just rewrote your database schema. Not because you asked it to — because its context included migration documentation from a different project, and it decided the current schema was "inconsistent." The migrations ran. The foreign keys changed. Your API broke in production.

The agent did exactly what it was told to do, given the information it had. The problem was what it knew — and what it shouldn't have known.

Context engineering is the discipline of controlling what information reaches each agent. In a single-agent setup, it's manageable. You toss everything into one context window and hope the model figures out what's relevant. In a multi-agent system, that approach falls apart fast. Different agents need different slices of your project knowledge, and getting the boundaries wrong creates agents that are either helplessly uninformed or dangerously overinformed.

Three Layers of Agent Context

Every agent in a well-structured system draws from three layers of context, each with a different lifecycle and scope.

Identity context (SOUL.md) defines who the agent is. Its role, capabilities, boundaries, and communication style. This is the most stable layer — a test runner agent's identity doesn't change between sessions or even between projects. It runs tests, reports results, and doesn't touch production code.

Project context (CLAUDE.md) defines the environment the agent works in. The tech stack, conventions, file structure, and project-specific rules. This layer changes when the project changes — a new dependency, a renamed directory, an updated deployment process.

Memory context (MEMORY.md + topic files) captures what the agent has learned through experience. Debugging insights, architectural decisions, user preferences. This layer evolves continuously as the project progresses. (For a deep dive on memory architecture, see AI Agent Memory Management.)

The three layers have different owners and different update frequencies:

| Layer | File | Owner | Update Frequency | |-------|------|-------|-----------------| | Identity | SOUL.md | Agent designer | Rarely (role changes) | | Project | CLAUDE.md | Team lead / human | Weekly (project evolves) | | Memory | MEMORY.md | Agent (auto) + human | Daily (learning) |

Mixing these layers is the most common context engineering mistake. When identity information ("I am a test runner") lives in the project file, every project gets its own copy of agent definitions. When project conventions live in memory files, they drift as agents overwrite them with session observations. Keep the layers separate and you get clean update boundaries.

Designing SOUL.md

A SOUL.md file is an agent's identity document. It tells the system — and the agent itself — what this agent is, what it does, and what it doesn't do. Here's the template:

# Agent: Frontend Developer

## Role
Build and maintain React components, handle styling,
and ensure accessibility compliance.

## Scope
- `src/components/` — full read/write access
- `src/styles/` — full read/write access
- `src/lib/` — read-only (consume, don't modify)

## Boundaries
- Never modify API routes or server-side code
- Never run database migrations
- Never push to main without PR review

## Communication
- Report progress after each component completed
- Flag accessibility issues as warnings, not blockers
- Use conventional commit format for all messages

## Tools
- read, write, edit, glob, grep

The five sections — Role, Scope, Boundaries, Communication, Tools — cover the essential dimensions of agent identity. Role and Scope define what the agent does. Boundaries define what it doesn't. Communication defines how it reports. Tools define what it can physically access.

The Boundaries section is arguably the most important. An agent without boundaries will fill any vacuum with helpful intentions. A documentation agent that can access the deployment pipeline will eventually "fix" a deploy script. A test runner with write access to source files will eventually "fix" a failing test by changing the implementation. Boundaries are how you prevent well-meaning agents from causing harm.

In a ClawPort workspace, SOUL.md files live in an agents/ directory and are auto-discovered by scanning for this exact file naming pattern. Each subdirectory represents an agent:

agents/
├── frontend-dev/
│   └── SOUL.md
├── test-runner/
│   └── SOUL.md
├── reviewer/
│   └── SOUL.md
├── deployer/
│   └── SOUL.md
└── scribe/
    └── SOUL.md

The Agent Registry

SOUL.md files define individual agents. The registry assembles them into a team. It resolves which agents exist, what they're configured to do, and how they relate to each other.

The resolution order matters because it determines which configuration wins when there are conflicts:

  1. User override$WORKSPACE_PATH/clawport/agents.json takes highest priority. If you've explicitly configured an agent, that configuration is authoritative.
  2. Auto-discovery — the system scans the agents/ directory for SOUL.md files and builds registry entries from their content. Role becomes the agent's description. Tools become the agent's capabilities. This is how most agents get registered.
  3. Bundled defaults — a built-in agents.json provides fallback definitions for common archetypes.

Auto-discovery is the default path for most teams. You create SOUL.md files, and the registry picks them up automatically. The override exists for cases where auto-discovery doesn't capture something — maybe you need a custom tool list, or you want to override the discovered name.

When multiple workspaces are configured (common in monorepos or multi-project setups), the registry merges agents from all workspaces. Name collisions are resolved by workspace priority — agents from higher-priority workspaces shadow agents with the same name from lower-priority ones.

Each auto-discovered agent gets assigned a color from a rotating palette of 15 options. This sounds cosmetic, but it's surprisingly important for observability. When you're watching five agents work in a dashboard, color-coding is how you instantly identify which agent produced which output. The palette rotates deterministically — the same agent always gets the same color across sessions.

Context Scoping

Context scoping is the principle of least privilege applied to information. Each agent should have access to the minimum context it needs to do its job, and nothing more.

This plays out across four dimensions:

Information scoping controls what files and knowledge each agent can see. A test runner doesn't need your deployment credentials. A documentation agent doesn't need your cost optimization data. Scope memory paths so each agent reads from and writes to its own subdirectory.

Tool assignment controls what actions each agent can take. The default tool sets from auto-discovery reflect this:

| Agent | Tools | |-------|-------| | Frontend dev | read, write, edit, glob, grep | | Test runner | read, bash (test commands only) | | Reviewer | read, grep, github-api | | Deployer | bash, github-api | | Scribe | read, write, edit |

Notice the test runner can't write files. The reviewer can't edit code. The scribe can't run bash commands. These constraints aren't limitations — they're safety rails that prevent agents from wandering outside their competence.

Memory isolation gives each agent its own memory path. When agents share a single memory directory, they overwrite each other's context. A test runner's notes about flaky tests aren't relevant to the frontend dev, and vice versa. Isolated memory paths prevent cross-contamination.

Model selection matches agent complexity to model capability. Not every agent needs Opus. A memory consolidation agent that summarizes daily logs can run on Haiku at $1 per million input tokens instead of Opus at $15 per million output tokens. A code reviewer that needs to understand architectural implications probably does need the stronger model. Match the model to the task, not the team.

The Orchestrator Pattern

In any multi-agent system, you need at least one agent with broad context — the orchestrator. This is the agent that decides which specialist to invoke, what context to pass, and how to combine results.

The key insight is that orchestrators and specialists need fundamentally different context windows:

Orchestrators need broad, shallow context: the project structure, the agent registry, the current task list, high-level status of each agent. They don't need to read individual source files or understand implementation details.

Specialists need narrow, deep context: the specific files they're modifying, the relevant test suites, the conventions for their domain. They don't need to know about other agents or the overall project timeline.

A worked example: the pipeline health check. The orchestrator knows which agents exist, what their schedules are, and which pipelines connect them. It constructs a health check prompt that includes:

  1. An overall health summary request
  2. Agent ownership audit — flagging any UNOWNED jobs
  3. Broken edge detection — finding errored source jobs
  4. Schedule gap analysis — identifying infrequent or overdue jobs
  5. Missing delivery checks — jobs with no configured output target
  6. Top 2-3 actionable recommendations

The orchestrator sends this prompt and streams back the analysis. It doesn't need to know how each individual agent works internally — it just needs the graph structure and status data. The specialist agents, in turn, don't need to know they're being health-checked. They just do their jobs, and the orchestrator observes the results.

This separation of concerns keeps context windows manageable. An orchestrator with 50 agents doesn't need 50 agents' worth of deep context. It needs a registry and a status board.

Naming Conventions as Context Signals

This might seem trivial, but naming conventions carry more context signal than most teams realize.

Agent names should be human-readable, descriptive, and consistent. The registry converts slugs to display names (test-runnerTest Runner), but the slug itself should be meaningful. When you see test-runner in a log stream, you immediately know what it does. When you see agent-7, you don't.

The same principle applies to the visual identity layer. Each agent gets a consistent color from the palette, which means test-runner is always the same shade of green in dashboards, log streams, and org maps. Over time, you develop an intuitive sense: green output means tests, purple means reviews, yellow means documentation. This is context engineering for humans — making the agent system legible at a glance.

Naming conventions for files follow the same principle. agents/test-runner/SOUL.md is self-documenting. config/agent_7.yaml requires you to open the file to understand it. (For more on managing agent teams at scale, see Taming Agent Sprawl.)

Reference Workspace Layout

Here's a complete directory tree for a well-structured multi-agent workspace:

project/
├── CLAUDE.md                      # Project context
├── agents/
│   ├── frontend-dev/
│   │   └── SOUL.md
│   ├── test-runner/
│   │   └── SOUL.md
│   ├── reviewer/
│   │   └── SOUL.md
│   ├── deployer/
│   │   └── SOUL.md
│   └── scribe/
│       └── SOUL.md
├── .claude/
│   └── projects/
│       └── your-project/
│           └── memory/
│               ├── MEMORY.md      # <200 lines, always loaded
│               ├── patterns.md    # Evergreen: confirmed conventions
│               ├── architecture.md # Evergreen: design decisions
│               └── 2026-03-10.md  # Daily log
├── clawport/
│   └── agents.json                # Optional: manual overrides
└── openclaw.json                  # Runtime config (search, flush)

Common mistakes in workspace organization:

Flat agent directories. Putting all SOUL.md files in a single agents/ directory without subdirectories means you can't add per-agent configuration files later. Always use agents/{name}/SOUL.md.

Shared memory. Routing all agents to the same memory directory. This works for 1-2 agents and falls apart at 3+. Isolate memory paths early.

Missing CLAUDE.md. The project context file is how every agent understands the environment. Without it, agents rely on memory alone, which may be stale or incomplete.

Overstuffed SOUL.md. Putting project-specific instructions in the identity file. SOUL.md should be portable across projects. If an instruction is project-specific, it belongs in CLAUDE.md or a project-scoped config.

No orchestrator. Running multiple specialist agents without an orchestrator means no agent has visibility into the overall system. Someone needs to be the coordinator, even if it's just a simple dispatcher. (For pipeline orchestration patterns, see How to Build AI Agent Pipelines.)

Context Engineering Is System Design

Context engineering isn't a one-time setup task. It's an ongoing system design practice, just like API design or database schema design. The interfaces between agents — what context flows where, who can read what, how information propagates — are the architecture of your multi-agent system.

Get the context boundaries right and your agents become a team: coordinated, specialized, and productive. Get them wrong and you get a group of individuals stepping on each other's work, overwriting each other's context, and making confident decisions based on incomplete information.

The principles are straightforward: separate identity from project from memory, scope context to the minimum needed, use naming as a context signal, and designate an orchestrator for system-wide visibility. The tooling to enforce these principles is what makes them practical at scale.

Designing a Claude Code agent team? ClawPort gives you auto-discovery, the org map, and agent profiles to get context boundaries right from day one. Free and open source.