Choosing a Framework Basics
9 examples to get you started with Choosing a Framework - 6 basic and 3 intermediate.
These sketches are conceptual and deliberately small. They show control-flow differences, not full production installs. API names can shift; treat snippets as teaching models and verify against current docs at build time.
Prerequisites
- Comfort with a basic agent loop: model call, tool call, observe, stop.
- Python reading level for short functions.
- Optional: skim What Actually Differs Between Agent Frameworks for vocabulary.
Basic Examples
1. Fix the Task Before You Fix the Framework
Compare frameworks only on the same goal, tools, and stop rules.
TASK = {
"goal": "Answer with the current weather for a city, then stop",
"tools": ["get_weather"],
"max_turns": 4,
"success": "returns temp_c and summary",
}- If the task changes between demos, you are ranking marketing, not frameworks.
- Write success and max turns first; they are architecture, not afterthoughts.
- Prefer one tool so differences in orchestration stand out.
Related: What Actually Differs Between Agent Frameworks - comparison axes
2. Shared Tool Surface (Portable Core)
Define the business tool once so both frameworks call the same capability.
def get_weather(city: str) -> dict:
# stand-in for a real API client
return {"city": city, "temp_c": 18, "summary": "cloudy"}
TOOLS = {"get_weather": get_weather}- Portable tools make migration cheaper later.
- Keep tools free of framework imports when you can.
- Return structured dicts, not free-form strings, when possible.
Related: Framework Lock-In Risks and How to Avoid Them - portability patterns
3. Framework A Shape: Explicit Graph (LangGraph-style)
Model the loop as nodes over shared state.
# Conceptual LangGraph-style control (not a full app)
state = {"city": "Berlin", "messages": [], "result": None}
def call_model(state):
# model decides: tool call or final answer
return {**state, "next": "tool", "tool_args": {"city": state["city"]}}
def call_tool(state):
out = TOOLS["get_weather"](**state["tool_args"])
return {**state, "result": out, "next": "end"}
# edges: model -> tool -> end (or model -> end)- Graphs make branches and stop edges visible.
- Shared state fields (
result,next) are easier to log than a pure chat blob. - Cost: you design nodes and edges before the demo looks "magical."
Related: The LangGraph Mental Model: Agents as State Graphs - graph model
4. Framework B Shape: Role + Task (CrewAI-style)
Model the loop as a specialist role assigned a task.
# Conceptual CrewAI-style control (not a full app)
agent = {
"role": "Weather Reporter",
"goal": "Fetch weather and summarize clearly",
"tools": ["get_weather"],
}
task = {
"description": "Get weather for {city} and return temp_c + summary",
"agent": agent,
"expected_output": "JSON with temp_c and summary",
}
# crew.kickoff(inputs={"city": "Berlin"})- Roles + tasks optimize for human-readable multi-agent stories.
- For a one-tool weather fetch, a full crew is optional overhead - that is the point of the comparison.
- Cost: orchestration is more "who does the work" than "which edge fires."
Related: The CrewAI Mental Model: Roles, Tasks, and Crews - role model
5. Side-by-Side Outcomes Checklist
Score both solutions on the same rubric after running the identical task.
scorecard = {
"correct_result": False, # structured weather fields present
"turns_used": 0, # lower is better for this task
"lines_of_glue": 0, # setup cost
"easy_to_add_approval": None, # yes/no gut check
"easy_to_unit_test_tool": None,
"clear_stop_reason": None,
}- Correctness ties often; setup cost and operability decide.
- "Easy approval" previews production needs even if the POC skips HITL.
- If both pass, pick the model your team can debug at 2 a.m.
Related: Framework Comparison Matrix: LangGraph, CrewAI, Microsoft Agent Framework & More - full matrix
6. Thin SDK Shape for Contrast (Provider-Native Sketch)
See a third style: agent + tools without graph or crew abstractions.
# Conceptual native-SDK style
agent = {
"name": "weather",
"instructions": "Use get_weather for city questions. Stop when answered.",
"tools": [get_weather],
}
# result = Runner.run(agent, "Weather in Berlin?")- Native SDKs minimize ceremony for single-provider stacks.
- You may outgrow them when you need complex durable graphs or multi-cloud routing.
- Compare ceremony honestly: fewer abstractions is a feature until you reinvent them.
Related: What Native Provider Agent Primitives Give You Over a Framework - native trade-offs
Intermediate Examples
7. Add One Branch: "Missing City"
Extend the same task so control-flow differences show up.
def next_step(state):
if not state.get("city"):
return "ask_city"
if state.get("result"):
return "end"
return "fetch_weather"- Graphs express this as an explicit conditional edge.
- Role/task systems often push branching into prompt text unless you add process structure.
- Thin SDKs rely on the model to ask a clarifying question - fine until you need guaranteed behavior.
Related: Branching and Conditional Edges for Multi-Path Agents - graph branching
8. Time-Box a Two-Framework Spike
Run a 90-minute bake-off, not a two-week rewrite contest.
spike = {
"minutes": 90,
"task": TASK,
"frameworks": ["graph_style", "crew_style"], # or native vs pydantic-ai
"must_capture": [
"install friction",
"lines of glue",
"trace readability",
"how stop works",
"how to add a second tool",
],
}- Spikes kill religious debates faster than blog posts.
- Capture evidence in an ADR, not Slack lore.
- Include one production-ish concern (stop reason or second tool), not only happy path.
Related: POC-to-Production Migration Paths Between Frameworks - after the spike
9. Decision Snapshot Template
Write the choice so a future teammate can challenge it.
decision = {
"task_class": "short tool-using Q&A",
"chosen": "graph_style", # example only
"why": "we expect approval nodes and resume within a quarter",
"not_chosen": "crew_style",
"why_not": "role overhead for single-tool flows; weaker fit for strict edges",
"revisit_when": "multi-role research pipeline becomes the main workload",
}- Framework choice is reversible if tools and schemas stay portable.
- "Revisit when" prevents both endless churn and permanent lock-in by silence.
- Match team skills as hard as match features (team skill checklist).
Related: Choosing a Framework Best Practices - evaluation practices | An ADR Template for Agent Framework Selection - write it down
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.