LLM Compiler: Compile A Task Into A Dependency Graph
Some tasks are not simple chains and not fully independent batches. A travel report may need city background first, then route suggestions based on it, then a final report.
You need to know what can run in parallel and what must wait.
LLM Compiler asks the model to produce a task graph, then executes by dependency.
One Sentence
LLM Compiler turns sequential execution into a dependency DAG plus scheduler, so independent subtasks do not wait on each other.
What Breaks Without It
| Problem | What it looks like | Risk |
|---|---|---|
| Everything runs serially | Simple | Independent work is slow |
| Everything runs in parallel | Fast | Dependencies are missing |
| Dependencies live in prose | Flexible | Python cannot schedule or audit |
What This Pattern Changes
| Who | Owns |
|---|---|
| Compiler model | Creates task nodes, deps, final instruction |
| Python scheduler | Executes by dependency |
| Worker model/tool | Runs each task |
| Final step | Combines dependency results |
Walk Through One Trace
| Node | Dependencies | Output |
|---|---|---|
t1: Write X |
none | X |
t2: Write Y |
t1 |
Y (using X) |
| final | t1, t2 |
Final: X + Y |
Flow
flowchart TD
T["Task"] --> C["Compile DAG"]
C --> A["t1: no deps"]
A --> B["t2: depends on t1"]
A --> F["final"]
B --> F
F --> O["Final answer"]
Code Walk
The model first returns a task graph:
model = MockLLM(
[
'{"tasks":[{"id":"t1","instruction":"Write X","deps":[]},{"id":"t2","instruction":"Write Y","deps":["t1"]}],"final":{"instruction":"Combine t1 and t2"}}',
"X",
"Y (using X)",
"Final: X + Y",
]
)
Full example:
from __future__ import annotations
from pathlib import Path
from agent_patterns_lab.patterns.llm_compiler import llm_compiler
from agent_patterns_lab.runtime import MockLLM, Tracer
def main() -> None:
tracer = Tracer()
model = MockLLM(
[
'{"tasks":[{"id":"t1","instruction":"Write X","deps":[]},{"id":"t2","instruction":"Write Y","deps":["t1"]}],"final":{"instruction":"Combine t1 and t2"}}',
"X",
"Y (using X)",
"Final: X + Y",
]
)
out = llm_compiler(model, task="Produce X then Y, then combine.", tracer=tracer)
print(out)
trace_path = tracer.export_jsonl(Path(".traces") / "53_llm_compiler.jsonl")
print(f"[trace] {trace_path}")
if __name__ == "__main__":
main()
Run:
UV_CACHE_DIR=.uv_cache PYTHONPATH=src uv run --no-sync python examples/53_llm_compiler.py
Nearby Patterns
| Pattern | Who decides next | Use when |
|---|---|---|
| Prompt Chaining | Python fixes linear steps | Order is known |
| ReWOO | Plan a batch of tool calls | Calls are mostly independent |
| LLM Compiler | Model creates dependency graph | Dependencies and parallelism both matter |
| Manager-Worker | Manager delegates dynamically | Task types emerge at runtime |
When To Use It
- Subtasks have clear dependencies.
- Some work can run in parallel.
- You want scheduler control.
- The DAG can be structurally validated.
When Not To Use It
- The task is short.
- Dependencies are unclear.
- The model often writes wrong plans.
- Dynamic expert delegation is a better fit.
Costs And Common Failures
| Failure | Symptom | Fix |
|---|---|---|
| Wrong deps | Downstream lacks upstream result | Validate DAG and cycles |
| Tiny nodes | Scheduling overhead dominates | Merge small tasks |
| Final loses info | Merge omits node output | Include all dependency results |
| Hard debugging | Unknown broken node | Trace node id, deps, output |
What To Read Next
LLM Compiler fits task graphs, not all planning.
For simple plan-then-execute, read Plan & Solve. For dynamic expert delegation, read Manager-Worker.