AI Senior GenAI Handbook
CHAPTER 05PRIORITY 0CONTROL THE UNCERTAINTY

Agentic Systems & LLM Application Engineering

Design observable, cost-bounded agent workflows with MCP, durable execution, multi-agent topologies, approvals, and managed runtimes on Bedrock and Vertex AI.

34 min read Interview drills

Learning objectives

By the end of this chapter, you should be able to:

  • Decide when an agent is warranted and when deterministic code, retrieval, or a form is safer.
  • Choose among router, planner–executor, supervisor/worker, pipeline, debate, and swarm topologies — and argue when a single agent with good tools beats all of them.
  • Design narrow tool contracts with schema validation, authorization, idempotency, and interpretable failures, and explain what MCP and A2A standardize versus what stays your responsibility.
  • Make multi-step executions resumable with checkpointing (LangGraph) or deterministic replay (Temporal), and reason about idempotent side effects under replay.
  • Separate working context, workflow state, and long-term memory; design episodic/semantic memory with compaction, provenance, and deletion.
  • Design human-in-the-loop approval bound to exact expiring actions, plus sandboxing for code-executing and computer-use agents.
  • Compare AWS Bedrock Agents/AgentCore and GCP Vertex AI Agent Builder/Agent Engine/ADK against a self-built LangGraph stack, with concrete trade-offs.

1. Earn the right to be agentic

An agent is a system in which a model chooses at least part of the action sequence at runtime. That flexibility is useful when the task is open-ended, the correct path depends on observations, and tool selection cannot be exhaustively encoded. It also expands the state space: more trajectories, model calls, permissions, latency, cost, and failure combinations. "Agentic" is therefore a design choice, not a maturity level — a point Anthropic's Building effective agents makes explicitly: use the simplest composable pattern that solves the task.

Deterministic function

Use when inputs and rules are known: calculations, schema transformations, authorization, validation, and irreversible side effects. It is cheap, testable, and explainable.

Fixed workflow

Use when steps are known but some steps need model judgment: classify → retrieve → draft → validate. Explicit control flow makes recovery and evaluation tractable.

Bounded agent

Use when the next information-gathering action depends on prior results. Constrain tools, steps, budget, scopes, and terminal outcomes.

Human decision

Use when policy, accountability, or irreversible impact requires judgment that the system is not authorized to make.

Apply the uncertainty–consequence test. Agent value rises with path uncertainty: research, diagnosis, codebase exploration, or heterogeneous support requests. Required control rises with consequence: moving money, deleting data, changing production, contacting a customer, or disclosing sensitive information. High uncertainty plus high consequence calls for a bounded agent that prepares evidence and a plan, then an explicit approval before action.

Define success and terminal outcomes

"Helpful response" is not an operational contract. Define allowed terminal states such as completed, needs_user_input, awaiting_approval, blocked_by_policy, budget_exhausted, and dependency_failed. For each, specify what the user sees and whether resumption is possible. A loop without a terminal-state model is a reliability bug waiting for traffic.

2. Choose an orchestration pattern from the control problem

Framework names matter less than who decides the next step and where state lives. Model the workflow as states, events, guarded transitions, side effects, and terminal states. Then choose a framework — or plain code — that expresses this model clearly.

PatternUse whenPrimary riskControl
RouterOne request maps to one specialist pathMisrouting or category driftConfidence threshold, fallback, labeled confusion matrix
State machineAllowed transitions and recovery must be explicitState explosionSmall typed state, invariants, terminal states
Planner–executorTask path depends on intermediate evidenceStale or impossible plansPlan validation, step cap, replan trigger
Supervisor/workerSeveral specialist capabilities must be coordinatedExtra calls and opaque delegationNarrow roles, shared outcome schema, central budget
PipelineStages have distinct contracts and can be validated between stepsError propagation without repairInter-stage schemas, gate checks, bounded repair loops
Parallel fan-out / swarmIndependent evidence can be gathered concurrentlyDuplicate work and merge conflictBranch budget, dedupe, deterministic aggregation
Multi-agent debateDistinct perspectives have measurable valueExpensive agreement theaterIndependent evidence, calibrated judge, stop rule

Multi-agent topologies — and when not to use them

The supervisor/worker topology is the workhorse: a coordinator decomposes the task, delegates to workers with narrow tool grants, and merges typed results under a central budget. It pays off when subtasks genuinely parallelize (breadth-first research, multi-source evidence gathering) or when permission separation matters — a read-only research worker cannot mutate anything even if compromised by injected content. The cost is real: multi-agent systems multiply token spend because each worker re-establishes context, and coordination failures (duplicate work, contradictory partial results, lost context at handoff) become your dominant defect class.

Figure 1 Supervisor/worker topology with permission-separated workers and a central budget
flowchart TD
  U["User request"] --> S["Supervisor: decompose, delegate, merge"]
  S -->|"subtask + budget slice"| W1["Research worker (read-only tools)"]
  S -->|"subtask + budget slice"| W2["Data worker (scoped SQL)"]
  S -->|"subtask + budget slice"| W3["Writer worker (no tools)"]
  W1 -->|"typed result"| S
  W2 -->|"typed result"| S
  W3 -->|"typed result"| S
  S --> V["Deterministic validation + merge"]
  V --> R["Final answer with source attribution"]
    

