This article is a machine translation of the contents of the following URL, which I wrote in Japanese:
Introduction
There are many situations where you want to give an AI agent up-to-date web information. Until now, you had to build the pipeline yourself: call a search API, fetch pages, summarize them, and attach sources.
Amazon Bedrock AgentCore offers two managed features for this part.
- Web Search is a tool that returns ranked search results. It was introduced in June 2026
- Web Answer is a tool that returns a finished answer with citations. It became generally available (GA) on November 5, 2026
Both are added as connectors on AgentCore Gateway and called via MCP. AWS describes them as "complementary", but when you actually have to choose, questions like these come up.
- If the only difference is what comes back, can't I do the same things with either one?
- If I want to control which domains are referenced, how far can each tool go?
- Which one can I use in the Tokyo Region? (As of 2026-11-08. Supported Regions may increase.)
This article organizes the specifications from the official documentation in tables, adds the results I confirmed on a real environment, and summarizes criteria for choosing between them.
So that readers who are new to Web Answer can follow along, the first half compares the two in tables, and the second half shows the verification results.
Key differences between Web Search and Web Answer
Here are the key points as a table first. The "Confirmed on a real environment" column shows what I confirmed in us-east-1 on 2026-11-08.
| Criterion | Web Search | Web Answer | Confirmed on a real environment |
|---|---|---|---|
| What it returns | Ranked results (text, url, title, publishedDate) | A synthesized answer with citations | Confirmed (Verification 1). Search has no structuredContent, and publishedDate is in a custom format or unknown. Answer's citation markers map to the order of first appearance after removing duplicates |
| Who composes the answer | The model of your own agent | The Web Answer side | Confirmed (Verification 1). Web Search returned only results (snippets), and Web Answer returned an answer with citations |
| Price (tool side) | $7 / 1,000 queries | $10 / 1,000 invocations | Official documentation (see below) |
| Regions (as of 2026-11-08) | 7 Regions including Tokyo | us-east-1 only (the blog says "more AWS Regions coming soon") | Official documentation |
| Domain control | Two layers: administrator and request (100 entries each) | Two layers: administrator and request (50 entries each) | Confirmed (Verification 3). Both kept to the administrator's boundary, but violations look different (Answer returns an error; Search narrows the results or returns an empty result) |
The choice is almost entirely decided by two questions: "Do you want to handle the results with your own model, or do you want a finished answer?" and "Do you need to keep everything in Tokyo?" For domain control, both could be fixed on the administrator side, but they behave differently when a request goes outside the boundary. Note that Web Search returns an empty result without an error.
Overview
First, here is the architecture as a diagram. The calling agent goes through the Gateway and calls two targets (connectors). The web index is operated by Amazon and sits outside your own account. The answer from Web Answer is written by a model on the Amazon side, and you cannot choose that model. The results from Web Search are turned into an answer by your own model, which you choose on the calling side.
Specification comparison by aspect
| No. | Aspect | Web Search | Web Answer |
|---|---|---|---|
| 1 | What it returns | Ranked results | A synthesized answer with citations |
| 2 | connectorId | web-search |
web-answer |
| 3 | Query length | Up to 200 characters | 1 to 30,000 characters |
| 4 | Result count control |
maxResults 1 to 25 (default 10) |
None |
| 5 | Domain lists | 100 each (request side) | 50 each (100 for exclude after merging) |
| 6 | Date filter | Yes (1.2.0 or later) | Yes (1.1.0 or later) |
| 7 | Location | None | userLocation.country |
| 8 | Regions (as of 2026-11-08) | 7 Regions (including Tokyo) | us-east-1 only |
| 9 | Price | $7 / 1,000 queries | $10 / 1,000 invocations |
| 10 | IAM permission on the service role (independent per tool) | InvokeWebSearch |
InvokeWebAnswer |
Detailed explanation of each aspect
Aspect 1: What each tool returns
AWS positions Web Search as follows.
"Web Search Tool on Amazon Bedrock AgentCore is different — it is backed by a web index that Amazon builds and operates directly."
——Web Search Tool(AgentCore Developer Guide)
Web Answer is described as searching the web, reading pages, and answering with citations.
"searches the web, reads relevant pages to ground its answer, and includes citations."
——Web Answer(AgentCore Developer Guide)
Here is the difference in response format, field by field.
Web Search (content[0].text is a JSON string)
{
"id": "824f89d0",
"results": [
{
"text": "...",
"publishedDate": "2024-10-07",
"url": "...",
"title": "..."
}
]
}
Web Answer (content[0].text is Markdown, and structuredContent holds the list of citations)
{
"isError": false,
"content": [{"type": "text", "text": "... [[1](https://example.com/basel-iii)]..."}],
"structuredContent": {
"answer": [
{
"text": "...",
"citations": [{"domain": "example.com", "url": "https://example.com/basel-iii"}]
}
]
},
"_meta": {"latencyMs": 5210}
}
Both of the above are examples from the official documentation. When I checked on a real environment (us-east-1, 2026-11-08, connectors Search 1.3.0 / Answer 1.1.0), I found the following differences (details in Verification 1).
- Web Search results have no
structuredContent; only the JSON string incontent[0].textis returned - Web Search's
publishedDateis not ISO-8601. It is a string such as05:00PM, Wednesday, September 09 2026, PDT, orunknown - Web Answer's citation marker
[[N]]did not correspond tocitations[N-1]. It corresponded to the Nth URL in order of first appearance after removing duplicates (looking up by index mismatched in 7 of 9 runs, while the deduplicated order matched in all 9)
Aspects 2 to 4: Differences from the caller's point of view
- Web Search is meant to be given short search keywords (up to 200 characters), and
maxResultslets you limit the number of results - Web Answer accepts a longer natural-language question (up to 30,000 characters). There is no way to specify the number of results
- Tool names have the form
<target name>___<tool name>(three underscores). On the real environment they wereweb-answer-tool___WebAnswerandweb-search-tool___WebSearch. On a Gateway with semantic search enabled,tools/listcan also include another tool (x_amz_bedrock_agentcore_search), so you need to pick by the end of the name (the Gateway I used for verification had semantic search disabled, so it was not included) -
tools/listandtools/callsucceeded when I sent SigV4-signed HTTP requests withoutinitialize. Web Search'stools/listincludestitleandannotations(readOnlyHint: true,openWorldHint: true) (connector 1.3.0)
Aspects 5 and 6: Domain and date filters
Both have two layers: a boundary that the administrator sets on the target, and conditions that the agent specifies on each call.
"Request-level filters cannot override the target-level exclude list or expand results beyond the target-level include list."
——Web Search Tool(AgentCore Developer Guide)
| Rule | Web Search | Web Answer |
|---|---|---|
| Request-side list limit | 100 each | 50 each |
| Handling of exclude | The administrator's exclude and the request's exclude are merged, and domains in the merged list are excluded | Same as left. Up to 100 entries after merging |
| When both sides have include | Only the intersection is used. An empty intersection is an error | Officially "only the intersection is used; an empty intersection is an error". In my tests, even with a non-empty intersection, it returned an error if even one non-permitted domain was included |
| Date specification | ISO-8601, UTC, both ends inclusive | Date only, or date-time (Z or +HH:mm allowed) |
| Required connector version | Filters from 1.2.0 | Filters from 1.1.0 |
In practice, if a regulated-industry customer wants the agent to reference only trusted domains, you can pin that with the administrator-side include. In Verification 3, I confirmed that domains outside the boundary specified from the request side, and domains that hit the administrator's exclude when included on the request side, did not appear in the results (one observation per pattern).
Aspect 8: Regions and data handling
| Item | Web Search | Web Answer |
|---|---|---|
| Supported Regions (as of 2026-11-08) | us-east-1, us-east-2, us-west-2, eu-west-1, ap-southeast-2, ap-northeast-1 (Tokyo), us-gov-west-1 | us-east-1 only |
| Scope of processing | Amazon-operated web index | Amazon-operated web index and knowledge graph. Answers are generated by a model on Bedrock using geographic cross-Region inference |
The supported Regions above are as of 2026-11-08. "us-east-1 only" for Web Answer describes the current situation, and the blog says "more AWS Regions coming soon". Because the supported Regions may increase, check the latest Region table before use. The verification in this article was done in us-east-1, which Web Answer supports.
If you want to keep everything within the Tokyo Region, Web Search is the only choice at present (2026-11-08). If you use Web Answer in us-east-1, you need to check the customer's requirements, because data processing involves a US Region.
"Zero data egress" means that queries and results do not leave the AWS environment. The wording differs between the blog (queries and results stay within the AWS environment) and the product page (they can also leave via a VPC or PrivateLink). I did not verify which wording matches the actual behavior. If the data exit point matters for a customer's requirements, check the official documentation or ask AWS.
Aspect 9: Price
| Item | Web Search | Web Answer |
|---|---|---|
| Tool unit price | $7.00 / 1,000 queries ($0.007 per call) | $10 / 1,000 invocations ($0.010 per call) |
| Gateway API | $0.005 / 1,000 calls | Same as left (because calls go through the Gateway) |
Gateway API charges depend on the number of ListTools, InvokeTool, and Ping calls. The unit prices are listed on the Amazon Bedrock AgentCore pricing page.
Aspect 10: Separation of IAM responsibilities
| Target | Permission |
|---|---|
| Gateway service role (Web Search) |
bedrock-agentcore:InvokeWebSearch (resource: arn:aws:bedrock-agentcore:us-east-1:aws:tool/web-search.v1) |
| Gateway service role (Web Answer) |
bedrock-agentcore:InvokeWebAnswer (resource: arn:aws:bedrock-agentcore:us-east-1:aws:tool/web-answer.v1) |
| Caller (execution role of the agent or harness) |
bedrock-agentcore:InvokeGateway (Gateway ARN) |
Verification 2 showed that InvokeGateway is required on the caller and not on the service role. InvokeWebAnswer and InvokeWebSearch on the service role are each required independently per tool (details in Verification 2).
What I confirmed on a real environment
The following is what I actually confirmed in us-east-1 on 2026-11-08. Each verification is written in this order: what I checked, the measurements, and what can be concluded.
Verification 1: Sending the same question to both and comparing the response formats
I checked the difference in response format and how citations are attached, using actual responses. I sent the same three questions to both Web Search and Web Answer. I fixed the questions to English because Web Answer supported English at launch.
| Question | Type | Question text |
|---|---|---|
| Q1 | Fact check | What is the maximum execution timeout of an AWS Lambda function? |
| Q2 | Regulation / policy | What is the minimum Common Equity Tier 1 capital ratio required under Basel III? |
| Q3 | Latest information | What are the recent updates to Amazon Bedrock AgentCore? |
I sent each question to each tool three times, for 18 calls in total. All returned HTTP 200 with isError false. Web Search used maxResults: 5. I recorded the response format, whether and where citations appear, whether publishedDate is present, and latency. For latency, I recorded both _meta.latencyMs and client-side timing for Web Answer, and only client-side timing for Web Search because it returns no _meta.
Latency (milliseconds; average of 3 runs; client side is the time of the whole HTTP request)
| Question | Search, client side | Answer, client side | Answer, server side (_meta.latencyMs) |
|---|---|---|---|
| Q1 (fact check) | 1,101 | 3,122 | 2,292 |
| Q2 (regulation) | 1,136 | 3,011 | 2,215 |
| Q3 (latest information) | 1,259 | 6,555 | 5,744 |
Differences in the response
| Aspect | Web Search | Web Answer |
|---|---|---|
| Top-level keys |
isError, content
|
isError, content, structuredContent, _meta
|
| Body |
content[0].text is a JSON string of the form {"id": ..., "results": [...]}, and results has maxResults entries (5) |
content[0].text is Markdown. Citations are [[N](url)]
|
| Contents of one item |
text (snippet, about 700 to 5,000 characters), title, url, publishedDate
|
The answer body and a list of citations (structuredContent.answer is one block) |
| Dates |
publishedDate is in the form 05:00PM, Wednesday, September 09 2026, PDT, or unknown (0 to 2 of 5 items were unknown) |
No date is attached |
| When the same question is sent 3 times | The set of result URLs was the same all 3 times. The whole response was not fully identical, though (the length was the same in some runs) | The body length changes between runs (whole-response character counts for Q1: 1,947 / 1,485 / 2,313) |
| Characters in the whole response | About 9,600 to 14,100 | About 1,400 to 2,500 for Q1 and Q2, about 10,000 to 12,700 for Q3 |
Actual content returned (Q1 "What is the maximum execution timeout of an AWS Lambda function?", first run)
Web Answer's answer (full content[0].text, 627 characters).
The standard maximum timeout for an AWS Lambda function is 900 seconds (15 minutes). [[1](https://docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html)]
There is one exception: for functions on Lambda Managed Instances, asynchronous and event source mapping invocations can be set to up to 5,400 seconds (90 minutes). [[2](https://aws.amazon.com/blogs/compute/announcing-90-minute-function-timeout-on-aws-lambda-managed-instances/)] Synchronous invocations on those instances still cap at 15 minutes. [[2](https://aws.amazon.com/blogs/compute/announcing-90-minute-function-timeout-on-aws-lambda-managed-instances/)]
Web Search results (maxResults: 5. The 5 snippets total 8,227 characters. The full text is in the collapsible section below).
| # | Title | URL | publishedDate | Snippet characters |
|---|---|---|---|---|
| 1 | Configure Lambda Event Function timeout | docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html | 05:00PM, Sunday, October 30 2016, PDT | 1,164 |
| 2 | Troubleshoot configuration issues in Lambda | docs.aws.amazon.com/lambda/latest/operatorguide/configurations.html | unknown | 2,312 |
| 3 | AWS SDK for Kotlin | docs.aws.amazon.com/sdk-for-kotlin/api/latest/lambda/.../timeout.html | unknown | 1,365 |
| 4 | Announcing 90-minute function timeout on AWS Lambda Managed Instances | aws.amazon.com/blogs/compute/announcing-90-minute-function-timeout-on-aws-lambda-managed-instances/ | 12:08PM, Wednesday, September 09 2026, PDT | 2,023 |
| 5 | AWS Lambda vs Step Functions vs EventBridge | jayendrapatil.com/aws-lambda-vs-step-functions-vs-eventbridge/ | 05:00PM, Wednesday, June 24 2026, PDT | 1,363 |
The full content[0].text of Web Search (Q1, first run, 9,595 characters) follows. Reading it side by side with Web Answer's answer (627 characters) shows how the citations differ.
Full response of Web Search (click to expand)
{
"id": "dafbd346",
"results": [
{
"publishedDate": "05:00PM, Sunday, October 30 2016, PDT",
"text": "Configure Lambda Event Function timeout Lambda runs your code for a set amount of time before timing out. Timeout is the maximum amount of time in seconds that a Lambda function can run. The default value for this setting is 3 seconds, but you can adjust this in increments of 1 second up to a maximum value \n\nof 900 seconds (15 minutes). For functions using AWS Lambda Managed Instances, asynchronous invocations and event source mapping invocations (except Amazon MQ and Amazon DocumentDB) support a maximum allowed value of 5,400 seconds (90 minutes). \n\nConfiguring timeout (AWS SAM) Determining the appropriate timeout value for a Lambda function If the timeout value is close to the average duration of a function, there is a higher risk that the function times out unexpectedly. The duration of a function can vary \n\nUnder General configuration , choose Edit . For Timeout , set a value between 1 and 900 seconds (15 minutes). Choose Save . Configuring timeout (AWS CLI) You can use the update-function-configuration command to configure the timeout value, in seconds. The following example command increases the function timeout to 120 seconds (2 minutes). ",
"title": "Configure Lambda Event Function timeout",
"url": "https://docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html"
},
{
"publishedDate": "unknown",
"text": "The following topics provide troubleshooting advice for common issues that you might encounter related to Lambda function configuration settings. Memory configurations You can configure a Lambda function to use between 128 MB and 10,240 MB of memory. By default, any function created in the console is assigned the smallest amount of memory. Many Lambda functions are performant at this lowest setting. However, if you are importing large code libraries or completing memory intensive tasks, 128 MB is not sufficient. \n\nTimeouts Timeouts for Lambda functions can be set between 1 and 900 seconds (15 minutes). For functions using AWS Lambda Managed Instances, asynchronous invocations and event source mapping invocations (except Amazon MQ and Amazon DocumentDB) support a maximum allowed value of 5,400 seconds (90 minutes). By default, the Lambda console sets this to 3 seconds. The timeout value is a safety valve that ensures functions do not run indefinitely. After the timeout value is reached, Lambda stops the function invocation. \n\nIf a timeout value is set close to the average duration of a function, this increases the risk that the function times out unexpectedly. The duration of a function can vary based on the amount of data transfer and processing, and the latency of any services the function interacts with. Common causes of timeout include: \n\n2. Duration – Before the function runs out of memory, it finishes invocations at a steady double-digit millisecond rate. As paging occurs, the duration takes an order of magnitude longer. 3. Error count – As the memory leak exceeds allocated memory, eventually the function errors due to the computation exceeding the timeout, or the execution environment stops the function. \n\nIn JavaScript, asynchronous callbacks are handled with an event loop. Other runtimes use different mechanisms to handle concurrency. When the function's execution environment ends, Lambda freezes the environment until the next invocation. \n\n1. The code calls the asynchronous doWork function using the await keyword in the handler. 2. The doWork function takes some period of time to complete before resolving the promise. 3. The function times out because doWork takes longer than the timeout limit allows and the callback result is not returned in a later invocation. ",
"title": "Troubleshoot configuration issues in Lambda",
"url": "https://docs.aws.amazon.com/lambda/latest/operatorguide/configurations.html"
},
{
"publishedDate": "unknown",
"text": "If you agree, AWS and approved third parties will also use cookies to provide useful site features, remember your preferences, and display relevant content, including relevant advertising. To accept or decline all non-essential cookies, choose “Accept†or “Decline.†To make more detailed choices, choose “Customize.†\n\nTo opt out of our use of cookies or similar technologies to engage in these activities, select “Opt out of cross-context behavioral ads†and “Save preferences†below. If you clear your browser cookies or visit this site from a different device or browser, you will need to make your selection again. For more information about cookies and how we use them, read our Cookie Notice. \n\nTo opt out of the use of other identifiers, such as contact information, for these activities, fill out the form here. For more information about how AWS handles your information, read the AWS Privacy Notice. \n\nThe amount of time (in seconds) that Lambda allows a function to run before stopping it. The default is 3 seconds, and the maximum allowed value is 900 seconds. For functions using Lambda Managed Instances, asynchronous invocations and event source mapping invocations (except Amazon MQ and Amazon DocumentDB) support a maximum allowed value of 5,400 seconds (90 minutes). For more information, see Lambda execution environment. ",
"title": "AWS SDK for Kotlin",
"url": "https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/lambda/aws.sdk.kotlin.services.lambda.model/-update-function-configuration-request/-builder/timeout.html"
},
{
"publishedDate": "12:08PM, Wednesday, September 09 2026, PDT",
"text": "Activating 90-minute function timeout You can now configure any Lambda function running on a Managed Instance with a timeout of up to 90 minutes (5,400 seconds) for async and ESM invocations. Synchronous invocations retain the existing 15-minute maximum. The function executes exactly as before: same runtime, same handler, same IAM execution role, same virtual private cloud (VPC) configuration. The only difference is that your function now supports longer continuous execution. Your initialization code (Init phase) is still limited to 15 minutes on Lambda Managed Instances. \n\nThere is no additional charge for using the 90-minute timeout. Standard Lambda Managed Instances pricing applies. 90-minute timeout and durable functions The 90-minute function timeout and durable functions are complementary. The function timeout (--timeout) controls how long each individual invocation can run, while the durable execution timeout (ExecutionTimeout in --durable-config) controls the total elapsed time from execution start to completion. Durable functions use checkpoints to track progress and automatically recover from failures through replay, re-executing from the beginning while skipping completed work. With today’s launch, each asynchronous invocation in a durable function running on a Managed Instance can now execute for up to 90 minutes continuously, while the corresponding durable execution can run for up to 1 year. For synchronous and event source mapping invocations, both the invocation and the corresponding durable execution are limited to 90 minutes. \n\nNote that invocations for Amazon MQ ESM and Amazon DocumentDB (with MongoDB compatibility) ESM remain limited to 15 minutes. Synchronous invocations (15 minutes maximum): Synchronous invocations retain the existing 15-minute maximum timeout. If you set your function timeout to greater than 15 minutes and invoke it synchronously, Lambda continues to apply the 15-minute timeout. The GetFunctionConfiguration API reports the configured timeout value. ",
"title": "Announcing 90-minute function timeout on AWS Lambda Managed Instances",
"url": "https://aws.amazon.com/blogs/compute/announcing-90-minute-function-timeout-on-aws-lambda-managed-instances/"
},
{
"publishedDate": "05:00PM, Wednesday, June 24 2026, PDT",
"text": "| event_date | 2026-08-11 |\n| title | AWS Lambda vs Step Functions vs EventBridge |\n| original_url | https://jayendrapatil.com/aws-lambda-vs-step-functions-vs-eventbridge/ |\n| source_domain | jayendrapatil.com |\n| search_queries_hash | 187d207b814cb47441a22825e67d4c83 |\n### search_queries (Level 0)\n#### search_queries - Item 1\n- What architecture pattern is best for decoupling microservices that react to a single event? : Amazon EventBridge with a custom event bus and content-based routing rules provides the most decoupled architecture, allowing producers to remain unaware of consumers.\n#### search_queries - Item 2\n- How much does AWS Step Functions Standard Workflow cost? : AWS Step Functions Standard Workflow costs $25.00 per 1 million state transitions.\n#### search_queries - Item 3\n- What is the difference between AWS Lambda, Step Functions, and EventBridge? : Lambda handles compute (executing code), Step Functions handles orchestration (coordinating multiple services into workflows), and EventBridge handles event routing (connecting producers and consumers) — they are complementary services often used together.\n#### search_queries - Item 4\n- What is the maximum execution duration for AWS Lambda? : Standard Lambda functions have a 15-minute timeout, MicroVMs support up to 8 hours, and Lambda Durable Functions can suspend for up to 1 year.",
"title": "AWS Lambda vs Step Functions vs EventBridge",
"url": "https://jayendrapatil.com/aws-lambda-vs-step-functions-vs-eventbridge/"
}
]
}
Comparing the two, you can see the following.
- Citations are attached differently. Web Answer attaches the source URL to each sentence of the answer (the
[[1](...)]and[[2](...)]above). Web Search only attachesurlandtitleto each result, and does not tell you which sentence is based on which result. When you compose an answer, your own model has to add the citations - The first Web Search snippet already contains the answer (up to 900 seconds, and 5,400 seconds on Managed Instances). However, the answer sits in the middle of explanatory text about how to configure the setting, and extracting it is the job of your own model
- The results also include content that is only weakly related to the answer. The third result contains the text of a cookie consent banner with garbled characters, and the fifth is a list of search queries from a third-party blog, which includes a statement that none of the other four contain: "MicroVMs support up to 8 hours". Deciding which to use is also the job of your own model. Web Answer's answer cited only two sources: the official documentation and an AWS blog
- Web Answer summarized the same content in a 627-character answer and returned it with a citation on each sentence. The numbers in the answer (900 seconds and 5,400 seconds) are the same as those in the first snippet
- The amount returned is 8,227 characters (5 results) for Web Search and 627 characters (Q1) for Web Answer, a difference of about 13 times
The difference in length comes from the difference in what each tool returns.
| Aspect | Web Search | Web Answer |
|---|---|---|
| What it returns | Excerpts (snippets) of the pages it found, returned without summarizing. Raw material | Only the answer to the question, written after reading the pages, plus citations. The page bodies are not returned |
| What determines the length | The number of results (maxResults) and the length of each snippet (about 700 to 5,000 characters this time). The difference between questions is small (about 9,600 to 14,100 characters for Q1 to Q3) |
The content of the question. Short for questions that can be answered briefly (about 1,400 to 2,500 characters for Q1 and Q2), and long for questions with a lot to answer (about 10,000 to 12,700 characters for Q3) |
| Who extracts the answer | Your own model | Web Answer |
In other words, Web Answer was short because the questions could be answered briefly. For Q3 (recent updates to AgentCore), Web Answer's answer was also about 10,000 characters, the same as Web Search's results. The essential difference is not length, but "whether it returns material or an answer". The following diagram summarizes what comes back for the same question (Q1).
For Q2 (the CET1 ratio under Basel III), Web Answer also answered "a minimum of 4.5%, plus a 2.5% buffer, so effectively 7%", citing three sources. Web Search returned five results, including IMF, BIS, Investopedia, and Wikipedia.
How to read Web Answer's citations
According to the official description, marker N corresponds to citations[N-1] of that block. In my measurements, the same URL appeared multiple times in citations, so the number of entries was larger than the number of distinct markers (for example, the first run of Q1 had 4 entries but only 2 unique URLs). Looking up by citations[N-1] mismatched the marker's URL in 7 of 9 runs, while looking up by the Nth URL in order of first appearance after removing duplicates matched in all 9 runs.
import re
PAT = re.compile(r"\[\[(\d+)\]\((https?://[^)]+)\)\]")
def unique_urls(citations):
seen = []
for c in citations:
if c["url"] not in seen:
seen.append(c["url"])
return seen
# URL of marker N = unique_urls(citations)[N-1]
Note that the sample is only 3 questions × 3 runs, in us-east-1, on a single day. There is no guarantee that this mapping always holds, and it may change with specification changes. If you process citations programmatically, it is safer to use the URL in the marker itself.
The results of Verification 1 affect the choice as follows.
- If you want to reason over the results with your own model, Web Search is faster (about 1.1 seconds versus about 3.1 seconds for Q1), and
maxResultslets you limit the number of results. However, dates have string variations andunknownis mixed in, so if you use dates as a filtering condition, it is safer to use the request-sidepublishedDateFilter(Verification 4) - If you want a finished answer, Web Answer returns it with citations, but it took about 6.6 seconds for the latest-information question (Q3). If latency matters, measure by question type before choosing
- When you use Web Answer's citations for display, use the URL in the marker, not the index into
citations
Verification 2: Separation of IAM responsibilities
To establish the minimum required permissions, I checked the behavior with the service role's InvokeWebAnswer / InvokeWebSearch present and absent, and with InvokeGateway attached to different roles.
| Configuration | Web Search | Web Answer |
|---|---|---|
2-1 Baseline: service role has only the dedicated permissions, caller has InvokeGateway
|
Success | Success |
2-2 Remove InvokeWebAnswer from the service role |
Success | Failure (HTTP 200, JSON-RPC error -32002: Execution role is not authorized for connector web-answer) |
2-3 Restore InvokeWebAnswer and remove InvokeWebSearch
|
Failure (HTTP 200, JSON-RPC error -32002: Execution role is not authorized for connector web-search) |
Success |
2-4 Add InvokeGateway to the service role (with both dedicated permissions) |
Success | Success |
2-5 Remove InvokeGateway from the caller (service role as in 2-4) |
Failure (HTTP 403, JSON-RPC error -32002: Authorization error - Insufficient permissions) |
Failure (same as left) |
I made the calls by assuming a dedicated verification IAM role (wa-verify-caller) with assume-role. After each permission change I waited 20 seconds before calling, and every configuration gave the expected result from the first call (no retries were needed to wait for propagation).
The results of Verification 2 show the following.
-
InvokeGatewayis required on the caller and not on the service role (in 2-1 it succeeded without it on the service role; in 2-4 adding it changed nothing; in 2-5 it failed without it on the caller) - The dedicated permissions on the service role are independent per tool. Removing only Web Answer's permission left Web Search working, and vice versa. You can remove the permissions for tools you don't use from the service role
- Errors appear in three different ways depending on the cause. This can also help you narrow down a permission problem
| Cause | HTTP status | How it is returned |
|---|---|---|
| The service role lacks the tool's permission | 200 | JSON-RPC error (-32002, Execution role is not authorized for connector ...) |
The caller lacks InvokeGateway
|
403 | JSON-RPC error (-32002, Authorization error - Insufficient permissions) |
| Invalid filter or date specification (Verifications 3 and 4) | 200 |
isError: true inside result (DependencyFailedException) |
Caller code will miss failures unless it checks all three places: the HTTP status, the JSON-RPC error, and result.isError.
Verification 3: Combination rules of the domain filters
To check the specification that "the agent cannot widen the boundary", I varied the combinations of include and exclude on the administrator side and the request side, and checked the results and errors.
| Pattern | Administrator side | Request side | Expected (official) | Measured |
|---|---|---|---|---|
| Empty intersection | include: docs.aws.amazon.com | include: bis.org | Web Answer: validation error | Both tools returned an error. Answer: include contains domains that are not permitted for this tool: bis.org. Search: Runtime domainFilter.include has no overlap with admin domainFilter.include
|
| Mixing in a domain outside the boundary | include: docs.aws.amazon.com | include: docs.aws.amazon.com, wikipedia.org | Domains outside the boundary are not used | Search: no error, and all 5 results were from docs.aws.amazon.com (only the intersection was used). Answer: error (rejected because wikipedia.org is not permitted; it fails even when there is an intersection) |
| Merging excludes | exclude: investopedia.com | exclude: imf.org | Both excluded | The two domains that had appeared in the baseline (Q2 of V1) no longer appeared in either tool (Search: bis.org, fraser.stlouisfed.org, debevoise.com, en.wikipedia.org, and others. Answer: bis.org, fraser.stlouisfed.org, mayerbrown.com) |
| Can the administrator's exclude be bypassed? | exclude: investopedia.com | include: investopedia.com | Cannot be overridden | Answer: error (include contains domains that are excluded, fully or partly, for this tool: investopedia.com. Remove them from include.). Search: HTTP 200, isError: false, 0 results (an empty result, not an error) |
Errors caused by filters were returned with HTTP status 200, isError: true, and DependencyFailedException - ... in the body. You cannot detect the failure from the HTTP status alone.
Verification 3 showed three things.
- The boundary set by the administrator was actually respected by both tools. Domains outside the boundary and domains the administrator excluded did not appear in the results (one observation per pattern)
- The way a violation looks is different. Web Answer reports an error if even one non-permitted or excluded domain is included in the request. Web Search quietly narrows down to the intersection, and when the request collides with an exclude, it returns an empty result without an error
- An agent that uses Web Search may interpret an empty result as "nothing was found". The calling side needs to decide how to handle zero results
Verification 4: Date filter
To see whether the date filter can be used for freshness requirements, I varied the range of publishedDateFilter and checked whether the results changed. I also checked the error when from is later than to.
| Condition | Web Search | Web Answer |
|---|---|---|
Limit to the last month (from: 2026-10-08, to: 2026-11-08, question Q3) |
All 10 results were in range (publishedDate from 2026-10-11 to 2026-11-06). Before filtering (V1), results from April to September 2026 were mixed in |
The cited sources were mainly pages from October to November 2026 (the Web Answer announcement page, October AgentCore announcements, and so on). Because the dates of the cited sources are not attached to the result, you can only judge whether they are within the range from the text |
from > to (from: 2026-11-08, to: 2026-10-08) |
Error: publishedDate.from (2026-11-08) must not be after publishedDate.to (2026-10-08)
|
Error: filters.publishedDateFilter.from must not be after to.
|
Verification 4 shows how to use it for freshness requirements.
- For use cases that need freshness, both can be narrowed with the request-side
publishedDateFilter. However, only Web Search lets you check the dates of the results yourself (Web Answer's citations carry no dates) - Errors in the date filter are also returned with HTTP 200 and
isError: true(same as Verification 3) - Web Search's
publishedDatewas a string containingPDTorPST. If you want to sort by date, you need to parse it yourself - Web Answer is given today's date when generating an answer, and this answer said "current date: November 7, 2026" (apparently the date in Pacific Time)
Criteria for choosing
Based on the results of Verifications 1 to 4, here is a summary by criterion. The "Basis" column shows which verification in this article it rests on.
| Criterion | Choose Web Search | Choose Web Answer | Basis |
|---|---|---|---|
| You want to reason over the returned results with your own model | Suitable (url, title, snippet, and date are returned) | Not suitable (a finished answer is returned) | Verification 1 |
| You want a finished answer to a sub-question | You need to synthesize it yourself | Suitable (returned with citations) | Verification 1 |
| Response speed matters | Fast (average about 1.1 to 1.3 seconds) | Varies by question (about 3.0 seconds; about 6.6 seconds for latest-information questions) | Verification 1 |
| You want to keep everything within the Tokyo Region | Suitable | Not possible as of 2026-11-08 (may change) | Region table |
| You want to pin the referenced domains on the administrator side | Possible with both. Outside the boundary, results are narrowed or empty | Possible with both. Specifying outside the boundary returns an error | Verification 3 |
| You want failures to be easy to notice | An empty result can be returned without an error | Invalid specifications are returned as errors | Verification 3 |
| You want to filter by date | Possible. You can check the result's publishedDate (custom format) |
Possible. The dates of cited sources are not attached to the result | Verification 4 |
| You want to guarantee citations are displayed in a machine-checkable way | Display the result's url yourself | The answer comes back with citations. Use the URL in the marker | Verification 1 |
Here is a rough guide for choosing.
- If you want to control how the results are handled by your own model, or you want to use Tokyo, choose Web Search
- If you want to use the finished answer and citations as they are, and us-east-1 is acceptable, choose Web Answer
- You can also use both. AWS also calls them "complementary", and you can split by question type, for example Web Answer for fact checks and Web Search for preliminary research
As for citations, for both tools it is a condition of use to keep and display the cited sources and links. Bulk extraction and building a competing index are prohibited.
How to verify it yourself
This shows a flow that readers can try in their own environment. The following is a shortened version of the code I actually used in the verification. I did the verification with a dedicated role and Gateway, and deleted everything after finishing.
You need AWS CLI v2, Python 3.10 or later, boto3 (1.43.91 at the time of verification), and requests. The Region is us-east-1.
1. Create the service role
The trust policy (trust.json). Replace <ACCOUNT_ID> with your own account ID.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "bedrock-agentcore.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {"aws:SourceAccount": "<ACCOUNT_ID>"},
"ArnLike": {"aws:SourceArn": "arn:aws:bedrock-agentcore:us-east-1:<ACCOUNT_ID>:gateway/*"}
}
}
]
}
The permissions policy (policy.json). It is required independently per tool.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "bedrock-agentcore:InvokeWebAnswer",
"Resource": "arn:aws:bedrock-agentcore:us-east-1:aws:tool/web-answer.v1"
},
{
"Effect": "Allow",
"Action": "bedrock-agentcore:InvokeWebSearch",
"Resource": "arn:aws:bedrock-agentcore:us-east-1:aws:tool/web-search.v1"
}
]
}
aws iam create-role --role-name wa-verify-gateway-role \
--assume-role-policy-document file://trust.json
aws iam put-role-policy --role-name wa-verify-gateway-role \
--policy-name wa-verify-base --policy-document file://policy.json
The inline policy of the created role looks like this in the console.
2. Create the Gateway and targets with Python
import time
import boto3
control = boto3.client("bedrock-agentcore-control", region_name="us-east-1")
gw = control.create_gateway(
name="wa-verify-gateway",
roleArn="arn:aws:iam::<ACCOUNT_ID>:role/wa-verify-gateway-role",
protocolType="MCP",
authorizerType="AWS_IAM",
)
gid = gw["gatewayId"]
while control.get_gateway(gatewayIdentifier=gid)["status"] != "READY":
time.sleep(3)
def add_target(name, connector_id, config_name):
t = control.create_gateway_target(
name=name,
gatewayIdentifier=gid,
targetConfiguration={"mcp": {"connector": {
"source": {"connectorId": connector_id},
"configurations": [{"name": config_name, "parameterValues": {}}],
}}},
credentialProviderConfigurations=[{"credentialProviderType": "GATEWAY_IAM_ROLE"}],
)
while control.get_gateway_target(gatewayIdentifier=gid, targetId=t["targetId"])["status"] != "READY":
time.sleep(3)
add_target("web-answer-tool", "web-answer", "WebAnswer")
add_target("web-search-tool", "web-search", "WebSearch")
Right after creating the role, it is safer to wait about 10 seconds for propagation before creating the Gateway. If you do not specify a version, the current default is used (at the time of verification, 1.1.0 for Web Answer and 1.3.0 for Web Search).
The Gateway reached the Ready status about 10 seconds after creation. Both targets also became Ready within a few seconds.
In the target list, the target types are displayed as "ウェブ回答ツール" (Web Answer tool) and "ウェブ検索ツール" (Web Search tool).
Settings screens in the console
You can make the same settings from the console. In step 3, "Add target", of the Gateway creation wizard, choose as follows. The console in the screenshots is displayed in Japanese, so the Japanese labels are shown in parentheses.
- Leave the target protocol as "MCP target" (MCP ターゲット)
- For the target type, choose "Connector - New" (コネクター - 新規). The other options are MCP server, Lambda ARN, REST API, and API Gateway
- "Pre-configured targets" (事前設定済みのターゲット) lists knowledge base (KB), Web Search tool (ウェブ検索ツール), Web Answer tool (ウェブ回答ツール), Step Functions, and other integrations. Choose "Web Answer tool" here
- When you choose "Web Answer tool", a blue notice appears. It says what the developer guide says: because it uses geographic cross-Region inference, data processing stays in commercial Regions within the specified geographic boundary (such as the US, EU, or APAC)
- For the outbound authentication setting, only "IAM role" (IAM ロール) can be selected (OAuth client, API key, and no authorization cannot be selected)
The correspondence with the code is as follows.
| Console item | Code item |
|---|---|
| Target type "Connector", pre-configured target "Web Answer tool" | connector.source.connectorId: "web-answer" |
| Pre-configured target "Web Search tool" | connectorId: "web-search" |
| Outbound authentication setting "IAM role" | credentialProviderType: "GATEWAY_IAM_ROLE" |
| "Domain filtering" (ドメインフィルタリング) under additional settings (included / excluded) |
parameterValues.domainFilter.include / exclude (the "administrator-side" boundary in Verification 3) |
When you open "Additional settings - Optional" (追加設定 - オプション), there is a "Domain filtering" item. Its description is "Set the domains to include in and exclude from this target", the current counts are shown as "Included: 0 · Excluded: 0", and you edit them with the "View and manage domains" button. In other words, the boundary that the administrator sets on the target, which Verification 3 dealt with, is set in the target's additional settings in the console.
On this screen (with additional settings opened), I did not see an item for choosing the connector version. If you want to pin the version, use source.version, as in the code in this article (I did not check whether it can be pinned in the console).
3. Call MCP with SigV4 signing
tools/list and tools/call worked without initialize.
import json
import boto3, requests
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
REGION = "us-east-1"
URL = "https://<GATEWAY_ID>.gateway.bedrock-agentcore.us-east-1.amazonaws.com/mcp" # <GATEWAY_ID> is the gatewayId returned by create_gateway (e.g. name-alphanumerics)
def rpc(method, params=None, session=None):
body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": method, "params": params or {}})
creds = (session or boto3.Session()).get_credentials().get_frozen_credentials()
req = AWSRequest(method="POST", url=URL, data=body,
headers={"Content-Type": "application/json",
"Accept": "application/json, text/event-stream"})
SigV4Auth(creds, "bedrock-agentcore", REGION).add_auth(req)
r = requests.post(URL, data=body, headers=dict(req.headers), timeout=120)
return r.status_code, r.text
print(rpc("tools/list"))
print(rpc("tools/call", {"name": "web-answer-tool___WebAnswer",
"arguments": {"query": "What is the maximum execution timeout of an AWS Lambda function?"}}))
print(rpc("tools/call", {"name": "web-search-tool___WebSearch",
"arguments": {"query": "What is the maximum execution timeout of an AWS Lambda function?",
"maxResults": 5}}))
The caller's IAM needs bedrock-agentcore:InvokeGateway (targeting the Gateway ARN). Check for failures in three places: the HTTP status, the JSON-RPC error, and result.isError (see Verifications 2 and 3).
4. Try the domain filters (optional)
Change the administrator-side boundary with update_gateway_target. The required arguments are gatewayIdentifier, targetId, and targetConfiguration.
control.update_gateway_target(
gatewayIdentifier=gid,
targetId="<TARGET_ID>",
name="web-search-tool",
targetConfiguration={"mcp": {"connector": {
"source": {"connectorId": "web-search"},
"configurations": [{"name": "WebSearch", "parameterValues": {
"domainFilter": {"include": ["docs.aws.amazon.com"]}
}}],
}}},
credentialProviderConfigurations=[{"credentialProviderType": "GATEWAY_IAM_ROLE"}],
)
On the request side, add filters to arguments.
{"query": "...", "filters": {"domainFilter": {"include": ["bis.org"]}}}
{"query": "...", "filters": {"publishedDateFilter": {"from": "2026-10-08", "to": "2026-11-08"}}}
5. Clean up
Delete the targets, the Gateway, and the IAM role, in that order.
for t in control.list_gateway_targets(gatewayIdentifier=gid)["items"]:
control.delete_gateway_target(gatewayIdentifier=gid, targetId=t["targetId"])
# Wait for the target deletions to complete
control.delete_gateway(gatewayIdentifier=gid)
aws iam delete-role-policy --role-name wa-verify-gateway-role --policy-name wa-verify-base
aws iam delete-role --role-name wa-verify-gateway-role
Conclusion
I started out with the understanding that Web Answer is "something where a model reads web search results and answers for you". After actually running both and comparing them, I found that the difference, where Web Search returns material in the form of search results and Web Answer returns an answer with citations, becomes the axis for choosing between them, and it even affects how errors look and which Regions you can use. If you want to use a finished answer and its citations as they are, choose Web Answer. If you want to handle the results with your own model, choose Web Search.
As of 2026-11-08, Web Answer is available only in us-east-1, but the blog says more Regions are planned. Connector versions and tool names may also change in the future.
References
- Announcing Web Answer on Amazon Bedrock AgentCore (2026-11-05)
- Getting started with Web Answer on Amazon Bedrock AgentCore (AWS Machine Learning Blog, 2026-11-05)
- Web Answer (AgentCore Developer Guide)
- Web Search Tool (AgentCore Developer Guide)
- Connector versions (AgentCore Developer Guide)
- Gateway target configuration (AgentCore Developer Guide)
- Web Answer (product page)
- Web Search (product page)
- Amazon Bedrock AgentCore pricing







Top comments (0)