Multi-Agent Orchestration
Agentix supports coordinator / sub-agent patterns. Define sub-agents on the coordinator's options; the coordinator automatically receives an Agent tool it can use to delegate work to them.
How it works
The coordinator receives an Agent tool automatically when agents are configured. It delegates tasks to sub-agents by calling that tool; each sub-agent runs its own independent agent loop and returns a result. Sub-agents are isolated — they do not inherit the coordinator's MCP servers or skills.
Basic setup
from agentix import AgentixAgentOptions, AgentixClient, AgentDefinition, ResultMessage
options = AgentixAgentOptions(
name="coordinator",
provider="anthropic",
model="claude-sonnet-4-20250514",
system_prompt="You are a coordinator. Delegate research to the researcher and writing to the writer.",
agents={
"researcher": AgentDefinition(
name="researcher",
description="Searches the web and gathers information on a topic.",
tools=["WebSearch", "WebFetch"],
),
"writer": AgentDefinition(
name="writer",
description="Takes research notes and produces polished written content.",
tools=["Read", "Write"],
),
}
)
async def main():
async with AgentixClient(options) as client:
async for msg in client.query("Write a short article about Python asyncio."):
if isinstance(msg, ResultMessage):
print(msg.result)
AgentDefinition fields
from agentix import AgentDefinition
AgentDefinition(
name="my-sub-agent", # required — must match the dict key in agents={}
description="What it does.", # required — shown to the coordinator when delegating
prompt="", # additional system prompt injected for this sub-agent
tools=["Read", "Glob"], # allow-list of tools; empty = inherit coordinator's config
provider="openai", # optional — override LLM provider
model="gpt-4o", # optional — override model
memory="none", # "none" | "user" | "project" | "local" — persistent memory scope
skills=None, # None = default discovery; explicit list to restrict
mcp_servers={}, # sub-agent-specific MCP configs (not inherited from coordinator)
disallow_system_skills=[], # exclude specific built-in skills; "all" disables all
agent_type=None, # optional label for hook differentiation
)
::: warning Sub-agent isolation
Sub-agents do not inherit MCP servers or user/project skills from the coordinator. If a sub-agent needs MCP tools, declare them explicitly in AgentDefinition.mcp_servers. If it needs skills, set skills explicitly — None triggers default discovery only for general-purpose agents.
:::
Sub-agent memory scoping
The memory field controls where a sub-agent stores persistent memories across runs:
| Value | Storage location | Use when |
|---|---|---|
"none" | — | Sub-agent is stateless (default) |
"project" | .agentix/ (relative to cwd) | Sub-agent builds per-project knowledge |
"user" | ~/.agentix/ | Sub-agent learns user preferences across projects |
"local" | .agentix-local/ | Machine-local facts; not committed to source control |
AgentDefinition(
name="researcher",
description="Gathers and retains domain knowledge.",
tools=["WebSearch", "WebFetch"],
memory="project", # researcher accumulates knowledge in .agentix/
)
See Memory for the full guide on agent and sub-agent memory.
Hooks for sub-agent events
from agentix import HookMatcher, SubagentHookContext
async def on_subagent_start(hook_input: dict, tool_use_id: str | None, ctx: SubagentHookContext) -> None:
print(f"Sub-agent starting: {hook_input['child_name']}")
async def on_subagent_stop(hook_input: dict, tool_use_id: str | None, ctx: SubagentHookContext) -> None:
print(f"Sub-agent finished: {hook_input['child_name']}")
options = AgentixAgentOptions(
hooks={
"SubagentStart": [HookMatcher(matcher=None, hooks=[on_subagent_start])],
"SubagentStop": [HookMatcher(matcher=None, hooks=[on_subagent_stop])],
}
)
File-based sub-agent definitions
Sub-agents can also be defined as Markdown files under .agentix/agents/. The coordinator discovers them automatically when cwd is set.
---
name: researcher
description: Searches the web and summarises findings.
tools:
- WebSearch
- WebFetch
memory: project
---
You are a research specialist. Always cite your sources.
Programmatic definitions in AgentixAgentOptions.agents take precedence over file-based ones with the same name.
Built-in fallback agent
When no registered sub-agent matches a delegation request, Agentix falls back to the built-in agentix_general_agent — a capable general-purpose agent that inherits the coordinator's provider and model. It is always registered and requires no configuration.
Strict agent validation
Enable strict_agent_validation to catch configuration errors at startup — recommended for CI:
options = AgentixAgentOptions(
strict_agent_validation=True, # raises ConfigurationError on invalid sub-agent definitions
agents={
"writer": AgentDefinition(
name="writer",
description="", # ← empty description raises ConfigurationError
)
}
)
Provider and model override
Sub-agents inherit the coordinator's provider and model by default. Override per sub-agent:
AgentDefinition(
name="cheap-summariser",
description="Summarises long documents quickly.",
tools=["Read"],
provider="openai",
model="gpt-4o-mini", # cheaper model for simple summarisation
)