Debate topologies — agents critiquing each other before a judge decides — show measurable factuality gains in research settings (Du et al., 2023), but only when critics have independent evidence or genuinely different capabilities. Swarms of homogeneous agents sharing a scratchpad are the least controllable topology: emergent coordination is emergent failure. Default heuristics: a single agent with well-designed tools beats a multi-agent system for most sequential tasks; add agents only for parallelism, specialization with different tool grants, or context isolation (keeping a 200k-token research dump out of the main thread). If the subtasks never run concurrently and share all permissions, you likely want functions, not agents.

Worked example: bounded refund investigation

Consider a support workflow that may inspect an order and draft a refund, but cannot issue it without policy checks and approval above a threshold. A useful graph:

Figure 2 Refund workflow with deterministic policy gate, approval branch, and explicit terminal states
flowchart TD
  A["Intake"] --> B["Validate input"]
  B -->|"missing input"| N["Terminal: needs_user_input"]
  B --> C["Lookup order (read tool)"]
  C -->|"not found"| N
  C --> D["Model proposes refund + rationale"]
  D --> P["Deterministic policy check"]
  P -->|"deny"| F["Terminal: blocked_by_policy"]
  P -->|"low impact"| E["Execute with idempotency key"]
  P -->|"high impact"| H["Human approval"]
  H -->|"approved"| E
  H -->|"rejected"| F
  E --> T["Terminal: completed"]
    
ALLOWED = {
    "validated": {"looked_up", "needs_user_input"},
    "looked_up": {"proposed", "not_found"},
    "proposed": {"policy_denied", "awaiting_approval", "approved"},
    "awaiting_approval": {"approved", "rejected"},
    "approved": {"completed", "dependency_failed"},
}

def transition(state, next_status):
    if next_status not in ALLOWED.get(state["status"], set()):
        raise ValueError("invalid workflow transition")
    return {**state, "status": next_status}

The model may propose an action and rationale, but deterministic code verifies policy and authorization. The approval stores the exact proposed action, resource ID, amount, policy version, and expiry. Execution uses an idempotency key. The system never interprets approval as permission for a later, altered action.

3. Treat tool calls as untrusted requests

Function calling is a protocol round trip: the application describes tools; the model emits a structured request; application code validates and authorizes it; the application executes the operation; and a structured result returns to the model. OpenAI, Anthropic, and Google all document this separation — the model proposes arguments while client-side code performs the function. Never let the model's selection bypass normal service controls. Providers differ in schema subsets, tool-call message formats, and stop reasons; the durable design is a narrow internal tool interface plus versioned provider adapters, tested against malformed arguments, unknown tools, duplicate calls, timeouts, and partial streaming failures.

A strong tool contract

  • Narrow intentget_order_status is safer and easier to select than run_api_request.
  • Constrained schema — enums, bounded lengths/ranges, required fields; reject unknown fields where supported.
  • Trusted identity — derive tenant, actor, and scopes from authenticated context; never accept them as model-controlled arguments.
  • Clear effects — distinguish read, reversible write, irreversible write, and external communication.
  • Idempotency — mutation tools accept or derive a key tied to workflow and semantic operation.
  • Typed result — separate ok, retryable error, permanent error, policy denial, and not-found; keep user-safe and operator detail distinct.
  • Limits — server-enforced timeout, pagination, result-size cap, rate/quota, and redaction.
{
  "name": "prepare_refund",
  "description": "Create a reviewable refund proposal; does not issue funds.",
  "input_schema": {
    "type": "object",
    "properties": {
      "order_id": {"type": "string", "pattern": "^ord_[A-Za-z0-9]+$"},
      "reason": {"type": "string", "maxLength": 500},
      "amount_minor": {"type": "integer", "minimum": 1}
    },
    "required": ["order_id", "reason", "amount_minor"],
    "additionalProperties": false
  }
}

Structured-output support can guarantee or improve schema conformance depending on provider and mode, but schema validity is not semantic validity. A perfectly formed order ID can belong to another tenant; a valid amount can exceed the refundable balance. Revalidate business invariants at execution time. Keep tool descriptions accurate and treat third-party descriptions as untrusted metadata.

Return errors the orchestrator can act on

A timeout, invalid input, expired credential, policy denial, and missing record need different control flow. Avoid returning a prose blob that the model must reinterpret. Use stable error codes, retryability, safe user message, and correlation ID. Do not expose tokens, stack traces, raw database errors, or private tool results to the model unnecessarily.

4. MCP and A2A: standard wiring, not delegated security

Before the Model Context Protocol, every agent framework re-implemented tool integration against every backend — an M×N adapter problem. MCP collapses it to M+N: hosts (the agent application) run one MCP client per connection to an MCP server, speaking JSON-RPC over stdio locally or streamable HTTP remotely. A server exposes three primitives with different control ownership, and the client/server negotiate capabilities at initialization. The practical consequence for platform teams: tool catalogs become independently deployable, versioned, governable artifacts — an internal API can be wrapped once as an MCP server and consumed by every agent runtime in the company, regardless of framework or model vendor.

PrimitiveControlled byWhat it isDesign duty
ToolsModel-invokedExecutable actions with JSON schemasValidation, authorization, idempotency, audit — same as any tool
ResourcesApplication-controlledReadable context (files, records, docs) addressed by URITenancy filtering, redaction, freshness
PromptsUser-invokedParameterized prompt templates the client surfacesVersioning, injection review
Figure 3 MCP architecture: one client per server, servers own downstream credentials
flowchart LR
  subgraph HA["Host application (agent runtime)"]
    M["Model loop"]
    C1["MCP client A"]
    C2["MCP client B"]
  end
  M --> C1
  M --> C2
  C1 -->|"JSON-RPC over stdio"| S1["MCP server: internal order API"]
  C2 -->|"JSON-RPC over streamable HTTP"| S2["MCP server: SaaS connector"]
  S1 -->|"tools, resources, prompts"| C1
  S2 -->|"tools, resources, prompts"| C2
  S1 --> D1["Order service (server-held credentials)"]
  S2 --> D2["Third-party API (scoped OAuth)"]
    

