Files
magnus919_agent-skills/llamaindex/references/agent-patterns.md
T
Magnus Hedemark 3e86349539 feat: add llamaindex — expert skill for LlamaIndex framework
Comprehensive skill covering:
- Core architecture (7 primitives, Settings, data flow)
- RAG strategies (basic through advanced with hybrid retrieval, reranking)
- Multi-agent orchestration (AgentWorkflow, handoff bug fix)
- Event-driven workflows (durable execution, checkpoint/resume)
- Production deployment (llama-deploy, debugging, observability)
- PropertyGraphIndex (knowledge graphs, hybrid retrieval)
- Evaluation and span-attached observability
- Integration ecosystem (vector stores, LlamaHub, LlamaParse)

9 reference files, 4 templates, 1 verification script.
MIT licensed. 100% AI agent portable (no platform-specific content).

Signed-off-by: Magnus Hedemark <magnus919@pm.me>
2026-07-09 13:32:53 -04:00

2.8 KiB

LlamaIndex Agent Patterns

Agent Types

Agent Tool Calling When to Use
FunctionAgent Native function calling API Models with tool-calling support
ReActAgent ReAct prompting pattern Models without native tool support

Pattern 1: AgentWorkflow (Built-in Multi-Agent)

from llama_index.core.agent.workflow import AgentWorkflow, FunctionAgent

research_agent = FunctionAgent(
    name="ResearchAgent",
    description="Searches and records notes",
    system_prompt="You are a researcher. Hand off to WriteAgent when ready.",
    tools=[search_web, record_notes],
    can_handoff_to=["WriteAgent"],
)

write_agent = FunctionAgent(
    name="WriteAgent",
    description="Writes reports from notes",
    can_handoff_to=["ReviewAgent"],
)

workflow = AgentWorkflow(
    agents=[research_agent, write_agent],
    root_agent=research_agent.name,
    initial_state={"report_content": "Not written yet."},
)

response = await workflow.run(user_msg="Write a report on the history of the web...")

Pattern 2: Orchestrator Agent (Sub-Agents as Tools)

Centralized control: one orchestrator calls sub-agents via tools.

orchestrator = FunctionAgent(
    name="Orchestrator",
    system_prompt="You orchestrate research, writing, and review...",
    tools=[call_research_agent, call_write_agent, call_review_agent],
)
response = await orchestrator.run(user_msg="Write a report...")

Pattern 3: Custom Planner (DIY Orchestration)

# LLM outputs structured plan in XML/JSON
# Python code parses and executes
for step in parse_plan(llm_response):
    agent = agents[step.agent_name]
    result = await agent.run(user_msg=step.input)

Streaming Events

AgentWorkflow emits five event types:

handler = workflow.run(user_msg="Your query")
async for event in handler.stream_events():
    if isinstance(event, AgentStream):
        print(event.delta, end="")  # Real-time output
    elif isinstance(event, AgentOutput):
        print(f"{event.current_agent_name}: {event.response.content}")

Known Bug: Agent Handoff

After handoff, the receiving agent may lose the user's original request because handoff messages push it out of ChatMemory.

Fix: Extend FunctionAgent.take_step():

class MyFunctionAgent(FunctionAgent):
    async def take_step(self, ctx, llm_input, tools, memory):
        last_msg = llm_input[-1].content if llm_input else ""
        if "handoff_result" in last_msg:
            for message in llm_input[::-1]:
                if message.role == MessageRole.USER:
                    llm_input.append(message)
                    break
        return await super().take_step(ctx, llm_input, tools, memory)

Also customize handoff_output_prompt with a handoff_result tag for reliable detection.