Multi-Agent System#
lit-mux supports deploying multiple AI agents with distinct configurations, roles, and capabilities. Agents can communicate with each other, operate autonomously via heartbeat, and be organized into hierarchies.
Agent Concepts#
What is an Agent?#
An agent is a configured AI entity with:
- Identity: Unique ID, name, and role
- Backend: Which LLM to use (Claude, Gemini, Ollama, etc.)
- Tools: Which MCP servers are available
- Behavior: System prompt, temperature, working directory
- Sessions: Conversations belong to agents
Agent vs Session#
| Concept | Purpose | Lifecycle |
|---|---|---|
| Agent | Configuration template | Long-lived, persisted |
| Session | Conversation instance | Created per conversation |
Think of agents as "personalities" and sessions as "conversations with that personality."
Creating Agents#
Via API#
import httpx
agent = httpx.post("http://localhost:8000/agents", json={
"id": "code-reviewer",
"name": "Code Reviewer",
"backend": "claude-cli",
"model": "claude-sonnet-4-20250514",
"role": "Senior Engineer",
"system_prompt": "You are a senior engineer reviewing code...",
"temperature": 0.3,
"working_dir": "/home/projects",
"mcp_servers": ["git", "filesystem"]
}).json()
Via Configuration File#
Agents can be defined in JSON files at ~/.config/lit-mux/agents/:
{
"id": "code-reviewer",
"name": "Code Reviewer",
"backend": "claude-cli",
"model": "claude-sonnet-4-20250514",
"role": "Senior Engineer",
"system_prompt": "You are a senior engineer reviewing code for quality, security, and best practices.",
"temperature": 0.3,
"working_dir": "/home/projects",
"mcp_servers": ["git", "filesystem"],
"metadata": {
"department": "engineering",
"specialty": "code-review"
}
}
Agent Configuration#
Core Fields#
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier |
name |
string | Human-readable name |
backend |
string | LLM backend (claude-cli, gemini, ollama, etc.) |
model |
string | Model ID for the backend |
role |
string | Agent's role/title |
system_prompt |
string | Instructions for the agent |
temperature |
float | Creativity (0.0-1.0) |
max_tokens |
int | Maximum response length |
working_dir |
string | Filesystem root for tools |
MCP Configuration#
{
"mcp_servers": ["git", "jira", "filesystem"],
"mcp_server_overrides": {
"jira": {
"project_key": "PROJ"
},
"filesystem": {
"allowed_directories": ["/home/projects"]
}
}
}
Heartbeat Configuration#
For autonomous agents that wake periodically:
{
"heartbeat_enabled": true,
"heartbeat_interval": 30,
"heartbeat_prompt": "Check for new tasks and update status...",
"heartbeat_stimuli": [
{
"type": "jira_tickets",
"project": "PROJ",
"jql": "assignee = currentUser() AND status = 'In Progress'"
},
{
"type": "git_commits",
"repo": "/home/projects/main"
}
]
}
Agent-to-Agent Messaging#
Agents can send messages to each other via typed message queues.
Sending Messages#
# From one agent to another
response = httpx.post("http://localhost:8000/messages/agent", json={
"from_agent_id": "project-manager",
"to_agent_id": "code-reviewer",
"content": "Please review PR #123",
"priority": "HIGH"
})
message_id = response.json()["id"]
Message Priority#
| Priority | Use Case |
|---|---|
LOW |
Background tasks, FYI |
NORMAL |
Standard requests |
HIGH |
Time-sensitive work |
URGENT |
Immediate attention needed |
Checking Message Status#
status = httpx.get(f"http://localhost:8000/messages/{message_id}").json()
# Returns: { "status": "delivered", "delivered_at": "..." }
MCP Tool for Messaging#
Agents can also send messages using the built-in MCP tool:
mcp__agent-messaging__send_agent_message(
to_agent_id="code-reviewer",
content="Please review PR #123",
priority="HIGH"
)
Agent Hierarchy#
Agents can be organized into parent-child relationships:
{
"id": "frontend-dev",
"name": "Frontend Developer",
"parent_id": "tech-lead",
"organization_id": "engineering-team"
}
Use Cases#
- Team Structure: Tech lead → developers
- Specialization: General assistant → domain experts
- Delegation: Manager agents that route to specialists
Organizations (Agent Groups)#
Group agents into organizations for multi-tenant deployments:
# Create organization
org = httpx.post("http://localhost:8000/organizations", json={
"name": "Engineering Team",
"metadata": {"department": "engineering"}
}).json()
# Create agent in organization
agent = httpx.post("http://localhost:8000/agents", json={
"id": "eng-assistant",
"name": "Engineering Assistant",
"organization_id": org["id"],
...
}).json()
Heartbeat System#
The heartbeat system enables autonomous agent behavior. Agents wake periodically to:
- Check for stimuli (new data, events, messages)
- Process and respond to stimuli
- Return to sleep
Stimuli Types#
| Stimulus | Description |
|---|---|
jira_tickets |
Check for Jira ticket updates |
git_commits |
Monitor repository commits |
inbox_messages |
Check message queue |
mattermost_check |
Monitor chat channels |
Heartbeat Flow#
┌─────────────┐
│ Sleep │
└──────┬──────┘
│ (interval elapsed)
▼
┌─────────────┐
│ Wake Up │
└──────┬──────┘
│
▼
┌─────────────┐
│ Check │
│ Stimuli │
└──────┬──────┘
│
▼
┌─────────────────┐
│ Stimuli Found? │
└────┬───────┬────┘
│ No │ Yes
│ ▼
│ ┌─────────────┐
│ │ Process │
│ │ Stimuli │
│ └──────┬──────┘
│ │
▼ ▼
┌─────────────┐
│ Sleep │
└─────────────┘
Heartbeat API#
# Check heartbeat status
status = httpx.get(f"http://localhost:8000/agents/{agent_id}/heartbeat/status").json()
# Returns: { "enabled": true, "last_wake": "...", "next_wake": "..." }
# WebSocket for real-time heartbeat events
ws = websocket.connect("ws://localhost:8000/ws/heartbeat")
while True:
event = ws.recv()
print(f"Heartbeat event: {event}")
Agent Sessions#
Each agent maintains its own sessions:
# Get sessions for an agent
sessions = httpx.get(f"http://localhost:8000/agents/{agent_id}/sessions").json()
# Search agent's sessions
sessions = httpx.get(
f"http://localhost:8000/agents/{agent_id}/sessions?q=code review"
).json()
Session Types#
| Session | Purpose |
|---|---|
primary_session_id |
Main conversation session |
heartbeat_session_id |
Autonomous heartbeat session |
processing_session_id |
Background task processing |
Agent Status#
Track agent activity:
agent = httpx.get(f"http://localhost:8000/agents/{agent_id}").json()
print(agent["status"]) # idle, receiving, processing, sending, error, offline
print(agent["active_conversations"])
print(agent["messages_in_queue"])
print(agent["last_activity"])
Streaming to Agents#
Stream messages directly to an agent (creates/uses their primary session):
with httpx.stream("POST",
f"http://localhost:8000/agents/{agent_id}/stream",
json={"message": "Review this code..."}
) as response:
for line in response.iter_lines():
print(line)
Best Practices#
Agent Design#
- Single Responsibility: Each agent should have a focused role
- Clear System Prompts: Be explicit about agent behavior
- Appropriate Tools: Only enable MCP servers the agent needs
- Temperature Tuning: Lower for precise tasks, higher for creative
Multi-Agent Patterns#
- Hub and Spoke: Central coordinator routes to specialists
- Pipeline: Agents process in sequence (e.g., draft → review → publish)
- Peer Network: Agents collaborate as equals
- Hierarchical: Management layers with delegation
Performance#
- Session Reuse: Use existing sessions when possible
- Message Batching: Group related messages
- Heartbeat Tuning: Balance responsiveness vs. resource usage
Example: Code Review Team#
// tech-lead.json
{
"id": "tech-lead",
"name": "Tech Lead",
"role": "Technical Lead",
"system_prompt": "You coordinate code reviews and delegate to specialists.",
"mcp_servers": ["git", "jira", "agent-messaging"]
}
// frontend-reviewer.json
{
"id": "frontend-reviewer",
"name": "Frontend Reviewer",
"role": "Frontend Specialist",
"parent_id": "tech-lead",
"system_prompt": "You review frontend code for React best practices.",
"mcp_servers": ["git", "filesystem"]
}
// backend-reviewer.json
{
"id": "backend-reviewer",
"name": "Backend Reviewer",
"role": "Backend Specialist",
"parent_id": "tech-lead",
"system_prompt": "You review backend code for security and performance.",
"mcp_servers": ["git", "filesystem"]
}
The tech lead receives review requests, analyzes the PR, and delegates to the appropriate specialist.