MCP is interoperability, not an authorization shortcut. The specification treats tool execution and arbitrary data access as high-risk and emphasizes consent and control; its authorization spec requires resource-bound OAuth tokens for HTTP transports and forbids token passthrough. An MCP server still needs authentication, per-tool scopes, tenant isolation, input validation, output redaction, rate limits, audit logs, and downstream credentials distinct from inbound credentials. New attack surface comes with the standard: malicious or mutated tool descriptions (a server can change its advertised tools after approval), confused-deputy patterns where a broadly-scoped server acts for a narrowly-authorized user, and supply-chain risk in community servers. Pin server versions, review descriptions like code, and put an MCP gateway with policy enforcement between agents and third-party servers.

A2A: agent-to-agent across trust boundaries

The Agent2Agent protocol (initiated by Google, now under the Linux Foundation) standardizes the layer above MCP: opaque agents delegating to each other across team or vendor boundaries. An agent publishes an Agent Card — capability metadata for discovery — and peers exchange long-running tasks with lifecycle states, messages, and artifacts, with streaming and push-notification support for work that takes hours. The mental model that lands in interviews: MCP connects an agent to its tools; A2A connects an agent to other agents it does not trust with its internal state, memory, or credentials. Reach for A2A when delegation crosses an organizational boundary where sharing tool credentials is impossible; inside one team and process, in-process multi-agent orchestration is simpler, cheaper, and easier to trace.

5. Design for interruption and replay

Multi-step systems fail between steps. A process can crash after an external write but before recording success; a user can approve hours later; a provider can time out after completing a request. Durable execution requires explicit persisted state and replay-safe side effects — not merely "retry three times." The industry has converged on two architectures for this.

Checkpointing versus deterministic replay

