Zero-dependency Python graph runtime for agent loops with Mermaid export
Project description
Graph Engineering
LangGraph energy. Zero dependencies. ~400 lines of readable Python.
Nodes are plain functions. Edges are fixed or conditional.
Control flow you can see — Mermaid, ASCII, Graphviz.
~20s demo — install, run the retry loop, print the trail + Mermaid.
The pitch
Most agent frameworks bury the control plane under adapters, schemas, vendors, and 40 transitive packages.
Graph Engineering is the opposite:
| You write | You get |
|---|---|
fn(state: dict) -> dict |
A real agent loop |
| Fixed + conditional edges | Retries, routers, handoffs |
g.render_mermaid() |
Paste-ready diagrams |
Nothing on pip |
Runs on stdlib alone |
research ──► write ──► verify ──► END
▲ │
└─ retry ─┘
flowchart TD
start((start)) --> research
research["research"]
write["write"]
verify["verify"]
END((END))
research --> write
write --> verify
verify -->|pass| END
verify -->|retry| write
Use this for teaching, prototypes, demos, notebooks, and tiny production loops where you want the graph to fit in your head.
Use LangGraph (or similar) when you need durable checkpoints, streaming platforms, or multi-actor infra at scale.
30-second quickstart
pip install simple-graph-agents
from simple_graph_agents import Graph, END
g = (
Graph("demo")
.node("research", lambda s: {**s, "notes": ["fact A", "fact B"]})
.node("write", lambda s: {**s, "draft": " ".join(s["notes"])})
.node("verify", lambda s: {**s, "ok": len(s.get("draft", "")) > 5})
.entry("research")
.edge("research", "write")
.edge("write", "verify")
.branch(
"verify",
lambda s: "pass" if s["ok"] else "retry",
path_map={"pass": END, "retry": "write"},
)
)
result = g.run({"topic": "agents"}, timed=True)
print(result.state["draft"])
print(result.trail()) # research -> write -> verify -> __end__
print(g.render_mermaid()) # paste into GitHub / mermaid.live
print(g.render_ascii()) # terminal sketch
Clone-and-run without install:
git clone https://github.com/cobusgreyling/graph-engineering.git
cd graph-engineering
python examples/minimal.py
python examples/research_write_verify.py
Live Mermaid viewer (no backend): demo →
Why people star this
- Zero dependencies — audit the whole runtime in one file
- Inspectable — Mermaid + ASCII + Graphviz +
RunResult.trace - Honest scope — not a platform; a sharp knife for control flow
- Teaching-grade API —
node/edge/branch/chain/validate - Copy-paste examples — research loops, tool routers, multi-agent handoffs
vs LangGraph (honest)
| Graph Engineering | LangGraph | |
|---|---|---|
| Install size | 0 runtime deps | Full stack |
| Mental model | Functions + dict state | Channels, reducers, checkpointers |
| Visualization | Mermaid / ASCII / DOT built-in | External / ecosystem |
| Durable execution | No (by design) | Yes |
| Streaming platform | No | Yes |
| Best for | Learn, demo, ship small loops | Production multi-actor systems |
| Lines of core | ~400 | Large framework |
If LangGraph is an airport, this is a bicycle. Both move people. Pick the right vehicle.
Install
pip install simple-graph-agents
From GitHub (main) or editable with tests:
pip install "git+https://github.com/cobusgreyling/graph-engineering.git"
git clone https://github.com/cobusgreyling/graph-engineering.git
cd graph-engineering
pip install -e ".[dev]"
pytest -q
Optional image export:
pip install "simple-graph-agents[graphviz]" # + system graphviz binaries
| PyPI | simple-graph-agents |
| Import | simple_graph_agents |
| Brand | Graph Engineering |
Examples
| Script | Pattern |
|---|---|
examples/minimal.py |
Smallest possible graph |
examples/research_write_verify.py |
Retry loop with test feedback |
examples/tool_router.py |
Plan → tool → observe → replan |
examples/multi_agent_handoff.py |
Researcher → writer → critic |
python examples/tool_router.py
python examples/multi_agent_handoff.py
API cheatsheet
| Method / type | Purpose |
|---|---|
add_node / node |
Register fn(state: dict) -> dict |
add_edge / edge |
Fixed edge; target may be END |
add_conditional_edges / branch |
router(state) -> str (+ optional path_map) |
chain("a", "b", "c") |
Linear path; adds edge to END by default |
set_entry / entry |
Where run starts |
validate() |
Reachability check (also run(..., validate=True)) |
run(state, max_steps=50, verbose=False, on_step=None, timed=False) |
Execute → RunResult |
RunResult.state / .history / .steps / .trace / .trail() |
Inspect the run |
render_mermaid() / render(path) |
Mermaid flowchart |
render_ascii() |
Terminal sketch |
render_graphviz(path=None, format="png") |
DOT (+ optional image) |
edges() |
(source, target, label) triples |
GraphError |
Definition and runtime errors |
END is the reserved terminal sentinel ("__end__").
State notes
- Input state is shallow-copied; nested lists/dicts are shared with the caller.
- Nodes may mutate and return the same object, or return a new dict.
- A node with no outgoing edge implicitly ends (routes to
END). - Cycles are allowed; guard with
max_steps.
Fluent style
g = (
Graph("pipeline")
.node("a", fa)
.node("b", fb)
.entry("a")
.chain("a", "b") # a → b → END
.validate()
)
result = g.run({}, timed=True, validate=True)
Mermaid & web demo
print(g.render_mermaid())
g.render("graph.mmd")
Paste into mermaid.live, GitHub markdown fences, or the local viewer:
python examples/research_write_verify.py
python -m http.server 8765 --directory demo
# open http://localhost:8765
Deployed demo: https://cobusgreyling.github.io/graph-engineering/
Design notes
- State is a dict. No schema engine required.
- No async / streaming. Add it inside the node if you need it.
- No LLM client. Swap stubs for OpenAI / Anthropic / local models.
- Routers return strings. Prefer
path_mapso Mermaid labels stay stable. - Duplicate edges raise. No silent overwrites.
validate()catches unreachable nodes before you ship a broken graph.
Layout
graph-engineering/
├── simple_graph_agents/ # installable package
│ ├── __init__.py
│ ├── graph.py # Graph, END, RunResult, renderers
│ └── py.typed
├── simple_graph.py # clone-and-run shim
├── examples/
│ ├── minimal.py
│ ├── research_write_verify.py
│ ├── tool_router.py
│ └── multi_agent_handoff.py
├── demo/ # vanilla JS Mermaid viewer
├── tests/
├── pyproject.toml
└── README.md
Development
pip install -e ".[dev]"
pytest -q
CI runs on Python 3.9–3.13 and executes every example.
Launch & growth
Stars don't appear from code alone. See LAUNCH.md for a practical playbook (HN, Reddit, X, blogs, demo GIFs).
If this saved you a dependency tree or taught a teammate agent control flow — star the repo and share the Mermaid of your graph. That's the whole marketing plan.
License
MIT — use it, fork it, keep it small.
Built by Cobus Greyling · part of the Engineering series for builders who want mechanisms, not magic.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file simple_graph_agents-0.2.0.tar.gz.
File metadata
- Download URL: simple_graph_agents-0.2.0.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ffa1c573658e83947e2425c20298f1840c9593351b8be37283ccd080d30dcfd
|
|
| MD5 |
1d994bd88e0c38aaf63a4edc3dce0935
|
|
| BLAKE2b-256 |
aba1c7431749492ad514d191fd15a41dc7097fc0d0626e7e94f6bbd299f5872d
|
File details
Details for the file simple_graph_agents-0.2.0-py3-none-any.whl.
File metadata
- Download URL: simple_graph_agents-0.2.0-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cccff87dbe8243fd7d3402654fcc00422034117c6bd26548b510a4cf9c4edff
|
|
| MD5 |
b90e10279ef2e08604b93429949693ee
|
|
| BLAKE2b-256 |
cdb1640f87da7449341a8901a6c776b768941bee6913dd15a39a099319631c5d
|