Forward deployed engineering, Part 6: Agent frameworks compared
ADK, LangGraph, CrewAI and AutoGen side by side, from the basics: the four patterns underneath every framework (ReAct, reflection, supervisor and graph), the same small router written in two frameworks, how to choose one for a customer, and how agents built with different frameworks still work together over A2A and MCP.
In Part 5 we connected the agent to Acme’s systems: the APIs, the content connectors and the identity provider. Now the build starts, and the first question from Acme’s platform team arrives before anyone writes a line of code: “Which framework are you using, and why?”
Acme’s data science team already has a working notebook built with LangGraph. A partner has pitched CrewAI. Someone on the platform team has read about AutoGen. The agents we build in the Production-ready agents series use Google’s Agent Development Kit (ADK). You are the forward deployed engineer embedded with Acme, so you need an answer with reasons the customer can check, and that answer has to still make sense after you leave.
This part covers what a framework does, the four patterns underneath all of them, each framework in the same format, the same task written in two frameworks, how to choose, and how agents built with different frameworks work together.
If you prefer to watch first, here is the heart of this part as a short animated explainer.
Video: how to choose an agent framework for a customer, and why the patterns matter more than the syntax, in three minutes. The narration is a synthetic voice; the script and animation are mine.
Where does this show up in an FDE job description?
Public FDE postings name frameworks and patterns directly. These lines come from Google Cloud’s public job listings, as of October 2026:
“Experience implementing multi-agent systems using frameworks (e.g., LangGraph, CrewAI, ADK) and complex patterns (e.g., ReAct, self-reflection, hierarchical delegation).”
Forward Deployed Engineer, GenAI, Google Cloud: preferred qualifications
“Experience in system design or orchestration frameworks (e.g., LangGraph, AutoGen, CrewAI).”
AI Outcome Customer Engineer IV, Forward Deployed Engineering: minimum qualifications
“Experience with agentic frameworks and harness layers, such as Google’s Agent Development Kit (ADK) or equivalent, protocol-level interoperability (MCP, Agent-to-Agent (A2A)) across third-party Independent Software Vendor (ISV) platforms.”
Staff Forward Deployed Engineer, Developer AI, Google Cloud: preferred qualifications
In plain words, you are expected to know more than one framework, to recognise the patterns underneath them, and to connect agents that were built with different tools. This post covers all three.
What does an agent framework actually do?
Part 1 of the agents series defines an agent as a model plus instructions, tools and a loop. You can write that loop yourself in a short Python file. A framework saves you from writing it again for every project.
The simple definition: an agent framework is a library that runs the agent loop for you, so that you only write the parts that are specific to your problem.
More precisely, a framework gives you six things:
- A model connector. One way to call a model, whether that is Gemini or another provider.
- Tool definitions. It turns a Python function into a tool (a function the model may ask your code to run), with a name, a description and typed parameters.
- Orchestration (deciding what runs next). The loop for one agent, plus ways to combine agents: one after another, in parallel, in a loop or as a graph.
- State and memory. State is what a run remembers between steps; memory is what the agent remembers between conversations.
- Callbacks or middleware (your code that runs before or after a model or tool call). This is where guardrails live.
- Observability and deployment hooks. Traces, logs and a way to run the agent as a service.
A web framework such as Django is the closest comparison: it runs the request loop and you write the views. In the same way, the agent framework runs the agent loop, its orchestration plays the part of URL routing, and its callbacks play the part of web middleware.
what an agent framework does: you write the instructions, tools, rules and checks; the framework gives you the model connector, the loop, orchestration, state, callbacks and tracing; a platform runs it; the model, data, tool code and evaluation set stay the same whichever framework you pick
Notice what does not change when you change framework: the model, the customer’s data, the code inside your tools and your evaluation set. My view: this is why the framework matters less than most people expect, and much less than discovery (Part 2) and data readiness (Part 4).
Which patterns sit underneath every framework?
The job description lists ReAct, self-reflection and hierarchical delegation. These are patterns: ideas that every framework implements in its own syntax. Once you know the patterns, you can read any framework’s code.
ReAct: think, act, observe, repeat
ReAct (reasoning and acting) comes from a 2022 paper by Yao and colleagues. The model writes a short reasoning step, picks a tool to call (the action), reads the result (the observation) and repeats until it can answer. Most tool-calling agents today run a ReAct loop.
At Acme, Maria in marketing asks “How did the Acme Pure Refill Launch do in Western Europe?” The marketing agent reasons that it needs spend and sales, calls the spend tool, reads the result, calls the sales tool, and then answers.
Choose ReAct when one agent with a handful of tools is enough and you cannot know the steps in
advance. In ADK this is an Agent with tools; in LangChain it is create_agent, which runs on
LangGraph.
the ReAct loop: the model reasons about what it needs, acts by calling a tool, observes the result and repeats until it can answer; here the marketing agent fetches spend and then sales before answering Maria
Reflection: draft, critique, revise
Reflection (the job description calls it self-reflection) adds a checking step. One step produces a draft, a second step critiques it, and the draft is revised. Two well-known papers describe the idea: Reflexion (Shinn and colleagues, 2023) and Self-Refine (Madaan and colleagues, 2023). The critic can be a model or plain code.
At Acme, the writer drafts the answer and code checks every number against the specialists’ findings (agents Part 5), because checking a number needs no judgement.
The check is ordinary code in the writer’s after-model callback. Simplified, the lines that matter are these:
def writer_after_model(callback_context, llm_response):
st = callback_context.state
text = "".join(p.text for p in llm_response.content.parts
if p.text and not p.thought)
evidence = [str(st[k]) for k in FINDINGS_KEYS if st.get(k)]
missing = ungrounded_numbers(text, evidence, st.get("question", ""))
if missing:
text = fallback_answer(evidence) # what the specialists reported
llm_response.content.parts = [types.Part(text=text)]
return llm_response
Part 5 of the agents series explains each line, including why the whole answer is replaced instead of patched.
Choose reflection when first drafts vary in quality and checking is cheaper than getting it right
first time. Always cap the rounds: in ADK, a LoopAgent takes max_iterations; in LangGraph, the
loop is a cycle with a conditional edge.
Supervisor: one agent hands work to others
A supervisor (also called a coordinator or manager) is an agent that reads the request and hands parts of it to worker agents. When workers can have workers of their own, the job description calls it hierarchical delegation. Usually a model makes the choice.
At Acme, a coordinator’s model would read Maria’s question and pick marketing or supply.
Choose a supervisor when there are many specialists, requests vary a lot and a wrong choice is cheap
to recover from. In ADK, you give a coordinator Agent a list of sub_agents and ADK creates a
delegation tool for each one. In CrewAI, Process.hierarchical with a manager_llm or
manager_agent does the same.
two more patterns: in reflection a writer drafts and a checker approves or sends the draft back, with a cap on rounds; in a supervisor pattern a model reads the request and hands it to one of several worker agents
Graph: code decides the order
A graph workflow is a set of nodes (steps) joined by edges (what runs next). Some nodes call a model; others are plain code, so they behave the same way every time and you can unit test them. Edges can branch and run steps in parallel.
At Acme, this is the router in Part 5 of the agents series: a small model tidies up the question, code picks the team and the specialists can run in parallel.
the Acme router in brief: front and route are plain code, extract and writer call a model, and route sends each question to marketing, supply, both in parallel, or a polite decline; every data path ends at the same checked writer
Part 5 of the agents series builds each node and edge of this graph.
Choose a graph when a rule must hold on every request, such as “only supply may compute
penalties”. ADK 2.0 has Workflow, LangGraph has StateGraph, CrewAI has Flows and Microsoft
Agent Framework has workflows.
Patterns combine. The Acme router is a graph whose specialist nodes are ReAct agents, with a reflection step in code at the end. My view: a supervisor is fine for a demo, but when a rule must hold every time, put the rule in a graph.
What are the four frameworks, and how are they different?
ADK (Agent Development Kit). Google’s open-source framework. Its README says that, while
optimised for Gemini, ADK is model-agnostic and deployment-agnostic. Its building blocks are the
Agent (an agent driven by a model), workflow agents (SequentialAgent, ParallelAgent and
LoopAgent) and, since version 2.0, graph Workflows made of function nodes, agent nodes and
routes. The documentation covers Python, TypeScript, Go and Java. ADK Python 2.0 has been generally
available (GA) since 19 May 2026, and the latest Python release is 2.12.0, from 13 October 2026.
ADK agents deploy to Agent Runtime and can be published to Gemini Enterprise
(agents Part 11 and
Part 12). Choose it when the customer
runs on Google Cloud and you want the framework, the runtime, identity and Gemini Enterprise to line
up.
LangGraph. From LangChain. Its documentation calls it “a low-level orchestration framework and
runtime for building, managing, and deploying long-running, stateful agents”. You build a
StateGraph over a typed, shared state; each node returns an update to that state; edges and
conditional edges decide what runs next. Checkpointers save the state after each step, so a run
can resume after a failure, and interrupts pause a run for a person to approve. LangChain’s
create_agent gives you a prebuilt ReAct agent on top. LangGraph 1.0 was released on 17 October
2025, and the latest release is 1.2.16, from 16 October 2026. Choose it when the customer’s team
already knows LangChain, or when you need fine control over state and resumable runs.
CrewAI. An open-source framework with two layers. Crews are teams of role-playing agents, each with a role, a goal and a backstory, working through tasks with a sequential or hierarchical process. Flows are event-driven workflows with state, conditions and loops; the documentation calls Flows the backbone of an application. The latest release is 1.15.28, from 14 October 2026. Choose it when the problem maps naturally to roles and tasks, and put the crews inside a Flow when you need control.
AutoGen and Microsoft Agent Framework. AutoGen was Microsoft’s research framework for agents that talk to each other. As of October 2026 its repository is archived, and the README says Microsoft is not providing bug fixes, security fixes, new features or support, and that new users should start with Microsoft Agent Framework: the direct successor, built by the same teams, combining AutoGen’s agent ideas with Semantic Kernel’s enterprise features. It supports Python and .NET, and its 1.0 Python package was published on 2 April 2026. Choose it when the customer builds on Microsoft’s stack. When a posting says AutoGen, read it as multi-agent conversation patterns, and do not start new production work on AutoGen itself.
the four frameworks side by side as of October 2026: ADK, LangGraph, CrewAI, and AutoGen with its successor Microsoft Agent Framework, compared by building block, routing in code, languages, latest release, A2A and MCP support, and best fit
One honest gap: these version numbers change every week. Check each project’s release notes on the day you decide, and write the date into the design document.
What does the same task look like in two frameworks?
Here is the core decision of the Acme router: a question comes in, code decides whether marketing or supply should answer, and the chosen specialist answers. The specialists are stubs, so the code runs without a model or an API key. I ran both versions with ADK Python 2.12.0 and LangGraph 1.2.16.
First, ADK:
the Acme routing decision in ADK: route is a plain function node that returns an Event with a route value, and a dict edge sends the question to the matching specialist
routeis a function node. It returns anEventwhoseroutevalue names the next step. No model is called, so it costs nothing and gives the same answer every time.- The dict edge maps each route value to a node. ADK runs only the one that matches.
- The output of one node becomes the next node’s
node_input. Data flows along the edges.
Now the same thing in LangGraph:
the same decision in LangGraph: a typed state shared by every node, a routing function that returns the name of the next node, and compile to get a runnable graph
- State is a typed dictionary shared by every node. Nodes return only the keys they change.
add_conditional_edgescalls the routing function and uses the returned key to pick the next node.compile()turns the builder into a graph you can run withinvoke.
Both are graphs, both route in plain Python, and the same unit test proves both. They differ in how data moves: ADK passes each node’s output to the next node, while LangGraph keeps one shared state. My view: once you see the pattern, the other syntax takes a day to learn, so the skills of the team that will own the code matter far more.
How do I choose a framework for a customer?
Ask six questions, in this order:
six questions for choosing a framework, in order: who will own it, where it will run, whether rules must hold every time, which languages the team uses, whether the project is maintained, and whether it speaks A2A and MCP
- Who will own it? The customer’s team keeps the code after you leave (Part 7), so a framework they know beats a slightly better one they do not.
- Where will it run? On Google Cloud with Agent Runtime and Gemini Enterprise, ADK lines up end to end.
- Must rules hold every time? Then you need graph workflows.
- Which languages? Microsoft Agent Framework adds .NET to the list in the diagram.
- Is it maintained? An archived project gets no security fixes.
- Does it speak A2A and MCP? All four current options do in some form.
For Acme, the answers point to ADK. Acme runs on Google Cloud, the agents will run on Agent Runtime, users will reach them through Gemini Enterprise, and the routing rules must hold every time. You do not throw away the data science team’s LangGraph notebook. It becomes evidence for the prototype in Part 7: you keep its test questions and its prompts. And because the router calls the specialists over A2A, the supply team could rebuild their agent in LangGraph later without the router changing at all.
How do agents built in different frameworks talk to each other?
Two open protocols make mixed systems possible:
- A2A (Agent2Agent) lets one agent find another, hand it work and get results back. As of October 2026 the latest released specification is 1.0.0, and it is a Linux Foundation project.
- MCP (Model Context Protocol) lets an agent discover and call tools on another server. The latest specification version is dated 28 July 2026.
Each framework supports them in its own way:
- ADK:
RemoteA2aAgentcalls remote agents, andMcpToolsetconnects to MCP servers. - LangGraph: LangSmith’s Agent Server offers an A2A endpoint at
/a2a/{assistant_id}that speaks A2A 1.0; LangChain’s MCP support is marked beta as of version 1.4. - CrewAI:
A2AClientConfigandA2AServerConfig(installcrewai[a2a]), and MCP servers as tools. - Microsoft Agent Framework: MCP clients for tools and A2A hosting samples.
mixing frameworks safely: Maria asks in Gemini Enterprise, the ADK router calls the marketing agent and a supply agent rebuilt in LangGraph over A2A, and each specialist calls its tools over MCP; the router never needs to know which framework is on the other side
The rule from Part 6 of the agents series still applies: use A2A when the other side is an agent with its own model, rules and permissions, and MCP when it is a tool. That post goes through agent cards, tasks and messages in detail.
An agent card is the small JSON document the router reads before it calls a specialist. This is the supply agent’s card, simplified:
{
"name": "acb_demo_supply",
"description": "Supply specialist for ACB: OTIF, ...",
"version": "0.1.0",
"supportedInterfaces": [
{"url": "https://.../a2a/app", "protocolBinding": "JSONRPC", "protocolVersion": "1.0"},
{"url": "https://.../a2a/app", "protocolBinding": "JSONRPC", "protocolVersion": "0.3"}
],
"capabilities": {"streaming": true, "extensions": [...]},
"defaultInputModes": ["text/plain"],
"skills": [{"id": "...", "name": "...", "description": "...", "tags": [...]}]
}
ADK builds most of it from the agent’s code, whichever framework sits on the other side. What is in an agent card? explains every field.
Try it: run the same router in both frameworks
You need Python 3.11 or later. Install both frameworks in a fresh virtual environment:
python3 -m venv .venv && source .venv/bin/activate
pip install google-adk langgraph
Save the ADK listing above as try_adk.py with this runner at the bottom:
import asyncio
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
async def main():
runner = Runner(app_name="acme", agent=root_agent,
session_service=InMemorySessionService(), auto_create_session=True)
for q in ["What did the spring campaign cost?", "What did the stockouts cost us?"]:
msg = types.Content(role="user", parts=[types.Part(text=q)])
async for ev in runner.run_async(user_id="maria", session_id=q, new_message=msg):
if ev.output and "answers" in str(ev.output):
print(ev.output)
asyncio.run(main())
Save the LangGraph listing as try_langgraph.py, ending with:
for q in ["What did the spring campaign cost?", "What did the stockouts cost us?"]:
print(graph.invoke({"question": q})["answer"])
When I ran each script, both printed the same thing:
marketing answers: What did the spring campaign cost?
supply answers: What did the stockouts cost us?
Then try these changes:
- Move the rule out. Put the keyword check in its own file,
rules.py, with no framework imports, and call it from bothroutefunctions. Write one pytest test for it. This is the habit that keeps business rules portable between frameworks. - Add a “both” route. In LangGraph, return a list of node names from the routing function and
both nodes run in parallel. In ADK, use a tuple of nodes and a
JoinNode, as in Part 5. Compare how much code each needs.
What can go wrong
- Choosing by demo. A great ten-minute demo says nothing about the customer’s runtime, identity provider or team skills. Ask the six questions first.
- Business rules inside framework classes. Changing framework then means rewriting them. Keep rules in plain Python.
- A supervisor for rules that must hold. A model choosing the route is usually right, and usually is not good enough for compliance.
- Reflection without a limit. A critic that is never satisfied runs up cost. Cap the rounds.
- Two frameworks in one process. Two runtimes and two tracing set-ups are hard to debug. Mix frameworks at an A2A boundary instead.
- Unpinned versions, or untested protocol versions. Pin versions, and test a real A2A call early, because one side may speak 1.0 and the other only 0.3.
What I would do now
- Read one sample from each framework’s documentation and find the four patterns in it.
- Run the two scripts above, then add the “both” route in each.
- Write the six questions, the customer’s answers and the date into your design document.
- Keep every business rule in a framework-free module with its own tests, and put an A2A boundary between agents owned by different teams.
What did we learn?
- An agent framework runs the agent loop for you, while the model, the data, the tool code and the evaluation set stay the same whichever framework you choose.
- Four patterns sit underneath every framework (ReAct, reflection, supervisor and graph), and once you know them you can read any framework’s code.
- When a rule must hold on every request, put it in a graph and decide it in plain code instead of asking a model to choose.
- ADK, LangGraph, CrewAI and Microsoft Agent Framework differ mostly in syntax and in how data moves between steps, so the skills of the team that will own the code matter more than small feature differences.
- Choose with six questions in order, starting with who will own the system and where it will run, and write the answers and the date into the design document.
- Agents built with different frameworks work together over A2A and reach tools over MCP, so mix frameworks at an A2A boundary and never inside one process.
What comes next?
The framework is chosen. In Part 7: Prototype in days, production in weeks, we build a prototype we plan to throw away, use AI-assisted coding to move faster, and then work through the hardening checklist and the handover to Acme’s own team. It builds on the choice made here: ADK for the router, with an A2A boundary between agents owned by different teams.
Sources
- Google Careers: Forward Deployed Engineer, Gen AI, Google Cloud
- Google Careers: AI Outcome Customer Engineer IV, Forward Deployed Engineering
- Google Careers: Staff Forward Deployed Engineer, Developer AI, Google Cloud
- Yao et al.: ReAct: Synergizing Reasoning and Acting in Language Models
- Shinn et al.: Reflexion: Language Agents with Verbal Reinforcement Learning
- Madaan et al.: Self-Refine: Iterative Refinement with Self-Feedback
- ADK documentation
- ADK on GitHub (README)
- ADK: workflows
- ADK: graph routes
- ADK: loop agents
- ADK: collaborative workflows and sub-agents
- ADK: MCP tools
- ADK: A2A protocol
- google-adk on PyPI
- LangGraph overview
- LangGraph: Graph API
- LangChain: agents (
create_agent) - LangChain: MCP
- LangSmith: A2A endpoint in Agent Server
- langgraph on PyPI
- CrewAI: introduction
- CrewAI: processes
- CrewAI: Flows
- CrewAI: Agent-to-Agent (A2A) protocol
- crewai on PyPI
- AutoGen on GitHub (archived notice)
- Microsoft Agent Framework overview
- Microsoft Agent Framework on GitHub
- Migration guide: AutoGen to Microsoft Agent Framework
- agent-framework on PyPI
- A2A protocol specification
- Model Context Protocol specification
Opinions are my own. Every fact in this post comes from the public documentation linked above. Acme Consumer Brands and its data are fictional.