AIP-C01 Agentic AI: Multi-Agent Systems, Safeguards, Human Review and MCP Tools
Agentic AI on AWS means building systems in which a foundation model plans, calls tools and works with other agents to complete a task, with memory, safeguards and human checkpoints around it. Task 2.1 of AIP-C01 covers the developer's side of that: managing agent memory and context with Strands Agents and Amazon Bedrock AgentCore Memory, choosing multi-agent patterns, implementing ReAct and chain-of-thought steps in AWS Step Functions, bounding agents with stopping conditions, timeouts, IAM and circuit breakers, coordinating several models, adding human review and feedback, and integrating tools through function definitions, Strands hooks and MCP servers hosted on AWS Lambda, Amazon ECS or AgentCore Gateway.
On this page10 sections
- Agent memory and state: session managers, conversation managers and AgentCore Memory
- Keeping long agent sessions inside the context window
- Multi-agent patterns: agents as tools, swarm, graph, workflow and AWS Agent Squad
- Structured reasoning: ReAct loops and chain-of-thought decomposition with Step Functions
- Stopping conditions, timeouts and circuit breakers
- IAM resource boundaries for agents and tools
- Model coordination: specialised models, selection frameworks and ensembles
- Human review, approval and feedback
- Tool integrations: standard definitions, validation, toolChoice and Strands hooks
- MCP servers and clients: Lambda, Amazon ECS, AgentCore Gateway and Strands MCPClient
- Separate agent state persistence (Strands session managers, AgentCore Memory) from context-window management (conversation managers), and scope long-term memory per user with strategies and namespaces.
- Choose between Strands agents as tools, swarm, graph and workflow patterns, and AWS Agent Squad classifier routing, from who must decide the execution path.
- Implement a ReAct loop and chain-of-thought decomposition in Step Functions around the Converse tool-use contract, with an iteration cap that ends in a best-effort answer.
- Bound agent behaviour with swarm limits and repetitive handoff detection, client-side tool timeouts, IAM session tags, permissions boundaries, Lambda resource policies and shared circuit breakers.
- Coordinate models with specialist tools, evaluation-driven subtask-to-model mapping in AppConfig, and ensemble aggregation (majority, weighted, cascade, judge).
- Add human review with .waitForTaskToken callbacks and timeouts, Bedrock agent user confirmation and return of control, and validated feedback collection through API Gateway.
- Define tools precisely, return validation errors as tool results, control toolChoice, customise behaviour with Strands hooks, and host and consume MCP servers on AWS.
Agent memory and state: session managers, conversation managers and AgentCore Memory
An agent's memory has two separate jobs, and AWS tooling gives each its own component. Persistence keeps a conversation's messages and agent state outside the process so the next request can restore them on any host. Context management decides which of those messages are actually sent to the model on each call. Confusing the two is the most common design error in this area: making the context window bigger does not help an agent that lost its state because the next request landed on a different container.
| Component | Job | Where state lives | Use it when |
|---|---|---|---|
| Strands session manager, file-backed (example) | Persist and restore messages and agent state by session ID | Local disk of one host | Single-host development or a workload pinned to one machine |
| Strands session manager, Amazon S3-backed (example) | Persist and restore messages and agent state by session ID | An S3 bucket every host can read | Horizontally scaled agents (ECS tasks, Lambda) with no sticky sessions |
| Strands conversation manager (null, sliding window, summarizing) | Shape the in-memory context sent to the model | In memory only | Long sessions that would overflow the context window |
| AgentCore Memory, short-term | Store each turn as an event (CreateEvent) per actor and session | Managed by AgentCore | Following a conversation within one session |
| AgentCore Memory, long-term | Extract durable records (facts, user preferences, session summaries) from events through configured strategies | Managed by AgentCore, organised in namespaces | Recalling what a user said in earlier sessions without replaying transcripts |
The two session managers above are examples: Strands also offers other session managers, such as one backed by AgentCore Memory, and the persistence-versus-context distinction applies to all of them.
AgentCore Memory: events, strategies and namespaces
Amazon Bedrock AgentCore Memory stores raw conversation turns as short-term events, identified by an actor ID (usually the user) and a session ID. Short-term memory alone is why an agent follows a conversation well inside a session but forgets everything when a new session starts. Long-term memory exists only when the memory resource has at least one strategy: built-in strategies extract semantic facts, user preferences or session summaries from the events, and the agent retrieves those records (for example at session start) instead of loading old transcripts into the prompt. Any design that feeds old raw turns back to the model is transcript replay, not extraction: the prompt keeps growing and the agent still has no distilled facts to retrieve.
Extracted records are written to a namespace, a path template that can include {actorId}, {sessionId} and {memoryStrategyId}. A namespace with no actor component, such as /facts/, pools every user's records, so a retrieval for one user can return another user's facts. Putting {actorId} in the namespace (for example /facts/{actorId}/) and retrieving from the namespace built from the authenticated user's ID keeps long-term memory per user on one shared memory resource. A {sessionId} namespace isolates too narrowly to survive across sessions, and a separate memory resource per user works but is heavy to operate at scale.
Keeping long agent sessions inside the context window
Long sessions are kept inside the context window by choosing the right Strands conversation manager and by keeping each tool result small. By default the conversation manager trims history after each agent cycle (it can also be configured to run before every model call), and it reduces context when a call fails because the context overflowed.
| Conversation manager | What it does with old messages | Cost and trade-off |
|---|---|---|
| Null | Nothing: the full history is always sent | Overflow is guaranteed in a long session |
| Sliding window (the default) | Keeps a fixed number of recent messages and evicts the oldest; can also truncate large tool results in place; can pin the first messages so they are never evicted | No extra model calls, but anything evicted is gone word for word and in meaning |
| Summarizing | Replaces a ratio of the oldest messages with a model-written summary while preserving a minimum number of recent messages verbatim | Early facts survive in condensed form; costs a summarisation call and rewrites the original wording |
Pick by the requirement. If early details must keep shaping answers but may be condensed, use the summarizing manager. If one specific early message (a task specification, or constraints the user stated up front) must stay word for word with no extra model calls, keep the sliding window and pin that first message. The context limit is about what is sent in: settings that govern how long the reply may be do not change it.
The second cause of overflow is the size of each observation. A tool that returns megabytes of raw logs fills the window no matter which manager you use. Fix it at the source: have the tool return a bounded excerpt with counts and a pointer (for example an S3 location) to the full output, so the agent can ask for more if it needs to.
Multi-agent patterns: agents as tools, swarm, graph, workflow and AWS Agent Squad
Choose a multi-agent pattern by asking who decides the path: the model, the developer, or the data within paths the developer has fixed. Strands Agents offers four patterns, and AWS Agent Squad adds routing across existing assistants.
| Pattern | Who decides the path | Fits |
|---|---|---|
| Agents as tools (Strands) | An orchestrator agent's model, which calls specialist agents as tools when it judges one fits | Open-ended requests where a coordinator delegates sub-questions |
| Swarm (Strands) | The agents themselves, handing the task to one another (emergent handoffs over shared context) | Collaborative problem solving where the route cannot be known in advance |
| Graph (Strands) | Developers declare nodes and edges; conditional edges evaluate earlier results so the data picks a branch; cycles are allowed with limits such as a maximum number of node executions | Auditable processes with branches and bounded loops, such as an editing step that may return a draft for rework a limited number of times |
| Workflow (Strands) | Developers, completely: a fixed task graph with explicit dependencies and no cycles; independent tasks run in parallel and each task receives a summary of its dependencies' results | Repeatable pipelines where auditors require the same sequence every run |
| AWS Agent Squad classifier | A classifier that reads each agent's description and the conversation history and routes every turn to the most suitable agent | One entry point over existing, heterogeneous assistants |
AWS Agent Squad (the open-source framework formerly called Multi-Agent Orchestrator) ships agent types for Amazon Bedrock models and agents, Amazon Lex bots and AWS Lambda functions, so existing assistants can be registered rather than rebuilt. It stores conversation history (for example in Amazon DynamoDB) so the classifier sees context, and its SupervisorAgent provides an agents-as-tools style in which a lead agent coordinates a team of sub-agents, in parallel where possible. Keyword routing in a Step Functions Choice state is brittle custom code by comparison, and Amazon Bedrock intelligent prompt routing chooses between models, not agents.
Structured reasoning: ReAct loops and chain-of-thought decomposition with Step Functions
A ReAct (reason, act, observe) loop lets a foundation model solve a problem step by step: the model reasons, asks for a tool, receives the observation and reasons again until it can answer. AWS Step Functions implements the loop explicitly around the Amazon Bedrock Converse API's tool-use contract:
- A Task state calls Converse with a
toolConfiglisting the tools. - A Choice state reads
stopReason. When it istool_use, the response containstoolUseblocks naming the tool and its input. - The workflow runs that tool (for example a Lambda function), appends the assistant message, then adds a user message containing a
toolResultwith the sametoolUseId, and loops back to the model. - Any other stop reason (normally
end_turn) means the model has answered, and the loop ends.
The model decides which tool runs and when; the workflow executes exactly what it asked for, and retry policies stay reserved for failures.
Bounding the loop
A ReAct loop has no built-in end except the model choosing to answer. A Standard workflow that loops for hours eventually fails on its execution history quota and the user gets nothing. The safe design carries an iteration counter in the state and uses a Choice state to route, at the limit, to a final model call without tools, which turns the cap into a best-effort answer. Execution-level timeouts end the run as a failure (a state's Catch cannot catch an execution timeout), so they are a backstop, not a stopping condition.
Chain-of-thought decomposition
When one prompt asks too much and answers skip parts of the question, split the reasoning into explicit steps: a model Task returns a JSON plan of sub-questions, a Map state answers each sub-question (with its own retrieval) concurrently over a list whose length is decided at run time (an inline Map is bounded by the payload quota and a concurrency limit; a Distributed Map handles very large lists), and a final Task synthesises the answers. A Parallel state needs branches fixed at design time, so it suits a known set of sub-tasks, not a plan the model writes. A single prompt that asks the model to think step by step improves reasoning but gives no per-step evidence, concurrency or audit record.
| Standard workflow | Express workflow | |
|---|---|---|
| Maximum duration | Up to one year | Five minutes |
| Callbacks with .waitForTaskToken | Supported | Not supported |
| Execution history | Kept by the service, each state's input and output visible | Only in CloudWatch Logs, if logging is enabled |
| Typical agentic use | Long reasoning chains, human review, auditable steps | High-volume, short, idempotent steps |
Stopping conditions, timeouts and circuit breakers
Safeguarded agent workflows stop runaway behaviour on purpose and fail in a way the model can handle. Each safeguard targets a different failure, so match it to the symptom.
Stopping conditions
- Iteration caps in Step Functions loops (see the ReAct section) end a reasoning chain gracefully.
- Swarm limits in Strands include a maximum number of handoffs and iterations, an overall execution timeout and a per-agent node timeout. These cut off long or slow runs, including legitimate long chains.
- Repetitive handoff detection in a Swarm watches a window of recent handoffs and stops the run when they involve fewer unique agents than a configured minimum. It catches two agents passing a task back and forth (ping-pong) as soon as it starts, without shortening legitimate chains that pass through many different agents.
- Per-request tool budgets with Strands hooks (see the tools section) cap calls to an expensive tool and let the agent answer from what it already has.
Timeouts inside tool Lambda functions
A Lambda function timeout ends the invocation with a generic error, which an agent cannot turn into a useful reply. To give the agent a meaningful result within a deadline, set a client-side timeout on the outbound call (shorter than the function timeout), catch it and return a normal result that says, for example, the pricing service did not respond in time. The function's own timeout stays as a backstop against runaway code; it is never the mechanism that produces a graceful answer.
Circuit breakers
A circuit breaker stops all callers from hammering a failing dependency. It is closed while calls succeed, opens after repeated failures so calls return immediately for a cool-down period, then goes half-open to let a trial call test recovery; success closes it again. Retries with backoff are different: they space out one run's attempts but do not stop concurrent runs from piling on.
- Shared state. Agent tools run as many concurrent executions, so the breaker's failure count and open-until time must live in a shared store such as Amazon DynamoDB. A module-level variable in a Lambda handler exists per execution environment and protects nothing.
- One trial call. When the cool-down ends, let a single execution claim the half-open trial with a DynamoDB conditional write, while the others still see the circuit as open. Otherwise every waiting execution calls the recovering API at once.
- Fail fast, gracefully. While open, return a tool result with an error status that says the service is unavailable. Raising an exception ends the agent run; an error result is information the model can explain to the user.
- Count only health failures. Timeouts, throttling and 5xx errors signal a sick dependency. A 400 caused by a malformed parameter is the model's mistake: return it to the model as an error result so it can correct the call, and do not let it open the circuit for everyone.
IAM resource boundaries for agents and tools
An agent's permissions must hold even when the model is manipulated, so boundaries belong in IAM, not in prompts. Anything the model can influence (its instructions, its inputs or the parameters it writes) is not a security boundary; IAM evaluates credentials the model cannot change.
Tenant isolation with session tags and dynamodb:LeadingKeys
When a tool reads a shared DynamoDB table keyed by tenant, never trust a tenant ID the model passes as a parameter. Have the tool assume a role with a session tag for the tenant taken from the caller's authenticated identity, and restrict the role with a dynamodb:LeadingKeys condition that must equal that principal tag (for example ${aws:PrincipalTag/tenant}). IAM then denies any read of another tenant's partition key, whatever the prompt says.
Permissions boundaries for delegated role creation
To let developers create their own agent tool roles without exceeding an approved set of actions, create a managed policy listing those actions to serve as a permissions boundary, and allow iam:CreateRole (and the policy-attachment actions) only with an iam:PermissionsBoundary condition naming it. A role's effective permissions are the intersection of its policies and its boundary, so an over-broad policy cannot exceed the ceiling. A service control policy caps the whole account (every team), and a session policy is opt-in for whoever assumes the role.
Locking down action group Lambda functions
Amazon Bedrock agents invoke action group Lambda functions as the bedrock.amazonaws.com service principal, authorised by the function's resource-based policy. Add an AWS:SourceArn condition with the specific agent's ARN so only that agent can invoke it; an AWS:SourceAccount condition alone admits every agent in the account. Separately, the function's execution role decides what the function can touch: grant only the read actions on the one table it needs, so a crafted parameter cannot write or reach other resources. The agent's service role controls neither of these.
Model coordination: specialised models, selection frameworks and ensembles
Model coordination means using more than one foundation model so each task gets the model that does it best at the right cost. There are three tools for this: give a missing capability to a specialist model, map subtasks to models from evidence, and combine several models' answers.
Specialised models as tools
When an agent needs a capability its model lacks, such as generating images, expose a model built for it (for example an image generation model on Amazon Bedrock) as a tool. The main model keeps doing what it does well and writes the prompt for the specialist. Each model stays on the work it was built for, rather than one model being stretched to cover a modality it does not have.
Model selection frameworks
A selection framework maps each subtask (classify, extract, draft) to a model chosen by evaluation. Run an evaluation per subtask on that subtask's labelled test set for each candidate, keep the models that clear the quality bar, and choose the cheapest. Store the subtask-to-model mapping in configuration such as AWS AppConfig so a new model can be adopted without redeploying code. The evidence must be per subtask and from your own data, and the mapping must live outside the code so it can change as models change. Amazon Bedrock intelligent prompt routing chooses per request between models in one family and does not validate new models for a subtask (request routing is covered in the FM API integrations lesson).
Ensembles and custom aggregation
| Aggregation | Works for | Notes |
|---|---|---|
| Majority vote | Labels from a fixed set | Invoke models concurrently (Step Functions Parallel state) to keep latency near one call; aggregate in Lambda; send no-majority items to a human |
| Weighted vote | Labels, when models differ in measured accuracy | Weights come from offline evaluation, not from a model's self-reported confidence, which is not calibrated |
| Cascade | Cutting ensemble cost | Call the cheaper models first and call the next model only when they disagree |
| Consensus by similarity | Free text, when agreement is a fair proxy | Picks the candidate most similar to the others; agreement is not correctness |
| Judge model with a rubric | Free text that must meet specific criteria | An evaluator model grades each candidate against the rubric and the source; adds a call |
Running the models one after another adds latency, and a primary model with fallbacks on error is resilience, not an ensemble.
Human review, approval and feedback
Human-in-the-loop AI is orchestrated with Step Functions callbacks: a .waitForTaskToken task hands a task token to the reviewer's system and pauses without polling; the review app calls SendTaskSuccess or SendTaskFailure with that token and the workflow continues immediately. Use a Standard workflow, which can wait for days; Express workflows support neither callbacks nor long waits. A Wait state plus a Lambda status check is polling.
- Route only what needs a person. A Choice state sends low-confidence or high-risk outputs to review and lets the rest flow straight through.
- Reach the reviewers where they work. Integrations such as
sqs:sendMessage.waitForTaskTokenput the item and token on a queue an existing app already reads. - Escalate on timeout. Without
TimeoutSeconds, a callback task can wait until the execution limit. Set it on the review task, CatchStates.Timeoutinto an escalation task (for example the manager) with its own timeout, and Catch that into a rejection state. Escalation is a change of route, so it belongs in Catch, and the timeout belongs on the review task rather than on the whole execution. - Amazon Augmented AI (A2I) is no longer open to new customers, so new designs build review with Step Functions and their own review UI.
Human approval inside Amazon Bedrock Agents
User confirmation is a per-function setting on an action group: when the agent decides to call that function, InvokeAgent asks the application to confirm, and the application returns the user's decision as confirmationState CONFIRM or DENY. Only a confirmation runs the existing Lambda fulfilment, so a sensitive action (such as closing a customer account) cannot be triggered by injected instructions alone, with almost no custom code. Prompt instructions and guardrails do not enforce an approval step.
Return of control (customControl RETURN_CONTROL) hands the action to the application instead of a Lambda function. InvokeAgent returns the action's parameters in invocationInputs with an invocationId; the application performs the work where it has access (for example a call that must use the end user's own credentials) and sends the outcome in the next request's sessionState.returnControlInvocationResults with the same invocationId. Only that field, matched by invocationId, completes the pending action. Return of control also enables confirmation, but moves both the prompt and the action into application code.
Feedback collection with API Gateway
To collect ratings with almost no code, use an Amazon API Gateway REST API: a request validator with a JSON schema model rejects missing fields or out-of-range ratings before the integration runs, and a direct DynamoDB integration (PutItem through a mapping template) writes the item without Lambda. HTTP APIs do not offer request validation, and Amazon Data Firehose has no DynamoDB destination. To record who rated, add an Amazon Cognito user pool authorizer and write the verified sub claim from $context.authorizer.claims in the mapping template, never a user ID the client sends in the body. Only a verified token establishes who the caller is.
Tool integrations: standard definitions, validation, toolChoice and Strands hooks
Models choose and call tools from their specifications, so reliable tool use starts with a precise definition and continues with validation that reports errors back to the model instead of crashing the loop.
Standardised tool definitions
In Strands, a Python function decorated with @tool becomes a tool whose description and per-argument descriptions come from its docstring (with an Args section) and whose types and required arguments come from its type hints. Without them the model guesses names and picks the tool for unrelated questions. In the Converse API, the equivalent is a toolSpec with a name, description and JSON inputSchema. The model sees only what the specification carries, so descriptions and argument documentation belong in the tool definition itself.
Validation and error results
Schemas express types and formats but not business rules such as "the end date must fall after the start date". Validate in the tool (for example the Lambda function) before calling the backend, and on failure return a toolResult with status error and a message explaining the rule. The model reads it like any observation and corrects its next call. Letting the exception escape crashes the loop, and retrying repeats the bad input. (The error status field is supported by Anthropic Claude models; other models can receive the error as text content.)
Controlling tool calls with toolChoice
| toolChoice | Effect |
|---|---|
auto (default) | The model decides whether to reply in text or call a tool |
any | The model must call one of the configured tools, but chooses which |
tool with a name | The model must call exactly that tool, which guarantees structured output from a shared tool list |
any and a named tool are supported by Anthropic Claude and some other models on Bedrock. Temperature changes randomness, not whether a tool is called.
Custom behaviour with Strands hooks
The Strands hooks API lets a hook provider react to agent lifecycle events, which is how you change behaviour around tools you cannot modify (for example tools from a third-party MCP server).
- BeforeToolCallEvent sees the tool name and input. A hook can edit the input or set
cancel_toolto a message: the tool is skipped and the message is returned to the model as the tool's result, so the agent can explain or answer from what it has. Use it for per-call allow-lists (permitted project codes) and budgets. - AfterToolCallEvent exposes the result as writable (and a retry flag). Use it to mask sensitive data, such as email addresses or phone numbers, before the model ever sees the result.
- BeforeInvocationEvent fires at the start of each user request, the right place to reset a per-request counter so a budget such as a fixed number of paid-API calls per request starts again on every request in a session.
Raising an exception from a hook fails the run, and an after-call hook is too late to stop a call that should never have run.
MCP servers and clients: Lambda, Amazon ECS, AgentCore Gateway and Strands MCPClient
The Model Context Protocol (MCP) standardises how agents discover and call tools, so the same tool server works with Strands, LangGraph or any MCP client. On AWS the hosting choice follows the tool's state and duration.
| Hosting | Fits | Limits |
|---|---|---|
| Stateless MCP server in AWS Lambda | Short, lightweight tools that keep nothing between calls; no servers to run | No session state across invocations; 15-minute maximum per invocation |
| MCP server on Amazon ECS (AWS Fargate) | Complex tools that keep per-session state, hold shared resources (connection pools) or run for a long time | A long-running service to operate; session affinity when state lives in a task |
| Amazon Bedrock AgentCore Gateway | Turning existing Lambda functions, OpenAPI-described REST APIs and Smithy models into MCP tools at one endpoint | Managed: inbound OAuth authorisation, outbound credential exchange per target, semantic tool search |
| Local stdio server | Development, or a tool private to one agent host | Starts a separate copy per agent; nothing is shared or centralised |
Amazon Bedrock agent action groups are not MCP tools, and a plain Amazon API Gateway REST API is not an MCP endpoint by itself. API Gateway's MCP proxy support (added in December 2025) turns an existing REST API into an MCP-compatible endpoint, and that feature is built on AgentCore Gateway, so the MCP layer is still AgentCore Gateway.
MCP client libraries for consistent access
The Strands MCPClient wraps an MCP transport and exposes the server's tools to an agent:
- Transport. Use stdio for a server started as a local subprocess, and Streamable HTTP for a remote, shared server (for example on ECS). Tool discovery and calls still go through MCP, so no tool definitions are written by hand.
- Lifecycle. Tools listed inside a
withblock stop working once the block closes (Strands raisesMCPClientInitializationError). Passing theMCPClientobject itself in the agent's tools list lets the agent manage the connection, opening it when it needs the tools and cleaning up afterwards, which suits a long-running service. - Tool filters.
tool_filterstakesallowedandrejectedlists of names or compiled regular expressions. An allow-list (for example names matchingsearch_.*) also hides tools a vendor adds later; a deny-list goes stale with every new tool. Filtering hides a tool from the model, whereas a before-call hook only blocks the call after the model has seen it. - Prefix. A per-client
prefixexposes tools as<prefix>_<tool>, which resolves duplicate tool names when two servers are registered on one agent.
Tip. Task 2.1 questions are long production scenarios about agents and tools in which several requirements are stated at once: who may decide the execution path, a cost or latency limit, a rule that must hold even if the model is manipulated, an account that is new to AWS, or code that may not be changed. Items test whether you can match the requirement to the right mechanism: persistence versus context management, developer-defined versus model-chosen orchestration, graceful stopping versus failure, IAM enforcement, callback-based human review, tool definitions and validation, and MCP hosting and client configuration. Expect multiple-response items that need two complementary changes.
- Persistence and context are different jobs: an S3-backed session manager restores state across hosts; a conversation manager decides what the model sees.
- AgentCore Memory long-term records exist only with a strategy; put {actorId} in the namespace to keep each user's records separate on one resource.
- Summarize when early context may be condensed; pin the first message of a sliding window when it must stay word for word at no extra cost; bound tool results at the source.
- Workflow = fixed pipeline; graph = developer-defined paths chosen by data, with capped loops; swarm and agents-as-tools = model-chosen routes; Agent Squad = classifier routing over existing assistants.
- A ReAct loop continues on stopReason tool_use with a toolResult in a user message; cap iterations with a Choice state that routes to a final call without tools.
- Safeguards match symptoms: repetitive handoff detection for ping-pong, client-side timeouts for hung calls, a shared DynamoDB circuit breaker with one half-open trial for failing dependencies.
- Enforce boundaries in IAM, not prompts: session tags with dynamodb:LeadingKeys, permissions boundaries required by iam:PermissionsBoundary, AWS:SourceArn on action group functions.
- Pick models per subtask from evaluations and keep the mapping in AppConfig; aggregate labels by vote and free text by a rubric judge.
- Human review is a Standard workflow .waitForTaskToken callback with TimeoutSeconds and Catch escalation; A2I is closed to new customers.
- Validate business rules in the tool and return an error toolResult; filter MCP tools with an allow-list and resolve name clashes with prefixes.
Frequently asked questions
What is the difference between a Strands session manager and a conversation manager?
A Strands session manager persists a conversation's messages and agent state to storage (local files or Amazon S3) and restores them by session ID, so a scaled-out agent can continue a conversation on any host. A conversation manager only decides which messages are sent to the model on each call (none removed, a sliding window, or a summary of older messages). Use a session manager for lost state across requests and a conversation manager for context-window overflow.
How does Amazon Bedrock AgentCore Memory remember users across sessions?
AgentCore Memory stores each turn as a short-term event under an actor ID and session ID. Long-term memory is produced only when the memory resource has a strategy, such as semantic facts, user preferences or session summaries, which extracts records from the events into a namespace. Including {actorId} in the namespace keeps each user's records separate, and the agent retrieves them at the start of a new session instead of replaying old transcripts.
When should I use a Strands graph instead of a workflow or a swarm?
Use a Strands graph when developers must define every allowed path in advance but the data should choose a branch at run time, including bounded loops such as a quality check that can return a draft for rework a limited number of times. A Strands workflow is a fixed task graph with no branches or cycles that runs the same sequence every time, and a swarm lets the agents decide the route through handoffs.
How do you implement a ReAct loop with AWS Step Functions and Amazon Bedrock?
A Task state calls the Converse API with a toolConfig, and a Choice state checks stopReason. When it is tool_use, the workflow runs the requested tool, appends the assistant message and a user message containing a toolResult with the same toolUseId, and calls the model again. Any other stop reason ends the loop. An iteration counter checked by the Choice state routes to a final call without tools so the loop always ends with an answer.
How do you stop an agent tool from reading another tenant's data?
Make IAM enforce the tenant, not the model. The tool assumes a role with a tenant session tag taken from the caller's authenticated identity, and the role's DynamoDB permissions carry a dynamodb:LeadingKeys condition that must match that principal tag. Even if a crafted prompt makes the model pass another tenant's ID, IAM denies the read.
How do you add human approval to a generative AI workflow on AWS?
Use an AWS Step Functions Standard workflow with a .waitForTaskToken task that sends a task token to the review app, for example through an Amazon SQS queue. The reviewer's decision is sent back with SendTaskSuccess or SendTaskFailure and the workflow resumes immediately. Set TimeoutSeconds on the task and catch States.Timeout to escalate. Amazon Augmented AI is no longer open to new customers. Inside Amazon Bedrock Agents, user confirmation on an action group function asks the user to confirm or deny before the function runs.
When should an MCP server run on AWS Lambda rather than Amazon ECS?
Run an MCP server on AWS Lambda when its tools are short and stateless, because Lambda keeps no session between invocations and stops after 15 minutes. Run it on Amazon ECS, typically with AWS Fargate, when tools keep per-session state, hold shared resources such as a database connection pool, or run longer. To expose existing Lambda functions and OpenAPI APIs as MCP tools with OAuth and per-target credentials, use Amazon Bedrock AgentCore Gateway.
How do you limit which MCP tools a Strands agent can see?
Set tool_filters on the Strands MCPClient. An allowed list of names or compiled regular expressions exposes only matching tools, which also hides tools the server adds later, while a rejected list blocks named tools but goes stale. If two servers on one agent share tool names, give each MCPClient a different prefix so the tools are exposed as prefix_toolname.
Source
This lesson covers the "Implementation and Integration" domain of the official AIP-C01 exam guide. Vendors revise their guides — check the source for the current version.
- AWS Certified Generative AI Developer – Professional (AIP-C01) exam guide — Amazon Web Services
Sign up free to mark lessons complete, bookmark topics and track your exam readiness.