AI Engineer World's Fair 2026
AI Agents Are Just Distributed Systems Now — Salman Munaf, TikTok
Read the talk
AI Agents as Distributed Systems: Designing for Uncertain Outcomes
Salman Munaf explains why agents that act on external systems need deterministic controls around retries, state, permissions and recovery.
From a talk by Salman Munaf
At a glance
Ideas worth remembering
External actions make the agent a probabilistic coordinator within a distributed system. Deterministic controls must constrain what its decisions can cause.
A timeout means the outcome is unknown. Request identifiers, idempotency keys and status lookups address uncertainty and duplicate effects; backoff, circuit breakers and budgets constrain the load and cost of retries.
Memory that influences actions needs an authority policy, provenance and invalidation. Persisted workflow records and traces must also preserve enough context to reconstruct failures.
Recovery must account for successful earlier steps. Compensation can correct an irreversible action’s consequences, as with a corrective email, without restoring the exact prior state.
Scope credentials and approvals to the intended operation. Separate reads from writes, allowlist tools, and bind approval to parameters, actor, timestamp and expiration: a $30 refund approval does not authorize $300.
Better models reduce mistakes but cannot eliminate infrastructure failures or stale data. Reliability depends on what the system permits, observes and can recover from when an agent is wrong.
When model output becomes an external action
Salman Munaf opens with a change in the scope of failure. A model that takes text and returns text can produce a wrong answer. An agent that calls external services can also change those services’ state. Its mistakes therefore extend beyond its output, and building it requires the distributed systems thinking used to manage interactions between independently operating systems.
He motivates this with a production-database deletion incident and an Air Canada chatbot example that he describes as an incorrect refund. His proposed controls for the database example are robust backups and scoped authority, including preventing an agent from deleting a production database. For the chatbot, he proposes retrieving policy from an authoritative source so that stale or incorrect information does not drive decisions. These examples identify different responsibilities: limiting what an agent can change and establishing what information it should trust.
The architectural boundary now includes the agent loop, its tools and the external services those tools reach. A useful design inventory must therefore identify the systems the agent talks to, the state it interacts with, the credentials it holds and the actions those credentials permit. Evaluating the model alone leaves these sources of side effects outside the assessment.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
A probabilistic coordinator needs deterministic controls
Munaf describes the agent as a probabilistic coordinator. Traditional distributed services also coordinated multistep workflows, but their decisions followed a mapped, deterministic structure. An agent can vary both the kind and the number of actions it takes. That flexibility makes the surrounding controls more important: the system needs deterministic restrictions on actions whose consequences would be unacceptable.
His typical loop plans, acts, observes the result, optionally persists information and decides what to do next. Each stage can cross a boundary. Planning may retrieve data; acting may call APIs, tools or databases; observing may receive only partial results. Those incomplete observations can influence later actions, while persistence can turn incorrect information into a durable input for future decisions. The next decision can compound the problem through an incorrect action or a retry storm.
Munaf recommends persisting each step’s actions and retrieved context so that a failure can be located and recovery can start from a known point. Recovery also needs an explicit decision for each step: what should happen if the call fails, and what compensating operation is appropriate if the action is unsafe or irreversible? His example is an incorrect email sent to a customer. Recording that it happened supports recovery, but the record alone does not define how to repair its consequences.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
A timeout leaves the outcome unknown
A tool call wraps an interaction with an external API, database or queue, so it inherits remote-call failure modes. Network delays and timeouts can obscure an operation’s outcome. Munaf describes a database write that succeeds even though the caller receives an error. The error reports what the caller observed; it does not necessarily establish whether the underlying state changed. A human might inspect the authoritative database to resolve this discrepancy, and an automated workflow needs an equivalent way to establish the outcome.
The refund example makes the ambiguity concrete. An agent calls a tool that refunds a customer, and the request times out. The agent cannot infer from that timeout alone whether the refund happened. If it treats the timeout as proof of failure and issues another refund, it risks duplicating a successful operation. The correct interpretation is that the outcome is unknown.
Munaf calls for request identifiers, idempotency keys and status lookups in the tool design. These serve related purposes: identifying the operation, preventing repeated requests from producing repeated side effects, and checking what happened to the earlier request. Together they give the workflow a way to resolve uncertainty without assuming that another attempt is harmless.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Retries need both duplicate protection and limits
Munaf describes retrying as an agent’s first response to failure. That makes idempotency a responsibility of the receiving API or tool: it should recognize a duplicate request and prevent another side effect. Duplicate protection must be built into the operation, because an agent deciding to retry is not itself evidence that repeating the action is safe.
Retries also create load, even when duplicate effects are prevented. A retry storm against an external API can cause cascading failures. Munaf therefore recommends limits on turns, spending and parallel calls to constrain how much work the agent generates, plus exponential backoff to reduce pressure on downstream dependencies between attempts. He also retains compensation operations for actions with side effects. These controls address different problems: repeated effects, excessive traffic and the consequences of work already performed.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Recovery across systems requires compensation
A multistep workflow can succeed in its first operations and fail later, leaving different systems in different stages of completion. Munaf’s example updates an internal ticket, sends a customer email and then fails to update the CRM. The recovery problem now includes the ticket and the email as well as the failed CRM update. The workflow needs a defined compensation operation for that partial outcome.
His email example shows why compensation does not always restore the exact prior state. If the agent has sent an incorrect message, the defined response may be an apology or a corrective email. That response addresses the mistake through another action; it does not erase the original communication. Recovery therefore depends on the meaning of each operation and needs to be specified for the agent.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Stop calls when dependencies or budgets cannot support them
Munaf returns to the agent loop to introduce circuit breakers. When a downstream dependency is unhealthy or saturated, a breaker should prevent the agent from continuing to call it. This places a system-enforced stopping condition around the agent’s attempts to recover and helps prevent those attempts from burdening the dependency further or spreading failure.
Rate limits and budgets constrain a different dimension of persistence: the agent may keep trying to solve a problem while accumulating cost. Maximum turns, maximum parallelism and maximum spending establish an explicit boundary on that effort. These ceilings constrain the agent’s freedom to continue, but they make the permitted resource commitment a property of the system rather than an open-ended consequence of its problem-solving loop.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Observability must reconstruct what the agent acted on
Munaf argues that logs alone are insufficient for understanding an agent failure. Teams need to reconstruct when the failure occurred, what happened, what information the agent was reacting to and why the workflow failed. Knowing only that a tool returned an error leaves out the inputs and preceding decisions needed to understand the outcome.
He calls for traces that include the model invoked, its prompt, tool calls and their requests, responses and errors, retrieved context, writes and approvals. These records connect the information available to the agent with the operations it attempted and the effects it produced. That connection is what makes a failure reconstructable across the model and the surrounding services.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
What does the system permit when the agent is wrong?
Munaf closes by separating improved model capability from the reliability of the overall architecture. Smarter models can reduce mistakes and improve the likelihood of correct operations. They cannot eliminate network failures, stale data or adversarial input. The architecture must therefore support bounding, observing and recovering from actions even when the model is capable.
Tool contracts make part of that architecture explicit. They should establish the permitted operations and clearly define request and response types and schemas. Idempotency belongs in the tools so that repeated requests do not repeat unsafe effects. The remaining controls need equally clear decisions: which data source wins when memories conflict, how retry policies and rate limits constrain repeated attempts, what permissions apply, and what traces and recovery paths exist.
His final design question is what the system lets the agent do when it is wrong. That makes incorrect decisions an expected condition the architecture must handle, with explicit limits on their consequences and a way to recover.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Read the complete timestamped transcript
- 0:01
[music]
- 0:12
Hello everyone. Good good afternoon. Uh
- 0:15
today uh I will be talking about AI
- 0:17
agents are also distributed systems.
- 0:20
So as uh the models have started to
- 0:24
become more complex. Initially the uh
- 0:27
LLM models were just text in text out
- 0:30
without performing any actions and uh
- 0:33
the
- 0:35
effect that they can produce was just a
- 0:38
wrong model output. However, with
- 0:42
now the capability of agent the agent
- 0:45
the rise in agent capabilities where the
- 0:47
systems can now talk to external systems
- 0:50
uh it has turned into a distributed
- 0:54
systems and it is important to
- 0:56
incorporate distributed systems thinking
- 0:59
and concepts when building AI agents. So
- 1:02
I will be going over uh that uh in this
- 1:05
talk.
- 1:07
So you guys might have uh heard about
- 1:11
incidents being caused by a AI agents.
- 1:14
Uh for instance, the replicate AI agent
- 1:18
deleting a production incident
- 1:20
production database or Air Canada
- 1:23
chatbot basically making an uh an
- 1:26
incorrect refund. And both of these uh
- 1:30
incidents or a lot of these incidents
- 1:32
could have been prevented uh by good
- 1:36
systems thinking when building these uh
- 1:40
AI agents. So for instance for the
- 1:42
replet a uh uh uh incident we could have
- 1:48
good uh
- 1:50
uh we could have robust backups. We
- 1:53
could have scoped authority. we should
- 1:54
we shouldn't ideally have uh allow AI
- 1:58
agents to delete production databases.
- 2:00
Uh moreover for Air Canada chatbot
- 2:04
it would have been uh a good idea to
- 2:06
have uh authoritative source of truth
- 2:09
retrieval so that it's not making uh uh
- 2:13
decisions based on stale or incorrect
- 2:15
policies.
- 2:19
So let's uh go over the transition from
- 2:21
chatbot to production system. Uh so
- 2:26
uh initially when we were in the uh in
- 2:30
the uh age where LLMs were just chat
- 2:33
bots uh we had prompt in and we were
- 2:37
outputting text there were no side
- 2:39
effects the agent was not interacting
- 2:41
with any other system.
- 2:44
However, uh due to agentic uh in the
- 2:48
agentic era in the agentic revolution,
- 2:51
now those agents uh by ingesting prompt
- 2:54
can uh run an agent loop, call external
- 2:58
services, call tools and also perform
- 3:00
state changes. The architectural
- 3:02
boundary now has moved uh way beyond an
- 3:06
LLM model. And the difference is that it
- 3:10
can now cause side effects in the
- 3:11
outside world. So when basic when
- 3:14
building AI agents, it is important to
- 3:17
recognize the external systems that it
- 3:19
is talking to, [clears throat] the
- 3:21
states that uh it is interacting with
- 3:25
and what credentials does it have and
- 3:28
the actions that it can perform.
- 3:32
uh I ideally like to think about it as
- 3:36
uh uh AI agents as basically having a
- 3:40
probabilistic coordinator.
- 3:42
In distributed systems as well, we used
- 3:44
to have services which were coordinating
- 3:46
uh multi-step workflows. However, they
- 3:49
were deterministic in nature. But in the
- 3:52
case of AI agent, the AI acts as a
- 3:55
probabilistic coordinator. The amount of
- 3:57
action, the kind of actions that it can
- 3:59
take can vary quite a lot. It is not
- 4:02
just a decision tree that uh we
- 4:05
typically in traditional systems would
- 4:08
have mapped out
- 4:10
and those uh actions can have severe
- 4:13
consequences uh ba uh if they are not
- 4:17
confined by our determinist by having
- 4:21
deterministic controls in place. So it
- 4:24
is important to ensure uh that we have
- 4:28
deterministic controls in place to
- 4:30
ensure that agent or the AI agent is not
- 4:33
performing any uh
- 4:36
any actions that might be uh uh
- 4:40
problematic.
- 4:42
So uh
- 4:45
let's uh discuss the how a typical agent
- 4:49
loop might look like. So at first it
- 4:53
might uh do some planning. Then based on
- 4:57
that plan it will it will perform an
- 4:59
action and it will then observe the
- 5:02
results of those actions and uh it might
- 5:05
persist that into some d some data store
- 5:09
and then decide what to do next.
- 5:12
Each step in this loop is basically
- 5:14
crossing a a boundary. During planning,
- 5:17
it can interact with data sources to
- 5:20
retrieve some data. Uh during action, it
- 5:23
can call external APIs, tools, uh
- 5:27
databases and perform any actions.
- 5:30
During observation phase, it can perform
- 5:33
it can get partial results and basically
- 5:37
plan or make subsequent actions based on
- 5:41
those partial results. It can persist
- 5:44
incorrect data or uh and uh when
- 5:48
deciding it might also
- 5:52
decide to uh perform an incorrect action
- 5:55
or uh worse it can also do a retry
- 5:59
storm.
- 6:01
So it is very important when building an
- 6:03
agent loop to persist every step of the
- 6:07
process. Whatever actions the agent is
- 6:09
doing, whatever context it is
- 6:11
retrieving, it is important to uh
- 6:13
persist that so that if anything fails,
- 6:16
the agent is able to recognize where it
- 6:18
failed and it can perform uh a
- 6:21
reversible action. Uh it can perform
- 6:24
undo operations. Similarly, there should
- 6:26
be explicit transactions uh identified
- 6:30
for each step. So for instance, if an
- 6:32
agent is making a call, if it fails,
- 6:35
what it should do? What should be the
- 6:37
transaction to compensate for a uh for a
- 6:40
irreversible or unsafe operation? For
- 6:43
instance, if an agent makes sends an
- 6:45
email to a a wrong email to a customer,
- 6:48
what should it do to compensate for
- 6:50
that?
- 6:53
So, uh tool calls are just wrappers
- 6:58
around uh external external APIs,
- 7:02
databases, cues, uh and so on.
- 7:06
And uh with uh when calling the when
- 7:10
making these remote calls, there are
- 7:13
some failures that you incorporate uh
- 7:16
such as network delays, timeouts, uh you
- 7:19
can make duplicate requests or worse the
- 7:22
server side request uh might succeed.
- 7:26
However, the client however the client
- 7:28
might be reported an error.
- 7:30
We have we have seen uh instances where
- 7:35
uh a data by base might have written the
- 7:37
data. However, due to some other errors,
- 7:40
the server might have reported uh uh to
- 7:44
us the error and
- 7:47
uh with humans in the loop we can make
- 7:50
we can basically perform correct
- 7:53
corrective actions based on uh by seeing
- 7:56
uh the database and actual source of
- 7:57
truth. But in agent's case, we need to
- 8:00
ensure that we have uh we have proper
- 8:03
guardrails in place. So for instance,
- 8:06
an agent calls refund customer uh tool
- 8:09
call which basically performs a refund
- 8:11
to the customer. The request times out
- 8:14
uh that did the refund happen or not?
- 8:18
What will the agent uh infer from that?
- 8:22
Would it retry uh refunding to the
- 8:24
customer? you basically the the timeout
- 8:27
does not actually mean that there a
- 8:29
failure had occurred. It means unknown.
- 8:32
And it is important to have uh when
- 8:36
designing these tools, it is important
- 8:38
to have request ids, item potency keys
- 8:42
so that when making duplicate requests,
- 8:44
they are not causing duplicate side
- 8:46
effects. uh and the system can always do
- 8:49
a status lookup like what the previous
- 8:52
request was and what was the status of
- 8:55
that so that it is not making side
- 8:57
effect it is not making side effects
- 9:00
with duplicate a with duplicate
- 9:02
requests.
- 9:05
So [clears throat] AI agents when they
- 9:09
whenever they uh uh whenever they uh
- 9:14
they face failures they retry the their
- 9:17
first uh action is to perform retries.
- 9:20
So it is really important to have item
- 9:23
potency baked in. uh it if a same
- 9:27
request is coming in to an external API
- 9:30
or the tool it should recognize that
- 9:32
this is a duplicate request and ensure
- 9:34
that no side effects are being take are
- 9:36
taking place. Moreover, uh we should
- 9:40
also prevent uh AI agents to perform
- 9:43
retry storms to external APIs because
- 9:45
this can cause cascading failures. uh we
- 9:49
we should have max turns budget spend
- 9:52
and max parallel calls to prevent uh to
- 9:56
uh to ensure that the fan out is not
- 9:59
that large. Moreover, we should have
- 10:02
exponential back back off in place to
- 10:04
ensure that uh the downstream
- 10:07
dependencies are not being uh burdened
- 10:11
and we should also have compensation uh
- 10:14
operations in place for uh operations
- 10:18
that uh that that can have side effects.
- 10:25
Uh
- 10:27
so uh
- 10:29
a lot of uh
- 10:32
teams when building AI agents think of
- 10:35
AI agent context as just a AI cont the
- 10:39
context that uh the AI agent has as uh
- 10:43
as just a context. However, when that
- 10:46
context can influence an action, it's a
- 10:49
state and that state can become stale
- 10:53
that can conflict with the authoritative
- 10:54
data or corrupt future actions that the
- 10:57
agent might perform.
- 10:59
I like to classify it into two different
- 11:02
types of uh memory that the agent has.
- 11:05
First is the short-term memory which is
- 11:07
the jet thread uh that the agent has uh
- 11:11
the which is tied to a single execution
- 11:13
thread and the second is the long-term
- 11:15
memory. It can be project files uh
- 11:18
system prompts uh databases that it
- 11:21
interacts with the cache layer and so
- 11:23
on.
- 11:25
It is important to uh to to decide what
- 11:29
will be the source of truth when these
- 11:32
uh different data sources have
- 11:35
conflicting information and we should
- 11:38
ideally treat memory as a cache which uh
- 11:43
can be invalidated which can have
- 11:46
provenence attached to it. So for
- 11:49
instance whenever a data store or a
- 11:51
database is updated or the source of
- 11:53
truth is updated we in we invalidate the
- 11:56
context or the memory that the agent has
- 11:59
to ensure that it is not making actions
- 12:01
based on the uh incorrect or stale data.
- 12:08
So
- 12:10
usually these agents perform multi-step
- 12:12
actions and uh the agent can succeed on
- 12:17
uh on uh on the first couple of steps
- 12:20
and then it fail. Uh it is important to
- 12:23
reverse the entire transaction that was
- 12:26
performed and these can uh then can
- 12:29
cross system boundaries. So for
- 12:31
instance, an agent can update an
- 12:34
internal ticket uh send an email to a
- 12:37
customer and fail to update the CRM. We
- 12:41
need to figure out what is the uh
- 12:45
correct compensation operation when it
- 12:48
when it hits that failure.
- 12:51
So for instance uh as I mentioned
- 12:53
earlier that uh it improperly uh it
- 12:59
improperly sends an incorrect email to
- 13:01
the customer. It is important that the
- 13:03
compensation operation is defined for
- 13:05
the AI agent to ensure that it is
- 13:07
sending an uh uh an apology email to the
- 13:11
customer or any or or any email or an
- 13:14
email that is correcting that mistake.
- 13:19
So uh
- 13:22
a the AI agent basically runs in a loop
- 13:25
and uh whenever uh like it can it can do
- 13:30
multiple calls. It can it can have a
- 13:33
retry uh retry loop that it can run
- 13:37
based uh whenever it fails. So it is
- 13:40
important to have uh circuit breakers
- 13:43
whenever it is making making external
- 13:45
calls uh to ensure that the uh that the
- 13:49
that it is not uh burdening the
- 13:52
downstream system. Uh for instance if a
- 13:56
downstream is unhealthy there should be
- 13:57
system break uh circuit breakers in
- 13:59
place that prevents AI agents to call
- 14:01
call that dependency. Moreover, it also
- 14:04
prevents cascading failures when for
- 14:06
instance the downstream dependency is uh
- 14:10
unhealthy or uh is saturated.
- 14:14
It is also important to assign rate
- 14:16
limits and budgets. Uh an agent can uh
- 14:21
go over uh can run your cost uh if it's
- 14:24
not assigned proper budgets and rate
- 14:26
limits. it will uh keep retrying and try
- 14:30
try to uh try to solve the problem that
- 14:33
if it if it's facing. So it is important
- 14:36
that it is uh that we have uh set up max
- 14:39
turns, max parallelism, max spend uh to
- 14:42
ensure that the model is not uh uh not
- 14:46
uh crossing the uh the budget boundary
- 14:49
that we have set.
- 14:52
Moreover, uh ideally uh usually whenever
- 14:58
we are building AI agents, uh we usually
- 15:02
try to give all the permissions that it
- 15:03
can have to ensure that it has all that
- 15:06
it can perform perform the task that we
- 15:08
have. That's the that's the uh first uh
- 15:14
uh thing that we have that that's the
- 15:16
first step that we take usually that to
- 15:19
give the AI agents all the uh cred all
- 15:21
the uh privileges to perform any actions
- 15:25
like for instance if it's interacting
- 15:27
with the database we just give it all uh
- 15:30
the readr access to the entire table.
- 15:32
However,
- 15:34
uh it is important to give scoped
- 15:37
credentials to it. There should be
- 15:39
separate read and write permissions and
- 15:41
there should be allow list for the tools
- 15:43
that it can call. A harmless model can
- 15:47
become dangerous when it can perform
- 15:49
unsafe operations. Moreover, uh a human
- 15:53
approval shouldn't be tied uh to a
- 15:56
blanket approval. It should be tied to
- 15:59
uh action, timestamp, actor and
- 16:03
expiration. So for instance, if a user
- 16:06
has given uh an approval to approve a
- 16:10
$30 refund, it shouldn't turn into a
- 16:13
subsequent approval for $300 refund.
- 16:17
It is important that whenever an
- 16:20
approval is given, it should be tied to
- 16:24
the particular parameters that it was uh
- 16:28
asked for.
- 16:31
So, uh observability is an important
- 16:36
requirement when building AI agents
- 16:38
because uh
- 16:41
and logs are not enough. Teams need to
- 16:43
reconstruct when an agent failed, what
- 16:45
happened, what information was was it
- 16:48
reacting to and why it failed. And logs
- 16:51
alone are not enough to uh for an agent
- 16:55
to uh for teams to determine that.
- 16:59
It is important to trace the model that
- 17:01
was called, the prompt that was uh that
- 17:04
was uh given to it and uh also the tool
- 17:08
calls that were made uh the request uh
- 17:11
that was made, the response from the
- 17:14
tool, the errors that it got, the
- 17:16
retrieved context, what the agent was uh
- 17:19
was the the retrieved information that
- 17:22
the agent was reacting to, the rights
- 17:24
that it made, and the approvals that it
- 17:26
got and so on.
- 17:31
So uh I would like to uh end with uh the
- 17:37
idea that yes model capability matters.
- 17:40
Having good models uh improves the uh
- 17:44
likelihood of it making uh correct
- 17:47
operations. Smarter models reduce
- 17:49
mistakes. It uh it uh improves the
- 17:54
capability that the model has. However,
- 17:56
it cannot eliminate network failures,
- 17:59
stale data or adversarial input. It is
- 18:03
important when building this
- 18:04
architecture,
- 18:06
we also reason about can we bound,
- 18:09
observe and recover from actions
- 18:12
performed by the AI agent. It is
- 18:14
important to have tool contracts in
- 18:16
place to ensure that uh it is only
- 18:21
allowed to make uh operations that it is
- 18:23
uh given that it is provided the
- 18:25
contract and the contracts are clearly
- 18:27
establishing the request and response uh
- 18:30
response uh response types uh the schema
- 18:35
and all these tools have item potency
- 18:37
baked into it. so that uh when repeated
- 18:41
requests are sent in uh it is not
- 18:43
causing unsafe operations to be retried.
- 18:46
Moreover, there should be source of
- 18:48
truth decisions made uh when there are
- 18:50
conflict conflicting uh memory states.
- 18:53
It is important uh for the agent to
- 18:56
realize this is the source of data that
- 18:58
it should rely on and we should have re
- 19:01
retry policies uh like rate limits set
- 19:05
in to ensure that the agent is not uh
- 19:07
retrying uh ext uh aggressively.
- 19:11
Moreover, uh permissions should be set
- 19:15
up. There should be traces and recovery
- 19:17
paths. So
- 19:20
when building AI agents, we should also
- 19:23
ask what the system lets it do when it
- 19:26
is wrong.
- 19:28
Thank you.
- 19:46
>> [music]