Multi-Agent Collaboration
Teams of specialized agents working on the same goal — one researches, one writes, one reviews, one publishes. They share a memory space so each agent can see what the others have done and make decisions accordingly.
The Challenge
Multi-agent systems face coordination challenges:
- Shared context - All agents need to see what others have done
- Work attribution - Track which agent performed which action
- Handoffs - One agent completes work, another picks up
- Parallel work - Multiple agents working simultaneously without conflicts
- Decision consistency - Agents must respect decisions made by others
How Memtrace Helps
Memtrace enables true multi-agent collaboration:
- Shared sessions - All agents read/write to same memory space
- Agent attribution - Every memory tagged with agent_id
- Cross-agent queries - Agents can filter by specific agents or see all
- Decision visibility - All agents see decisions made by others
- Temporal coordination - Time-based queries show recent work across all agents
Example: Content Pipeline
A team of agents creates content: researcher gathers information, writer drafts content, editor reviews, publisher distributes.
Agent Setup
from memtrace import Memtrace, RegisterAgentRequest, CreateSessionRequest
memtrace = Memtrace("http://localhost:9100", "mtk_...")
# Register specialized agents
researcher = memtrace.register_agent(RegisterAgentRequest(
name="researcher",
description="Gathers information and sources",
))
writer = memtrace.register_agent(RegisterAgentRequest(
name="writer",
description="Drafts articles from research",
))
editor = memtrace.register_agent(RegisterAgentRequest(
name="editor",
description="Reviews and improves drafts",
))
publisher = memtrace.register_agent(RegisterAgentRequest(
name="publisher",
description="Publishes approved content",
))
Shared Session
# Create shared session for content project
session = memtrace.create_session(CreateSessionRequest(
agent_id=researcher.id,
metadata={
"project": "golang-concurrency-article",
"deadline": "2026-02-20",
"target_platform": "blog",
},
))
Phase 1: Research
# Researcher stores findings
memtrace.remember(
researcher.id,
"Go channels enable safe communication between goroutines",
session_id=session.id,
tags=["research", "channels", "concurrency"],
importance=0.9,
)
memtrace.remember(
researcher.id,
"Source: Go official docs - effective_go.html#channels",
session_id=session.id,
tags=["source", "official_docs"],
importance=0.7,
)
memtrace.remember(
researcher.id,
"sync.WaitGroup is common pattern for coordinating goroutines",
session_id=session.id,
tags=["research", "sync", "concurrency"],
importance=0.9,
)
# Mark research phase complete
memtrace.decide(
researcher.id,
"Research complete - collected 15 key facts about Go concurrency",
"Sufficient material for article, covered channels, goroutines, and sync patterns",
)
Phase 2: Writing
# Writer reads all research
ctx = memtrace.get_session_context(session.id, ContextOptions(
include_types=["episodic", "decision"],
))
# Writer has access to:
# - All research findings
# - All sources
# - Researcher's completion decision
# Writer creates draft
memtrace.remember(
writer.id,
"Drafted article introduction focusing on channels as core concept",
session_id=session.id,
tags=["draft", "introduction"],
importance=0.8,
)
memtrace.remember(
writer.id,
"Article structure: Intro -> Channels -> Goroutines -> Patterns -> Conclusion",
session_id=session.id,
tags=["draft", "structure"],
importance=0.9,
)
memtrace.decide(
writer.id,
"Draft complete - 1500 words, covers all research points",
"Included all key concepts from research phase, added code examples",
)
Phase 3: Editing
# Editor reads everything
ctx = memtrace.get_session_context(session.id, ContextOptions())
# Editor sees:
# - All research findings and sources
# - Draft structure and content
# - Writer's completion decision
# Editor provides feedback
memtrace.remember(
editor.id,
"Introduction is too technical, needs simpler explanation for beginners",
session_id=session.id,
tags=["feedback", "introduction"],
importance=0.9,
)
memtrace.remember(
editor.id,
"Code examples are excellent, very clear",
session_id=session.id,
tags=["feedback", "code_examples", "positive"],
importance=0.7,
)
memtrace.decide(
editor.id,
"Request revision - introduction needs simplification",
"Overall strong draft but accessibility concern for target audience",
)
Phase 4: Revision
# Writer reads editor feedback
editor_feedback = memtrace.search_memories({
"agent_id": editor.id,
"session_id": session.id,
"tags": ["feedback"],
})
# Writer addresses feedback
memtrace.remember(
writer.id,
"Simplified introduction, added analogy comparing channels to postal mail",
session_id=session.id,
tags=["revision", "introduction"],
importance=0.8,
)
memtrace.decide(
writer.id,
"Revision complete - addressed editor feedback",
"Introduction now more accessible while maintaining technical accuracy",
)
Phase 5: Publishing
# Publisher reads final state
ctx = memtrace.get_session_context(session.id, ContextOptions())
# Publisher sees:
# - Original research
# - Draft creation
# - Editor feedback
# - Writer revisions
# - All decisions
# Publisher can verify:
editor_approved = memtrace.search_memories({
"agent_id": editor.id,
"session_id": session.id,
"tags": ["approval"],
})
if editor_approved.memories:
memtrace.remember(
publisher.id,
"Published article to blog: golang-concurrency-guide",
session_id=session.id,
tags=["published", "blog"],
importance=1.0,
)
memtrace.decide(
publisher.id,
"Project complete - article live on blog",
"All phases completed: research, writing, editing, publishing",
)
# Close session
memtrace.close_session(session.id)
Example: Code Review Team
Multiple agents collaborate on code review: security scanner, style checker, test reviewer, integration reviewer.
Agent Setup
security_agent = memtrace.register_agent(RegisterAgentRequest(
name="security-reviewer",
description="Checks for security vulnerabilities",
))
style_agent = memtrace.register_agent(RegisterAgentRequest(
name="style-reviewer",
description="Enforces code style and best practices",
))
test_agent = memtrace.register_agent(RegisterAgentRequest(
name="test-reviewer",
description="Reviews test coverage and quality",
))
integration_agent = memtrace.register_agent(RegisterAgentRequest(
name="integration-reviewer",
description="Checks integration with existing codebase",
))
Parallel Review
# Create session for PR review
session = memtrace.create_session(CreateSessionRequest(
agent_id=security_agent.id,
metadata={
"pr_number": "42",
"repository": "my-app",
"author": "developer",
},
))
# All agents review in parallel
# Security agent
memtrace.remember(
security_agent.id,
"Found SQL injection vulnerability in auth.go:45",
session_id=session.id,
tags=["security", "critical", "sql_injection"],
importance=1.0,
)
# Style agent
memtrace.remember(
style_agent.id,
"Missing error handling in api.go:123",
session_id=session.id,
tags=["style", "error_handling"],
importance=0.7,
)
# Test agent
memtrace.remember(
test_agent.id,
"New function auth.ValidateToken lacks unit tests",
session_id=session.id,
tags=["testing", "missing_coverage"],
importance=0.9,
)
# Integration agent
memtrace.remember(
integration_agent.id,
"New API endpoint not documented in OpenAPI spec",
session_id=session.id,
tags=["integration", "documentation"],
importance=0.8,
)
Aggregate Review
# Summary agent reads all reviews
all_issues = memtrace.search_memories({
"session_id": session.id,
"memory_type": "episodic",
})
# Group by severity
critical = [m for m in all_issues.memories if m.importance >= 0.9]
warnings = [m for m in all_issues.memories if 0.7 <= m.importance < 0.9]
# Create summary
memtrace.decide(
"summary-agent",
"Reject PR - critical security issue must be fixed",
f"Found {len(critical)} critical issues, {len(warnings)} warnings. Security issue is blocking.",
)
Example: Research and Analysis
Multiple agents work together on market research: data collector, analyzer, summarizer.
Data Collection
# Collector agent gathers data
memtrace.remember(
"collector",
"Competitor A pricing: Basic $10/mo, Pro $25/mo, Enterprise $100/mo",
session_id=session.id,
tags=["pricing", "competitor_a"],
importance=0.9,
)
memtrace.remember(
"collector",
"Competitor B pricing: Starter $15/mo, Business $40/mo",
session_id=session.id,
tags=["pricing", "competitor_b"],
importance=0.9,
)
Analysis
# Analyzer reads collected data
pricing_data = memtrace.search_memories({
"agent_id": "collector",
"session_id": session.id,
"tags": ["pricing"],
})
# Analyzer stores insights
memtrace.remember(
"analyzer",
"Competitor A targets SMB market with low entry point",
session_id=session.id,
tags=["analysis", "market_segment", "competitor_a"],
importance=0.8,
)
memtrace.remember(
"analyzer",
"Competitor B focuses on mid-market, no free tier",
session_id=session.id,
tags=["analysis", "market_segment", "competitor_b"],
importance=0.8,
)
memtrace.decide(
"analyzer",
"Our pricing should target gap between A and B",
"Market analysis shows opportunity at $18-22/mo price point",
)
Summarization
# Summarizer creates final report
ctx = memtrace.get_session_context(session.id, ContextOptions())
# Summarizer sees:
# - All collected data
# - Analysis insights
# - Pricing recommendation decision
# Creates executive summary
memtrace.remember(
"summarizer",
"Created executive summary highlighting $20/mo recommendation with competitive analysis",
session_id=session.id,
tags=["summary", "executive_report"],
importance=1.0,
)
Best Practices
Clear Agent Roles
Define specific responsibilities for each agent:
description="Handles X, does not do Y"
Agent Attribution
Always specify which agent performed action:
memtrace.remember(agent_id, ...) # Not anonymous
Cross-Agent Queries
Query specific agents or all agents as needed:
# Specific agent
memories = memtrace.search_memories({"agent_id": researcher.id})
# All agents in session
memories = memtrace.search_memories({"session_id": session.id})
Decision Visibility
Make decisions explicit so other agents see them:
memtrace.decide(agent_id, "What was decided", "Why this decision")
Session Metadata
Store project context in session metadata:
metadata = {
"project": "article-pipeline",
"phase": "research",
"deadline": "2026-02-20",
}
Handoff Markers
Mark phases complete with decisions:
memtrace.decide(
agent_id,
"Phase X complete - ready for next agent",
"All requirements met, deliverables ready",
)
Benefits
- True collaboration - Agents build on each other's work
- No duplication - Agents see what others already did
- Consistent decisions - All agents respect shared decisions
- Clear attribution - Track which agent did what
- Audit trail - Full history of multi-agent workflow
- Flexible pipelines - Easy to add/remove agents from pipeline