Multi-Agent Orchestration
Agentix supports coordinator / sub-agent patterns. Define sub-agents on the coordinator's options; the coordinator automatically receives a Task tool it can use to delegate work to them.
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
)
Sub-agents do not inherit MCP servers from the coordinator. Provide
mcp_serversonAgentDefinitionexplicitly if a sub-agent needs them.
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, context: SubagentHookContext) -> None:
print(f"Sub-agent starting: {hook_input['child_name']}")
async def on_subagent_stop(hook_input: dict, context: 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
)