smolagents is the right choice when you value a small library you can fully understand, the code-agent approach fits your task, and you can execute code safely. It's the wrong choice when you need a big ecosystem, can't sandbox, or your tasks are simple isolated calls. This closing post gives the honest verdict and places smolagents in the landscape.
smolagents is the right choice when you value a small library you can fully understand, the code-agent approach fits your task, and you can execute code safely — and the wrong choice when you need a big ecosystem, can't sandbox, or your tasks are simple isolated calls.
Strands is the right framework when you want to trust a capable model to drive and get out of its way — and the wrong one when you need to guarantee a process. This closing post gives the honest verdict on when to reach for Strands, how it compares to its peers, and how the model-driven approach fits the wider agent landscape.
Strands is the right framework when you want to trust a capable model to drive and get out of its way — and the wrong one when you need to guarantee a process. The honest verdict on when to reach for Strands and how it compares.
Underneath the code-agent magic is a simple, readable loop — the kind of loop smolagents's minimalism lets you actually understand. And when one agent isn't enough, the same minimal parts compose into multi-agent systems, where a manager agent's code calls other agents as if they were tools.
Underneath the code-agent magic is a simple, readable loop that smolagents's minimalism lets you actually understand. And when one agent isn't enough, the same parts compose into multi-agent systems, where a manager agent's code calls other agents like tools.
A model-driven agent decides its own path, which means you cannot know what it did without watching — so observability isn't a nice-to-have in Strands, it's a requirement. Built on OpenTelemetry and shaped by AWS's own production use, Strands treats seeing inside the agent as first-class, because a loop you can't see is a loop you can't trust.
A model-driven agent decides its own path, so you cannot know what it did without watching — observability isn't a nice-to-have in Strands, it's a requirement. Built on OpenTelemetry and shaped by AWS's own production use.
A framework earns its place not in the demo but in production — under real traffic, real failures, and the need to observe, control cost, and evolve. Pydantic AI's typed, testable design carries into production well, and paired with observability and the model-agnosticism it's had all along, it makes agents you can actually operate. This closing post covers taking a Pydantic AI agent live.
A framework earns its place in production — under real traffic, failures, and the need to observe, control cost, and evolve. Pydantic AI's typed, testable design carries into production well, paired with observability and model-agnosticism.
A code agent is only as good as the model writing the code — and smolagents, true to its Hugging Face roots and minimalist ethos, lets you run almost any model behind it: open models from the Hub, hosted APIs, local models, anything reachable through its integrations. Model choice matters especially here, because the model's code-writing ability is the agent's ability.
A code agent is only as good as the model writing the code — and smolagents lets you run almost any model: open models from the Hub, hosted APIs, local models. Model choice matters especially here, because the model's code-writing ability is the agent's ability.
One model-driven agent handles a lot, but some problems want a team — a specialist per subtask, or a coordinator delegating to workers. Strands builds multi-agent systems from the same minimal parts, most elegantly by making an agent a tool another agent can call, so the model-driven approach scales up without new machinery.
One model-driven agent handles a lot, but some problems want a team. Strands builds multi-agent systems from the same minimal parts, most elegantly by making an agent a tool another agent can call — the model-driven approach scaling up.
A chain answers one call; a conversation needs to remember. LangChain handles memory by treating conversation history as data you manage and pass in — and, for anything beyond simple chat history, hands state management to LangGraph. Knowing which is which keeps your stateful applications clean instead of tangled.
A chain answers one call; a conversation needs to remember. LangChain handles memory by treating conversation history as data you manage and pass in — and, for richer state, hands state management to LangGraph.
Most agent code is tested by running it and eyeballing the output — because testing agents properly is genuinely hard. Pydantic AI's whole design has been quietly building toward making it easy: type safety, dependency injection, and test models combine so you can unit-test agent logic deterministically, offline, without ever calling a real LLM. This is arguably the framework's biggest practical advantage.
Most agent code is tested by running it and eyeballing the output, because testing agents properly is hard. Pydantic AI's design builds toward making it easy: type safety, dependency injection, and test models let you unit-test agent logic deterministically, offline, with no real LLM.
CrewAI makes it easy to build a multi-agent system and just as easy to build one that's slow, expensive, and unreliable — so production CrewAI is mostly about discipline: measure it, keep it as simple as the problem allows, and use Flows for the parts that must be dependable.
CrewAI makes it easy to build a multi-agent system and just as easy to build one that's slow, expensive, and unreliable — so production CrewAI is mostly discipline: measure it, keep it simple, and use Flows where it must be dependable.
The frontier is genuinely exciting and genuinely oversold, and telling the difference matters — so this closing post is an honest accounting of what self-evolving agents cannot yet do, what can go wrong, and what remains unsolved.
The frontier is genuinely exciting and genuinely oversold. An honest accounting of what self-evolving agents cannot yet do, what can go wrong, and what remains unsolved.
Even an agent that thinks in code needs tools — the functions its code calls to reach beyond itself. smolagents defines them the same minimal way it does everything: a decorated Python function. The twist is that in a code agent, tools are called from within code, which is what makes composing them so natural.
Even an agent that thinks in code needs tools — the functions its code calls. smolagents defines them the same minimal way (a decorated function), and the twist is that tools are called from within code, which is what makes composing them so natural.
The model drives a Strands agent, so which model you use is the single biggest determinant of how well it works — and Strands keeps that a swappable choice across providers rather than locking you to one. Model-agnosticism isn't a convenience here; in a model-driven framework it's foundational.
The model drives a Strands agent, so which model you use is the biggest determinant of how well it works — and Strands keeps that a swappable choice across providers. Model-agnosticism isn't a convenience here; it's foundational.
Chains follow a path you define; agents decide the path themselves. LangChain gives you both the tools an agent uses and — increasingly through LangGraph — the machinery to run agent loops reliably. Understanding where LangChain's tools end and LangGraph's orchestration begins is the key to building agents that work rather than agents that wander.
Chains follow a path you define; agents decide the path themselves. LangChain gives you the tools an agent uses and — increasingly through LangGraph — the machinery to run agent loops reliably. Knowing where tools end and orchestration begins is the key.
A single agent run answers one question; a conversation needs memory, and a good user experience needs the answer to appear as it's generated. Pydantic AI handles both through its message system — the record of what was said that you pass between runs — and streaming, which delivers typed output progressively. Together they turn one-shot agents into conversational, responsive ones.
A single run answers one question; a conversation needs memory, and good UX needs the answer to appear as it's generated. Pydantic AI handles both through its message system — the record you pass between runs — and streaming that delivers typed output progressively.
An agent's reasoning loop is flexible but opaque and hard to control. A workflow is the opposite: you make the orchestration explicit as steps and events, trading some autonomy for the predictability, testability, and control that complex applications need.
An agent's reasoning loop is flexible but opaque and hard to control. A workflow is the opposite: you make orchestration explicit as steps and events, trading some autonomy for the predictability, testability, and control complex applications need.
A crew is only a real team if its members remember what happened and can hand work to each other — and CrewAI's memory and delegation features are what turn a set of independent agents into something that actually collaborates.
A crew is only a real team if its members remember what happened and can hand work to each other — memory and delegation are what turn a set of independent agents into something that actually collaborates.
Every frontier method is a search, and a search is only as good as the evaluator that ranks its candidates — so at the frontier, evaluation stops being a measurement and becomes the single most dangerous component in the system.
Every frontier method is a search, and a search is only as good as the evaluator that ranks its candidates — so at the frontier, evaluation becomes the single most dangerous component in the system.
The pieces from this series — routing, query transformation, graded retrieval, multi-hop, and evaluation — assemble into one system that reasons about retrieval as carefully as it reasons about the answer, while spending only as much as each question needs.
Routing, query transformation, graded retrieval, multi-hop, and evaluation assemble into one system that reasons about retrieval as carefully as the answer — while spending only as much as each question needs.
The power of code agents comes with a sharp edge: you are executing code written by an LLM, and an LLM can be wrong, or manipulated into writing something harmful. Running that code unsandboxed is one of the most dangerous things you can do in an application, so sandboxing isn't optional for code agents — it's the price of admission.
The power of code agents comes with a sharp edge: you are executing code written by an LLM, which can be wrong or manipulated. Running it unsandboxed is one of the most dangerous things you can do — so sandboxing is the price of admission.
In a model-driven agent, tools are everything the agent can actually do — the model supplies the reasoning, the tools supply the capability. Strands makes defining them almost trivial (decorate a Python function) and plugs into MCP's large ecosystem, so equipping an agent well becomes the developer's main lever.
In a model-driven agent, tools are everything the agent can do — the model supplies the reasoning, the tools supply the capability. Strands makes defining them trivial and plugs into MCP, so equipping an agent well is the developer's main lever.
Two more levers of control: how hard the model thinks, and how you bound what it spends. Both have measured sweet spots — and both have a trap that quietly wastes money. The sharpest is a cap that most people reach for first and that saves nothing at all: max_tokens.
Two levers of control: how hard the model thinks, and how you bound what it spends. Both have measured sweet spots — and both have a trap that quietly wastes money. The sharpest is a cap most people reach for first that saves nothing: max_tokens.
Dependency injection is the least flashy Pydantic AI feature and quietly one of the most important — it's what lets your agents reach real databases, API clients, and user context without hard-wiring them, and it's the single biggest reason Pydantic AI agents are so testable. Borrowed straight from how good backend frameworks work, applied to agents.
Dependency injection is the least flashy Pydantic AI feature and quietly one of the most important — it lets agents reach real databases and clients without hard-wiring them, and it's the single biggest reason Pydantic AI agents are so testable.
The moment you expose a query engine as a tool, RAG stops being a fixed pipeline and becomes a decision: the agent decides whether to retrieve, from which source, and whether one search was enough. That is agentic RAG, and it's built into LlamaIndex.
The moment you expose a query engine as a tool, RAG stops being a fixed pipeline and becomes a decision: the agent decides whether to retrieve, from which source, and whether one search was enough. That is agentic RAG.
Crews give agents autonomy, which is powerful and unpredictable; Flows give you back deterministic control — an event-driven engine where you decide exactly what runs when, with crews slotted in only where autonomy is actually wanted.
Crews give agents autonomy, which is powerful and unpredictable; Flows give you back deterministic control — an event-driven engine where you decide exactly what runs when, with crews slotted in only where autonomy is wanted.
The most common question about the two big agent protocols is which one to use — and the answer is almost always "both," because they solve different problems: MCP connects an agent to its tools, A2A connects an agent to other agents.
The most common question about the two big agent protocols is which to use — and the answer is almost always both, because MCP connects an agent to its tools and A2A connects an agent to other agents.
The deepest form of self-evolution is recursive: not an agent that improves its answers, but an agent that improves the process that improves agents — a system reaching up a level to modify itself.
The deepest form of self-evolution is recursive: not an agent that improves its answers, but an agent that improves the process that improves agents — a system reaching up a level to modify itself.
The two systems everyone builds — retrieval-augmented generation and tool-using agents — are where DSPy's declarative approach pays off most, because they are exactly the multi-step pipelines whose prompts are hardest to tune by hand.
RAG and tool-using agents are where DSPy's declarative approach pays off most — they are exactly the multi-step pipelines whose prompts are hardest to tune by hand.
Every agentic technique in this series adds cost and complexity, so the only way to know any of it is worth it is to measure — and RAG needs measurement on two fronts at once: did it retrieve the right things, and did it answer faithfully from them?
Every agentic technique adds cost, so the only way to know it is worth it is to measure — and RAG needs measurement on two fronts: did it retrieve the right things, and did it answer faithfully from them?
Everything in this series — the budget, the system prompt, retrieval, memory, tools, and compaction — comes together as a pipeline that assembles the right window on every single turn, deliberately rather than by accident.
The budget, system prompt, retrieval, memory, tools, and compaction come together as a pipeline that assembles the right window on every turn — deliberately rather than by accident.
The two protocols people keep pitting against each other are actually two halves of the same architecture — MCP gives an agent its tools, A2A gives it collaborators, and real systems need both.
MCP gives an agent its tools, A2A gives it collaborators, and real systems need both. How the two protocols compose — tools within an agent, agents between — in one architecture.
The claim that agents should write code isn't just aesthetic — Hugging Face backs it with measured results: code agents take fewer steps, make fewer LLM calls, and score better on hard benchmarks. This post examines the evidence and the mechanism, so you understand not just that code actions win but why.
The claim that agents should write code isn't just aesthetic — Hugging Face backs it with measured results: code agents take fewer steps, make fewer LLM calls, and score better on hard benchmarks. This examines the evidence and the mechanism.
Strands's agent loop is deliberately small: a prompt goes in, the model decides, tools run if needed, results feed back, and it repeats until the model is done. What makes it distinctive isn't the loop's shape — every agent has one — but that Strands exposes it plainly and lets the model drive it, with only three ingredients you provide.
Strands's agent loop is deliberately small: a prompt goes in, the model decides, tools run if needed, results feed back, and it repeats until the model is done. Three ingredients you provide, and a loop the model drives.
An agent that can only talk is a chatbot; an agent that can act needs tools. In Pydantic AI, a tool is just a typed Python function you decorate — the framework reads its type hints to tell the model how to call it, validates the model's arguments, and runs it. Function calling stops being schema-wrangling and becomes writing ordinary typed functions.
An agent that can only talk is a chatbot; one that can act needs tools. In Pydantic AI, a tool is just a typed Python function you decorate — the framework reads its type hints to tell the model how to call it, validates arguments, and runs it.
An agent without tools can only think and write; tools are what let it act — search the web, query a database, call an API — and turning a Python function into a CrewAI tool is deliberately almost effortless.
An agent without tools can only think and write; tools are what let it act — search the web, query a database, call an API — and turning a Python function into a CrewAI tool is deliberately almost effortless.
What if the optimizer's update step were not a numeric gradient but a paragraph of natural-language reflection? That is the bet behind reflective optimizers — and one of them rivals reinforcement learning while using a fraction of the rollouts.
What if the optimizer's update step were not a numeric gradient but a paragraph of natural-language reflection? That is the bet behind reflective optimizers — one of which rivals RL with a fraction of the rollouts.
Some questions cannot be answered by any single search because the answer is assembled from facts that must be found in sequence, each retrieval informed by the last — and that is what iterative, multi-hop retrieval provides.
Some questions cannot be answered by any single search because the answer is assembled from facts found in sequence, each retrieval informed by the last — that is iterative, multi-hop retrieval.
When context threatens to overflow, you compress it; and when you have a huge window to spend, you still should not fill it — because a long context is not used as well as a short, focused one.
When context threatens to overflow you compress it; and when you have a huge window you still should not fill it — because a long context is not used as well as a short, focused one.
When agents from different organizations delegate real work to each other, trust cannot be assumed, so A2A builds authentication into the Agent Card and demands it on every request.
When agents from different organizations delegate real work, trust cannot be assumed, so A2A builds authentication into the Agent Card and demands it on every request.
An MCP server can run code and see context on the model's behalf, which makes it powerful and dangerous in equal measure — this is how to deploy one without handing attackers the keys.
An MCP server can run code and see context on the model's behalf. Authentication, prompt-injection and tool-poisoning risks, human-in-the-loop, sandboxing, and a production checklist.
The pieces from this series — memory, self-refinement, a skill library, and an evaluation gate — combine into one modest architecture that actually gets better as it runs, without the hype and without the footguns.
Memory, grounded self-refinement, a verified skill library, and an evaluation gate combine into one buildable architecture that gets better as it runs — safely.
The single idea that defines smolagents is that an agent's action is a snippet of Python, not a JSON blob. It sounds like a minor encoding detail and turns out to change what an agent can do in a single step — because code carries logic, loops, variables, and composition that structured tool calls simply can't express.
The single idea that defines smolagents is that an agent's action is a snippet of Python, not a JSON blob. It sounds like an encoding detail and turns out to change what an agent can do in one step — because code carries logic, loops, and composition JSON can't.
The model-driven approach is not just how Strands works — it's a stance on where intelligence should live in an agent. Put it in the model's reasoning, not in developer-authored control flow. This post unpacks why that stance is increasingly the right one, and where it isn't.
The model-driven approach is a stance on where intelligence should live in an agent: in the model's reasoning, not in developer-authored control flow. This post unpacks why that stance is increasingly right, and where it isn't.
This is the feature Pydantic AI is named for and built around: you declare a Pydantic model as your agent's output type, and you get back a validated instance of it — not a string to parse, not JSON to hope about, but a real typed object. It turns the single most brittle part of LLM applications into the most reliable.
This is the feature Pydantic AI is named for: you declare a Pydantic model as your agent's output type and get back a validated instance — not a string to parse. It turns the most brittle part of LLM applications into the most reliable.
Agents and tasks are the pieces; the crew is what assembles them into a working team, and its process — sequential or hierarchical — decides whether they run like an assembly line or a delegating manager.
The crew assembles agents and tasks into a working team, and its process — sequential or hierarchical — decides whether they run like an assembly line or a delegating manager.
The technique that produced superhuman game-playing — a system improving by competing against copies of itself — has an LLM analogue: models that generate their own training signal and bootstrap their way up without new human labels.
The technique that produced superhuman game-playing has an LLM analogue: models that generate their own training signal and bootstrap up without new human labels — and the reward-source problem at its center.
Naive RAG trusts whatever it retrieved, which is how it produces confident answers grounded in the wrong documents; self-correcting retrieval adds the step it was missing — checking the results before using them.
Naive RAG trusts whatever it retrieved, which is how it produces confident answers grounded in the wrong documents. Self-correcting retrieval adds the missing step: check the results before using them.
Tool definitions and structured data quietly consume a large share of the context budget, and how you select, describe, and format them shapes both what fits and how well the model uses it.
Tool definitions and structured data quietly consume a large share of the context budget, and how you select, describe, and format them shapes both what fits and how well the model uses it.
Long-running agent work needs a way to report progress without the client holding its breath, and A2A offers two: stream the updates live, or register a webhook and get called back.
Long-running agent work needs a way to report progress without the client holding its breath. A2A offers two: stream the updates live over SSE, or register a webhook and get called back.
A server is only half the story; the client is what connects to it, discovers its capabilities, and turns a model's intent into real tool calls.
Build an MCP client that launches a server, discovers its tools, and drives them from a language model — the core of what every MCP host does internally.
A system that changes itself can improve itself right off a cliff, so the evaluation and guardrails are not an afterthought to self-evolving agents — they are the thing that makes them safe to run at all.
A system that changes itself can improve right off a cliff. Measuring evolution honestly, reward hacking, drift and collapse, and the guardrails that keep it safe.
Most agent frameworks have the model call tools by emitting JSON. smolagents, Hugging Face's deliberately tiny library, makes the model write Python code instead — "agents that think in code." That one design choice, plus a ruthless commitment to minimalism, is what the whole library is about, and it turns out to matter more than it sounds.
Most agent frameworks have the model call tools by emitting JSON. smolagents, Hugging Face's deliberately tiny library, makes the model write Python code instead — 'agents that think in code.' That one choice, plus ruthless minimalism, is the whole library.
Most agent frameworks ask you to design the workflow — the steps, the branches, the orchestration. Strands Agents, AWS's open-source SDK, makes the opposite bet: give the model a goal and tools, and let it drive. That model-driven philosophy is the whole point, and understanding it is understanding why Strands feels different from everything else.
Most agent frameworks ask you to design the workflow. Strands Agents, AWS's open-source SDK, makes the opposite bet: give the model a goal and tools, and let it drive. That model-driven philosophy is the whole point.
The Agent is where everything in Pydantic AI comes together — model, instructions, tools, typed dependencies, and typed output, bundled into one reusable, testable object you define once and run many times. Understanding the Agent as a configured, type-parameterized unit is the key that makes the rest of the framework fall into place.
The Agent is where everything in Pydantic AI comes together — model, instructions, tools, typed dependencies, and typed output, bundled into one reusable, testable object you define once and run many times.
An agent is a capability; a task is the assignment — and the two fields that define a task, its description and its expected output, are where you turn "a smart agent" into "the specific result I need."
An agent is a capability; a task is the assignment — and the two fields that define a task, its description and its expected output, are where you turn 'a smart agent' into 'the specific result I need.'
Four popular agent frameworks, four genuinely different philosophies — and the right choice is decided less by features than by how much control you want, how your team thinks, and what you're actually building.
Four popular agent frameworks, four genuinely different philosophies — the right choice is decided less by features than by how much control you want, how your team thinks, and what you're building.
Borrow the oldest idea in optimization — mutate a population, select the fittest, repeat — and point it at prompts and agents, and you get a search that escapes local optima a gradient never could.
Borrow the oldest idea in optimization — mutate a population, select the fittest, repeat — point it at prompts and agents, and you get a search that escapes local optima a gradient never could.
Real systems have more than one place to look, and the answer to "not everything should be retrieved from the same index — or retrieved at all" is to route queries and to treat retrieval as a tool the agent chooses to call.
Real systems have more than one place to look. The answer is to route queries to the right source — and to treat retrieval as a tool the agent chooses to call, or skips entirely.
A conversation that never forgets eventually overflows, so managing what history an agent carries forward — and how it remembers across sessions — is one of the defining problems of context engineering.
A conversation that never forgets eventually overflows, so managing what history an agent carries forward — and how it remembers across sessions — is a defining problem of context engineering.
A2A defines what agents exchange independently of how it travels, so the same operations work over JSON-RPC, gRPC, or plain REST — and the operation set is small enough to hold in your head.
A2A defines what agents exchange independently of how it travels, so the same operations work over JSON-RPC, gRPC, or plain REST — and the operation set is small enough to hold in your head.
Everything in the series so far comes together here: a small but complete Model Context Protocol server, in Python, exposing a tool, a resource, and a prompt, runnable and testable in minutes.
Build a complete MCP server in Python with the official SDK — a notes service with a tool, a resource, and a prompt — and test it end to end with the MCP Inspector.
The most ambitious form of self-evolution stops tweaking one agent and starts searching a space of many, letting a meta-process discover agent designs no human wrote.
The most ambitious self-evolution searches a population of agent designs. Automated Design of Agentic Systems, evolutionary prompt search, debate, and self-play.
Most agent frameworks treat the LLM's output as text you hope to parse. Pydantic AI treats it as typed, validated data — bringing the discipline that made Pydantic the backbone of Python data validation to the messy world of LLM agents. If you've ever wished your agent's output was a real typed object instead of a string you cross your fingers over, this framework was built for you.
Most agent frameworks treat the LLM's output as text you hope to parse. Pydantic AI treats it as typed, validated data — bringing the discipline that made Pydantic the backbone of Python data validation to the messy world of LLM agents.
A CrewAI agent is defined less by code than by three sentences — its role, goal, and backstory — and getting those right is the highest-leverage thing you do, because they are the prompt that shapes everything the agent does.
A CrewAI agent is defined less by code than by three sentences — its role, goal, and backstory — and getting those right is the highest-leverage thing you do, because they are the prompt that shapes everything the agent does.
The most striking frontier result is a meta-agent that writes agents — defining them as code, testing them, archiving the good ones, and inventing architectures that outperform the best humans hand-built.
The most striking frontier result is a meta-agent that writes agents — defining them as code, testing them, archiving the good ones, and inventing architectures that outperform the best humans hand-built.
If a signature says what a step does, a module says how to get the model to do it — and because modules are parameterized, swapping one for another changes the reasoning strategy without touching your intent.
If a signature says what a step does, a module says how to get the model to do it — Predict, ChainOfThought, ReAct — and because modules are parameterized, swapping one changes the strategy without touching your intent.
The user's question is written to be asked, not to be searched, so the first thing an agentic RAG system should do is turn that question into queries that actually retrieve well.
The user's question is written to be asked, not searched, so the first thing an agentic RAG system should do is turn that question into queries that actually retrieve well.
Agents need to exchange more than plain strings — instructions, files, images, structured data, and finished deliverables — and A2A's content model handles all of it with three composable objects.
Agents exchange more than plain strings — instructions, files, images, structured data, and finished deliverables. A2A's content model handles all of it with three composable objects.
Tools let a model act, but resources and prompts are how a Model Context Protocol server feeds it the right context and gives users repeatable ways to invoke it.
Beyond tools, MCP servers expose resources (read-only context by URI) and prompts (reusable templates). What each is for, how they appear on the wire, and how to choose.
Asking a model to check its own work sounds like free improvement, but whether it actually helps depends entirely on where the feedback comes from — and getting this wrong is the most common way self-evolving agents fool themselves.
Self-critique is tempting but dangerous: without a real external signal, models often fail to self-correct and can get worse. Where self-critique works and where it drifts.
CrewAI takes the most intuitive metaphor for multi-agent AI — a team of specialists with roles collaborating on a job — and makes it the programming model, which is both its great strength and the thing to be disciplined about.
CrewAI takes the most intuitive metaphor for multi-agent AI — a team of specialists with roles collaborating on a job — and makes it the programming model, which is both its strength and the thing to be disciplined about.
The first wave of self-evolving agents tuned one agent's memory and prompts; the frontier stops tuning a fixed agent and starts searching the space of agent designs itself.
The first wave of self-evolving agents tuned one agent's memory and prompts; the frontier stops tuning a fixed agent and starts searching the space of agent designs itself.
Agentic RAG is what you get when retrieval stops being a fixed pipeline step and becomes a set of decisions an agent reasons through — whether to retrieve, what to search for, from where, how many times, and whether to trust the result.
Agentic RAG is what you get when retrieval stops being a fixed pipeline step and becomes a set of decisions an agent reasons through — whether, what, from where, how many times, and whether to trust results.
The single biggest cost lever in most AI systems is not clever prompting — it is not using an expensive model for work a cheap one would do just as well.
The single biggest cost lever in most AI systems is not clever prompting — it is not using an expensive model for work a cheap one would do just as well. Right-sizing and routing models to tasks.
Delegating real work between agents is rarely a quick round trip, so A2A makes the task a first-class object with an explicit lifecycle that survives long-running, interruptible, asynchronous collaboration.
Delegated work is rarely a quick round trip, so A2A makes the task a first-class object with an explicit lifecycle that survives long-running, interruptible, asynchronous collaboration.
Tools are the part of the Model Context Protocol that lets a model do things instead of just talk about them, and their design is what separates an agent that helps from one that flails.
Tools are the MCP primitive that lets a model act. How to define them, the tools/list and tools/call methods, results versus errors, and designing tools a model can actually use.
An agent whose action space is fixed can only ever recombine what it was given, but an agent that writes and banks its own skills grows more capable the longer it runs.
An agent that writes and banks its own verified skills grows more capable the longer it runs. Voyager's skill library and how to build a self-extending action space.
Beyond the interactive terminal, Claude Code can run headless in scripts and CI — which unlocks automation, and raises the stakes on permissions, review, and trust.
The capstone: running Claude Code headless in scripts and CI (PR review, batch ops, scheduled jobs) — and the guardrails it demands: least privilege, sandboxing, gating the produced artifact with human review, and the series' layered recap.
Modern production AI is rarely "a model" — it is a foundation model wrapped in retrieval, context engineering, tools, and guardrails — and the biggest architectural mistake is reaching for fine-tuning before exhausting the cheaper, more reversible options.
Production AI is rarely a model — it's a composed system, and the biggest mistake is fine-tuning before exhausting cheaper, reversible options. Phase 3: compose before you train.
The retrieve-then-generate pipeline that launched a thousand demos hits a wall on real questions, and understanding exactly where it breaks is the case for making retrieval agentic.
The retrieve-then-generate pipeline that launched a thousand demos hits a wall on real questions. Understanding exactly where naive RAG breaks is the case for making retrieval agentic.
Before one agent can delegate to another it has to find it and understand what it can do, and in A2A that self-description is a single structured document called the Agent Card.
Before one agent can delegate to another it must find it and understand it. In A2A that self-description is a single structured document — the Agent Card.
The same JSON-RPC messages can travel down a subprocess pipe or across the network, and choosing the right transport is mostly a question of where your server lives and who it serves.
The same MCP messages travel over a subprocess pipe or the network — stdio for local tools, streamable HTTP for remote services. How each works and when to choose it.
The prompt is the agent's program, so an agent that can rewrite its own prompts is an agent that can rewrite its own behavior — and there are now principled ways to make that search work.
The prompt is the agent's program. Self-Refine, DSPy, and Promptbreeder turn prompt engineering into an automated search the system runs on itself.
Slash commands and skills turn a workflow you keep re-explaining into something you invoke by name — packaging repeatable expertise so you (and your team) don't prompt it from scratch every time.
Packaging repeatable workflows: custom slash commands for frequent explicit tasks, and skills — self-contained procedures the agent loads when relevant — turning tribal knowledge into invokable, versioned team assets. Matching the mechanism to frequency.
Tools are one half of an agent's world and other agents are the other half, and A2A is the open standard that lets agents built by different teams, in different frameworks, discover and delegate to each other as peers.
A2A is the open standard that lets agents built by different teams, in different frameworks, discover and delegate to each other as peers — the agent-to-agent complement to MCP's agent-to-tools.
Underneath every tool call and resource read is a small, well-defined conversation in JSON-RPC that begins with a handshake and a negotiation over what each side can do.
Under every MCP tool call is a JSON-RPC conversation that starts with an initialize handshake and a capability negotiation. Here is the wire protocol in detail.
The cheapest way to make an agent evolve is to let it remember what happened and reflect on it, turning yesterday's failure into today's context.
The cheapest way to make an agent evolve is to let it remember and reflect. Reflexion's verbal learning and the Generative Agents memory stream — and how to build a modest version.
Hooks turn "please always run the formatter" from a hope into a guarantee — deterministic shell commands that fire on Claude Code's lifecycle events, no matter what the model decides.
Hooks are shell commands that fire deterministically on lifecycle events — auto-format on edit, block edits to protected paths, run checks, notify. When to use a hook (guarantee) vs CLAUDE.md (influence) vs permissions (gate), and keeping them safe.
A model is only as useful as the context and tools it can reach, and MCP is the open standard that lets any AI app plug into any tool through one interface instead of a hundred bespoke integrations.
MCP turns the M×N mess of wiring every AI app to every tool into M+N: wrap each system as a server once, make each app a client once, and any app can use any system.
Most agents are frozen the moment they ship, repeating the same mistakes forever, and self-evolving agents are the attempt to break that ceiling by letting the system improve itself as it runs.
Most agents are frozen at deployment and repeat their mistakes forever. Self-evolving agents route their own experience back into their own behavior — here are the axes of change and the loop underneath them.
Subagents let Claude Code delegate a focused task to a separate agent with its own context — keeping the main conversation clean and letting independent work run in parallel.
Subagents delegate a focused task to a separate agent with its own context — for context isolation and parallelism. When to delegate (independent, context-heavy, specialized), defined agent types, and keeping the main session as accountable orchestrator.
Why agents and retrieval turn a prompt injection into real-world action, how to red-team the highest-risk AI surface with benign canaries, and the least-privilege controls that shrink an attacker's blast radius.
The highest-risk modern surface: indirect injection via RAG/tools, tool abuse and excessive-agency exploitation, memory poisoning, multi-step attacks, and data-exfiltration channels — with a canary methodology and least privilege as the primary control.
The Model Context Protocol lets Claude Code reach beyond your codebase — into your databases, issue trackers, docs, and services — through a standard, pluggable interface.
The Model Context Protocol lets Claude Code reach beyond the codebase into databases, trackers, docs, and services through a standard interface — what MCP is, how to connect servers, and treating each server as a least-privilege trust decision.
Two tightly-linked OWASP LLM risks that turn a clever prompt injection into real-world damage — and the Python patterns that shrink the blast radius: treat model output as untrusted input, and give agents the least agency they can get away with.
Two OWASP risks that turn an injection into damage: insecure output handling (model output is untrusted input — never eval/shell/SQL it unescaped) and excessive agency (least-privilege tools, allow-lists, human approval for irreversible actions, audit logs).
How to invoke a managed Agent for Amazon Bedrock from Go — where the server owns the reason-act loop, and your job is to call InvokeAgent, range the event stream, accumulate the answer chunks, and read the trace for observability.
Agents for Amazon Bedrock from Go: the managed reason-act loop that runs server-side (vs the DIY Converse loop), invoking an agent alias with InvokeAgent, streaming the response and trace events, and keeping multi-turn state with a SessionId.
The capstone of the Evaluating Agents in Go series: how to score a conversation instead of a single reply, how to attribute errors across a coordinator and its sub-agents, and how to build rubric, safety, and hallucination judges in Go when the framework hands you no eval package.
The capstone of the Evaluating Agents in Go series: how to score a conversation instead of a single reply, how to attribute errors across a coordinator and its sub-agents, and how to build rubric, safety,...
The single highest-leverage setup step for Claude Code is a good CLAUDE.md — the file where you write down, once, the context and conventions you'd otherwise repeat every session.
The highest-leverage setup step: a good CLAUDE.md that gives durable project context (build/test commands, conventions, gotchas, what not to do), how it layers, and the settings/permissions that tune autonomy safely and shareably.
How to wire agent evaluations into continuous integration in Go — running a slow, model-calling eval harness under `go test`, setting per-metric thresholds that fail the build on a regression, and living honestly with the fact that these gates are softer than unit tests.
How to wire agent evaluations into continuous integration in Go — running a slow, model-calling eval harness under `go test`, setting per-metric thresholds that fail the build on a regression, and living...
Getting great results from Claude Code is less about clever prompts and more about a disciplined loop: give context, specify clearly, let it work, review, and steer.
The disciplined loop that gets great results: explore → plan → execute → review, specifying like you'd brief a colleague, steering actively, managing context, and right-sizing delegation to the checks (tests) the agent can loop against.
Give the hand-rolled Go agent from post 11 a memory it can carry between turns and a plan it can follow across many steps — a compacting conversation buffer, retrieval over the post-8 vector store, and a plan-then-execute-then-reflect loop, all built from scratch.
Give the agent memory and planning in Go: a compacting short-term conversation buffer, long-term memory as timestamped embeddings in the vector store, and planning — plan-then-execute, reflection and re-planning when observations contradict the plan, and task decomposition.
Where good eval cases actually come from — seeding by hand, harvesting from production telemetry, and curating a golden dataset in Go that doesn't rot the moment your prompt changes.
Where good eval cases actually come from — seeding by hand, harvesting from production telemetry, and curating a golden dataset in Go that doesn't rot the moment your prompt changes.
An agentic coding tool that lives in your terminal, reads and edits your real codebase, runs commands, and works through multi-step tasks — not an autocomplete, but a collaborator you delegate to.
The opener to a Claude Code series: what an agentic, terminal-native coding tool actually is — it takes a goal and executes multi-step work on your real codebase, with permissions keeping you in control — and the mental model that makes it click.
Building a real agent loop in Go by hand — an LLM in a loop that picks tools, runs them, reads the results, and repeats until the task is done — so you can see there is no magic behind LangGraph, MAF, or ADK.
Build a minimal but real agent loop in Go by hand: an Agent with a tool registry and a reason-act Run loop, an iteration budget, validation against hallucinated tools, feeding tool errors back as observations, and parallel tool calls — the loop frameworks formalize, demystified.
How to score an agent's final answer against a reference — from exact string match, through ROUGE-1 unigram overlap, to an LLM judge — with original Go you can drop into a test suite. Part 5 of Evaluating Agents in Go.
How to score an agent's final answer against a reference — from exact string match, through ROUGE-1 unigram overlap, to an LLM judge — with original Go you can drop into a test suite. Part 5 of Evaluating...
From the smallest possible agent to a browsable service — the core loop, the four ways to run it, how memory and tools attach, and two ways to put a server in front of it.
From the smallest possible agent to a browsable service — the core loop, the four ways to run it, how memory and tools attach, and two ways to put a server in front of it.
How to wrap an agent run to log, guard, retry, redact, and secure it — using middleware seams that sit entirely outside the agent's own logic.
How to wrap an agent run to log, guard, retry, redact, and secure it — using middleware seams that sit entirely outside the agent's own logic.
A complete guide to what an agent remembers — from a single conversation held in a session, to durable facts injected on every run, to the per-request values that reach a tool without ever touching the model's schema.
A complete guide to what an agent remembers — from a single conversation held in a session, to durable facts injected on every run, to the per-request values that reach a tool without ever...
From a single decorated async function to an explicit graph of executors and agent nodes — the core workflow model in Microsoft Agent Framework, and the two APIs that express it.
From a single decorated async function to an explicit graph of executors and agent nodes — the core workflow model in Microsoft Agent Framework, and the two APIs that express it.
Once you can wire a chain of executors, the graph earns its keep: concurrency, durable state, composition, and control — the patterns that turn a toy pipeline into a system that survives a crash.
Once you can wire a chain of executors, the graph earns its keep: concurrency, durable state, composition, and control — the patterns that turn a toy pipeline into a system that survives a crash.
How to pause a workflow for a human decision, package a whole workflow as an agent, and see exactly what a run did — through OpenTelemetry spans and a rendered graph — in Microsoft Agent Framework.
How to pause a workflow for a human decision, package a whole workflow as an agent, and see exactly what a run did — through OpenTelemetry spans and a rendered graph — in Microsoft Agent Framework.
A complete guide to coordinating many agents — from a fixed pipeline, to parallel fan-out, to a self-routing mesh, to a planner that decides who acts next, to publishing an agent as a network service other agents can call.
A complete guide to coordinating many agents — from a fixed pipeline, to parallel fan-out, to a self-routing mesh, to a planner that decides who acts next, to publishing an agent as a network...
A complete guide to where a Microsoft Agent Framework agent gets its model — from direct Foundry inference to OpenAI-compatible endpoints, service-managed agents, hand-rolled providers, and container hosting.
A complete guide to where a Microsoft Agent Framework agent gets its model — from direct Foundry inference to OpenAI-compatible endpoints, service-managed agents, hand-rolled providers, and...
Once an agent can call tools, the next questions are what it can read, what it returns, how long it can run, where its facts come from, how it's defined, and whether it actually works — this guide answers all seven.
Once an agent can call tools, the next questions are what it can read, what it returns, how long it can run, where its facts come from, how it's defined, and whether it actually works — this guide...
A guide to the two hosting concerns every agent eventually hits — seeing it run in a local chat window with a live call inspector, and keeping its state alive across crashes on Durable Task infrastructure.
A guide to the two hosting concerns every agent eventually hits — seeing it run in a local chat window with a live call inspector, and keeping its state alive across crashes on Durable Task...
How to score what an agent did, not just what it said — building trajectory metrics in Go from an exact-match baseline up to arg-aware, order-tolerant scoring, with a readable diff of expected vs. actual.
How to score what an agent *did*, not just what it *said* — building trajectory metrics in Go from an exact-match baseline up to arg-aware, order-tolerant scoring, with a human-readable diff of expected vs....
The core of the series: a minimal, original evaluation harness in Go. Run an agent under test through adk-go's runner, capture the tool-call trajectory and the final response behind an adapter you own, and score them with `go test`.
The core of the series: a minimal, original evaluation harness in Go. Run an agent under test through adk-go's runner, capture the tool-call trajectory and the final response behind an adapter you own, and...
Before you can evaluate an agent in Go, you need a mental model of what "evaluating an agent" even means. This post unpacks the conceptual core of Google's Agent Development Kit eval framework — cases, trajectories, metrics, thresholds — the parts that are language-agnostic, so the rest of this series can implement them as plain Go types and functions.
Before you can evaluate an agent in Go, you need a mental model of what "evaluating an agent" even means. This post unpacks the conceptual core of Google's Agent Development Kit eval framework — cases,...
A complete guide to giving a Microsoft Agent Framework agent the ability to act — from a plain Python function the model can call, to provider-hosted sandboxes, remote MCP servers, and higher-level packaging patterns like Skills and CodeAct.
A complete guide to giving a Microsoft Agent Framework agent the ability to act: function tools, provider-hosted tools (code interpreter, file search, web search), local and hosted MCP, plus Skills and CodeAct — with the code and gotchas for each.
The opener to a series on evaluating agents in Go: why an agent isn't a function you can unit-test, why "it worked in the demo" doesn't survive contact with production, and the two things actually worth measuring — the steps it took and the answer it gave.
The opener to a series on evaluating agents in Go: why an agent isn't a function you can unit-test, why "it worked in the demo" doesn't survive contact with production, and the two things actually worth...
Predicting who will leave is the easy half. The hard half is acting on it: treating the persuadable, respecting a budget, and proving the intervention actually kept anyone.
Predicting attrition and acting on it: churn features and labels, uplift vs propensity (treat the persuadable), and an agentic retention workflow that recommends and executes interventions with guardrails and holdout mea…
When an AI agent spends your money, "the user said so" is not evidence. A signed mandate chain is.
A deep dive on the mandate chain as evidence: verifiable credentials (VCs), signing, the non-repudiable Intent→Cart→Payment chain, revocation and expiry, and why this replaces 'trust me, the user said so' with cryptograp…
How three cryptographically signed mandates turn an agent's purchase into a non-repudiable audit trail.
Google's open Agent Payments Protocol (AP2).
A hybrid allocator where a quantitative core owns the money, a language model only whispers tilts, and hard constraints plus a human bound everything before a single order goes out.
A hybrid allocator: quantitative signals set the baseline (mean-variance / risk parity) while an LLM proposes tilts from qualitative context, constrained by risk limits and human review.
How AI agents that discover, choose, and pay on your behalf break the assumptions baked into every checkout, and the protocol stack rushing in to fix them.
What agentic commerce is: AI agents that discover, select, and pay on a user's behalf.
Turning a firehose of unstructured headlines into a disciplined, point-in-time trading signal.
Turning unstructured news into a tradable signal with LLMs: entity/event extraction, sentiment scoring, aggregation to a per-asset signal, latency and point-in-time constraints, and combining qualitative signals with a q…
Lesson 7 of Harness Engineering in Go — a sensitive action pauses for a human decision, and the whole suspension is nothing more than a Lesson 2 checkpoint marked awaiting_approval.
Series finale, Lesson 7: a sensitive action pauses for human approval, where suspension is just a Lesson 2 checkpoint marked awaiting_approval, the deadline is checked first so a late yes is void, and the action must be idempotent.
Lesson 6 of Harness Engineering in Go — a supervisor splits a task, fans out to concurrent workers behind a semaphore, and fans the results back in decomposition order, with each worker's failure (or panic) isolated to one result.
Lesson 6: bounded fan-out behind a semaphore, ordered fan-in via a pre-sized results slice, and per-worker fault isolation so one sub-agent panicking becomes one failed result instead of crashing the whole run.
Large language models earn their place in regulated finance as fast, well-supervised assistants — not as autonomous agents with a hand on the money.
Where LLMs fit in regulated finance: document analysis/extraction, retrieval-grounded Q&A, and agentic decision support — plus the guardrails (grounding, human-in-the-loop, output validation, audit trails) that keep them…
Lesson 5 of Harness Engineering in Go — a triage step that first-matches a keyword and hands the request to a specialist, and the exact place a substring table stops being able to think.
Lesson 5: a triage router first-matches a keyword to hand intent to a specialist, and the exact point a substring table stops being able to think.
Lesson 4 of Harness Engineering in Go — three collaborating stores (a thread, a knowledge index, and a summarizer) behind interfaces, and an honest accounting of where each local stand-in leaks.
Lesson 4: memory is three stores, not one — an append-only thread, a keyword knowledge index, and a lossy first-and-last summarizer — and an honest account of where each local stand-in leaks against Azure.
The reference capstone for the 26-part series — every canonical ADK term, defined concisely.
The capstone of the series: every core ADK concept defined in one place — agents and orchestration, tools, sessions/state/memory, context and callbacks, runtime and streaming, models, grounding, evaluation, protocols, and deployment.
Lesson 3 of Harness Engineering in Go — how a context deadline and `exec.CommandContext` reap a runaway snippet, why the two-shaped `Result` distinguishes a timeout from a failure, and the leak that makes a local subprocess a teaching tool, not a security boundary.
Lesson 3: run agent-written code behind a hard timeout with exec.CommandContext, distinguish OK from TimedOut, and face the leak — a subprocess is not a security boundary.
How ADK's config loader turns a declarative YAML file into a fully-built agent — and why treating an agent as data changes who gets to edit it.
Defining an agent declaratively in YAML and loading it via from_config — the loader reads, resolves, and validates the config into a built agent, so config-as-data works without writing code.
Lesson 2 of Harness Engineering in Go — a workflow that saves its progress after each step and picks up exactly where it died, proven by a test that kills a real subprocess mid-run.
Lesson 2: a workflow that checkpoints after every step and resumes from the last one after a crash, why at-least-once execution forces idempotent steps, and the atomic-rename store that survives a killed process.
How caching a large, stable prompt prefix cuts latency and cost — and the ADK config that decides when it pays off.
Context caching cuts latency and cost by caching large, stable context — system prompt, reference docs, tool definitions — so repeated calls don't re-send and re-process the same tokens.
The reference capstone — each term in the series, defined in plain English and grouped by what it does.
The capstone of the series: every LangGraph concept defined in one place — the graph model, state and reducers, persistence, human-in-the-loop, agents and tools, parallelism, streaming, and the surrounding ecosystem.
Lesson 1 of Harness Engineering in Go — why the input guardrail is a hard block, not a warning, and how a plain `net/http` handler wraps the model call so it tests without a running server.
Lesson 1: why the input guardrail is a hard block rather than flag-and-pass, why it counts runes instead of bytes, and how a plain net/http handler wraps the (stubbed) model call so it tests with httptest.
Post 23 of 26 in "Google ADK, Concept by Concept" — how a planner turns one-shot answers into inspectable plan-then-act reasoning.
Structuring an agent's reasoning: planners that make the model plan-then-act (ReAct-style), the built-in thinking feature, and how a planner improves multi-step tool use over naive prompting.
The higher-level building blocks LangGraph stacks on top of the graph engine — pausing for a human, running an agent loop, calling tools, and fanning out dynamically.
The building blocks on top of the core graph: interrupt() to pause for human input, create_react_agent and ToolNode for tool-using agents, and the Send API for dynamic parallel fan-out with a reducer fan-in.
The final lesson: a recipe agent whose JSON replies are turned into trackable state snapshots by a middleware, so the client can render the recipe as it evolves.
The server side of AG-UI state management: middleware emits a DataContent state snapshot from the model's JSON so the client can adopt shared state across turns.
Seven patterns that turn a bare model call into production agent infrastructure — each written first as offline Go behind an interface, so the leap to Azure is a swap, not a rewrite.
Seven patterns that turn a bare model call into production agent infrastructure, each written first as offline Go behind an interface (the seam) so the leap to Azure is a swap, not a rewrite.
How ADK closes the write-code, run-it, read-the-output loop — and why "unsafe" is a warning, not a typo.
Letting an agent write and run code: built-in and container-based code executors, safe sandboxed execution, how results flow back into the conversation, and the security tradeoffs.
How a checkpointer turns a graph run into something you can stop, reload, and replay from any point in its history.
A checkpointer saves state at every superstep boundary, so a run can pause, resume on a thread_id, and even fork from an earlier checkpoint (time-travel). This is the foundation human-in-the-loop is built on.
The server hosts an agent with one approval-gated tool — the model may propose calling it, but the framework refuses to run it until a human on the other end says yes.
The server side of AG-UI human-in-the-loop: gate a tool with tool.ApprovalRequiredFunc so the server suspends the run and resumes on the client's decision.
How ADK skills bundle instructions, tools, and resources into folders an agent can browse and load on demand.
Skills package reusable capabilities — instructions, tools, resources, including file-based skills — so they can be discovered and attached to agents, promoting reuse across projects.
Watching a LangGraph run happen — the three things `.stream()` can show you, and why they fall out of the superstep model for free.
stream() exposes a run in three modes: values (full state after each node), updates (what each node changed), and debug (the raw event stream). Streaming falls out naturally from the superstep model.
The mirror image of backend tools: the server hosts the agent but the tools live on the client, so the handler must forward tool calls instead of running them.
The server side of AG-UI frontend tools: set DisableFuncAutoCall so the server forwards tool calls to the client to execute and awaits the result.
Wrapping Go agents in A2A, MCP, and AG-UI transports, then a full client/server app that ties the whole series together.
Wrap Go agents in A2A, MCP, and AG-UI transports, then run the end-to-end client/server capstone where a host agent uses remote specialists as tools.
cross-cutting concerns registered once on the Runner instead of copied onto every agent
Plugins are cross-cutting hooks that apply globally across every agent, tool, and runner — logging, policy, metrics, caching — as opposed to per-agent callbacks. When a plugin beats a callback.
How a single `Command` object folds a state update and a routing decision together — and the tiny lowering that makes `goto` just another guarded edge.
Command lets a node return a state update and a goto in one object, moving the routing decision inside the node. It is the cleanest way to express supervisor handoffs and dynamic control flow.
Same AG-UI transport as the getting-started server, but now the hosted agent carries a tool the model can call server-side while it answers.
The server side of AG-UI backend tools: attach server-owned function tools to the Foundry agent so the tool round-trip stays entirely server-side.
Durable workflows in Go: checkpoint and rehydrate, pause on a RequestPort for a human, nest sub-workflows, and coordinate through scoped shared state.
Durable Microsoft Agent Framework workflows in Go: checkpoint and rehydrate a fresh graph, pause on a RequestPort for a human, nest sub-workflows, and coordinate via scoped shared state.
How ADK's model abstraction lets you swap Gemini for Claude, GPT, or Ollama without touching a line of agent code
ADK is model-agnostic: use Gemini natively or plug in Claude, GPT, or Ollama via LiteLLM and a model registry, swapping the model without changing agent code.
The single most important pattern in LangGraph — a branch plus a back-edge, and the `recursion_limit` that keeps it from running forever.
Branching plus a back-edge is a cycle, and that cycle IS the agent loop: model proposes tool calls, tools run, control returns to the model, repeat until done. Plus recursion_limit, the guardrail that stops a runaway loop.
The client half streams events over SSE; this is the process on the other end of the wire — a Foundry agent wrapped in an HTTP handler that speaks AG-UI.
The AG-UI server half: wrap a Foundry agent in aguiprovider.NewJSONHTTPHandler and serve it over HTTP/SSE for any AG-UI client to drive.
The prebuilt orchestration builders in agent-framework-go — Sequential, Concurrent, Group Chat — plus wrapping a whole workflow as one agent.
The Sequential, Concurrent, and Group Chat orchestration builders in agent-framework-go, plus wrapping a whole workflow as one nestable agent.
Post 18 of 26 in "Google ADK, Concept by Concept" — retrieval tools, grounding metadata, rendering citations, and the retrieve→augment→generate loop.
Grounding answers in real data: retrieval tools, grounding metadata returned with responses, rendering citations from that metadata, and the retrieve-augment-generate RAG pattern in ADK.
How one router function plus a `path_map` dict lowers to exactly one edge firing per step.
A conditional edge is a router function plus a path map: the router reads state and returns a key, the path map turns that key into the next node. This is how branching (and, next post, loops) are expressed.
The final lesson ties the whole Go tutorial into one small product: an assistant that answers questions about your docs — grounded, cited, and refusing to guess.
The capstone: a grounded DocQA agent that answers only from embedded docs via a search_docs tool, cites sources, and refuses to guess — with an optional reviewer.
Agents as graph executors in Go: switch routing, fan-out/fan-in barriers, and mixing typed function nodes with agent nodes.
Agents as Go workflow executors: switch routing, fan-out and fan-in barriers, and mixing typed function nodes with agent nodes in one graph.
Two open protocols that let an agent reach outside its own process — one to borrow tools, one to call other agents as peers.
Two interoperability protocols: MCP lets an agent consume tools from external servers, and A2A — HTTP for agents — lets one agent discover and call another remote agent as a peer over HTTP.
How the four smallest pieces of the LangGraph API turn a bag of nodes into a program you can run.
Edges, START, END, compile() and invoke() are the four smallest pieces that turn a bag of nodes into a runnable program. Here is the full lifecycle of a tiny two-node graph.
This lesson hosts one specialized Foundry agent over the A2A protocol, publishing an agent card the client can discover.
Host one Foundry agent over A2A: newMux pins the card interface URL, wraps the agent in an a2aprovider executor, and serves the card plus JSON-RPC routes.
The graph model underneath every multi-agent app: executors as nodes, edges as data flow, and typed events streaming out of `WatchStream` as it runs.
The Microsoft Agent Framework workflow model in Go: executors bound to IDs, AddEdge wiring, WithOutputFrom, and typed WatchStream events - plus an upstream route-builder fix.
Stack the guardrails — callbacks, model filters, restricted tools, and clean-room sandboxing — so that if one layer misses, the next one catches
Layered defense-in-depth for agents: input/output guardrails via callbacks, Gemini safety settings, restricting tools, and sandboxing untrusted actions.
A LangGraph node is just a function — it reads the whole state and returns only the channels it changed.
A node is just a function: it receives the whole current state and returns only the channels it changed. Understand the partial-update contract and the immutable-snapshot guarantee that makes supersteps safe.
This lesson builds a Foundry host agent that discovers remote A2A agents by their cards and calls each one as a tool.
A Foundry host agent resolves remote A2A agent cards and turns each remote agent into a callable tool with agenttool.New over the a2aprovider.
Wrap every run in an OpenTelemetry span, gate risky tool actions behind a permission handler, and swap model providers behind one agent.Agent.
Wrap every Microsoft Agent Framework run in an OpenTelemetry span, gate risky tool actions behind a permission handler, and swap Anthropic, OpenAI, Gemini, Copilot, and Azure behind one agent.
How OpenTelemetry traces, structured logs, and token metrics turn an agent's event stream into something you can debug in production.
Seeing inside a running agent: OpenTelemetry tracing with spans for agent, model, and tool steps, structured logging, and exporting traces to debug latency and tool-call trajectories.
The one idea that makes everything else in LangGraph click: nodes don't pass messages, they update a shared state — and reducers decide how.
State is a typed dict of channels; each channel has an optional reducer. No reducer overwrites; a reducer (like add_messages or operator.add) combines. This is the single idea the rest of LangGraph is built on.
How a whole workflow binds as a single executor inside a larger workflow, so pipelines compose two levels deep.
inproc.BindSubworkflowAsExecutor binds a whole workflow as one node; an order pipeline nests Payment and FraudCheck two levels deep, and inner events still bubble up.
A guardrail that blocks a run before the model, chained ahead of a logger — and the upstream nil-update panic I fixed along the way.
A guardrail middleware that blocks an Microsoft Agent Framework Go run before the model, chained ahead of a logger — plus the tool-approval nil-update panic I fixed upstream in PR #472.
How `adk deploy` builds, pushes, and ships an agent in a single step — and the ack-after-invocation rule that keeps event-driven agents reliable.
Deploying an agent: adk deploy with its cloud_run and agent_engine subcommands, containerizing the app, and reliability rules like ack-after-invocation so failures are redelivered, not dropped.
The foundational mental model — why "the graph" is a Pregel program, and how shared state differs from message passing.
LangGraph is shared-state, not message-passing, and both models descend from Google's Pregel/BSP: work advances in supersteps that end at a synchronization barrier. Get this mental model first and the whole API stops being magic.
How one executor stores a value in scoped shared state and later executors read it back — instead of copying a whole payload down every edge.
One executor stores a document with QueueStateUpdate; fan-out counters read it back with ReadState, and an AddFanInBarrierEdge aggregates once both deliver. Offline.
Decoding typed structs from a run, draining a streamed response, and sending an image with `RunMessage`.
Decode typed structs from a run, drain a streamed response by ranging it, and send an image with RunMessage and DataContent.
How ADK turns "did the agent behave correctly?" into a number you can gate a merge on.
Measuring agent quality: eval sets, scoring both the trajectory (right tools, right order) and the final response, criteria configs, and the adk eval CLI — a Python-first workflow today.
How WithTelemetry instruments a whole workflow with OpenTelemetry spans, then agentworkflow.NewAgent wraps the graph so it behaves like one agent.
WithTelemetry instruments a French-to-English workflow with OpenTelemetry spans, then agentworkflow.NewAgent wraps the graph so RunText drives the whole pipeline.
A Session threads history into each run; a ContextProvider carries memory across sessions — and because a Session is JSON, both survive a process restart.
A Session threads history into each run and a ContextProvider carries memory across sessions. Because a Session is JSON, both survive a process restart.
token streaming, the accumulate-and-reconcile consumer pattern, and full-duplex live streaming for voice
Consuming output as it is produced: partial events and token streaming, the accumulate-and-reconcile consumer pattern, and bidi/live streaming for voice and interactive UIs.
How a workflow graph forms a cycle: two executors feed each other until one yields an output — the workflow analogue of a while-loop.
A workflow graph is not a DAG: two edges form a GuessNumber to Judge cycle that runs a binary search and exits only when Judge yields an output. The while-loop analogue.
Wrap a typed Go function as a tool, let the model call it, and compose whole agents as tools.
Wrap a typed Go function as a tool with functool.MustNew, let the model call it, and compose whole agents as tools with agenttool.New.
How an agent actually runs — a Runner drives an invocation and hands you back a stream of events, not a single answer.
How ADK runs an agent: the Runner drives an invocation that yields a stream of Event objects — content, tool calls, state deltas, control signals. The event loop explains streaming, callbacks, and state.
How a RequestPort pauses a workflow, emits a request to a human, and feeds their answer back into the graph.
A RequestPort emits a RequestInfoEvent and suspends the workflow; the driver answers with SendResponse. A guess-the-number cycle shows the pause/resume mechanism.
The minimal loop in Go: a Foundry provider, an Agent with instructions, run collected and streamed — and what RunText hands back.
The minimal Microsoft Agent Framework loop in Go: a foundryprovider agent, DefaultAzureCredential, and one RunText you either Collect or range over as a Go 1.23 iterator.
before/after the agent, model, and tool steps — and the single short-circuit rule that turns them into guardrails
Callbacks are lifecycle hooks around the agent, model, and tool steps — before/after each — used for guardrails (short-circuit by returning a response), logging, and mutating requests and responses.
How an edge assigner delivers one message to a chosen subset of targets — a multi-way switch that may fall through to more than one case.
WithEdgeAssigner yields target indexes via an iter.Seq[int], so a single message reaches several branches at once — a long email goes to both assistant and summary, offline.
Why I learned the whole framework in Go by writing one runnable lesson per concept, against Azure AI Foundry, instead of reading the docs top to bottom.
I learned the whole Microsoft Agent Framework in Go by building one runnable lesson per concept against Azure AI Foundry. Here is the 12-track map.
ReadonlyContext, CallbackContext, ToolContext, InvocationContext — and why the read-only vs mutable distinction is a feature, not a limitation.
The context objects ADK passes into tools and callbacks — InvocationContext, ToolContext, CallbackContext, ReadonlyContext — what each exposes and why the read-only vs mutable split matters.
How a switch builder fans one edge into three mutually-exclusive branches — the workflow analogue of switch/case/default.
AddSwitch/AddCase/WithDefault fans one edge into three mutually-exclusive branches with a guaranteed fallback — the workflow analogue of switch/case/default, fully offline.
Turning agents into a service you can run and expose, then a full DocQA app that ties the whole series together.
Host Microsoft Agent Framework agents with DevUI, A2A, MCP, and AG-UI, then build DocQA — a grounded, cited multi-agent app that ties the whole Python series together.
Session state is for small text and JSON. When your agent produces a PNG, a PDF, or a WAV, it belongs in the artifact store — binary-native, versioned, and out of the session record.
Artifacts are binary/file data agents produce or consume: ArtifactService saves and versions named artifacts, loaded and saved via context, keeping large blobs out of session state.
How a graph workflow forks: a predicate on each edge decides whether a message may pass, turning the graph into an if/else expressed as data flow.
The first 03-workflows lesson: AddDirectEdge attaches a func(any) bool to each edge so a spam-detection graph forks into send vs. handle-spam branches, offline.
Durable workflows in Python: checkpoint and resume, pause for a human with request_info, and package a workflow as an agent.
Durable Microsoft Agent Framework workflows in Python: checkpoint and resume every superstep, suspend on request_info for a human decision, and package a workflow as an agent.
State remembers things inside one chat; Memory is the searchable archive that lets an agent recall what you told it weeks ago.
Memory is long-term recall across sessions, distinct from per-session state: MemoryService stores and retrieves prior context, surfaced via a recall tool so an agent remembers a user over time.
How to express the classic MapReduce word-count as a five-stage workflow graph — fan-out to mappers, barrier to a shuffler, fan-out to reducers, barrier to completion.
MapReduce word-count as a five-stage workflow: fan-out to mappers, barrier to a shuffler, fan-out to reducers, barrier to completion, coordinated via shared state.
Five prebuilt multi-agent shapes — Sequential, Concurrent, Group Chat, Handoff, Magentic — and when each beats hand-wiring a graph.
Sequential, Concurrent, Group Chat, Handoff, Magentic — the five prebuilt Microsoft Agent Framework orchestrations in Python and when each beats hand-wiring a graph.
A clear-eyed look at trust models, who signs what, rails, credential handling, and settlement — and why these four overlap more than they compete.
A clear-eyed comparison across trust model, who signs what, payment rails supported, credential handling, settlement, and best-fit use cases.
A `Session` is the conversation; `state` is the key-value bag agents and tools read and write — and the prefix on a key decides how long it lives.
A Session holds a conversation; state is a scoped key-value store (session/user/app/temp) read and written by tools, injected into instructions via {state} templating, and persisted by SessionService.
How to broadcast one input to several executors in parallel and join their answers with a barrier — the core workflow graph primitives, with no LLM in the way.
A start executor broadcasts a question to two experts via a fan-out edge; a fan-in barrier edge joins both answers before the aggregator yields output.
Agents as graph nodes: switch-case routing, fan-out/fan-in, and mixing plain functions with agent steps in one workflow.
Agents are just workflow executors: switch-case routing, fan-out/fan-in concurrency, and mixing plain function nodes with agent nodes in one graph.
Four protocols, four jobs: how tools, agent-to-agent messaging, and payment rails compose into one buying flow.
How the layers compose: MCP gives an agent tools and context; A2A lets agents talk to each other; AP2/ACP/x402 are the payment rails those agents call when money must move.
How a plain function becomes a callable tool, how ToolContext reaches session state, and how long-running tools pause a run for a human.
Tools give agents capabilities: a plain function becomes a tool with its signature as the schema, plus ToolContext, built-in tools, and long-running/human-in-the-loop tools across Python and Go.
How to pause a workflow to ask a human, checkpoint every super-step, then rewind the whole graph to a saved checkpoint and replay.
A RequestPort pauses to ask a human for a guess while every super-step is checkpointed, then RestoreCheckpoint rewinds the whole graph including tries state.
The graph model underneath every multi-agent app: executors as nodes, edges as data flow, and typed events streaming out as it runs.
The Microsoft Agent Framework workflow model in Python: executors as nodes, edges as data flow, switch-case routing, and typed streaming events - learned model-free.
The surface a store must expose when the buyer is an AI agent, not a browser — and why it is the fintech reliability playbook wearing a new hat.
What a store must expose to sell to agents: a machine-readable product feed/catalog, agentic checkout endpoints, acceptance of delegated payment tokens, idempotency keys for retried agent calls, webhooks for async status…
How one agent routes work to specialists — and why the description field is the most important string you write.
Agent hierarchies and LLM-driven delegation: sub_agents, how the description field drives auto-transfer, and coordinator/dispatcher patterns — contrasted with deterministic workflow agents.
How to snapshot a workflow after every super-step, then rewind the same live run to an earlier checkpoint and replay from it.
Same guess-the-number graph, but RestoreCheckpoint rewinds the live run to the 6th snapshot and replays forward — no fresh workflow instance needed.
Turn agent runs into OpenTelemetry spans, block prompt injection with information-flow control, and swap model providers behind one Agent API.
Turn Microsoft Agent Framework agent runs into OpenTelemetry spans, block prompt injection with information-flow control, and swap model providers behind one Agent API.
When software holds the card and clicks "buy," the old questions — was this the cardholder, did they mean to, who pays if not — all get harder to answer.
The new fraud surface: prompt injection turning a shopping agent into an attacker's buyer, hijacked delegated credentials (Visa saw ~450% more dark-web 'AI Agent' chatter in H1 2026), and disputes when an agent acted on…
When you want fixed control flow, don't ask the model — wire it yourself.
Sequential, Parallel, and Loop agents compose sub-agents in fixed patterns — deterministic orchestration where you, not the model, decide control flow, with state flowing between steps.
How to snapshot a running workflow at every super-step, then throw the instance away and rebuild a fresh workflow that resumes from a saved checkpoint.
A cyclic guess-the-number workflow snapshots state each super-step, then a brand-new workflow instance is rehydrated from a checkpoint via ResumeStreaming.
Wrapping an agent run with async seams that log, time, guard, and short-circuit — without touching the agent's logic.
Wrapping an Microsoft Agent Framework agent run in Python with async middleware seams — timing, logging, and a guardrail that short-circuits a tool call before it runs.
How an AI agent turns a shopper's intent into a settled purchase, and where ACP and AP2 plug into the same eight-stage skeleton.
A complete walkthrough: product discovery via an AI surface → cart assembly → user approval/mandate → delegated payment token → merchant checkout → authorization → fulfillment → receipts/webhooks.
description, instruction, generation params, and structured output — the dials on almost every agent you'll build
The four knobs on almost every ADK agent: description (for delegation), instruction with {state} templating, generation params, and structured output — Python Pydantic model vs Go genai.Schema.
How to collapse a whole multi-agent workflow into a single agent so callers use it exactly like any leaf agent.
A concurrent French+English workflow is hosted as one agent via agentworkflow.NewAgent, with IncludeOutputsInResponse surfacing the merged output.
Typed results from `response_format`, consuming a stream event by event, and sending an image alongside text.
Three dials on one run() call: typed results via response_format, consuming a stream event by event, and sending an image alongside text.
When software spends money on your behalf, the merchant has to answer two questions before the charge clears: which agent is this, and what did the human actually let it do.
How a merchant verifies WHICH agent is acting and WHAT it may do.
An `LlmAgent`, a `Runner`, a `Session`, and a CLI that runs it all — the four pieces the other 25 concepts sit on top of.
The smallest ADK agent and the machinery around it: an LlmAgent, the Runner, a Session, and the adk CLI (adk web / adk run) that runs your agent with a dev UI or REPL — no server code.
How a multi-agent group chat pauses to ask a human for approval before one gated tool is allowed to run.
A QA and DevOps agent collaborate in a group chat where DeployToProduction is gated by tool.ApprovalRequiredFunc, pausing the workflow for human approval.
How a stateless agent remembers: sessions carry one conversation, context providers carry knowledge across all of them.
Microsoft Agent Framework agents are stateless. Sessions carry one conversation; context providers carry memory across all of them. Here is the mental model in real code.
How Visa and Mastercard are reshaping tokenization so an AI agent can pay on your behalf — with scoped credentials, agent-aware identity, and the network doing what it has always done: authenticate, authorize, tokenize.
How the card networks are adapting tokenization for agents.
How two Foundry agents cooperate inside a cyclic graph workflow where one of them owns the loop control.
Two Foundry agents cooperate in a cyclic workflow: a SloganWriter drafts, a FeedbackProvider critiques and owns loop control via YieldOutput vs SendMessage.
Turn a plain Python function into something the model can call, and watch the tool-call loop close itself.
Turn a plain Python function into a tool the model can call. The @tool decorator, the tool-call loop, multiple tools, and what the model actually sees.
How Coinbase revived a dormant status code so software agents can pay for what they use, one request at a time.
Coinbase's x402 revives the dormant HTTP 402 Payment Required status code so agents pay for resources machine-to-machine.
This lesson teaches how to build a cyclic workflow where a Writer and Critic loop until approval, using `AddSwitch` to route on structured output.
A cyclic Writer-Critic-Summary workflow: the Critic emits a structured CriticDecision, AddSwitch routes on Approved, and Context state caps the revision loop at maxIterations.
The minimal loop: a Foundry chat client, an Agent with instructions, run non-streaming and streaming — and what actually comes back.
The minimal Microsoft Agent Framework loop in Python: a FoundryChatClient, an Agent whose instructions are its whole personality, run non-streaming and streaming.
How Stripe and OpenAI turned "buy it for me" into an open standard — product feeds, delegated payment tokens, and OAuth consent.
The Agentic Commerce Protocol co-developed by Stripe and OpenAI that powers Instant Checkout in ChatGPT.
This lesson teaches how deterministic function executors and agent-backed executors compose in one graph with the same `AddEdge` wiring.
One workflow that mixes deterministic executors with two Foundry agent nodes for jailbreak detection and response, joined by the same AddEdge wiring and TurnToken triggering.
Why I learned the whole framework by writing one runnable lesson per concept, against Azure AI Foundry, instead of reading the docs top to bottom.
I learned the whole Microsoft Agent Framework in Python by building one runnable lesson per concept against Azure AI Foundry. Here is the 12-track map.
This lesson teaches how to embed a whole built workflow as a single executor inside a larger one — workflows compose.
Embed an entire built workflow as one executor with inproc.BindSubworkflowAsExecutor, composing a Prefix to SubWorkflow to PostProcess parent graph that runs fully offline.
This lesson teaches how to chain three role-specialised agents — researcher → fact_checker → reporter — into one sequential workflow and stream each stage.
A sequential workflow of three role-specialised Foundry agents — researcher, fact_checker, reporter — built with NewSequentialWorkflowBuilder and streamed stage by stage.
This lesson teaches that orchestration is a property of the workflow, not the agents — the same three agents drop into three different built-in graph shapes.
The same three agents dropped into three built-in agentworkflow builders — sequential, concurrent, and round-robin group chat — showing orchestration is a property of the graph, not the agents.
This lesson teaches how to host real `agent.Agent`s as workflow executors and chain them into a sequential pipeline.
Host three translation agents as workflow executors and chain them French to Spanish to English, using DisableForwardIncomingMessages and a TurnToken to drive a strict pipeline.
This lesson teaches how to build a two-executor pipeline and watch it run as a live stream of typed events.
Your first Agent Framework Go workflow: two string executors wired by an edge, run with RunStreaming and watched as a stream of typed events, fully offline.
Compose three kinds of Agent Skill — code-defined, struct-based, and file-based — into a single agent through one skills context provider.
One skills ContextProvider blending three origins: in-memory volume and temperature skills plus a file-based unit-converter, unified behind one tool surface for the model.
The demo is easy; the production agent is hard. An agent that works impressively in a demo can fail unpredictably in the real world — looping, hallucinating, taking wrong actions, or racking up huge costs — because the same flexibility that makes agents powerful makes them unreliable. Building agents that actually work in production is a discipline of managing that unreliability: adding guardrails, evaluating rigorously, and, most importantly, knowing when not to use an agent at all. This closing post is about that discipline.
The demo is easy; the production agent is hard. The same flexibility that makes agents powerful makes them unreliable — looping, hallucinating, taking wrong actions, racking up costs. Building agents that actually work is a discipline of managing that unreliability, and knowing when NOT to use an agent at all.
An Agent Skill — on-demand instructions, resources, and scripts — defined entirely in Go, with no SKILL.md files on disk.
An Agent Skill built from Go closures: instructions, a static and a runtime-generated resource, and a convert script that runs in-process with no SKILL.md files.
The instinct, once single agents work, is to build teams of them — a researcher agent, a writer agent, a critic agent, all collaborating like a little organization. It's an appealing vision, and sometimes exactly right. But multi-agent systems are also where a lot of complexity and cost hides, and the honest guidance is more restrained than the hype: use multiple agents when the problem genuinely calls for it, and prefer a single well-designed agent when it doesn't. Understanding the multi-agent patterns — and their real tradeoffs — is what lets you make that call well.
The instinct, once single agents work, is to build teams of them — a researcher, a writer, a critic, collaborating like an organization. Sometimes that's right. But multi-agent systems are also where a lot of complexity and cost hides, and the honest guidance is restrained: use multiple agents when the problem genuinely calls for it, and prefer a single well-designed agent when it doesn't.
Teach an agent a capability from a folder of files — a SKILL.md manifest, resources, and scripts — loaded on demand via progressive disclosure.
Teach an agent from a SKILL.md manifest, resources, and scripts on disk: fsskills scans the tree and a skills ContextProvider exposes load, read, and run tools.
The first output is rarely the best output — a truth as old as writing, and one that applies to agents too. An agent that acts once and moves on repeats its mistakes; an agent that looks back at what it did, judges whether it worked, and tries again can dramatically improve. Reflection — the agent evaluating and correcting its own work — is what turns a one-shot attempt into an iterative process that gets better, and it's one of the most powerful patterns for making agents reliable on hard tasks.
The first output is rarely the best output. An agent that acts once and moves on repeats its mistakes; an agent that looks back at what it did, judges whether it worked, and tries again can dramatically improve. Reflection turns a one-shot attempt into an iterative process that gets better.
The provider is the swappable back end: the same Joker agent, one-shot and streaming, now through the OpenAI API.
The same Joker agent, one-shot and streaming, through openaiprovider: openai.NewClient reads OPENAI_API_KEY and the model name lives in AgentConfig, not a Foundry deployment.
An LLM is, fundamentally, stateless — it remembers nothing between calls except what you put in its context window. For an agent that takes many steps or works across many sessions, that's a serious problem: without memory, every step starts from scratch, and nothing is ever learned. Memory is how agents overcome statelessness — holding the context of the current task, and carrying knowledge across tasks and time. Understanding the kinds of agent memory, and their limits, is essential to building agents that can handle real, extended work.
An LLM is fundamentally stateless — it remembers nothing between calls except what you put in its context. For an agent that takes many steps or works across sessions, that's a serious problem. Memory is how agents overcome statelessness — holding the current task's context, and carrying knowledge across tasks and time.
A provider whose "credential" is a local process, gated by a human-in-the-loop permission handler for every action the model wants to take.
A provider whose credential is a local copilot CLI process, with an OnPermissionRequest handler that approves or rejects each shell action the model wants to run.
Ask an agent to "research this market and write a report" and it faces the same problem a person would: the task is too big to do in one leap. The answer, for agents as for people, is to break it down — decompose the goal into steps, and work through them. Planning is how agents handle complexity that the basic reason-act loop alone would fumble, and the patterns for doing it — from planning upfront to decomposing on the fly — are among the most important in agent design.
Ask an agent to 'research this market and write a report' and it faces the same problem a person would: the task is too big to do in one leap. The answer, for agents as for people, is to break it down. Planning is how agents handle complexity that the basic reason-act loop alone would fumble.
How swapping in the Gemini provider changes the constructor and credential — and nothing else about your agent.
The Joker agent, unchanged, now backed by Google Gemini: geminiprovider.NewAgent takes a genai.Client and an API key instead of an Azure token credential.
An LLM on its own can only do one thing: generate text. It can't search the web, run code, query a database, check the current time, or send a message — it can only produce words. Tools are what break that confinement, turning a model that can only talk into an agent that can act. Tool use is arguably the single most important capability that makes agents possible, and understanding how it works — and how to design tools well — is central to building effective agents.
An LLM on its own can only do one thing: generate text. Tools are what break that confinement, turning a model that can only talk into an agent that can act. Tool use is arguably the single most important capability that makes agents possible.
This lesson teaches how to connect to a remote MCP server and decorate the tools it exposes with your own local behavior before an agent uses them.
List a remote MCP server's tools, then wrap each FuncTool with a logging decorator via embedding plus one Call override — MCP tools compose like any tool.FuncTool.
Strip away the frameworks, the tooling, and the jargon, and every LLM agent reduces to one simple loop: think about what to do, do it, look at what happened, repeat. This reason-act-observe cycle — crystallized by the ReAct pattern — is the beating heart of every agent, and understanding it deeply is understanding agents themselves. Once you see the loop clearly, agent frameworks stop being mysterious: they're all just implementations of this same fundamental cycle.
Strip away the frameworks and every LLM agent reduces to one simple loop: think about what to do, do it, look at what happened, repeat. This reason-act-observe cycle — crystallized by the ReAct pattern — is the beating heart of every agent, and understanding it deeply is understanding agents themselves.
This lesson teaches how to attach the hosted web-search tool and read the citation annotations the service returns with its answer.
Attach hostedtool.WebSearch so Foundry grounds its answer on live results, then pull CitationAnnotations off content headers with a pure, unit-testable extractor.
"Agent" has become one of the most overused and least precise words in AI — applied to everything from a chatbot with a system prompt to a fully autonomous system that writes and ships code. Cutting through the hype requires a clear definition: an agent is a system where an LLM decides its own actions in a loop, using tools, until a goal is met. That one distinction — the model choosing what to do next, rather than following a fixed script — is what separates a genuine agent from a workflow, and it's where both the power and the difficulty come from.
'Agent' has become one of the most overused words in AI. Cutting through the hype requires a clear definition: an agent is a system where an LLM decides its own actions in a loop, using tools, until a goal is met. That one distinction — the model choosing what to do next, rather than following a fixed script — is where both the power and the difficulty come from.
This lesson teaches the hosted tool: a marker that lets the Foundry service run code the model writes, instead of a Go function you implement.
Attach hostedtool.CodeInterpreter, a zero-value marker with no Run method, so Foundry executes model-written Python in a sandbox to solve sin(x) + x^2 = 42.
This lesson teaches how to bundle related function tools onto a Go type and attach the whole group to an agent as one slice.
Bundle GetWeather and GetCurrentTime onto one Go type, expose them as a tool.Tool slice, and let the model call both in a single turn — plugins as an organizing idea.
The patterns that worked, the traps we fell into, and what we'd do differently.
What worked, what was hard, and what we'd do differently. Real numbers: 18 agents, 90 days, 5 governance policies, 4 provider swaps.
This lesson teaches a middleware chain where a guardrail can block a run before the model is ever called, chained ahead of a logger.
Chain a guardrail middleware that yields its own refusal and skips the model ahead of a logger — short-circuiting a harmful request offline before Foundry is called.
Running agents on Cloud Run, exposing via A2A, and wiring into production systems.
Deploy Microsoft Agent Framework multi-agent systems on Cloud Run with A2A agent-to-agent communication, autoscaling, load balancing, and production observability dashboards.
This lesson teaches the simplest form of multi-agent delegation: wrapping one agent as a tool another agent can call.
Wrap a specialist WeatherAgent with agenttool.New into a tool.Tool and hand it to a French TravelAgent — one model orchestrating another with no workflow engine.
How to instrument agents for observability, error handling, and audit logging.
Migrate ADK callbacks to Microsoft Agent Framework composable middleware: decorators for audit logging, retry with backoff, token budget enforcement, and OpenTelemetry tracing.
This lesson teaches how to send a question and an image together in one message to a vision-capable Foundry agent.
Put a TextContent and a base64 DataContent JPEG in one message and hand it to a vision agent — multimodal input with no upload step, embedded at compile time.
How to port ADK's model hard-codes to Microsoft Agent Framework's provider factory pattern.
Zero-code LLM provider swaps across environments: Ollama for dev, OpenAI for staging, Azure Foundry for prod. Same agents, different models.
This lesson teaches how a Foundry agent borrows tools from a remote MCP server and calls them as if they were local functions.
Connect a Foundry agent to Microsoft Learn's public MCP endpoint over streamable HTTP, list its tools, and hand the whole slice to the agent as proxied tools.
How to port tools, add policy enforcement, and integrate OPA.
Migrate ADK functions to Microsoft Agent Framework governed tools with policy enforcement, DLP scanning, approval gates, and OPA integration for production agent systems.
How one middleware wraps every agent run in an OpenTelemetry span tagged with the gen_ai semantic attributes — the same one-line hook you use for logging.
otelprovider.NewMiddleware wraps every run in an OpenTelemetry span tagged with gen_ai attributes — the same one-line middleware hook you use for logging.
How conversation threads replace session state; how to track token usage across agent chains.
Sessions to threads: porting multi-turn state from ADK to Microsoft Agent Framework. Token budgeting, long-term memory, and conversation audit trails.
How to serialize an agent.Session to disk and resume it later, so a follow-up prompt still remembers earlier turns across a process restart.
An agent.Session serializes with encoding/json, so you can marshal it to disk or a database and resume it later with the model still remembering earlier turns.
How to port ADK's orchestration callbacks to Microsoft Agent Framework builders without losing control.
How to port ADK's orchestration callbacks to Microsoft Agent Framework builders without losing control. The executor pattern: you own the loop.
How to make the model return a typed Go struct instead of prose — hand RunText a pointer, get back populated fields.
Pass RunText a pointer to a Go struct via WithStructuredOutput and the framework asks the model for matching JSON, then unmarshals it straight into your fields.
The philosophy, trade-offs, and what we learned converting 18+ agents in 3 months.
The philosophy, trade-offs, and what we learned converting 18+ agents in 3 months. Provider abstraction as the foundation for portable agents.
How to gate a sensitive tool behind human consent: the run pauses, hands you an approval request, and only calls the tool once you approve.
Wrap a tool with ApprovalRequiredFunc and the run pauses with a ToolApprovalRequestContent; approve it, feed the decision back on the same session, and the tool fires.
How to wrap an ordinary Go function as a tool the model can call, with the schema derived automatically from its types.
Wrap a plain Go func with functool.MustNew and the framework derives its JSON schema and drives the tool call inside a single RunText — two model round-trips, one call.
How to keep a conversation's history on the Foundry service instead of in local memory, so the client never resends the transcript.
Create a Foundry project conversation, bind its ID into a session with WithServiceID, and let the service keep the transcript across turns without resending it.
How an agent.Session carries conversation history so a second prompt can refer back to the first.
A client-side agent.Session carries conversation history so a second prompt can refer back to the first. Create it with CreateSession, thread it with WithSession.
How the Foundry provider snaps a project endpoint, a credential, and a model deployment name into a runnable agent.
The Foundry provider is three inputs: a project endpoint, a credential, and a model deployment name. See how foundryprovider.NewAgent snaps them into an agent.
Back the agent with Azure OpenAI's Responses API, and toggle whether conversation state lives on the server or locally.
Back an agent with Azure OpenAI Responses via NewResponsesAgent, and use DisableStoreOutput to keep chat history local instead of stored server-side.
The same agent primitive, wired to Azure OpenAI's Chat Completions API where the model name is your deployment name.
Back an agent with Azure OpenAI Chat Completions via NewChatCompletionsAgent, where the Model field is your Azure deployment name, not a catalog model ID.
Reach a Foundry-hosted model through the OpenAI-compatible Responses API by configuring a plain openai.Client with three request options.
Reach a Foundry model through the OpenAI-compatible API by configuring an openai.Client with base URL, an Azure token credential, and the ai.azure.com scope.
Point the same agent at an Azure AI Foundry project endpoint using the project Responses API mode.
Run an agent against an Azure AI Foundry project: foundryprovider.NewAgent plus ModelDeployment selects project Responses API mode from the project endpoint.
The same agent primitive as the Foundry lessons, backed by the Anthropic (Claude) provider instead of Azure AI Foundry.
A provider swap onto Anthropic Claude: build an anthropic.Client, pass it to anthropicprovider.NewAgent, and run the identical agent surface.
This lesson swaps the LLM behind an agent for another agent, reached over the A2A protocol instead of a model API.
Back a Go agent with another agent over the A2A protocol: resolve the remote card, open a gRPC client, and wrap it with a2aprovider.NewAgent.
How to borrow tools from a remote Model Context Protocol server and hand them to a Foundry agent as ordinary tools.
Connect to Microsoft Learn's public MCP server with mcptool.Connect and ListTools, then hand the borrowed tools to a Foundry agent as ordinary agent.Config.Tools.
How a shared state snapshot rides along with every AG-UI turn, so client and server-hosted agent stay in sync on evolving structured data.
Share a JSON state snapshot across AG-UI turns — server middleware emits a DataContent snapshot from the model's JSON and the client adopts it via toStateContent and extractState.
How an approval-required tool makes the server pause a run and wait for a human on the client to say yes or no.
Gate a tool behind tool.ApprovalRequiredFunc so the AG-UI server pauses the run, then answer the approval from the client with a message round-trip loop.
How the server-hosted agent can call a tool that actually runs on the client, and the one flag that makes it work.
Let a server-hosted agent call a client-side tool over AG-UI — the server sets DisableFuncAutoCall and forwards the call to the client, which runs the Go function locally.
How an AG-UI-hosted agent runs a server-side function tool while the thin client just streams the conversation.
Give an AG-UI-hosted agent a server-side search_restaurants tool via functool while the thin SSE client just streams the reply — the tool round-trip stays invisible.
How to take the same Foundry agent from earlier lessons and serve it over the AG-UI protocol so a separate client can drive it over HTTP+SSE.
Serve an unchanged Foundry agent over the AG-UI protocol with one aguiprovider.NewJSONHTTPHandler call, then drive it from a credential-free SSE client.
How a memory ContextProvider backed by an Azure AI Foundry store lets an agent recall you in a brand-new session.
Attach a Foundry-backed memory ContextProvider that retrieves before and stores after each run, so a fresh session still recalls facts keyed by a scope.
How a real shell tool lets the model run commands, and an environment provider tells it which shell it is driving.
Pair a run_shell tool with an EnvironmentProvider that probes the shell once and injects OS-correct idioms, contrasting stateless and persistent shell modes.
How to keep a long-running conversation inside the context window by chaining compaction strategies from gentle to aggressive.
Chain four compaction strategies from tool-result collapse to summarization to sliding window to truncation, each gated by a trigger and a preservation floor.
How a ContextProvider injects extra messages and tools into every run — a live todo list and calendar — with state that survives serialize and resume.
A ContextProvider injects a live todo list and calendar into each run and contributes session-mutating tools, with state that serializes to JSON and resumes.
How wrapping one agent as a tool.Tool lets an orchestrator agent delegate to a specialist — composition all the way down, with no routing code.
Wrap a specialist agent with agenttool.New so an orchestrator calls it like any tool, cascading two levels deep from orchestrator to weather agent to leaf function.
How one message can bundle a text prompt and an image, and why that forces RunMessage instead of the RunText shortcut.
Bundle a TextContent prompt and a base64 DataContent image into one message.Message and run it with RunMessage instead of the text-only RunText shortcut.
How to publish an agent as a discoverable tool on a Model Context Protocol server so any MCP client can invoke it.
Wrap an agent with agenttool.New then register it with mcptool.AddTool to serve it over MCP on stdio, so any MCP client can discover and invoke it.
How Go's constructor-over-an-interface idiom lets you inject a real Foundry agent into a service — and a fake into its test — through the same seam.
Inject a Foundry agent into a service through a two-method ChatAgent interface, so main injects the real agent and the test injects a fake through the same constructor.
How to turn every agent run into an OpenTelemetry span with the SDK's otelprovider middleware.
Wire otelprovider.NewMiddleware into agent.Config.Middlewares to open a gen_ai span around every run, exported to whatever TracerProvider you register globally.
How to teach an agent to load and persist conversation memory in your own store via a custom history provider.
Implement a custom agent.HistoryProvider with Provide and Store hooks so the agent loads and persists history in your store; DisableStoreOutput keeps it the single source of truth.
How to serialize an agent.Session to storage and resume the same conversation later, even from a new process.
Serialize an agent.Session with encoding/json, store the bytes, and reload them into a fresh Session in another process to resume the exact same conversation.
How to make the agent return a typed Go struct instead of free-form prose, via a JSON schema derived from your type.
Two ways to get typed output from an agent: per-run agent.WithStructuredOutput, or agent.WithResponseFormat with jsonformat.MustFor baked into Config.RunOptions.
How to pause a run for human approval before the framework is allowed to execute a tool.
Wrap a tool with tool.ApprovalRequiredFunc so the run pauses and returns a ToolApprovalRequestContent; approve or decline, then resume with RunMessage on the same session.
How to wrap a plain typed Go function as a tool the model can call mid-run.
Wrap a plain typed Go function with functool.MustNew and attach it via agent.Config.Tools so the model can call it; the SDK infers the JSON schema from the signature.
How an agent.Session carries conversation history across RunText calls so the model remembers earlier turns.
Thread conversation history across RunText calls with an agent.Session and agent.WithSession, so a follow-up prompt builds on the previous turn; a new session starts fresh.
How to wrap every agent run with a middleware — the standard hook for logging, tracing, and guardrails.
Wrap every agent run with an agent.Middleware in the Foundry Go SDK: one pass-through function that observes messages and updates without altering the result.
How to resume a long-running remote agent stream after it drops — using a continuation token to reconnect instead of re-sending the expensive query.
Capture the continuation token from a streamed remote run, then reconnect with WithContinuationToken and no messages to resume the same task to completion.
How to pin which transport a client uses when a remote A2A agent advertises several bindings at once.
Pin the transport an A2A client uses via PreferredTransports so binding negotiation is deterministic, while the wrapped remote agent stays a plain agent.Agent.
How to drive a slow remote agent that answers with a continuation token, then poll that token to completion instead of blocking on one long call.
Ask a remote A2A agent with AllowBackgroundResponses, get a continuation token, and poll with WithContinuationToken and no messages until the token clears.
How to discover a remote A2A agent's advertised skills and hand each one to a local host agent as an ordinary function tool.
Resolve a remote A2A agent card, turn each advertised skill into a function tool with derived names and descriptions, and hand them to a local Foundry host agent.
The other primitive: a directed graph of executors wired by edges, running fully offline with no model, no credential, no Foundry.
Wire two executors into an uppercase to reverse pipeline with the fluent workflow builder and run it fully offline via inproc.Default, iterating ExecutorCompletedEvents.
A custom ContextProvider gives the agent memory: it reads stored facts before a run and learns new ones after — all through the Session.
A custom ContextProvider wires Provide and Store hooks around every run so the agent reads remembered facts before the call and learns new ones after, all in the Session.
One Session threaded through every call turns two stateless one-shots into a single conversation that remembers.
Thread one agent.Session through every RunText call with agent.WithSession to turn stateless one-shots into a single conversation that remembers.
Hand the agent a plain Go function it can decide to call mid-conversation — the model requests it, the framework runs it, the result flows back.
Register a plain Go function as a tool with functool.MustNew; the model decides when to call it, the framework runs it, and the result flows back into the answer.
The smallest useful agent: give a model instructions and a name, hand it a message, get a response — collected or streamed.
Build the smallest useful agent from instructions and a model, then run the same RunText call two ways — collected all at once and streamed token-by-token.
The zero-network preflight that confirms your Foundry config and Azure credential chain exist before you run a single agent.
A zero-network preflight that confirms your Foundry endpoint, model deployment, and Azure credential chain exist before you run a single agent.