llamaindex-workflows
Skill0 starsChanged 5 months agoMITView on GitHub
This skill should be used when the user wants to "build a LlamaIndex Workflow", design "event-driven agent steps", handle "workflow state / HITL / streaming", or "orchestrate agentic steps with Workflows". Owns the event-driven workflow model (events, steps, Context/state, branching, looping, human-in-the-loop, streaming, durability) and the judgment of when a Workflow is the right abstraction; defers serving a workflow as an API to `llamaindex-deploy` and plain RAG component wiring to `llamaindex-framework`.
In this repository12 other files it gives its agents.
- liteparseSkill
- llamacloud-classifySkill
- llamacloud-extractSkill
- llamacloud-indexSkill
- llamacloud-parseSkill
- llamacloud-self-hostingSkill
- llamacloud-sheetsSkill
- llamacloudSkill
- llamacloud-splitSkill
- llamaindex-cookbooksSkill
- llamaindex-deploySkill
- llamaindex-frameworkSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 37
Workflow vs. multi-agent orchestration: When several agents must cooperate, the choice is between a prebuilt multi-agent abstraction and a …
- Very specific: line 62
Contextis the shared store + run handle: Use it for cross-step state, for emitting events to the stream, and for the human-in-the-loop … - Very specific: line 154
Treat as live lookups, never memorized: package names/versions, the exact event class and Context/step method names, the HITL event names, …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
LlamaIndex Workflows — Event-Driven Orchestration
Workflows are LlamaIndex's event-driven abstraction for orchestrating multi-step, agentic
logic. Instead of wiring a DAG of nodes, define @step methods (Python) / handlers (TypeScript)
that consume an event and emit one or more events. The framework infers the graph from those
input/output event types and runs steps as their inputs arrive — so branching, looping, fan-out,
and joins are expressed in ordinary async Python/TS, not in graph edges.
This skill holds the mental model and design judgment. For exact class/method signatures, fetch
live (see "Fetching facts"). For serving a finished workflow over HTTP, defer to
llamaindex-deploy. For assembling plain RAG components (loaders, indexes, query engines, retrievers)
without orchestration, defer to llamaindex-framework.
When a Workflow is the right abstraction
Reach for a Workflow only when the control flow itself is the problem. Decision shortcuts:
- Single query → answer, linear (retrieve → synthesize) → use a query engine / chain from
llamaindex-framework. A Workflow adds ceremony with no payoff. - Branching on intermediate results, loops/retries, fan-out + join, or multiple cooperating steps → Workflow. This is the sweet spot.
- Needs to pause for a human, then resume (approvals, clarifying questions) → Workflow with human-in-the-loop. Nothing else in the stack pauses cleanly.
- Long-running / must survive a crash or restart → Workflow with durability/checkpointing.
- Streaming intermediate progress to a UI → Workflow emits events to a stream as it runs.
- Just calling one prebuilt agent (e.g.
FunctionAgent) → use the agent directly; reach for a custom Workflow once you need to orchestrate around or between agents.
See references/workflow-patterns.md for the full when-to-use table and the build sequence.
Workflow vs. multi-agent orchestration. When several agents must cooperate, the choice is between a prebuilt multi-agent abstraction and a custom Workflow that runs each agent as a step. Reach for the prebuilt agent/handoff pattern when the coordination is a standard hand-off (router → specialist → back). Drop to a custom Workflow when the coordination itself is non-standard — conditional routing on agent output, human gates between agents, partial-result joins, or per-agent retry policies. The Workflow gives you the seams to insert that logic; a prebuilt orchestrator hides them. Start with the prebuilt path and graduate to a Workflow only when you hit a coordination need it cannot express.
The core model
The shift from a DAG to an event graph is the whole point: in a DAG you declare edges and the
engine walks them; in a Workflow you declare what each step consumes and produces, and the engine
derives the edges. That inversion is why control flow lives in ordinary Python/TS — an if that
returns a different event is a branch, an event that routes backward is a loop. There is no
separate flow-definition language to keep in sync with the code.
- Events are the unit of flow. Subclass the event base for type safety; each carries arbitrary (typically Pydantic) payload. The set of event types a step accepts/returns defines its place in the graph.
- Entry and exit are special events. A start event begins the run (its attributes come from the
.run(...)kwargs); a stop event ends it and carries the result. Subclass them for typed I/O. - Steps consume one event, emit the next. A step that returns event type
Bis automatically wired to whatever step acceptsB. No manual edge declaration. - Validation is upfront. The framework checks the event graph is connected (no orphan/unreachable steps, every emitted event has a consumer) before running — catching wiring bugs early.
Contextis the shared store + run handle. Use it for cross-step state, for emitting events to the stream, and for the human-in-the-loop pause/resume. State lives in a typed store on the Context rather than in step return values when many steps need it.
Branching, looping, fan-out
- Branch: a step emits one of several event types; the matching downstream step runs. Conditional
routing is just an
ifchoosing which event to return. - Loop / retry: a step emits an event that routes back to an earlier step (e.g. a validation step re-emits the work event on failure). Loops are cycles in the event graph, expressed naturally.
- Fan-out (parallel): emit multiple events from one step to run branches concurrently; a
collector/join step waits for the expected number of results before proceeding. The Context
provides the primitive to gather N events of a type. Prefer this over manual
asyncioplumbing.
Because steps fire when their input event arrives — not in source order — concurrency falls out for free: two steps consuming the same event run in parallel, and independent branches advance independently. Sequencing comes from the event dependencies, not from where a method sits in the file. Cap any loop with a counter held in Context so a step that keeps re-emitting its own trigger cannot run forever.
Human-in-the-loop (HITL)
The workflow pauses, surfaces a request to the outside world, and resumes when a response comes back — without losing in-flight state. Conceptually: a step emits an "input required" event; the runtime surfaces it (via the stream); external code submits a "human response" event; a waiting step resumes. Because Context holds the state, the pause can span an HTTP round-trip or longer. This is the backbone of approvals and clarification loops. Exact event/method names drift — fetch live.
Streaming
A run exposes a stream of events as it executes. Steps write progress events to the stream via the Context; the caller iterates the handler's stream to drive a UI (token deltas, tool-call traces, step boundaries). The final result still comes from awaiting the run handle. Use streaming whenever a user is watching — do not block on the final stop event for long runs.
Durability
Runs can be checkpointed so a crashed or restarted process resumes mid-flight rather than
restarting. In-memory state is the default; durable backends (e.g. SQLite for single-process, a
Postgres/DBOS-backed store for distributed production) persist handler state and enable automatic
recovery. Treat durability as a deployment-time decision: develop in-memory, add a persistence backend
when the workflow is long-running or must not lose progress. The serving layer that wires this up is
llamaindex-deploy territory — here, just design steps to be idempotent and resumable (no
side effects that break on replay).
The serving model (brief — defer the how-to)
A finished Workflow is exposed over HTTP by a workflow server that turns each workflow into REST
endpoints supporting synchronous run and async (handler-id + poll) execution, plus event injection for
HITL and a debugging UI. Know that this path exists so you design workflows to be serializable and
resumable — but for the actual llamactl / server setup, hand off to llamaindex-deploy.
Minimal examples (illustrative — fetch exact signatures live)
Python:
# Standalone package surface (verify install + imports live — see "Fetching facts").
# A compatibility path under llama_index.core.workflow also exists.
from workflows import Workflow, step
from workflows.events import Event, StartEvent, StopEvent
class Retrieved(Event):
text: str
class RAGFlow(Workflow):
@step
async def retrieve(self, ev: StartEvent) -> Retrieved:
return Retrieved(text=do_retrieve(ev.query))
@step
async def synthesize(self, ev: Retrieved) -> StopEvent:
return StopEvent(result=llm_answer(ev.text))
# result = await RAGFlow(timeout=60).run(query="...")TypeScript (@llamaindex/workflow): define a workflow, register handlers keyed on event types, and
run it the same event-in/event-out way. Confirm package and API live — the TS surface evolves.
Common pitfalls (see references for the full taxonomy)
- Using a Workflow for a linear single-shot query — over-engineering; use a query engine.
- Holding state in step return values when many steps need it — put it in the Context store instead.
- A step emits an event no step consumes (or vice versa) — caught by upfront validation; fix the event types.
- Forgetting the join/collector step on a fan-out — the workflow stalls waiting for results.
- Non-idempotent side effects that break on checkpoint replay.
- Blocking on the final result when a UI needs streamed progress.
Fetching facts (do not hardcode)
Treat as live lookups, never memorized: package names/versions, the exact event class and
Context/step method names, the HITL event names, and streaming/checkpointer APIs — they drift across
releases. Fetch via:
- Docs MCP (wired, no auth):
mcp__plugin_llamacloud_docs__search_docsfor concepts,mcp__plugin_llamacloud_docs__read_docfor a known page,mcp__plugin_llamacloud_docs__grep_docsfor an exact symbol. - Clean-markdown fallback: append
index.mdto anyhttps://developers.llamaindex.ai/...page URL andWebFetchit.
Anchor pages: /python/llamaagents/workflows/ (model + examples: branching, looping, HITL,
streaming, checkpointing), /python/llamaagents/workflows/deployment/ (serving model — defer the
how-to), and the TypeScript @llamaindex/workflow docs for the TS surface.
Additional resources
references/workflow-patterns.md— when-to-use-a-Workflow decision table, event/step design patterns, state-vs-return-value calls, HITL and streaming decision guidance, durability/idempotency rules, the build/test sequence, and the full pitfall taxonomy.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

