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.
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.
| Pattern | Use when | Primary risk | Control |
|---|---|---|---|
| Router | One request maps to one specialist path | Misrouting or category drift | Confidence threshold, fallback, labeled confusion matrix |
| State machine | Allowed transitions and recovery must be explicit | State explosion | Small typed state, invariants, terminal states |
| Planner–executor | Task path depends on intermediate evidence | Stale or impossible plans | Plan validation, step cap, replan trigger |
| Supervisor/worker | Several specialist capabilities must be coordinated | Extra calls and opaque delegation | Narrow roles, shared outcome schema, central budget |
| Pipeline | Stages have distinct contracts and can be validated between steps | Error propagation without repair | Inter-stage schemas, gate checks, bounded repair loops |
| Parallel fan-out / swarm | Independent evidence can be gathered concurrently | Duplicate work and merge conflict | Branch budget, dedupe, deterministic aggregation |
| Multi-agent debate | Distinct perspectives have measurable value | Expensive agreement theater | Independent 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.
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:
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 intent —
get_order_statusis safer and easier to select thanrun_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.
| Primitive | Controlled by | What it is | Design duty |
|---|---|---|---|
| Tools | Model-invoked | Executable actions with JSON schemas | Validation, authorization, idempotency, audit — same as any tool |
| Resources | Application-controlled | Readable context (files, records, docs) addressed by URI | Tenancy filtering, redaction, freshness |
| Prompts | User-invoked | Parameterized prompt templates the client surfaces | Versioning, injection review |
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.
| Dimension | LangGraph checkpointing | Temporal replay |
|---|---|---|
| Unit of persistence | State snapshot per superstep | Append-only event history |
| Nondeterminism | Tolerated in nodes; you own idempotency | Forbidden in workflow code; isolated in activities |
| Built for | LLM-native graphs, streaming, human interrupts | Mission-critical, months-long business workflows |
| Ops burden | You run the checkpoint store and workers | Cluster or Temporal Cloud; heavier but battle-tested |
| Sweet spot | Agent loops with minutes-to-days human gates | Agent steps embedded in transactional business processes |
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.
| Failure | Response | Why |
|---|---|---|
| Rate limit with retry hint | Bounded delayed retry or alternate capacity | Likely transient; avoid synchronized retry storm. |
| Malformed model arguments | Return validation detail; one bounded repair attempt | Repeated sampling can loop without new information. |
| Policy denial | Terminal denial or human policy path | Technical retries must not override governance. |
| Mutation timed out | Query by idempotency key before retry | The remote side may have committed. |
| Dependency outage | Checkpoint, degrade or pause, show recoverable status | Preserves 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 class | Default control | Example |
|---|---|---|
| Read, low sensitivity | Scoped authorization + logging | Read public product documentation |
| Read, sensitive | Least privilege + purpose/tenant check + redaction | Retrieve a customer record |
| Reversible write | Preview + idempotency + bounded auto-execution policy | Create a draft ticket |
| Irreversible/high impact | Exact human approval + separation + audit | Issue funds or delete production data |
| External communication | Recipient/content preview + approval or explicit policy | Send 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.
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.
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.
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:
- A — Aim and authority: user outcome, risk, actor, tenant, and actions the system may never take.
- G — Graph and state: deterministic baseline, model decisions, topology choice, transitions, invariants, terminal states.
- E — Execution contracts: narrow tools (in-process or MCP), schemas, validation, idempotency, typed results, deadlines.
- N — Non-happy paths: retries, ambiguous writes, dependency failure, no progress, rejection, crash-and-resume semantics.
- T — Telemetry and tests: traces, versions, trajectory/outcome evals, injection cases, release gates.
- 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
- Identify runtime path uncertainty that fixed rules cannot economically cover.
- Compare value against added trajectory, safety, cost, and evaluation complexity.
- 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?
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
- Define who selects one route, creates a changing plan, or delegates among specialists.
- Map each to misrouting, stale plans, or opaque/expensive delegation.
- 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?
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
- Define terminal states and progress invariants.
- Cap wall time, calls, tokens, replans, repeated action/result fingerprints, and cost.
- 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?
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
- Narrow intent, discriminating description, constrained fields, and no model-supplied identity.
- Separate proposal/read/mutation tools and declare effects.
- 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?
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
- Classify the outcome as ambiguous, not failed.
- Query or reconcile by stable idempotency/operation key.
- 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?
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
- Explain checkpointing: state snapshots per superstep, thread-scoped resume, interrupts — with you owning node idempotency.
- Explain deterministic replay: event history, side effects isolated in activities, engine-owned retries/timers.
- 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?
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
- Present exact target, arguments, effect, rationale, and policy evidence.
- Bind decision to actor, argument hash, policy version, expiry, and one operation; invalidate on change.
- 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?
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
- Treat content as data; preserve instruction hierarchy but assume the model will sometimes comply with injections.
- Contain via capability allowlists, server-side identity/scope, egress control, and approval on consequence.
- 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?
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
- State is authoritative typed data for transitions/resumption; context is per-call and bounded; memory is intentionally retained across sessions.
- Split memory into episodic events and semantic facts with provenance and confidence; consolidate in the background, not on the hot path.
- 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?
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
- Require parallelism, specialization with different tool grants, permission separation, or context isolation — otherwise one agent with tools.
- Map topologies: supervisor/worker for decompose-and-merge, pipeline for staged contracts, debate only with independent evidence, swarm rarely.
- 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?
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
- Describe host/client/server roles, JSON-RPC transports, and the tools/resources/prompts primitives with capability negotiation.
- Explain the M×N to M+N integration collapse and governable, framework-independent tool catalogs.
- 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?
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
- MCP is agent-to-tool; A2A is agent-to-agent across trust boundaries with opaque internals.
- Describe Agent Cards for discovery and task lifecycle with streaming/push for long-running work.
- 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?
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
- Confirm no API/MCP path exists; frame UI automation as the integration of last resort with compounding per-step error and cost.
- Architecture: sandboxed browser profile, domain allowlist, default-deny egress, credential injection at a proxy, action validator, human gates on login/payment/destructive steps.
- 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?
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
- Decompose the platform problem: runtime isolation, tool gateway, memory, identity, observability.
- 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.
- 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?
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
- Isolate per session in a microVM/gVisor-class sandbox, never in the orchestrator process.
- Default-deny egress with domain allowlist; no ambient credentials — broker short-lived scoped tokens server-side.
- 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?
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
- Acknowledge value in uncertain, reversible information work with human gates on consequence.
- Name brittleness: compounding step errors, injection exposure, opaque trajectories, cost variance, and accountability gaps; cite computer-use benchmark gaps as evidence.
- 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?
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
- Authority firstWrite the authority matrix and terminal states; mark transitions as deterministic, model-selected, or human-controlled.
- ContractsImplement typed state and narrow read/proposal/execution tools; serve reads via MCP; inject actor and tenant server-side; add idempotency keys to execution.
- DurabilityPersist LangGraph checkpoints, version prompt/model/tool schemas, and support resume after process kill — including an approval interrupt held overnight.
- TelemetryAdd end-to-end traces with safe metadata: per-step timing/tokens, attempts, budget, approval, and terminal reason.
- EvaluationBuild a scenario set for route choice, argument accuracy, policy result, trajectory length, injection resistance, and recovery.
- 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.
Primary sources
Links checked . Provider APIs and protocol revisions change; pin versions and re-check deployed semantics.
- Model Context Protocol — specification and safety principles
- Model Context Protocol — authorization and resource-bound tokens
- A2A — Agent2Agent protocol specification and Agent Cards
- LangGraph — checkpoints, threads, pending writes, and recovery
- LangGraph — interrupts and human-in-the-loop resumption
- Temporal — durable execution, workflows, and activities
- AWS — Amazon Bedrock Agents user guide
- AWS — Amazon Bedrock AgentCore (Runtime, Gateway, Memory, Identity)
- Google Cloud — Vertex AI Agent Builder
- Google Cloud — Vertex AI Agent Engine overview
- Google — Agent Development Kit documentation
- Anthropic — Building effective agents
- Anthropic — tool-use execution boundary and computer use
- OpenAI — function calling lifecycle and tool definitions
- OpenTelemetry — semantic conventions, including GenAI instrumentation
- Du et al. — Improving Factuality and Reasoning through Multiagent Debate (arXiv)
- OSWorld — benchmarking computer-use agents in real environments (arXiv)
- WebArena — a realistic web environment for autonomous agents (arXiv)