Skip to main content
This guide helps you decide if hypergraph is the right tool for your project.

Use Hypergraph When…

You Want One Framework to Master

Instead of learning one tool for DAGs and another for agents, learn one framework that handles both.
Use CaseWhat You Learn
ETL pipelinesSame @node decorator, same Graph, same runner
Agentic loopsAdd @route and END, same everything else
Multi-agent orchestrationNest graphs with .as_node(), same mental model

Your Workflows Have Natural Hierarchy

Real AI systems aren’t flat. They have structure:
Evaluation Loop (DAG)
└── Multi-turn Chat (cyclic)
    └── RAG Pipeline (DAG)
        └── Embedding (single node)
If your workflows have this kind of nesting — DAGs inside cycles, cycles inside DAGs — hypergraph’s hierarchical composition is a natural fit.

Evaluation Harness

Outer: Evaluation harness (DAG)
Inner: Chat agent (cyclic)
Pattern: Test cyclic workflows at scale

Prompt Optimization

Outer: Prompt optimization (cyclic)
Inner: Pipeline under test (DAG)
Pattern: Iterate on prompts

Batch Processing

Outer: Batch processing (DAG)
Inner: Per-item workflow (may have branches)
Pattern: Fan-out with .map()

Multi-Turn RAG

Outer: Conversation loop (cyclic)
Inner: RAG retrieval (DAG)
Pattern: Query → retrieve → generate → repeat

You Value Pure, Testable Functions

If you want to test your logic without framework setup or mocking:
# This works — no Graph, no Runner, no setup
def test_my_node():
    result = my_node.func(input_value)
    assert result == expected
Your functions are just functions. The @node decorator adds metadata, not magic.

You’re Building Multi-Turn AI Workflows

Conversational AI, agentic loops, iterative refinement — these require cycles:
from hypergraph import Graph, node, route, END

@node(output_name="draft")
def generate(context: str, feedback: str = "") -> str:
    return llm.generate(context, feedback)

@node(output_name="quality")
def evaluate(draft: str) -> float:
    return quality_score(draft)

@route(targets=["generate", END])
def should_continue(quality: float, attempts: int) -> str:
    if quality > 0.9 or attempts >= 5:
        return END
    return "generate"  # Loop back for another iteration

@node(output_name="attempts")
def increment(attempts: int = 0) -> int:
    return attempts + 1

graph = Graph([generate, evaluate, should_continue, increment])
Hypergraph handles cycles naturally with @route and END. No external loop needed.

You Want Minimal Boilerplate

Define functions, name outputs, and let hypergraph infer the edges:
from hypergraph import Graph, node

@node(output_name="embedding")
def embed(query: str) -> list[float]:
    return model.embed(query)

@node(output_name="docs")
def retrieve(embedding: list[float]) -> list[str]:
    return db.search(embedding)

@node(output_name="answer")
def generate(docs: list[str], query: str) -> str:
    return llm.generate(docs, query)

graph = Graph([embed, retrieve, generate])

Don’t Use Hypergraph When…

You Need a Simple Script

If your task is “call this function, then call that function,” you don’t need a graph framework:
# Just do this
result1 = step_one(input)
result2 = step_two(result1)
result3 = step_three(result2)
Hypergraph adds value when you have non-trivial composition, reuse, or control flow. For simple sequential scripts, plain Python is clearer.
When to consider hypergraph instead:
  • You have 5+ steps with complex dependencies
  • You need to reuse the pipeline with different inputs
  • You want to test individual steps in isolation
  • You need conditional branching or loops
  • You want to compose smaller pipelines into larger ones

You Need Production Maturity Today

Hypergraph is in alpha. The core features work, but:
  • Breaking API changes are possible
  • Ecosystem integrations are limited
  • Community is smaller than mature alternatives
  • Production testing at scale is limited
If you need a battle-tested solution today, consider:
  • LangGraph for agentic workflows
  • Hamilton for data/ML pipelines
  • Prefect for production orchestration
See the Comparison page for detailed framework comparison.

You’re Doing Simple LLM Calls

If you’re just calling an LLM API and returning the result, you don’t need orchestration:
# Just call the API directly
response = openai.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": query}],
)
print(response.choices[0].message.content)
When to use hypergraph for LLM workflows:
  • You’re chaining multiple LLM calls (e.g., RAG, multi-step reasoning)
  • You need retrieval, reranking, or other preprocessing
  • You have conditional logic (e.g., route based on query type)
  • You want multi-turn conversations with state

You Need Specialized Orchestration Features

Hypergraph focuses on the graph model. If you need:
FeatureConsider Instead
Scheduling, retries, monitoringPrefect, Temporal
Distributed execution across clustersRay, Dask, Airflow
HPC/SLURM integrationPipefunc
Built-in lineage tracking UIHamilton
LangChain tool integrationsLangGraph

Summary Decision Matrix

If you want…Use hypergraph?Why
One framework for DAGs and agents✅ YesCore strength - unified model
Hierarchical workflow composition✅ YesFirst-class support with .as_node()
Pure, testable functions✅ YesFunctions are framework-agnostic
Multi-turn AI workflows✅ YesNative cycle support with @route
Minimal boilerplate✅ YesAutomatic edge inference
Simple scripts (3-5 steps)❌ NoPlain Python is clearer
Production maturity today⚠️ MaybeEvaluate alpha status carefully
Simple LLM API calls❌ NoCall the API directly
Distributed execution❌ NoUse Ray, Dask, or Airflow

Real-World Use Cases

Where Hypergraph Shines

1

Multi-Turn RAG Systems

Conversation loops with retrieval steps inside each turn. Natural hierarchy: cyclic chat contains DAG retrieval.
rag = Graph([embed, retrieve, rerank, generate])  # DAG
chat = Graph([rag.as_node(), accumulate, should_continue])  # Cycle
2

Agent Evaluation Harnesses

Test agentic workflows at scale. DAG evaluation contains cyclic agents.
agent = Graph([decide, act, observe, should_continue])  # Cycle
eval_harness = Graph([load_cases, agent.as_node(), score])  # DAG
3

Prompt Optimization Loops

Iteratively improve prompts. Cyclic optimization contains DAG workflow under test.
workflow = Graph([preprocess, generate, postprocess])  # DAG
optimize = Graph([workflow.as_node(), evaluate, improve, should_continue])  # Cycle
4

Complex ETL with Conditional Logic

Data pipelines with routing based on content type, validation, or quality.
@route(targets=["process_json", "process_csv", "process_parquet"])
def route_by_type(file_type: str) -> str:
    return f"process_{file_type}"

graph = Graph([detect_type, route_by_type, process_json, process_csv, ...])

Where Hypergraph Doesn’t Fit

1

One-off Scripts

# Just do this
data = load()
cleaned = clean(data)
save(cleaned)
2

Production Scheduling

Need cron, retries, monitoring? Use Prefect or Temporal.
3

Distributed Training

Training large models across clusters? Use Ray or Dask.
4

Simple API Endpoints

@app.post("/chat")
def chat(query: str):
    return llm.generate(query)

Next Steps

Quickstart

Try hypergraph with a working example in 5 minutes.

Comparison

See detailed comparison with LangGraph, Hamilton, and others.

Core Concepts

Deep dive into nodes, graphs, and runners.

Real-World Examples

Production-ready RAG, evaluation, and multi-agent examples.

Build docs developers (and LLMs) love