Code Review Agent
Fan-out over changed files. 3 models per file. Merge best answers. Synthesize report.
map_over= + ensemble_n= + merge_fn=
@node(outputs=ChangedFiles)def parse_diff(raw_diff: Annotated[str, FromInput]) -> ChangedFiles: return parse_git_diff(raw_diff)
@node(outputs=FileReview, prompt="review this file for bugs and security issues", model="reason", map_over="parse_diff.files", map_key="path", ensemble_n=3, merge_fn="pick_best")def review(file: ChangedFile) -> FileReview: ...
@node(outputs=Report, prompt="synthesize all findings into a final report", model="fast")def report(review: list[FileReview]) -> Report: ...uv add neograph && python review_agent.pyThat’s a production code review agent. Here’s what those 8 lines do:
ChangedFile in, FileReview out — validated at assembly time, not runtimeReport is a Pydantic model, not a string blobThe same thing in raw LangGraph? 130 lines. Two state models, two graphs, a router, a barrier, a reducer, manual edge wiring, and a subgraph wrapper. See the comparison.
A function is a node. A parameter name is an edge. The graph assembles itself.
@node(outputs=Claims, prompt='decompose', model='reason')def decompose(topic: Annotated[str, FromInput]) -> Claims: ...
@node(outputs=Classified, prompt='classify', model='fast')def classify(decompose: Claims) -> Classified: ...# ^^^^^^^^^# this parameter name IS the dependencyclassify takes decompose: Claims — neograph reads the signature, verifies decompose produces Claims, and wires the edge. Rename the function? Your IDE flags the broken reference before you hit save.
Mode is inferred. prompt= + model= = LLM call. Neither = the function body runs. Keywords add superpowers: map_over= for fan-out, ensemble_n= for N-way ensemble, interrupt_when= for human approval gates.
Code Review Agent
Fan-out over changed files. 3 models per file. Merge best answers. Synthesize report.
map_over= + ensemble_n= + merge_fn=
Lead Research Pipeline
For each lead: scrape website, search news, synthesize findings, qualify and score.
Each fan-out + sub-construct + LLM synthesis
Document Analyzer
Chunk large docs. Decompose each chunk with Oracle ensemble. Loop until quality threshold met.
Each x Oracle fusion + Loop refinement
Spec Builder
Describe a workflow in plain English. LLM generates the pipeline spec. neograph validates and compiles it.
LLM-driven runtime construction
neograph handles:
| You write | neograph handles |
|---|---|
@node(map_over="items") | Fan-out router, Send() dispatch, barrier, dict collection, dedup |
ensemble_n=3, merge_fn="best" | N generators x M models, merge barrier, result selection |
interrupt_when=lambda s: ... | Checkpointer setup, interrupt/resume flow, human feedback injection |
Annotated[T, FromInput] | Config injection, bundled model construction, DI resolution |
prompt="analyze" | Prompt compilation, structured output, retry with error feedback |
| Parameter names | DAG inference, topological sort, type validation, fan-in wiring |
ConstructError: Node 'verify' declares inputs=ClusterGroup but no upstream produces a compatible value. upstream producers: - node 'cluster': Clusters hint: did you forget to fan out? try .map(lambda s: s.cluster.groups, key='...') at my_pipeline.py:4268 compile-time check fixtures backed by a rustc-style fixture suite. If it compiles, it runs. Validate any pipeline without executing: neograph check my_pipeline.py.
uv add neographfrom neograph import node, construct_from_module, compile, run
@node(outputs=Result, prompt="do the thing", model="reason")def my_agent(topic: str) -> Result: ...
graph = compile(construct_from_module(__import__(__name__)))result = run(graph, input={"topic": "hello", "node_id": "demo"})1362 tests. Hypothesis property-based testing. MIT license. Built on LangGraph.
Documentation © 2025-2026 Constantine Mirin, mirin.pro. Licensed under CC BY-ND 4.0.