pyagent-blueprint vs. LangGraph¶
LangGraph models a multi-agent system as an explicit StateGraph: nodes, edges, and a shared state
object, all wired in Python. pyagent-blueprint's langgraph adapter compiles a YAML manifest into
that exact same StateGraph API — so the comparison isn't "YAML vs. LangGraph," it's "author your
graph as a manifest vs. author it as code," while both ultimately execute the identical LangGraph
runtime.
This is a real, verified adapter — not an aspirational one. pyagent-blueprint-adapter-langgraph's
compile() builds a genuine langgraph.graph.StateGraph, calling add_node()/add_edge() for each
agent in the workflow and compiling it with LangGraph's own .compile(); run() invokes it via the
real ainvoke() path. It's certified against the same AdapterConformanceSuite every other adapter
must pass.
Same pipeline, two authoring styles¶
Hand-written LangGraph:
from langgraph.graph import END, START, StateGraph
from typing import TypedDict
class GraphState(TypedDict):
input: str
output: str
def researcher_node(state: GraphState) -> GraphState:
# call your LLM here
return {"output": "research summary"}
def writer_node(state: GraphState) -> GraphState:
return {"output": "final draft"}
graph = StateGraph(GraphState)
graph.add_node("researcher", researcher_node)
graph.add_node("writer", writer_node)
graph.add_edge(START, "researcher")
graph.add_edge("researcher", "writer")
graph.add_edge("writer", END)
app = graph.compile()
Equivalent pyagent-blueprint manifest:
api_version: pyagent/v1
metadata:
name: research-pipeline
version: 1.0.0
providers:
primary:
model: gpt-4.1-mini
agents:
researcher:
prompt: "Research the topic and produce a summary"
provider: primary
writer:
prompt: "Turn the research summary into a final draft"
provider: primary
workflows:
pipeline:
pattern: pipeline
agents:
stages: [researcher, writer]
from pyagent_blueprint.adapter import AdapterRegistry
from pyagent_blueprint.ir import BlueprintIR
from pyagent_blueprint.loader import load_blueprint
spec = load_blueprint("research-pipeline.yaml")
ir = BlueprintIR.from_spec(spec)
adapter = AdapterRegistry.discover()["langgraph"]()
artifact = adapter.compile(ir) # a real langgraph.graph.StateGraph, compiled
result = await adapter.run(artifact, workflow="pipeline", input_="multi-agent orchestration trends")
Both produce the same StateGraph shape under the hood. The manifest version adds: static
validation (pyagent-blueprint validate research-pipeline.yaml) before any node runs, a semantic
diff (pyagent-blueprint diff old.yaml new.yaml) between versions, and a stable diagnostic if a
declared governance feature (a budget, an SLA, a memory tier) has no LangGraph-side equivalent yet —
rather than that feature being silently ignored by hand-written code.
Where LangGraph is still the better fit¶
If your control flow needs genuinely dynamic graph construction at runtime — nodes and edges decided by the output of a previous step, not knowable ahead of time — write it directly in LangGraph. Blueprint's IR models a declared, typed workflow; it does not attempt to express arbitrary runtime graph mutation. The adapter targets the common case (named patterns compiled to a static graph shape), not LangGraph's full expressiveness.
Migrating an existing LangGraph app¶
There is no dedicated LangGraph→Blueprint migration guide yet — this is intentionally sequenced
behind the Agent Spec interop bridge (Step 8 of the engineering roadmap), so that migration guidance
can point at a real, lossless import path rather than a manual rewrite. Until then, the pattern above
— re-declaring an existing graph's nodes as agents: and its edges as a pipeline/supervisor/etc.
workflow — is the direct manual route.