Why Blueprint?¶
Most multi-agent frameworks make you choose your runtime before you design your system: a
LangGraph StateGraph, a CrewAI Crew, an AutoGen conversation. The orchestration logic and the
execution engine are the same lines of Python — which means every migration, every framework
evaluation, and every "let's also support X" request means rewriting the system from scratch.
pyagent-blueprint separates the two. You declare what your system does — agents, workflows,
providers, contracts, governance — in a single YAML manifest. A RuntimeAdapter decides how it
runs. The same manifest compiles against five structurally different adapters today, unmodified.
How this relates to the homepage comparison
The homepage compares PyAgent's overall feature set against LangChain, CrewAI, and AutoGen (pattern count, routing, memory, and more). This page and the pages under it go one layer deeper on a single, specific claim from that table — the YAML-vs-code tradeoff and cross-runtime portability — with real adapter code, not just a feature checklist.
The same manifest, five runtimes¶
api_version: pyagent/v1
metadata:
name: customer-support
version: 1.0.0
providers:
primary:
model: gpt-4.1-mini
agents:
classifier:
prompt: "Classify into: billing, tech, general"
provider: primary
billing:
prompt: "Handle billing inquiries"
provider: primary
tech:
prompt: "Handle technical support"
provider: primary
workflows:
support:
pattern: supervisor
agents:
classifier: classifier
routes:
billing: billing
tech: tech
pyagent-blueprint validate customer-support.yaml
pyagent-blueprint adapters # list every registered adapter
pyagent-blueprint test customer-support.yaml # contract conformance vs. MockLLM, no live API calls
Choosing which adapter compiles and runs a workflow is a Python-API decision today (the CLI's
compile command uses the bundled native runtime by default) — pick an adapter class from
AdapterRegistry.discover() and call its compile()/run() directly:
from pyagent_blueprint.adapter import AdapterRegistry
from pyagent_blueprint.ir import BlueprintIR
from pyagent_blueprint.loader import load_blueprint
spec = load_blueprint("customer-support.yaml")
ir = BlueprintIR.from_spec(spec)
for name in ("langgraph", "crewai", "pyagent"):
adapter_cls = AdapterRegistry.discover()[name]
adapter = adapter_cls()
artifact = adapter.compile(ir)
result = await adapter.run(artifact, workflow="support", input_="I was charged twice")
That's not a hypothetical — it's what the RuntimeAdapter conformance suite actually certifies.
Every adapter below implements the same contract (compile(ir) -> CompiledArtifact, an always-async
run()) and is tested against the same AdapterConformanceSuite, which checks compile/run
correctness, diagnostic completeness (governance features are honored or reported via a stable
diagnostic code — never silently dropped), and pattern-intent preservation:
| Adapter | Execution model | What actually runs |
|---|---|---|
pyagent (native) |
Full 18-pattern registry | pyagent_patterns.orchestration.Supervisor etc. |
langgraph |
Declared node/edge graph | Real StateGraph(...).add_node(...).add_edge(...), compiled and invoked |
openai_agents |
Handoff/turn-based | Real Agent + Runner.run() |
crewai |
Role-based crew | Real Agent/Task/Crew.kickoff_async() |
semantic_kernel |
Event/service-oriented | Real Kernel + ChatCompletionAgent.get_response() |
single_agent / sequential_chain / state_machine / simple_loop |
Zero-dependency reference shapes | Pure stdlib, ships in core |
What you get that hand-written orchestration code doesn't¶
- Diff and review like infrastructure.
pyagent-blueprint diff old.yaml new.yamlproduces a semantic diff over the IR — not a text diff of hand-wired Python — so a PR reviewer can see exactly which agent, route, or SLA changed. - Validate before you run anything. Static analysis (dangling references, schema violations) catches mistakes before an LLM call is ever made.
- Governance is never silently dropped. Budgets, SLAs, memory tiers, guardrails, recovery
policies, and human-in-the-loop checkpoints are either honored by the adapter or surfaced as a
stable
CompileDiagnosticcode (e.g.BUDGET_UNSUPPORTED,MEMORY_TIER_UNSUPPORTED,CHECKPOINT_UNSUPPORTED) — so you always know, deterministically, what a given runtime supports. - Package and test without live API calls.
pyagent-blueprint test(contract conformance) andpyagent-blueprint package(Agent Unit archives) both work against aMockLLM, so CI can validate a system's shape before spending a token. - Zero mandatory runtime dependency. Core
pyagent-blueprintdepends only onpydantic,pyyaml, andclick. You install a runtime adapter — the bundledpyagentreference stack, one of four zero-dependency stdlib adapters, or a third-party package — only when you're ready to run.
When a blueprint isn't the right fit¶
To be direct about the tradeoff: if your orchestration logic depends on dynamic, runtime-computed control flow that can't be expressed as a static graph (e.g. an agent that decides to spin up an arbitrary number of sub-agents based on a live computation), hand-written code in your chosen framework is still the right tool. Blueprint's IR models agents, typed workflows, and named patterns — it's declarative by design, and that's a real constraint, not just a feature.
See the pattern-specific comparisons for how this plays out against real frameworks:
Or start from the concepts: What is an agent blueprint? and What is multi-agent orchestration?