Checkpointing (LangGraph's model): the orchestrator persists a snapshot of graph state at every superstep to a checkpointer backed by Postgres or similar. LangGraph's persistence docs describe thread-scoped checkpoints, pending writes, fault recovery, and time-travel debugging; its interrupt mechanism pauses a thread for human input and resumes from saved state — with the explicit caveat that side effects before an interrupt must be idempotent because the node re-runs on resume. Deterministic replay (Temporal's model, shared by Azure Durable Functions): workflow code must be deterministic; every side effect (model call, tool call, timer) runs in an activity whose result is recorded in an event history. After a crash, the engine re-executes the workflow function and feeds back recorded results, reconstructing exact state without re-running effects. Retries, timeouts, heartbeats, and multi-day waits are engine primitives.

DimensionLangGraph checkpointingTemporal replay
Unit of persistenceState snapshot per superstepAppend-only event history
NondeterminismTolerated in nodes; you own idempotencyForbidden in workflow code; isolated in activities
Built forLLM-native graphs, streaming, human interruptsMission-critical, months-long business workflows
Ops burdenYou run the checkpoint store and workersCluster or Temporal Cloud; heavier but battle-tested
Sweet spotAgent loops with minutes-to-days human gatesAgent steps embedded in transactional business processes
Figure 4 Crash between external commit and local record: recovery via checkpoint reload and idempotent replay
sequenceDiagram
  participant O as "Orchestrator"
  participant CP as "Checkpoint store"
  participant T as "Refund tool"
  O->>CP: persist state before execute step
  O->>T: execute refund with idempotency key K1
  T-->>O: committed
  Note over O: crash before success is recorded
  O->>CP: reload thread on restart
  CP-->>O: last checkpoint shows execute pending
  O->>T: replay call with same key K1
  T-->>O: already applied, same result returned
  O->>CP: record success and advance
    

Retry ownership

Place retries at one layer whenever possible. SDK, HTTP client, orchestrator, queue, and tool service each retrying can multiply calls. Retry only transient failures, with exponential backoff, jitter, a deadline, and a total attempt budget. Respect provider retry hints. Do not retry policy denials or deterministic validation failures. If a request has ambiguous outcome, reconcile using an operation key or read-before-retry.

FailureResponseWhy
Rate limit with retry hintBounded delayed retry or alternate capacityLikely transient; avoid synchronized retry storm.
Malformed model argumentsReturn validation detail; one bounded repair attemptRepeated sampling can loop without new information.
Policy denialTerminal denial or human policy pathTechnical retries must not override governance.
Mutation timed outQuery by idempotency key before retryThe remote side may have committed.
Dependency outageCheckpoint, degrade or pause, show recoverable statusPreserves user trust and avoids runaway cost.

Termination is a product feature

Enforce maximum wall time, model calls, tool calls, repeated identical calls, replans, tokens, and monetary budget. Detect no-progress cycles using normalized action/result fingerprints. On exhaustion, preserve a partial result and missing requirements where safe. A hard "something went wrong" after ten hidden retries wastes both evidence and trust.

6. Separate context, state, and memory

Conversation history is not a database, and a vector store is not automatically memory. Use three distinct concepts:

  • Working context: bounded messages, evidence, tool results, and instructions needed for the current model call.
  • Workflow state: authoritative typed fields required to resume and enforce transitions.
  • Long-term memory: intentionally retained facts or summaries available across sessions, with provenance, consent, correction, and deletion.

Episodic and semantic memory, and the compaction pipeline

Long-term memory splits along the same lines as human memory research. Episodic memory records what happened: specific interactions, decisions, and outcomes, time-stamped and immutable ("user rejected the summary format on 2026-07-12"). Semantic memory stores distilled facts and preferences ("user prefers bullet summaries; account tier is enterprise"), each carrying provenance back to its episodic sources and a confidence level. A background consolidation job — run at session end or on a schedule, not inline on the hot path — extracts candidate facts from episodes, deduplicates against existing memory, resolves conflicts by recency and evidence, and expires stale entries. This is the same design implemented by managed offerings: Bedrock AgentCore Memory's short-term/long-term strategies and Vertex AI Agent Engine's Memory Bank both separate raw session events from extracted durable facts.

Keep raw authoritative values in workflow state; format them into prompts at call time. Summaries are lossy and should carry source references and versions. Treat retrieved memory as untrusted context: it can be stale, incorrectly attributed, or deliberately poisoned by earlier injected content. Enforce tenant/user boundaries before retrieval, never after. Do not silently promote a model inference into a user fact, and do not store secrets or sensitive tool results merely because they might help a later response.

Manage the context window as a budget

Reserve space for system/tool schemas, current request, evidence, and output. Drop irrelevant history; compact older turns into summaries that explicitly preserve unresolved commitments, pending constraints, and open questions — the three things naive summarization loses first. Retrieve only task-relevant memory and cap tool outputs. Compaction failures are silent, so evaluate long-running conversations and resume cases specifically. Cache stable prefixes only when provider semantics, privacy, and version invalidation are understood (Chapter 2 covers the serving mechanics; Chapter 3 covers context engineering in depth).

7. Put authority outside the model

Prompt injection is a control-flow attack: untrusted content attempts to redefine instructions or induce tool use. Label and delimit external content, but do not depend on prompting alone. Authorization must be enforced by trusted code at the tool boundary. Give each workflow an explicit capability set and derive scopes from the authenticated actor, tenant, environment, and approved purpose.

Action classDefault controlExample
Read, low sensitivityScoped authorization + loggingRead public product documentation
Read, sensitiveLeast privilege + purpose/tenant check + redactionRetrieve a customer record
Reversible writePreview + idempotency + bounded auto-execution policyCreate a draft ticket
Irreversible/high impactExact human approval + separation + auditIssue funds or delete production data
External communicationRecipient/content preview + approval or explicit policySend email to a customer

Human-in-the-loop approval as a state machine

Request approval for the exact action, not a vague plan. Show target, effect, sensitive fields, cost/amount, environment, and why the action is requested. Bind the approval to a content hash of the arguments, a policy version, the approving actor, and an expiry; invalidate it whenever material arguments change. Separate proposer from executor where risk warrants. Design the reviewer experience deliberately: batch low-risk approvals to avoid alert fatigue, surface diffs rather than raw payloads, and make rejection a first-class state that carries feedback back into the workflow rather than a dead end.

Figure 5 Approval lifecycle: bound to exact arguments, expiring, invalidated on change
stateDiagram-v2
  [*] --> Proposed
  Proposed --> AutoExecute: within auto policy
  Proposed --> AwaitingApproval: high impact action
  AwaitingApproval --> Approved: reviewer approves exact args
  AwaitingApproval --> Rejected: reviewer rejects with reason
  AwaitingApproval --> Expired: approval TTL elapsed
  Approved --> Invalidated: arguments changed
  Invalidated --> Proposed
  Approved --> Executed: idempotent execution
  AutoExecute --> Executed
  Executed --> [*]
  Rejected --> [*]
  Expired --> [*]
    

Sandboxing code-executing agents

Any agent that runs generated code, shells, or browsers needs an execution boundary stronger than a prompt. The standard stack, from inside out:

  • Isolation — run generated code in a microVM or gVisor-class sandbox per session, never in the orchestrator process; managed runtimes (AgentCore Runtime, Agent Engine code execution) provide session-isolated sandboxes for exactly this reason.
  • Egress control — default-deny outbound network; allowlist specific domains. Data exfiltration via an innocent-looking HTTP call is the primary injection payoff.
  • No ambient credentials — the sandbox holds no long-lived secrets; tools broker scoped, short-lived tokens server-side.
  • Resource caps — CPU, memory, disk, wall time, and process count limits; a runaway loop is a denial-of-wallet.
  • Audit — record commands, file mutations, and network attempts; sample into security review.

8. Computer-use and browser agents: the integration of last resort

Computer-use agents perceive a screen (screenshots, sometimes accessibility trees or DOM) and act through clicks, keystrokes, and scrolls; browser agents are the web-scoped variant, often driving Playwright against the DOM instead of pixels. They matter because the long tail of enterprise work lives in UIs without APIs — legacy ERP screens, partner portals, internal admin consoles. They are also the least reliable agent class in production: every step is a vision-model round trip (seconds of latency, real token cost), and errors compound across the 20–50 steps a nontrivial task takes. On OS-level benchmarks like OSWorld and realistic web benchmarks like WebArena, even frontier agents remain far below human success rates — improving fast, but not a reliability profile you build unattended irreversible actions on.

Figure 6 Guarded computer-use loop: validator and sandbox between model and environment
flowchart LR
  G["Goal + constraints"] --> M["Model plans next UI action"]
  M --> V["Action validator (domain allowlist, action policy)"]
  V -->|"allowed"| B["Sandboxed browser or VM"]
  V -->|"blocked"| HIL["Escalate to human"]
  B -->|"sensitive step (login, payment)"| HIL
  B --> SS["Screenshot + DOM observation"]
  SS --> M
  HIL -->|"human completes or approves"| B
    

Production guardrails follow directly from the threat model. The rendered page is untrusted input, so a webpage can inject instructions into the agent — treat every observation as adversarial. Run the browser in a disposable, sandboxed profile with a domain allowlist and default-deny egress. Never give the model raw credentials: inject secrets at a trusted proxy or have a human complete login steps, so screenshots and traces never contain passwords. Gate payments, sends, deletes, and permission changes on human confirmation. Record the full action/screenshot trace for audit and replay. And check the decision order: if an API or MCP server exists for the target system, use it — UI automation costs roughly an order of magnitude more per task in latency and tokens and breaks on every front-end redesign. Anthropic's tool-use documentation ships computer use with equivalent cautions.

9. Managed agent platforms: AWS and GCP versus building it yourself

Everything in sections 4–8 — durable sessions, tool gateways, memory infrastructure, identity propagation, sandboxes, observability — is undifferentiated heavy lifting that both clouds now sell. On AWS, Bedrock Agents is the opinionated managed orchestrator (instructions, action groups from OpenAPI/Lambda, knowledge bases, return-of-control for client-side execution), while Bedrock AgentCore is the framework-agnostic platform layer: Runtime (serverless sessions with microVM isolation, long-running executions), Gateway (turns existing APIs and Lambda functions into MCP tools), Memory (short/long-term with extraction strategies), Identity (OAuth token vault so agents act on behalf of users), plus managed Code Interpreter and Browser tools — running any framework and any model. On GCP, Vertex AI Agent Builder is the umbrella: the open-source Agent Development Kit (ADK) for code-first multi-agent development with built-in evaluation, and Agent Engine as the managed runtime with sessions, Memory Bank, sandboxed code execution, and native A2A support — deployable from ADK, LangGraph, or LangChain.

AWS

  • Bedrock Agentsmanaged orchestrator: action groups, KBs, return-of-control
  • AgentCore Runtimeserverless sessions, microVM isolation, long executions
  • AgentCore Gatewayexisting APIs/Lambda exposed as MCP tools
  • AgentCore Memoryshort-term events + long-term extraction strategies
  • AgentCore IdentityOAuth token vault, delegated user authority
  • Step Functionsdeterministic workflow backbone around agent steps

Google Cloud

  • Vertex AI Agent Builderumbrella console + governance for agents
  • Agent Development Kitopen-source code-first framework, multi-agent, evals
  • Vertex AI Agent Enginemanaged runtime: sessions, Memory Bank, sandboxes
  • A2A supportagent-to-agent interop, Agent Cards
  • Workflows / Cloud Rundeterministic backbone or self-hosted runtime

Fully managed orchestrator

Bedrock Agents or Agent Builder console agents. Fastest to demo; least control over the loop, prompt assembly, and failure semantics. Fits standard tool-plus-RAG assistants owned by small teams.

Your framework on managed runtime

LangGraph or ADK deployed to AgentCore Runtime / Agent Engine. You own graph logic and contracts; the cloud owns session isolation, scaling, identity, memory. The current default for serious teams.

Fully self-built

LangGraph plus your own Postgres checkpointer, sandboxes, and gateway on ECS/Cloud Run. Maximum control and portability; you staff the undifferentiated infrastructure and its security reviews.

The trade-off conversation interviewers want: managed platforms buy you session isolation, identity, and memory infrastructure you would otherwise build badly under deadline, at the price of a thicker lock-in surface (memory schemas, identity flows, and gateway configs are harder to port than model APIs) and less visibility when the loop misbehaves. Self-built LangGraph maximizes control and portability but makes you the security and reliability owner for sandboxes, token handling, and checkpoint storage. The middle path — your graph, their runtime — is winning because it splits the lock-in: your orchestration logic stays portable code while the cloud absorbs the parts auditors ask about.

10. Operate the agent as a distributed system

One user request may span router, model, retriever, several tools, approval wait, and final synthesis. Give it a trace ID and create spans for each meaningful step. Capture workflow/step name, model and prompt version, tool name, attempt, status, latency, token usage, cache outcome, budget remaining, and safe error category. Do not record raw prompts or tool payloads by default; OpenTelemetry's GenAI semantic conventions warn that message content can contain sensitive information. Chapter 11 covers the full LLMOps stack; here, own the agent-specific signals.

Trajectoryevaluate the path, not just the final answer
p95 stepstool calls per task — the cost and latency driver (example metric)
0tolerated unauthorized tool attempts in the test suite
1 ownerexactly one layer owns retries

Observe outcomes and trajectories

End-to-end task success alone hides inefficient or unsafe routes. Measure correct tool selection, argument validity, authorization denials, unnecessary calls, repeated calls, plan changes, step success, approval rate/time, recovery success, and terminal-state distribution. Pair quality with latency and cost. Sample failed, expensive, long, denied, and novel traces into evaluation datasets (Chapter 6 covers trajectory evaluation methodology).

Use hierarchical budgets

Start with an end-to-end deadline and cost ceiling. Allocate child timeouts per dependency with room for response construction. Enforce model-call, tool-call, parallel-branch, output-token, and retry budgets. Cancel abandoned work when the client disconnects or the outcome becomes terminal. Streaming improves perceived latency but complicates error semantics: distinguish provisional progress from committed result, and never stream a claim of success before a side effect is confirmed.

Degrade by preserving the user's goal

  • If the planner fails, fall back to a fixed supported workflow or ask a targeted question.
  • If a nonessential tool fails, return a partial result with the missing source named.
  • If the primary model is unavailable, use a validated fallback only for routes it passed; fallback must preserve the contract — schema, safety policy, tool permissions.
  • If approval infrastructure is unavailable, pause; do not silently auto-approve or discard the proposal.
  • If a mutating tool has ambiguous outcome, reconcile before telling the user to retry.

Interview playbook

Use AGENTS to structure a design answer:

  1. A — Aim and authority: user outcome, risk, actor, tenant, and actions the system may never take.
  2. G — Graph and state: deterministic baseline, model decisions, topology choice, transitions, invariants, terminal states.
  3. E — Execution contracts: narrow tools (in-process or MCP), schemas, validation, idempotency, typed results, deadlines.
  4. N — Non-happy paths: retries, ambiguous writes, dependency failure, no progress, rejection, crash-and-resume semantics.
  5. T — Telemetry and tests: traces, versions, trajectory/outcome evals, injection cases, release gates.
  6. S — Spend and safe rollout: token/tool/time budgets, shadow mode, approvals, canary, fallback; managed versus self-built runtime.

Common traps

  • Calling a prompt chain an "agent" without identifying any runtime decision.
  • Letting model-generated tenant IDs, URLs, SQL, or scopes reach a tool unvalidated.
  • Assuming structured output means business-correct or authorized output.
  • Retrying a timed-out mutation without idempotency or reconciliation.
  • Using conversation history as authoritative workflow state.
  • Proposing a multi-agent swarm where one agent with better tools and context isolation would do.
  • Presenting MCP or A2A as a security mechanism rather than an interoperability layer.
  • Describing human approval without binding it to exact, expiring action arguments.
  • Recommending a computer-use agent for a system that has an API.
  • Tracing sensitive content by default or omitting model/prompt/tool versions.

Question bank

Answer with control boundaries, measurable failure behavior, and the smallest justified architecture.

Q1When should a workflow become an agent?

Strong answer outline

  1. Identify runtime path uncertainty that fixed rules cannot economically cover.
  2. Compare value against added trajectory, safety, cost, and evaluation complexity.
  3. Keep deterministic invariants and propose a bounded agent with terminal states and an exit condition.

Follow-up probes

  • What is the fixed-workflow baseline?
  • What evidence would remove the agent?
Self-check

Pass if agenticity is an earned trade-off; fail if natural-language input alone is treated as justification.

Q2Compare router, planner–executor, and supervisor patterns.

Strong answer outline

  1. Define who selects one route, creates a changing plan, or delegates among specialists.
  2. Map each to misrouting, stale plans, or opaque/expensive delegation.
  3. Give a concrete workload and a simpler baseline for each.

Follow-up probes

  • When may branches run in parallel?
  • How do you evaluate the supervisor itself?
Self-check

Pass if control flow and failure modes differ clearly; fail if patterns are only framework class names.

Q3How do you prevent an agent from looping forever?

Strong answer outline

  1. Define terminal states and progress invariants.
  2. Cap wall time, calls, tokens, replans, repeated action/result fingerprints, and cost.
  3. Checkpoint and return a safe partial outcome or targeted question on exhaustion.

Follow-up probes

  • What counts as progress?
  • Can the user resume after budget exhaustion?
Self-check

Pass if both static budgets and dynamic no-progress detection appear; fail if only "max iterations" is named.

Q4What makes a good tool schema?

Strong answer outline

  1. Narrow intent, discriminating description, constrained fields, and no model-supplied identity.
  2. Separate proposal/read/mutation tools and declare effects.
  3. Server-side business validation, authorization, limits, idempotency, and typed errors.

Follow-up probes

  • How do you evolve a schema without breaking traces?
  • What if arguments validate but are semantically wrong?
Self-check

Pass if syntax, semantics, and authority are distinct; fail if JSON Schema is treated as the whole boundary.

Q5A payment tool times out. Should the agent retry?

Strong answer outline

  1. Classify the outcome as ambiguous, not failed.
  2. Query or reconcile by stable idempotency/operation key.
  3. Retry only if the remote contract is idempotent; otherwise pause/escalate and never claim completion.

Follow-up probes

  • Where is the operation key generated and stored?
  • What if status lookup is also unavailable?
Self-check

Pass if duplicate side effects are explicitly prevented; fail if backoff alone is proposed.

Q6Compare LangGraph checkpointing with Temporal-style durable execution for agents.

Strong answer outline

  1. Explain checkpointing: state snapshots per superstep, thread-scoped resume, interrupts — with you owning node idempotency.
  2. Explain deterministic replay: event history, side effects isolated in activities, engine-owned retries/timers.
  3. Pick by workload: LLM-native loops with human gates versus agent steps inside long transactional business processes; note managed runtimes internalize session persistence.

Follow-up probes

  • Why must side effects before a LangGraph interrupt be idempotent?
  • Why can't a model call live in Temporal workflow code?
Self-check

Pass if replay semantics and nondeterminism constraints are concrete; fail if "both persist state" is the depth.

Q7How should human approval work for a high-impact tool?

Strong answer outline

  1. Present exact target, arguments, effect, rationale, and policy evidence.
  2. Bind decision to actor, argument hash, policy version, expiry, and one operation; invalidate on change.
  3. Design the reviewer workflow: batching, diffs, rejection with feedback, audit, and safe resume.

Follow-up probes

  • How do you prevent approval fatigue?
  • What happens during an approval-service outage?
Self-check

Pass if approval cannot be reused for an altered action; fail if "human in the loop" is a generic UI step.

Q8How do you defend against prompt injection in retrieved or browsed content?

Strong answer outline

  1. Treat content as data; preserve instruction hierarchy but assume the model will sometimes comply with injections.
  2. Contain via capability allowlists, server-side identity/scope, egress control, and approval on consequence.
  3. Add injection test cases to CI, trace denials safely, and review memory writes for poisoning.

Follow-up probes

  • Can a classifier solve injection?
  • How does injected content exfiltrate data through tool output or URLs?
Self-check

Pass if containment survives a model mistake; fail if prompt wording is the only defense.

Q9Distinguish working context, workflow state, and long-term memory. How would you build agent memory?

Strong answer outline

  1. State is authoritative typed data for transitions/resumption; context is per-call and bounded; memory is intentionally retained across sessions.
  2. Split memory into episodic events and semantic facts with provenance and confidence; consolidate in the background, not on the hot path.
  3. Cover tenant-scoped retrieval, conflict resolution, staleness, deletion propagation, and poisoning defenses.

Follow-up probes

  • Can a summary ever be authoritative?
  • When does compaction lose a pending commitment, and how do you test for it?
Self-check

Pass if the three stores have different contracts and memory has a write policy; fail if every prior message is called memory.

Q10When is a multi-agent system justified, and which topology would you pick?

Strong answer outline

  1. Require parallelism, specialization with different tool grants, permission separation, or context isolation — otherwise one agent with tools.
  2. Map topologies: supervisor/worker for decompose-and-merge, pipeline for staged contracts, debate only with independent evidence, swarm rarely.
  3. Budget inter-agent calls; evaluate contribution by ablation; name coordination failures (duplication, handoff loss) as the new defect class.

Follow-up probes

  • How does token cost scale with worker count?
  • How do you stop agreement theater in debate?
Self-check

Pass if agents add measurable value beyond personas and a "when not" is stated; fail if complexity is the objective.

Q11What does MCP standardize, and what does it deliberately not solve?

Strong answer outline

  1. Describe host/client/server roles, JSON-RPC transports, and the tools/resources/prompts primitives with capability negotiation.
  2. Explain the M×N to M+N integration collapse and governable, framework-independent tool catalogs.
  3. State what remains yours: authorization, tenancy, validation, redaction, audit; cite resource-bound tokens and the token-passthrough prohibition; name tool-description mutation and confused-deputy risks.

Follow-up probes

  • When is a direct in-process function simpler than an MCP server?
  • How do you govern third-party MCP servers?
Self-check

Pass if interoperability is separated from security policy; fail if MCP is called a secure tool bus by default.

Q12How does A2A differ from MCP, and when do you actually need it?

Strong answer outline

  1. MCP is agent-to-tool; A2A is agent-to-agent across trust boundaries with opaque internals.
  2. Describe Agent Cards for discovery and task lifecycle with streaming/push for long-running work.
  3. Justify A2A only for cross-org/cross-vendor delegation where credential sharing is impossible; prefer in-process orchestration within one team.

Follow-up probes

  • How do you authenticate and rate-limit a peer agent?
  • What do you log when the remote agent is a black box?
Self-check

Pass if the trust-boundary framing is explicit; fail if A2A is proposed for two agents in the same process.

Q13Design a browser/computer-use agent for a legacy portal without an API.

Strong answer outline

  1. Confirm no API/MCP path exists; frame UI automation as the integration of last resort with compounding per-step error and cost.
  2. Architecture: sandboxed browser profile, domain allowlist, default-deny egress, credential injection at a proxy, action validator, human gates on login/payment/destructive steps.
  3. Operations: full action/screenshot audit trail, replayable traces, benchmark-informed reliability expectations, fallback to human completion.

Follow-up probes

  • How does a malicious page attack the agent?
  • What breaks when the portal redesigns its front end?
Self-check

Pass if the page is treated as adversarial input and secrets never reach the model; fail if reliability is assumed.

Q14Bedrock Agents/AgentCore versus Vertex AI Agent Engine/ADK versus self-built LangGraph — how do you choose?

Strong answer outline

  1. Decompose the platform problem: runtime isolation, tool gateway, memory, identity, observability.
  2. Map offerings: Bedrock Agents / console agents as managed orchestrators; AgentCore and Agent Engine as framework-agnostic runtimes; self-built as maximum control with owned security burden.
  3. Recommend by team maturity, compliance, and portability: often your graph on their runtime, with lock-in analyzed at the memory/identity layer, not the model layer.

Follow-up probes

  • Where exactly is the lock-in in each option?
  • How would you migrate memory between platforms?
Self-check

Pass if trade-offs are layer-by-layer with a contextual recommendation; fail if it is vendor cheerleading or reflexive build-it-yourself.

Q15How would you sandbox an agent that executes generated code?

Strong answer outline

  1. Isolate per session in a microVM/gVisor-class sandbox, never in the orchestrator process.
  2. Default-deny egress with domain allowlist; no ambient credentials — broker short-lived scoped tokens server-side.
  3. Cap CPU/memory/time/processes, audit commands and network attempts, and destroy the sandbox after the session.

Follow-up probes

  • Why is egress control the highest-value guardrail?
  • What changes when the sandbox needs package installation?
Self-check

Pass if exfiltration and credential theft are the named threats; fail if a Docker container with open network is called a sandbox.

Q16Give your view on the limits of autonomous agents in production today.

Strong answer outline

  1. Acknowledge value in uncertain, reversible information work with human gates on consequence.
  2. Name brittleness: compounding step errors, injection exposure, opaque trajectories, cost variance, and accountability gaps; cite computer-use benchmark gaps as evidence.
  3. Advocate bounded autonomy: deterministic invariants, approval by consequence class, trajectory evals, durable execution, and gradual rollout.

Follow-up probes

  • Which measurable capability change would expand your autonomy budget?
  • Where would you deploy full autonomy today?
Self-check

Pass if the position is nuanced and operational; fail if it is categorical hype or dismissal.

Proof artifact: a resumable, approval-bound agent

Build a support workflow against a fake order service. It may read an order, retrieve a policy, propose a refund, and — only after deterministic policy checks — execute a low-value simulated refund or request human approval. Expose the read tools through a small MCP server to demonstrate protocol fluency. Use synthetic data and fake funds. The artifact demonstrates controls, not production outcomes.

Steps

  1. Authority firstWrite the authority matrix and terminal states; mark transitions as deterministic, model-selected, or human-controlled.
  2. ContractsImplement typed state and narrow read/proposal/execution tools; serve reads via MCP; inject actor and tenant server-side; add idempotency keys to execution.
  3. DurabilityPersist LangGraph checkpoints, version prompt/model/tool schemas, and support resume after process kill — including an approval interrupt held overnight.
  4. TelemetryAdd end-to-end traces with safe metadata: per-step timing/tokens, attempts, budget, approval, and terminal reason.
  5. EvaluationBuild a scenario set for route choice, argument accuracy, policy result, trajectory length, injection resistance, and recovery.
  6. Rollout drillRun shadow mode over synthetic scenarios, then enable only the reversible fake action behind a feature flag.

Metrics

  • Task completion and correct terminal-state rate by scenario.
  • Tool selection precision/recall, argument validity, and business-invariant pass rate.
  • Unauthorized action attempts and cross-tenant disclosures — both must be zero in the test suite.
  • Median/p95 model calls, tool calls, tokens, wall time, and example cost per terminal state.
  • Duplicate side effects after crash-and-replay — must be zero with idempotent fake execution.
  • Checkpoint recovery and user-visible safe-degradation success rate.

Deliberate failure injection

Crash after the fake refund service commits but before the workflow records success; resume and prove no duplicate. Time out policy retrieval; exhaust the model-call budget; change a proposal after approval and verify approval invalidation; return malicious instructions inside a policy document served over MCP; submit a model-generated tenant ID; and make the approval service unavailable. Capture trace and terminal behavior for each.

What to present

Present the state diagram, authority matrix, one tool schema, the MCP server manifest, a crash-and-resume trace, an injection-denial trace, evaluation results by slice, and a short argument for which steps were deliberately kept non-agentic — plus what you would delegate to AgentCore or Agent Engine in a production version. Label every metric as a synthetic artifact measurement.

Chapter review

Reliable agent engineering is control engineering around probabilistic decisions. Keep authority in trusted code, express state and termination explicitly, make tools narrow and replay-safe, standardize integration with MCP without outsourcing security to it, persist checkpoints or event histories for resumability, bound every resource, sandbox anything that executes, and evaluate trajectory as well as outcome. Add autonomy — and additional agents — only where runtime uncertainty creates measured value.

Glossary

Agent
A system in which a model chooses part of the action sequence at runtime.
Capability
An explicitly granted operation available to a workflow, distinct from what a model requests.
Checkpoint
A persisted workflow boundary from which execution can be inspected or safely resumed.
Idempotency key
A stable operation identifier that lets a service return the same result without repeating the effect.
Interrupt
A deliberate pause that persists state and awaits external input such as approval.
MCP
Model Context Protocol: standard host/client/server wiring exposing tools, resources, and prompts.
A2A
Agent2Agent protocol for delegating tasks between opaque agents across trust boundaries.
Episodic memory
Time-stamped records of what happened in past sessions; the raw input to consolidation.
Semantic memory
Distilled durable facts with provenance and confidence, extracted from episodes.
Durable execution
Running workflows so crashes resume from persisted state or replayed event history, not from scratch.
Trajectory
The ordered sequence of model decisions, tool calls, observations, and transitions.
Sandbox
An isolated execution environment with egress control, no ambient credentials, and resource caps.

Mastery checklist

  • I can justify every model-selected step against a deterministic baseline.
  • I can draw states, guarded transitions, terminal outcomes, and recovery paths.
  • I can pick a multi-agent topology — or reject multi-agent — from parallelism, permissions, and context isolation.
  • I can design a tool whose schema, authority, effect, and errors are explicit, in-process or over MCP.
  • I can explain MCP primitives and A2A's trust-boundary role without outsourcing security to either.
  • I can contrast checkpointing and deterministic replay, and state their idempotency obligations.
  • I can design episodic/semantic memory with consolidation, provenance, and deletion.
  • I can bind human approval to one exact, expiring action and design the reviewer workflow.
  • I can sandbox code-executing and browser agents against exfiltration and credential theft.
  • I can compare AgentCore, Agent Engine/ADK, and self-built LangGraph layer by layer.
Search all 16 chaptersResults include concepts, diagrams, trade-offs, and interview questions.