AI Engineer World's Fair 2025
Building Applications with AI Agents
Read the talk
Building Applications with AI Agents
A useful agent needs more than tool access: clear interfaces, maintainable orchestration, deterministic safeguards, and an evaluation loop that turns failures into improvements.
From a talk by Michael Albada
Before you start: Familiarity with language models, API calls, and basic software testing will help; the Python example uses only standard-library features.
Why does a promising prototype remain hard to ship?
How do you turn an agent that handles straightforward requests into a system that reliably handles the difficult ones? Michael Albada approaches that problem from cybersecurity: at the time of the recording, he introduces himself as a principal applied scientist at Microsoft, contributing to Security Copilot and its agents. His background includes about two years at Microsoft, four years working on geospatial machine learning at Uber, and earlier startup work.
The talk distills his roughly 300-page book, Building Applications with AI Agents. At recording time, seven chapters were in early release and he expected it to go to print the following month. This is a slide-led overview, with supporting code examples available for deeper study: the focus is the promise of agents, the components needed for production, and the mistakes that prevent those components from delivering value.
Albada reports a 254% increase over three years in accepted Y Combinator companies describing themselves as agentic or building agents. That signals interest, but it does not establish reliability. Academic agent tasks involve sequences of tool calls, executions, and interactions with complex environments; a plausible first response is only one part of completing the work.
Albada contrasts results in the 50s, 60s, and 70s on agent benchmarks with hypothetical single-digit results five or ten years earlier. This is a broad progress comparison, not a controlled historical evaluation. The accompanying slide identifies AgentBench, CRMArena, and Mobile-Bench, with a single-app, single-task condition attached to Mobile-Bench. Accelerating capability is a reason to build, but not to expect perfection. Albada uses 70% prototype accuracy as an illustration of the easy initial progress before the increasingly difficult long tail; he does not specify a task or scoring protocol for that figure.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Agency and effectiveness are separate axes
An agent, in Albada’s definition, can reason, act, communicate, and adapt to solve tasks. The foundation model supplies the base capability; additional components make it more effective in particular environments. Following Andrew Ng’s framing, agency is a continuum rather than a binary property. Albada adds a second axis: effectiveness. More agency is useful only insofar as it helps solve the problem.
Robotic process automation illustrates why these axes must remain separate. A fixed automation can have little agency while delivering substantial economic value. Its weakness is brittleness: small input changes can break the workflow and force people to maintain it manually. Agents promise greater flexibility in responding to those changes, but that flexibility must preserve the automation’s effectiveness.
The four quadrants make the design constraint concrete. Robotic process automation occupies low agency and high efficacy; the intended destination for AI agents is high agency and high efficacy. Bad chatbots occupy the ineffective, low-agency corner. Powerful systems that act without being effective occupy the corner Albada labels “Future News Stories.” Increase autonomy only while preserving useful performance.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Expose actions, not your entire API inventory
Tool use starts with a simple extension of next-token prediction. An autoregressive model can generate a function call instead of natural-language prose. The application can then connect that call to functionality exposed through an API. This gives the model access to a much wider range of capabilities, while making the choice of exposed functionality a consequential safety decision.
The resulting model–tool observation loop repeats until the agent can produce its final answer:
- Parse the model’s output to identify the requested tool call.
- Invoke the tool.
- Return the tool’s response to the model as an observation.
- Let the model use that information to continue the task or produce the customer-facing output.
The observation matters because each action can supply information the model did not have when it chose that action.
Now consider an organization with 300 APIs. Registering 300 corresponding agent tools is not automatically a useful interface. Albada reports that exposing more tools in an individual prompt or completion reduced accuracy in his team’s experience, as tool meanings collided. He supplies no measured effect size or universal tool-count threshold. The practical response is to reduce the choices available at one time and group related functionality logically.
A tool should have a narrow scope, a specific name, and a clear description. It should feel like one human-facing action, rather than an arbitrary reflection of how the backend happens to divide its APIs. That makes tool design an interface-design problem: the model needs to distinguish when an action applies and what invoking it will accomplish.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Start with the simplest maintainable workflow
Once tools exist, orchestration determines who chooses the next step. Start with a chain if the task fits one: a known sequence is easier to measure, keeps costs down, and supports reliability. When the task requires alternatives, branching logic can let the model select a path through a predefined tree.
Cybersecurity provides a useful example. A workflow can assess an incident’s severity, decide which information is missing, and perform several hops of enrichment and reasoning. A fully agentic pattern gives the model more control: it repeatedly chooses which actions to invoke to complete the work.
| Pattern | Who chooses the next step? | Main tradeoff |
|---|---|---|
| Chain | A predefined sequence | Simple to measure and operate |
| Branching workflow | The model chooses among defined paths | Flexibility within a bounded structure |
| Agent loop | The model repeatedly chooses actions | More freedom; harder evaluation and optimization |
The recommendation is not to preserve a fixed workflow at any cost. Invoking the bitter lesson, Albada points to the moment when chains and trees become convoluted and difficult to maintain. That is a reason to consider more model-directed orchestration, and possibly fine-tuning, rather than continuing to accumulate hand-built branches.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Keep mandatory business rules outside the model
Model-directed orchestration does not require model-enforced business rules. Suppose an action is permitted only when A, B, and C are all true. Asking the model to remember and apply that rule makes a fixed requirement depend on generated behavior. Instead, expose tools that update the individual conditions, sanitize and validate those updates, and maintain the state outside the model.
The following Python example expresses that boundary using Albada’s three conditions. A and B begin satisfied while C is false. A valid update to C changes the action’s eligibility; it does not execute the action.
python
from dataclasses import dataclass, replace
@dataclass(frozen=True)
class Conditions:
A: bool = False
B: bool = False
C: bool = False
def update_condition(
state: Conditions, name: str, value: object
) -> Conditions:
if name not in {"A", "B", "C"}:
raise ValueError("Unknown condition")
if type(value) is not bool:
raise ValueError("Condition must be a boolean")
return replace(state, **{name: value})
def action_allowed(state: Conditions) -> bool:
return state.A and state.B and state.C
state = Conditions(A=True, B=True, C=False)
assert not action_allowed(state)
state = update_condition(state, "C", True)
assert action_allowed(state)
The application retains the current state and checks action_allowed at the action boundary. The model can help gather information and request updates, but deterministic code owns the mandatory gate. Validation must also establish whatever domain evidence each condition requires; accepting a boolean alone does not establish that a business requirement has been met.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Use multiple agents to control tool scope
Tool overload supplies a concrete reason to split a single agent into several. Group semantically similar tools, register each group with a specialist agent, and use a coordinator to route tasks to the appropriate specialist. The overall system can then support more functionality without presenting every tool to every completion.
That coordinated architecture differs from agents built independently by different teams discovering and collaborating with one another. Albada says most successful multi-agent systems he has seen were built by one team able to coordinate the parts. The Agent2Agent Protocol aims toward the broader interoperability problem. In the recording, he treats that as an early direction with technical and security questions still to resolve, rather than an already-solved consequence of adopting a protocol.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Define the agent through expected behavior
Evaluation is what makes architecture choices answerable. Albada again characterizes reaching 70–80% accuracy as relatively easy, without specifying a task or measurement protocol. The hard questions begin when deciding how many agents to use, how many tools to expose, which model to select, and what kind of memory to provide. Without a rigorous evaluation set, those choices are difficult to distinguish from guesses.
This suggests test-driven development for agents: define the inputs and expected outputs, then improve the implementation against that behavioral contract. Albada contrasts this with treating labeling as work to outsource to Mechanical Turk. Architects and engineers must take ownership of what the agent should do. Those expectations give the team a stable basis for decisions even as models and frameworks change.
Build the set from a recurring review process: run user inputs through the agent, inspect the outputs with human reviewers, and add reviewed examples to the evaluation set. The set grows as the team learns what its users actually need and where the agent fails.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Improve from batches of failures
Once the evaluation set exists, run it through the agent, analyze failures, cluster and summarize the outputs, and use those patterns to suggest improvements. This moves the unit of analysis from a memorable bad answer to a category of failures.
Several tools support different parts of that process:
- Synthetic inputs: IntellAgent can help generate test inputs when privacy or security prevents access to raw user data, or when the product has not shipped yet.
- Adversarial testing: Microsoft’s PyRIT supports attempts to jailbreak, red-team, or otherwise compromise an agent before release.
- Evaluation-set construction: Label Studio helps teams build labeled datasets.
These address distinct needs: obtaining cases, probing hostile behavior, and recording judgments about expected behavior.
Automatic prompt optimization and automatic prompt engineering extend the loop from identifying failures to proposing changes. Albada names Trace, TextGrad, and DSPy, describing a foundation model acting as a judge and feeding improvement suggestions back through an agent flow. His gradient analogy captures the direction of the approach; it should not imply that every optimizer in these libraries calculates the same kind of gradient.
The alternative is development by anecdote: inspect an example, make a plausible change, and hope it helps. Batch evaluation lets the team judge changes against aggregate behavior instead. Albada compares this to neural-network optimization, where larger batches can provide a better direction for an update. His reference to steps toward a global minimum is an analogy for more informed improvement, not a convergence guarantee for agent workflows.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Make deployed behavior visible
Deployment creates an observability problem that Albada likens to an iceberg. Generative models produce plenty of content, but the visible examples do not reveal the full range of customer use cases and failures. Once the system reaches users, understanding everything happening beneath that surface becomes difficult.
Detailed logs and traces provide the raw material for learning. Albada recommends OpenLLMetry and OpenTelemetry integrations, followed by clustering and automated summarization to identify the main failure categories. Instrumentation is useful when it helps the team understand what to improve, rather than merely accumulating more generated text to inspect.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Close the learning loop and provide a safe exit
Albada ranks insufficient evaluation as the largest limitation he sees. Tool design is another recurring source of failure: the agent may lack a needed tool, descriptions may be unclear or inaccurate, or several tools may overlap enough to confuse selection. Reducing the number of exposed tools is therefore not the same as removing necessary capability. The interface must be both sufficient and distinguishable.
Excessive complexity makes these problems harder to diagnose. Add a new mechanism only after testing shows that it improves the user experience. A second failure is lack of learning: generated content accumulates, but the team does not get from observations to root causes and useful changes. The engineering task is to tighten that loop, not simply to collect more outputs.
Safety adds a further requirement: the system must know when automated work should stop. Coming from cybersecurity, Albada treats agentic systems as a new class of potential vulnerability. PyRIT can support testing at multiple layers, but sound software engineering remains necessary throughout the stack. Build tripwires and detectors at different stages so critical cases can exit automated execution and fall back to human review. That safe exit is part of the design, not something to improvise after a failure.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
The purpose is more useful work
Albada closes with Paul Krugman’s observation: “Productivity isn't everything, but in the long run it is almost everything.” The economic connection is output per worker: sustained improvements in living standards depend on increasing what people can accomplish. Albada sees agent design patterns as the beginning of an increase in that capacity. The ambition is not merely to produce more model output, but to help each person complete more useful work.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Resources
From the talk
Generates policy-based test scenarios, simulates user conversations and diagnoses conversational-agent failures.
An open-source framework for identifying risks in generative-AI systems through security testing.
Guides for creating labeling projects and collecting annotations for datasets.
A framework for optimizing agent workflows using computational graphs and generative optimizers.
Google’s original announcement of a protocol for communication and coordination between agents from different vendors and frameworks.
An introduction to tracing LLM applications with OpenTelemetry-compatible instrumentation.
Further reading
The author’s companion repository with agent scenarios, evaluation examples and observability integrations.
The research paper introducing TextGrad and its text-based approach to automatic differentiation.
The original DSPy paper on declarative modules and optimization of language-model pipelines.
Transcript & slides
Loading transcript and slides…