Collaboration patterns + structured knowledge
When one agent + many tools is not enough
| Pattern | Description | When to use |
|---|---|---|
| Supervisor | Lead delegates to specialists | Distinct domains (research / write / code) |
| Handoff | Specialist takes full control | Customer support tiers |
| Critic-reviewer | Generator + validator loop | Quality-sensitive output |
| Map-reduce | Parallel workers → merge | Long doc analysis, batch tasks |
| A2A federation | Cross-org agent discovery | Partner APIs, external agents |
Frameworks: LangGraph (recommended), AutoGen, CrewAI, OpenAI Agents SDK.
from langgraph.graph import StateGraph, START, END
class TeamState(TypedDict):
messages: Annotated[list, add_messages]
next: str # which worker to call
def supervisor(state: TeamState):
# LLM decides: researcher | writer | reviewer | FINISH
decision = llm.invoke(SUPERVISOR_PROMPT + str(state["messages"]))
return {"next": parse_next(decision)}
def researcher(state): ...
def writer(state): ...
def reviewer(state): ...
builder = StateGraph(TeamState)
builder.add_node("supervisor", supervisor)
builder.add_node("researcher", researcher)
builder.add_node("writer", writer)
builder.add_node("reviewer", reviewer)
builder.add_edge(START, "supervisor")
builder.add_conditional_edges("supervisor", lambda s: s["next"],
{"researcher": "researcher", "writer": "writer", "reviewer": "reviewer", "FINISH": END})
for worker in ["researcher", "writer", "reviewer"]:
builder.add_edge(worker, "supervisor") # report back
Max 3 critic rounds; else escalate to human.
Structured facts as nodes & edges — not text chunks
(Alice) --[REPORTS_TO]--> (Bob)
(Project-X) --[OWNED_BY]--> (Alice)
(Project-X) --[USES]--> (PostgreSQL)
Multi-hop question: "What DB does my manager's project use?" needs 2+ hops
| Question type | Vector RAG | Graph retrieval |
|---|---|---|
| "Summarize refund policy" | Strong | Overkill |
| "Who owns the project that uses Kafka?" | Often misses link | Strong (multi-hop) |
| "List all systems 2 hops from Payment API" | Weak | Native (BFS / Cypher) |
| Unstructured PDFs | Strong | Needs extraction first |
SYSTEM: Extract (subject, predicate, object) triples from the text.
Return JSON array. Use UPPER_SNAKE predicates.
TEXT: "Alice Chen leads Project Phoenix, which runs on PostgreSQL.
She reports to Bob, VP of Engineering."
OUTPUT:
[
{"s":"Alice Chen","p":"LEADS","o":"Project Phoenix"},
{"s":"Project Phoenix","p":"RUNS_ON","o":"PostgreSQL"},
{"s":"Alice Chen","p":"REPORTS_TO","o":"Bob"}
]
MERGE (a:Person {name: "Alice Chen"})
MERGE (p:Project {name: "Project Phoenix"})
MERGE (db:Tech {name: "PostgreSQL"})
MERGE (b:Person {name: "Bob"})
MERGE (a)-[:LEADS]->(p)
MERGE (p)-[:RUNS_ON]->(db)
MERGE (a)-[:REPORTS_TO]->(b)
Tools: LLMGraphTransformer (LangChain), GraphRAG indexer (Microsoft), Neo4j LLM KG Builder.
Agent chooses: vector search, graph traverse, or both
LLM converts natural language → Cypher query → execute on Neo4j → results as context.
# User: "What database does Alice's project use?"
Cypher:
MATCH (a:Person {name:"Alice Chen"})-[:LEADS]->(p:Project)-[:RUNS_ON]->(db)
RETURN p.name, db.name
# Result → inject into LLM prompt → natural language answer
async def retrieve(query: str):
vector_hits = await vector_db.similarity_search(query, k=5)
entities = extract_entities(query)
graph_hits = neo4j.run(subgraph_query(entities, hops=2))
return merge_and_deduplicate(vector_hits, graph_hits)
Community summaries + global/local search for corpus-scale graphs
10–20 short pages about people, projects, and systems. Enough for 3-hop questions.
| Question | Expected retrieval path |
|---|---|
| Who leads Project Phoenix? | 1-hop: Person—LEADS—Project |
| What stack does my skip-level manager's team use? | 2-hop: REPORTS_TO + RUNS_ON |
| Summarize all security-related projects | GraphRAG global OR tag filter + vector |
| Metric | Meaning | How |
|---|---|---|
| Task success rate | Final output meets spec | Human / LLM judge |
| Handoff accuracy | Supervisor picked right worker | Label expected route |
| Critic pass rate | First-draft vs after-review | Compare iterations |
| Token cost | Total tokens vs single agent | Log per node |
| Latency | Wall-clock with parallel workers | Trace timestamps |
| Metric | Meaning |
|---|---|
| Triple precision | Extracted relations correct? |
| Multi-hop recall | Gold entities in k-hop subgraph? |
| Graph answer faithfulness | Answer supported by subgraph? |
# Multi-hop KG eval
def multi_hop_recall(query_entities, gold_entities, subgraph_fn, hops=2):
nodes = subgraph_fn(query_entities, hops)
found = sum(1 for g in gold_entities if g in nodes)
return found / len(gold_entities)
Retrieval metrics: Retrieval Engineering. Full matrix: Evaluation Guide.