Skip to main content

One Framework for the Full Spectrum

From batch data pipelines to multi-turn AI agents. One elegant API that spans the entire workflow spectrum.

Why Hypergraph?

DAG frameworks can’t handle agents. Agent frameworks have too much ceremony. You shouldn’t need different tools for data pipelines and agentic AI. Hypergraph spans the full spectrum — from batch data pipelines to multi-turn AI agents — with the same minimal API.
from hypergraph import Graph, node, SyncRunner

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

@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)

# Edges inferred from names - no wiring needed
graph = Graph(nodes=[embed, retrieve, generate])

# Run the graph
runner = SyncRunner()
result = runner.run(graph, {"text": "RAG tutorial", "query": "What is RAG?"})
print(result["answer"])
embed produces embedding. retrieve takes embedding. Connected automatically.

Get Started in 5 Minutes

Install hypergraph and run your first workflow. From zero to working graph in minutes.

Compare with Other Frameworks

See how hypergraph compares to LangGraph, Hamilton, Prefect, and Pipefunc.

When to Use Hypergraph

Understand if hypergraph is the right tool for your project.

Core Concepts

Deep dive into nodes, graphs, runners, and routing patterns.

Key Differentiators

1. One Framework to Master

Learn one tool that works for everything. The same patterns work across the entire spectrum:
  • ETL pipelines? Same @node decorator, same Graph, same runner
  • Agentic loops? Add @route and END, same everything else
  • Multi-agent orchestration? Nest graphs with .as_node(), same mental model

2. Natural Hierarchy

Real AI workflows nest DAGs inside cycles and cycles inside DAGs:
# The chat is a cyclic graph
chat = Graph([retrieve, generate, accumulate, should_continue])

# Wrap it as a node for evaluation
eval_pipeline = Graph([
    load_test_cases,
    chat.as_node(),  # Cyclic graph as a single node
    score_responses,
    aggregate_metrics,
])
Hypergraph’s hierarchical composition makes this explicit and clean.

3. Automatic Edge Inference

No manual wiring. Name your outputs and inputs consistently — edges are inferred:
@node(output_name="embedding")
def embed(text: str) -> list[float]:
    return model.embed(text)

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

# Edges inferred: embed → retrieve (via "embedding")
graph = Graph([embed, retrieve])

4. Pure, Testable Functions

Your functions are just functions. Test them directly:
# Test without the framework — no setup, no mocking
def test_embed():
    result = embed.func("hello world")
    assert len(result) == 768

5. Build-Time Validation

Catch errors when you build the graph, not at 2am in production:
Typos, missing connections, type mismatches — caught at construction time.
@route(targets=["step_a", "step_b", END])
def decide(x: int) -> str:
    return "step_c"  # Typo!

graph = Graph([decide, step_a, step_b])
# GraphValidationError: Route target 'step_c' not found.
# Valid targets: ['step_a', 'step_b', 'END']
# Did you mean 'step_a'?

6. Think Singular, Scale with Map

Write logic for one item. Scale to many with .map():
# Write for ONE document
@node(output_name="features")
def extract(document: str) -> dict:
    return analyze(document)

# Scale to 1000 documents
results = runner.map(graph, {"document": documents}, map_over="document")
The framework handles fan-out, parallelism, and caching.

The Full Spectrum

PatternExample Use CasesHypergraph Features
Batch PipelinesETL, ML inference, data transformations@node, Graph, automatic edges
BranchingConditional routing, document classification@ifelse, @route
Agentic LoopsMulti-turn chat, iterative refinement@route, END, cycles
HierarchicalNested workflows, evaluation harnesses.as_node(), graph composition
Multi-AgentAgent teams, orchestrationAll of the above combined

Examples by Complexity

1

Simple Pipeline

Linear data flow, automatic edge inference.
graph = Graph([load, transform, save])
2

Add Branching

Route execution based on data.
@ifelse(when_true="process", when_false=END)
def should_process(is_valid: bool) -> bool:
    return is_valid

graph = Graph([validate, should_process, process])
3

Add Loops

Multi-turn conversations, iterative refinement.
@route(targets=["generate", END])
def should_continue(messages: list) -> str:
    if len(messages) > 10:
        return END
    return "generate"

graph = Graph([generate, accumulate, should_continue])
4

Add Hierarchy

Nest graphs for reuse and composition.
rag = Graph([embed, retrieve, generate], name="rag")

workflow = Graph([
    validate_input,
    rag.as_node(),  # Nested graph
    format_output,
])

Beyond AI/ML

While the examples focus on AI/ML use cases, hypergraph is a general-purpose workflow framework. It has no dependencies on LLMs, vector databases, or any AI tooling. Use it for any multi-step workflow: ETL pipelines, business process automation, testing harnesses, or anything else that benefits from graph-based orchestration.

Installation

uv add git+https://github.com/gilad-rubin/hypergraph.git
# or
pip install git+https://github.com/gilad-rubin/hypergraph.git
Alpha: API may change between releases. Core features are stable — nodes, graphs, runners, routing, and cyclic graphs.

Next Steps

Quickstart

Get running in 5 minutes with a complete example.

Comparison

See how hypergraph compares to LangGraph, Hamilton, and others.

When to Use

Decide if hypergraph is right for your project.

Core Concepts

Master nodes, graphs, and runners.

Build docs developers (and LLMs) love