使用全托管的 Bedrock Managed Knowledge Base 构建私有知识库问答 Agent
本文介绍了如何基于 Amazon Bedrock Managed Knowledge Base 构建私有知识库问答 Agent:以 S3 中的 Markdown 作为数据源,通过 AWS CLI 创建全托管知识库、配置 Smart Parsing 连接器并同步数据;随后用 Python 与 Java SDK 调用 Retrieve 与 AgenticRetrieveStream 两类检索接口;最后经 AgentCore Gateway 将知识库封装为 MCP 工具,供 Kiro 等 AI 开发工具通过 Cognito JWT 认证后调用,并给出各环节的最小 IAM 权限与实验资源清理方法。
一、背景
1、发布了什么新产品
2026 年 6 月,AWS 正式发布 Amazon Bedrock Managed Knowledge Base。它是 Amazon Bedrock Knowledge Bases 新增的全托管 RAG(Retrieval-Augmented Generation,检索增强生成)方案,目标是让开发者在不自行部署向量数据库、数据摄取流水线和检索基础设施的情况下,为生产级 AI Agent 接入企业数据。
Managed Knowledge Base 将数据摄取、文本与向量存储、嵌入、语义重排序及检索优化整合为托管服务,目前提供 Amazon S3、Microsoft SharePoint、Atlassian Confluence、Google Drive、Microsoft OneDrive 和 Web Crawler 六种预置数据源连接器,支持文本、图像、音频和视频等多模态内容。检索能力方面,提供混合检索、文档排序和 Agentic Retrieval(代理式检索)。代理式检索能够针对复杂的多跳问题自动进行查询规划、迭代检索、中间结果评估和重排序,即返回的是 Agent 处理后的结果,而不是只执行一次向量相似度查询。
AWS 官方发布说明:Amazon Bedrock Managed Knowledge Base is now generally available
2、现在全托管知识库新特性和过去的 Bedrock 知识库有何不同
新的托管知识库叫做 Bedrock Managed Knowledge Bases,原先的 Bedrock 知识库现在叫做 Customer-managed Knowledge Bases。
| 对比 | Bedrock Managed Knowledge Bases | 过去的 Customer-managed Knowledge Bases |
|---|---|---|
| 数据存储 | Amazon Bedrock 全托管自动扩缩的数据存储,统一保存嵌入、文本、元数据和原始文件 | 客户选择、配置并维护向量及文本数据存储,包括 S3、Redis、Aurora PostgreSQL、OpenSearch 等,或者客户自建 |
| Embedding 模型 | 内置托管嵌入模型,也可选择满足要求的自定义 Embedding 嵌入模型 | 客户自行选择 Embedding 嵌入模型 |
| 重排序 | 内置托管语义重排序,也可指定 Bedrock 重排序模型 | 客户自行选择和配置重排序模型 |
| 检索方式 | 支持语义混合检索和 Agentic Retrieval | 客户根据所选数据存储配置检索策略,不支持托管的 Agentic Retrieval |
| 数据来源插件 | 当前支持 S3、SharePoint、Confluence、Google Drive、OneDrive、Web Crawler 和 Custom 七类连接器 | 主要支持 S3 和 Custom 数据源 |
| 内容解析 | 提供面向多模态文件类型的内置解析能力 | 客户在默认文本解析、基础模型解析和 Bedrock Data Automation 等方式之间选择 |
| 服务对外暴露为 MCP | 使用 AgentCore Gateway 暴露为 MCP,支持作为原生 Gateway Connector Target 挂载 | 不能与 AgentCore Gateway 自动集成,需要暴露为 MCP 的话要额外编写代码做封装和集成 |
| 基础设施责任 | 无须自行部署和维护向量数据库 | 用户需要负责所选向量数据库的配置、扩缩、更新和成本治理 |
| 适用场景 | 希望以较少运维工作获得端到端托管 RAG、企业连接器和代理式检索 | 需要自定义向量数据库、索引结构或底层检索策略 |
因此,两种方案的核心差异是谁来负责向量生成和存储的管理工具。Managed Knowledge Base 实现全自动;Customer-managed Knowledge Base 则保留向量生成、存储服务的可定制性。
3、使用前提、是否必须要挂在 AgentCore Gateway 下
Managed Knowledge Base 不必须挂载在 AgentCore Gateway 下。用户自己开发的应用可以使用 AWS SDK 或 Amazon Bedrock 的知识库检索 API 直接调用检索能力。只有在需要把知识库暴露为标准 MCP(Model Context Protocol,模型上下文协议)工具,或者需要由 Gateway 统一处理工具发现、入站认证、参数约束、路由和可观测性时,才需要配置 AgentCore Gateway。
直接调用 Managed Knowledge Base 的基本前提包括:
- 在 Managed Knowledge Base 已开放的 AWS 区域中创建资源,并准备一个受支持的数据源;
- 为创建和管理知识库的 IAM 身份授予 Knowledge Base、Data Source 和 Ingestion Job 等必要操作权限;
- 使用 Amazon Bedrock 自动创建的服务角色,或者按最小权限原则创建自定义服务角色,使其能够访问所需的 Bedrock 模型和数据源;
- 完成数据源同步后,由应用通过
Retrieve或AgenticRetrieveStream等检索 API 访问知识库。
如果选择通过 AgentCore Gateway 提供 MCP 接口,还需要额外满足以下条件:
- 已创建 Managed Knowledge Base,并取得 Knowledge Base ID;
- 已创建 AgentCore Gateway,并将知识库添加为 Gateway Connector Target;
- Gateway 服务角色至少具备校验知识库和执行所选检索操作所需的
bedrock:GetKnowledgeBase、bedrock:Retrieve或bedrock:AgenticRetrieveStream权限; - Managed Knowledge Base Connector 的出站认证只支持
GATEWAY_IAM_ROLE;调用方还需要通过 Gateway 配置的 IAM 或 JWT 等入站认证。
Gateway 会将知识库暴露为两个 MCP 工具:Retrieve 用于执行单次混合检索并返回相关段落和来源;AgenticRetrieveStream 用于执行多步骤代理式检索,并可流式返回带引用的综合答案。
4、文档解析能力说明
Bedrock Managed Knowledge Base 提供全托管的 Smart Parsing(智能解析)能力。同步数据源时,服务会根据内容类型自动选择解析方式,无须指定解析模型;它不仅提取正文,还能够理解扫描文档、表格、图表、示意图、混合版式以及音视频内容。解析完成后,服务再按照所选分块策略生成可检索的内容片段。
AWS 官方资料当前明确列出的常用格式如下:
| 内容类型 | 支持的格式或扩展名 | 解析说明 |
|---|---|---|
| 纯文本与标记文档 | .txt、.md、.html |
.txt、.md 和 .html 应使用 UTF-8 编码 |
| Microsoft Word 文档 | .doc、.docx |
可提取正文;Smart Parsing 还能处理 DOCX 中的复杂版式和视觉内容 |
| Microsoft PowerPoint 演示文稿 | .ppt、.pptx |
可解析幻灯片中的文字、表格、图表和图片 |
| 表格与结构化文件 | .csv、.xls、.xlsx |
可提取表格内容并用于检索 |
| PDF 文档 | .pdf |
支持文本型 PDF、扫描型 PDF,以及包含表格、图表、示意图和图片的视觉内容 PDF |
| 独立图像 | .jpg、.jpeg、.png |
可处理图像中的文字和视觉信息;实际可用性还取决于数据源类型 |
| 音频与视频 | 音频文件、视频文件 | Managed Knowledge Base 能够解析媒体内容;具体封装格式、编码和限制应以所使用连接器的控制台提示及最新官方文档为准 |
对于视觉内容文档,AWS 当前明确说明 PDF、PPT/PPTX 和 DOCX 单文件最大为 500 MB;音频文件最大为 2 GB;视频文件最大为 10 GB。
目前 Bedrock 托管知识库仅支持
SMART_PARSING这一种解析器,不支持其他多模态模型作为文档解析器。由于SMART_PARSING对中文的支持有普遍问题,建议把 PDF 转换为 Markdown 后再上传到知识库。
5、使用托管知识库主要成本项
Amazon Bedrock Managed Knowledge Base 采用按实际存储量和检索调用量计费的模式。使用托管解析器、托管嵌入模型和托管重排序器时,这三项能力不单独收费;主要成本来自索引存储以及标准检索或代理式检索调用。
| 计费项目 | 计费单位 | 价格 | 说明 |
|---|---|---|---|
| Index Storage(索引存储) | 每 GB 原始数据、每月 | 5.00 美元 | 对同步到托管搜索索引中的原始数据容量收费,是知识库持续存在期间的主要固定成本 |
| Standard Retrieval(标准检索) | 每 1,000 次 Retrieve API 调用 |
1.00 美元 | 对托管索引执行语义与关键词混合检索 |
| Agentic Retrieval 代理式检索的 Agent 调用 | 每 1,000 次 AgenticRetrieveStream API 调用 |
4.00 美元 | 此项对应使用托管大语言模型进行查询规划的费用 |
| Agentic Retrieval 代理式检索的底层检索 | 每 1,000 次底层 Retrieve API 调用 |
1.00 美元 | 每次代理式检索可能执行一次或多次底层检索,因此需要与代理式检索调用费累加计算 |
二、配置 Managed Knowledge Base
1、准备数据源 - 以 S3 存储桶 + PDF 文件为例
本节使用 Amazon S3 存放 PDF 文档,并在后续步骤将该存储桶配置为 Managed Knowledge Base 的数据源。S3 存储桶必须是 General Purpose Bucket,并且必须与 Managed Knowledge Base 位于同一个 AWS 区域。
本文直接使用已经准备好的 bedrock-managed-kb-demo-us-east-1 存储桶,将用于测试的 PDF 文件上传到该存储桶。文末的清理步骤不会删除其中的对象或存储桶本身。
2、定义环境变量
REGION="us-east-1"
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
KB_NAME="managed-kb-pdf-demo"
DATA_SOURCE_NAME="managed-kb-pdf-s3-source"
KB_ROLE_NAME="BedrockManagedKbPdfDemoRole"
BUCKET_NAME="bedrock-managed-kb-demo-us-east-1"
printf 'REGION=%s\nACCOUNT_ID=%s\nBUCKET_NAME=%s\n' \
"$REGION" "$ACCOUNT_ID" "$BUCKET_NAME"
返回结果类似如下:
REGION=us-east-1
ACCOUNT_ID=123456789012
BUCKET_NAME=bedrock-managed-kb-demo-us-east-1
3、创建 Managed Knowledge Base 所需要的 IAM Role
创建知识库之前,需要准备一个知识库运行所需要的 IAM 角色。这个角色策略允许读取 S3原始数据存储桶。
需要注意的是,创建 IAM Policy 时候需要将 SourceArn 限定在当前账号和区域的 knowledge-base/*,这里需要用通配符。因为知识库目前还没有创建,当创建知识库时候,其 ARN ID 是自动分配的,因此在之前无法预知,所以先在 IAM Policy 内用通配符完成创建。创建完毕后,在生产上线前,再调整 Policy 到最小范围,把通配符替换为实际知识库 ID。
创建策略和角色:
cat > /tmp/managed-kb-trust-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "bedrock.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "${ACCOUNT_ID}"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:bedrock:${REGION}:${ACCOUNT_ID}:knowledge-base/*"
}
}
}
]
}
JSON
aws iam create-role \
--role-name "$KB_ROLE_NAME" \
--assume-role-policy-document file:///tmp/managed-kb-trust-policy.json \
--description "Service role for the Managed Knowledge Base PDF demo"
返回结果类似如下(部分字段节选):
{
"Role": {
"Path": "/",
"RoleName": "BedrockManagedKbPdfDemoRole",
"Arn": "arn:aws:iam::123456789012:role/BedrockManagedKbPdfDemoRole"
}
}
为服务角色添加最小化的 S3 读取权限。该策略只允许列出本文使用的存储桶并读取其中的对象:
cat > /tmp/managed-kb-s3-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListSourceBucket",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::${BUCKET_NAME}"
},
{
"Sid": "ReadSourceDocuments",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::${BUCKET_NAME}/*"
}
]
}
JSON
aws iam put-role-policy \
--role-name "$KB_ROLE_NAME" \
--policy-name "ReadManagedKbSource" \
--policy-document file:///tmp/managed-kb-s3-policy.json
KB_ROLE_ARN=$(aws iam get-role \
--role-name "$KB_ROLE_NAME" \
--query 'Role.Arn' \
--output text)
echo "KB_ROLE_ARN=$KB_ROLE_ARN"
返回结果类似如下:
KB_ROLE_ARN=arn:aws:iam::123456789012:role/BedrockManagedKbPdfDemoRole
4、检查当前执行者是否有 PassRole 权限(可选)
本文的一系列操作都是基于 AWS CLI 脚本进行,这样无须在 AWS 控制台界面上点击,只要复制/粘贴脚本就可以运行。如果您本机为 AWS CLI 配置的 Access Key/Secret Key 是具备管理员权限的,那么可以跳过本章节。如果您的 Access Key/Secret Key 是隶属于一个普通的 IAM User,那么这个 IAM User 还需要具有 PassRole 权限。需要为当前执行者再加挂如下 IAM Policy。
请替换其中的变量为真实实验环境。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PassManagedKnowledgeBaseRoleToBedrock",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::${ACCOUNT_ID}:role/${KB_ROLE_NAME}",
"Condition": {
"StringEquals": {
"iam:PassedToService": "bedrock.amazonaws.com"
}
}
}
]
}
5、创建知识库
等待 IAM 角色完成传播后,生成 Managed Knowledge Base 配置:
cat > /tmp/managed-kb-config.json <<'JSON'
{
"type": "MANAGED",
"managedKnowledgeBaseConfiguration": {
"embeddingModelType": "MANAGED"
}
}
JSON
创建 Managed Knowledge Base,并保存返回的 Knowledge Base ID:
KB_ID=$(aws bedrock-agent create-knowledge-base \
--name "$KB_NAME" \
--description "Managed Knowledge Base for the S3 PDF demo" \
--role-arn "$KB_ROLE_ARN" \
--knowledge-base-configuration file:///tmp/managed-kb-config.json \
--region "$REGION" \
--query 'knowledgeBase.knowledgeBaseId' \
--output text)
echo "KB_ID=$KB_ID"
返回结果类似如下,其中 Knowledge Base ID 是由服务生成的 10 位标识符:
KB_ID=ABCDEFGHIJ
创建知识库时候会立刻返回知识库 ID,但是创建到就绪需要1-3分钟才能完成。
执行如下命令查询状态:
aws bedrock-agent get-knowledge-base \
--knowledge-base-id "$KB_ID" \
--region "$REGION" \
--query 'knowledgeBase.{Id:knowledgeBaseId,Name:name,Status:status,FailureReasons:failureReasons}'
以上命令返回的 Status 字段为 CREATING 则是创建中,创建完成后 ACTIVE。如果状态为 FAILED,应先查看 FailureReasons,不要继续创建数据源。
6、创建完毕后更新 IAM Policy 到最小化权限(可跳过、但推荐执行)
前文创建时候提到了先在 IAM Policy 中通配符授权,允许 Bedrock 做知识库所有操作。创建完毕后,日常运行应将 Bedrock 访问权限缩小到仅 当前 Knowledge Base ID。
编写如下策略完成修改:
cat > /tmp/managed-kb-trust-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "bedrock.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "${ACCOUNT_ID}"
},
"ArnEquals": {
"aws:SourceArn": "arn:aws:bedrock:${REGION}:${ACCOUNT_ID}:knowledge-base/${KB_ID}"
}
}
}
]
}
JSON
aws iam update-assume-role-policy \
--role-name "$KB_ROLE_NAME" \
--policy-document file:///tmp/managed-kb-trust-policy.json
执行成功的话没有任何返回结果,不会报错。
7、为知识库创建 S3 Managed Connector
下面生成 S3 Managed Connector 配置文件并加载。
cat > /tmp/managed-kb-s3-connector.json <<JSON
{
"type": "MANAGED_KNOWLEDGE_BASE_CONNECTOR",
"managedKnowledgeBaseConnectorConfiguration": {
"mediaExtractionConfiguration": {
"imageExtractionConfiguration": {
"imageExtractionStatus": "ENABLED"
}
},
"connectorParameters": {
"type": "S3",
"version": "1",
"connectionConfiguration": {
"bucketName": "${BUCKET_NAME}",
"bucketOwnerAccountId": "${ACCOUNT_ID}"
}
}
}
}
JSON
DATA_SOURCE_ID=$(aws bedrock-agent create-data-source \
--knowledge-base-id "$KB_ID" \
--name "$DATA_SOURCE_NAME" \
--description "PDF documents stored in the S3 data source bucket" \
--data-source-configuration file:///tmp/managed-kb-s3-connector.json \
--data-deletion-policy DELETE \
--vector-ingestion-configuration \
'{"parsingConfiguration":{"parsingStrategy":"SMART_PARSING"}}' \
--region "$REGION" \
--query 'dataSource.dataSourceId' \
--output text)
echo "DATA_SOURCE_ID=$DATA_SOURCE_ID"
返回结果类似如下:
DATA_SOURCE_ID=ABCDEFGHIJ
创建数据源后立刻返回 ID,但其状态变为 AVAILABLE 可能需要等待几分钟。执行如下命令检查状态:
aws bedrock-agent get-data-source \
--knowledge-base-id "$KB_ID" \
--data-source-id "$DATA_SOURCE_ID" \
--region "$REGION" \
--query 'dataSource.{Id:dataSourceId,Name:name,Status:status,FailureReasons:failureReasons}'
只有数据源达到 AVAILABLE 状态后,才能启动首次同步。
8、同步数据/更新数据
执行如下命令启动数据摄取,并保存 Ingestion Job ID:
INGESTION_JOB_ID=$(aws bedrock-agent start-ingestion-job \
--knowledge-base-id "$KB_ID" \
--data-source-id "$DATA_SOURCE_ID" \
--description "Initial ingestion of PDF documents" \
--region "$REGION" \
--query 'ingestionJob.ingestionJobId' \
--output text)
echo "INGESTION_JOB_ID=$INGESTION_JOB_ID"
返回结果类似如下:
INGESTION_JOB_ID=ABCDEFGHIJ
查询数据摄取状态和统计信息:
aws bedrock-agent get-ingestion-job \
--knowledge-base-id "$KB_ID" \
--data-source-id "$DATA_SOURCE_ID" \
--ingestion-job-id "$INGESTION_JOB_ID" \
--region "$REGION" \
--query 'ingestionJob.{Status:status,Statistics:statistics,FailureReasons:failureReasons}'
在摄取过程中,返回结果显示的状态为 IN_PROGRESS,扫描成功完成后应返回 COMPLETE。Statistics 中应显示扫描和索引的文档数量,并且失败文档数量应为 0。如果您的知识库文件较多,或者文件数量较少但是篇幅多,且打开了图片识别,那么第一次扫描花费数分钟时间是正常的。
如果后续新增、修改或删除 S3 中的文件,需要再次调用 start-ingestion-job;后续同步是增量执行的,仅扫描变化的文件。
所有成功同步到知识库的数据,都可以被具备该知识库 bedrock:Retrieve 权限的 IAM 身份检索。如果您需要针对同一个存储桶内知识库读取文件时候进行更细致的权限配置,例如对同一个存储桶内的不同文件分别授权给不同知识库,那么可以通过 S3 Prefix 前缀,以及 ACL 来配置。具体请参考官方文档:https://docs.aws.amazon.com/bedrock/latest/userguide/kb-test-retrieve-acl.html
至此配置完成,现在开始编写查询代码。
三、使用 AWS SDK 查询知识库 - Python 代码示例
1、环境配置
Managed Knowledge Base 支持 Retrieve 和 AgenticRetrieveStream 两类查询 API。
注意:Managed Knowledge Base 不能使用过去知识库示例的
RetrieveAndGenerate或RetrieveAndGenerateStreamAPI。如果需要由服务进行多步骤检索并生成带引用的答案,应改用AgenticRetrieveStream。
(1) 运行查询知识库需要的最小权限
运行 Python 程序的 IAM 身份至少需要对目标知识库执行 bedrock:Retrieve。建议使用如下最小权限策略,并将占位符替换为实际值:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RetrieveFromManagedKnowledgeBase",
"Effect": "Allow",
"Action": "bedrock:Retrieve",
"Resource": "arn:aws:bedrock:<REGION>:<ACCOUNT_ID>:knowledge-base/<KB_ID>"
}
]
}
(2) 克隆代码
Python 环境使用 uv 统一管理。将代码从 Github 克隆到本地,同步环境,然后即可运行。
# 安装 uv 包管理工具
# MacOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows Powershell
# powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# 克隆代码
git clone <Github地址>
cd python
uv sync
(3) 设置环境变量
现在需要通过环境变量传入区域和知识库 ID 。注意,本文第二章创建知识库使用的环境变量是 Shell 级别的环境变量,Python代码读取不到,因此需要再设置一次环境变量。在本文第二章节中,执行 echo $KB_ID 可打出知识库 ID。
如果之前的终端窗口关闭了,那么可以执行如下命令获取知识库 ID。
aws bedrock-agent list-knowledge-bases \
--region us-east-1 \
--query 'knowledgeBaseSummaries[].{ID:knowledgeBaseId,Name:name}' \
--output table
返回结果包含 ID 和知识库名称。将知识库 ID 代入环境变量:
export AWS_REGION="us-east-1"
export KB_ID="<知识库 ID>"
2、调用检索召回接口(Retrieve)
本节先使用同步的 Retrieve API 完成单次混合检索。该接口返回相关文本片段、相关性分数和来源位置,不调用生成式模型组织最终答案,适合由应用自行处理检索结果。
uv run python retrieve_managed_kb.py "上车、下车的发动机功率各自是多少?"
由此可看到 Bedrock Managed 知识库和查询代码工作正常。其中返回结果会包含 score 召回得分、知识库出处(原始S3的URL)、相关文字等。
如果返回 AccessDeniedException,应检查运行程序的 IAM 身份是否具备 bedrock:Retrieve,以及策略中的区域、账号和 Knowledge Base ID 是否准确。如果返回空结果,应确认 Ingestion Job 状态已经变为 COMPLETE,并检查摄取统计信息中是否存在失败文档。
3、调用代理式检索接口(AgenticRetrieveStream)
(1) 代理式检索接口工作原理
AgenticRetrieveStream 是 Managed Knowledge Base 提供的代理式检索接口。与只执行一次检索并返回相关片段的 Retrieve 不同,它会调用基础模型分析问题,将复杂问题拆分为一个或多个子查询,针对配置的知识库执行多轮检索,并判断当前结果是否足以回答原始问题。如果信息不足,服务会继续规划和检索;如果需要总结整篇文档或核对完整上下文,还可以通过 GetDocumentContent 展开全文。默认情况下,接口会基于最终检索结果流式生成自然语言答案及引用。
| 对比 | Retrieve |
AgenticRetrieveStream |
|---|---|---|
| 检索过程 | 单次混合检索 | 基础模型规划、多轮检索和结果充分性评估 |
| 返回内容 | 文本片段、分数和来源 | 流式答案、引用、去重后的检索结果和执行轨迹 |
| 复杂问题 | 由应用自行拆解和组合结果 | 自动拆分多跳问题并迭代补充信息 |
| 模型调用 | 不生成答案 | 默认调用基础模型规划并生成答案 |
| 延迟与成本 | 较低且相对稳定 | 因模型调用和多轮检索而更高 |
| 适用场景 | 搜索、召回、由应用自行生成答案 | 跨章节对比、归纳总结、多条件分析和需要引用的复杂问答 |
其主要执行过程如下:
用户问题
↓
Planning:分析问题并生成子查询
↓
Retrieval:对一个或多个知识库执行检索
↓
评估结果是否充分 ── 否 ──→ 继续规划和检索
│
├─ 必要时执行 Full document expansion,读取完整文档
↓ 是
Response generation:流式生成答案
↓
Result:返回去重结果、完整答案和引用
该接口返回事件流,应用需要逐个处理以下事件:
traceEvent:报告Planning、Retrieval、SpeculativeRetrieval和FullDocumentExpansion等步骤,适合展示进度或排查检索过程;responseEvent:包含生成答案的增量文本片段,应用可以边接收边显示;result:最后返回去重后的检索结果,以及完整答案和引用信息;- 异常事件:可能包含权限不足、限流、依赖失败或参数校验失败等信息。
(2) 调用代理式检索接口的最小 IAM 权限
AgenticRetrieveStream 不仅需要读取知识库,还需要调用基础模型和在必要时读取完整文档。运行代码的 IAM 身份至少需要如下权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RunAgenticRetrieval",
"Effect": "Allow",
"Action": "bedrock:AgenticRetrieveStream",
"Resource": "*"
},
{
"Sid": "ReadManagedKnowledgeBase",
"Effect": "Allow",
"Action": [
"bedrock:Retrieve",
"bedrock:GetDocumentContent"
],
"Resource": "arn:aws:bedrock:<REGION>:<ACCOUNT_ID>:knowledge-base/<KB_ID>"
},
{
"Sid": "InvokePlanningAndResponseModel",
"Effect": "Allow",
"Action": "bedrock:InvokeModelWithResponseStream",
"Resource": "*"
}
]
}
注意:以上策略按照 AWS 当前官方示例,对 AgenticRetrieveStream 和 InvokeModelWithResponseStream 使用 Resource: "*",知识库读取权限则限定到本文创建的 Knowledge Base ARN。生产环境还应结合权限边界、Service Control Policy(SCP,服务控制策略)和受支持的资源级权限进一步约束调用范围。如果配置 Guardrail,还需要增加 bedrock:GetGuardrail 和 bedrock:ApplyGuardrail 权限。
(3) 运行代码示例
项目中的 agentic_retrieve_managed_kb.py 使用托管基础模型和托管重排序模型,处理流式答案,并将引用映射回 S3 来源。执行如下命令:
uv run python agentic_retrieve_managed_kb.py "这份文档描述了这款产品的哪些信息?"
如需查看规划、检索、推测性检索和全文展开过程,可以增加 --show-trace 参数。
注意:代理式检索会产生基础模型调用、多轮检索、重排序以及可能的全文读取成本,延迟也高于单次
Retrieve。对于关键词搜索或单一事实查询,应优先使用Retrieve;只有问题需要跨文档、跨章节推理或自动生成带引用答案时,才建议使用AgenticRetrieveStream。
四、使用 AWS SDK 查询知识库 - Java 代码示例
1、环境配置
运行环境使用 Java 11 或更高版本,可以选择 OpenJDK 或 Amazon Corretto 等发行版。
# 克隆代码
git clone <Github地址>
cd java
mvn clean package
现在设置知识库 ID。如果之前的创建知识库的终端窗口关闭了,那么可以执行如下命令获取知识库 ID。
aws bedrock-agent list-knowledge-bases \
--region us-east-1 \
--query 'knowledgeBaseSummaries[].{ID:knowledgeBaseId,Name:name}' \
--output table
返回结果包含 ID 和知识库名称。将知识库 ID 代入环境变量:
export AWS_REGION="us-east-1"
export KB_ID="<知识库 ID>"
2、仅调用检索召回接口(Retrieve)
mvn clean package 会通过 Maven Shade Plugin 将程序及 AWS SDK 依赖分别打入两个可执行 JAR。其中,本节使用的 target/retrieve-managed-kb.jar 已将 RetrieveManagedKb 写入 JAR 的 Main-Class 清单,因此运行时不需要再声明 Java 类名。
Retrieve API 只执行一次检索,返回相关文本片段、相关性分数和原始文档位置,不调用基础模型生成答案。该方式的延迟和成本相对较低,适合关键词搜索、单一事实查询,以及由应用自行处理检索结果的场景。运行程序的 IAM 身份需要具备第三章第 1 节所述的 bedrock:Retrieve 权限。
执行如下命令:
java -jar target/retrieve-managed-kb.jar "上车、下车的发动机功率各自是多少?"
程序使用 Managed Search 执行检索,将最大返回结果数设置为 5,并使用 MANAGED 类型的托管重排序模型。返回结果包含相关性分数、知识库来源和召回文本,输出结构如下,其中具体内容由知识库中的文档决定:
[1] score=<相关性分数>
source=s3://<bucket-name>/<object-key>
<召回文本>
如果不希望通过 KB_ID 环境变量传入知识库 ID,也可以在命令行中显式指定。命令行参数的优先级高于环境变量:
java -jar target/retrieve-managed-kb.jar \
--knowledge-base-id "<Knowledge Base ID>" \
"上车、下车的发动机功率各自是多少?"
如果返回权限不足错误,应检查当前 IAM 身份是否具备目标知识库的 bedrock:Retrieve 权限。如果没有返回检索结果,应确认 Ingestion Job 已经完成,并检查数据源同步统计信息中是否存在失败文档。下面转向代理式检索接口。
3、调用代理式检索接口(AgenticRetrieveStream)
本节使用独立的 target/agentic-retrieve-managed-kb.jar。该 JAR 已将 AgenticRetrieveManagedKb 写入 Main-Class 清单,可以直接通过 java -jar 启动,不需要声明类名,也不需要传入用于选择场景的子命令。
AgenticRetrieveStream 会使用托管基础模型分析问题,按需生成子查询并执行多轮检索,然后以事件流方式返回生成答案、引用和最终检索结果。示例同时将基础模型类型和重排序模型类型设置为 MANAGED。运行程序的 IAM 身份需要具备第三章第 3 节所述的 bedrock:AgenticRetrieveStream、bedrock:Retrieve、bedrock:GetDocumentContent 和 bedrock:InvokeModelWithResponseStream 权限。
执行如下命令:
java -jar target/agentic-retrieve-managed-kb.jar "这份文档描述了这款产品的哪些信息?"
程序会持续输出 responseEvent 中的增量文本,并在收到最终 result 事件后输出引用片段及其 S3 来源。输出结构如下:
回答:
<流式生成的答案>
引用:
[1] <引用片段>
source=s3://<bucket-name>/<object-key>
如需观察 Planning、Retrieval、Speculative Retrieval 和 Full Document Expansion 等代理执行步骤,可以增加 --show-trace 参数。Trace 信息输出到标准错误流,不会影响标准输出中的答案内容:
java -jar target/agentic-retrieve-managed-kb.jar \
--show-trace \
"这份文档描述了这款产品的哪些信息?"
注意:AgenticRetrieveStream 会产生基础模型调用、多轮检索、托管重排序以及可能的全文读取成本,其延迟和费用通常高于单次 Retrieve。对于单一事实查询,应优先使用上一节的 retrieve-managed-kb.jar;只有问题需要跨章节分析、自动拆解或生成带引用答案时,才建议使用本节的代理式检索接口。
五、将知识库封装为 MCP 便于从互联网应用调用和集成
第二章到第四章展示的是通过 AWS SDK 直接调用 Retrieve 与 AgenticRetrieveStream 检索知识库。如果需要让运行在开发者本机或互联网应用中的 AI 工具,以标准 MCP(Model Context Protocol,模型上下文协议)方式调用知识库,则需要把知识库挂载到 Bedrock AgentCore Gateway。Gateway 会将一个托管知识库暴露为两个 MCP 工具:Retrieve 执行单次混合检索,AgenticRetrieveStream 执行多步骤代理式检索并流式返回带引用的答案;调用方无须在请求中传入 Knowledge Base ID,知识库 ID 被隐藏在 Gateway 之后。
Managed Knowledge Base 作为 Gateway Connector Target 时,出站认证只支持基于 IAM 的 GATEWAY_IAM_ROLE 凭证提供方类型,即 Gateway 以 bedrock 服务身份代入执行角色调用知识库。入站认证,即 MCP 客户端到 Gateway 之间的认证,则由 Gateway 的 Authorizer 决定,可选 AWS IAM 或 CUSTOM_JWT 两类。在面向一般开发者的场景中,开发者可能因为企业权限管理的关系,本机并不具备 IAM Access Key/Secret Key,因此从管理便利性上,本机的 AI 开发工具采用 JWT 认证更加方便。实际配置中,可采用 Amazon Cognito 签发 JWT 的 CUSTOM_JWT 认证方式,客户端配置文件中不写入任何长期密钥,首次使用时经浏览器登录完成认证,后续由 Refresh Token 静默续期。
本章给出两条路径,二选一即可:
- 第 1 节:针对已创建的 AgentCore Gateway、现存 Cognito 用户池和用户,仅为其新增一个知识库 Target。适用于此前创建过 AgentCore Gateway 并且挂载有别的 MCP 的场景。
- 第 2 节:从零创建一个全新的 Gateway,包含 Cognito 认证服务与知识库 Target。适用于尚无任何 AgentCore Gateway 与认证服务的全新环境。
无论采用哪条路径,AgentCore Gateway 执行角色都必须具备校验和检索知识库的权限:
bedrock:GetKnowledgeBase用于创建 Target 时校验知识库;bedrock:Retrieve对应Retrieve工具;bedrock:AgenticRetrieveStream对应AgenticRetrieveStream工具。
其中前两者可限定到具体的 Knowledge Base ARN,bedrock:AgenticRetrieveStream 不支持资源级限定,只能授予 *。
1、将托管知识库挂载到现有的 Bedrock AgentCore Gateway 上
本节复用 AgentCore Gateway 和现有 Cognito 用户池。前提条件如下:
- AgentCore Gateway 已创建使用 CUSTOM_JWT 认证,认证已指向现有 Cognito 用户池;
- 已取得本文第二章创建的 Knowledge Base ID,且知识库状态为
ACTIVE; - 操作者具备修改 IAM 角色和策略权限。
(1) 定义环境变量
首先定义环境变量。查询现有知识库 ID。执行如下命令:
aws bedrock-agent list-knowledge-bases \
--region us-east-1 \
--query 'knowledgeBaseSummaries[].{ID:knowledgeBaseId,Name:name}' \
--output table
返回结果类似如下:
---------------------------------------
| ListKnowledgeBases |
+-------------+-----------------------+
| ID | Name |
+-------------+-----------------------+
| ABCDEFGHIJ | managed-kb-pdf-demo |
+-------------+-----------------------+
这里可包含 ID 和知识库名称。
将知识库 ID 代入环境变量。其中 GATEWAY_NAME 为现有创建的 AgentCore Gateway 名称,KB_ID 替换为查询知识库实际返回的值:
REGION="us-east-1"
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
GATEWAY_NAME="websearch-kiro-jwt-gateway"
KB_ID="<刚才获取的知识库ID>"
GATEWAY_ID=$(aws bedrock-agentcore-control list-gateways \
--region "$REGION" \
--query "items[?name=='${GATEWAY_NAME}'].gatewayId | [0]" \
--output text)
echo "GATEWAY_ID=$GATEWAY_ID"
返回结果类似如下:
GATEWAY_ID=websearch-kiro-jwt-gateway-xxxxxxxxxx
(2) IAM Policy 配置
Managed Knowledge Base 连接器复用 Gateway 创建时指定的执行角色,因此需要在该角色上补充知识库检索权限。执行如下命令查出该 Gateway 当前使用的执行角色名称:
KB_GATEWAY_ROLE_ARN=$(aws bedrock-agentcore-control get-gateway \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query 'roleArn' \
--output text)
KB_GATEWAY_ROLE_NAME="${KB_GATEWAY_ROLE_ARN##*/}"
echo "KB_GATEWAY_ROLE_NAME=$KB_GATEWAY_ROLE_NAME"
返回结果类似如下:
KB_GATEWAY_ROLE_NAME=AgentCoreWebSearchKiroGatewayRole
为该执行角色新增一条只读检索知识库的内联策略。该策略把校验和检索权限限定到当前知识库,bedrock:AgenticRetrieveStream 按官方要求授予 *:
cat > /tmp/managed-kb-gateway-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ValidateKnowledgeBase",
"Effect": "Allow",
"Action": "bedrock:GetKnowledgeBase",
"Resource": "arn:aws:bedrock:${REGION}:${ACCOUNT_ID}:knowledge-base/${KB_ID}"
},
{
"Sid": "RetrieveFromKnowledgeBase",
"Effect": "Allow",
"Action": "bedrock:Retrieve",
"Resource": "arn:aws:bedrock:${REGION}:${ACCOUNT_ID}:knowledge-base/${KB_ID}"
},
{
"Sid": "AgenticRetrieveStream",
"Effect": "Allow",
"Action": "bedrock:AgenticRetrieveStream",
"Resource": "*"
}
]
}
JSON
aws iam put-role-policy \
--role-name "$KB_GATEWAY_ROLE_NAME" \
--policy-name "ManagedKbRetrievePolicy" \
--policy-document file:///tmp/managed-kb-gateway-policy.json
执行成功没有终端回显。备注:为既有 Web Search Gateway 的执行角色追加知识库权限后,该角色会同时具备调用 Web Search 后端和检索知识库两类权限,这是符合预期的,同一个 Gateway 会同时暴露 Web Search 与知识库两组工具。
(3) 将知识库挂载到 Gateway
下面生成知识库 Target 的连接器配置文件。连接器 ID 固定为 bedrock-knowledge-bases;示例同时挂载 AgenticRetrieveStream 与 Retrieve 两个工具,基础模型类型与重排序模型类型均使用 MANAGED。
MCP 工具暴露给调用方(如 Kiro)的能力描述,通过每个工具配置项中与 name 同级的 description 字段设置。调用方执行 /mcp 或让 Agent 发现工具时看到的正是这段文本,因此应写清该工具的检索行为与适用场景。需要区分以下三处 description,它们作用各不相同:
- 工具配置项顶层的
description(与name同级):即 MCP 工具本身的能力描述,是本节要设置的字段; retrievers[].description:仅用于AgenticRetrieveStream,描述某个被检索的知识库(retriever),供代理式检索在多知识库场景下区分数据来源,不是工具描述;parameterOverrides[].description:描述某个暴露给 Agent 的入参(如查询文本、返回条数),用于向 Agent 说明该参数含义,属于可选配置。
以下配置为两个工具分别写入了顶层 description,可按知识库实际内容自行修改:
cat > /tmp/managed-kb-gateway-target.json <<JSON
{
"mcp": {
"connector": {
"source": {
"connectorId": "bedrock-knowledge-bases"
},
"configurations": [
{
"name": "AgenticRetrieveStream",
"description": "检索工程机械知识的托管知识库并生成答案。原始文件位于 S3 存储桶,执行多步骤代理式检索:自动拆解复杂问题、多轮检索并按需展开全文,流式返回带引用的综合答案。适用于跨章节归纳、多条件分析等需要引用的复杂问答。",
"parameterValues": {
"retrievers": [
{
"description": "返回结果的知识原始位置是 S3 存储桶 URL 文档知识库",
"configuration": {
"knowledgeBase": {
"knowledgeBaseId": "${KB_ID}"
}
}
}
],
"agenticRetrieveConfiguration": {
"foundationModelType": "MANAGED",
"rerankingModelType": "MANAGED"
}
}
},
{
"name": "Retrieve",
"description": "检索工程机械知识的托管知识库。原始文件位于 S3 存储桶,仅执行检索, 返回与查询最相关的原始文本片段、相关性分数及 S3 来源,不生成答案。适用于关键词搜索和单一事实查询。",
"parameterValues": {
"knowledgeBaseId": "${KB_ID}"
}
}
]
}
}
}
JSON
TARGET_ID=$(aws bedrock-agentcore-control create-gateway-target \
--gateway-identifier "$GATEWAY_ID" \
--name "managed-kb" \
--target-configuration file:///tmp/managed-kb-gateway-target.json \
--credential-provider-configurations '[{"credentialProviderType":"GATEWAY_IAM_ROLE"}]' \
--region "$REGION" \
--query targetId --output text)
echo "TARGET_ID=$TARGET_ID"
返回结果类似如下:
TARGET_ID=XXXXXXXXXX
创建 Target 后,Gateway 会异步校验配置,通常约 30 秒完成,其间会对绑定的知识库执行一次 GetKnowledgeBase 校验。执行如下命令查询 Target 状态,等待其变为 READY:
aws bedrock-agentcore-control list-gateway-targets \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query "items[?name=='managed-kb'].{targetId:targetId,status:status}"
返回结果如下:
[
{
"targetId": "XXXXXXXXXX",
"status": "READY"
}
]
如果状态为 FAILED,返回结果会包含失败原因,常见原因是执行角色缺少 bedrock:GetKnowledgeBase 权限、Knowledge Base ID 拼写错误或知识库尚未 ACTIVE。
(4) 使用者客户端 MCP 配置
上一步的 Target 变为 READY 后,MCP 客户端无须改动配置即可发现新工具。以 Kiro 为例,在完成 MCP 认证的前提下,重新执行 /mcp 即可在 agentcore-gateway 下看到 Retrieve 与 AgenticRetrieveStream 两个新增的知识库工具,随后在对话中提问即可触发对知识库的检索。
由于复用的是同一个 Gateway URL 和同一个 Cognito 应用客户端,MCP 客户端(如 Kiro)的 mcp.json 配置无须任何改动;为 Gateway 新增知识库 Target 后,Retrieve 与 AgenticRetrieveStream 两个工具会自动出现在既有的 MCP 工具清单中。
现在即可正常调用知识库 MCP。
2、创建全新的 Bedrock AgentCore Gateway
本节面向尚无任何 Gateway 与认证服务的全新环境,从零创建 Cognito 认证服务,再创建一个 CUSTOM_JWT 认证的 Gateway 并挂载知识库 Target。
(1) 定义环境变量
因为知识库目前只在 us-east-1 可用,因此 Cognito 也创建在同一区域。定义环境变量:
REGION="us-east-1"
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
USER_POOL_NAME="managed-kb-pool"
COGNITO_DOMAIN_PREFIX="managed-kb-${ACCOUNT_ID}"
补充 Gateway 与角色相关的变量,并替换 KB_ID 为第二章知识库实际返回的值:
KB_ID="<第二章创建的 Knowledge Base ID>"
KB_GATEWAY_ROLE_NAME="ManagedKbGatewayRole"
KB_GATEWAY_NAME="managed-kb-mcp-gateway"
(2) 创建 Cognito
创建 Cognito 用户池:
USER_POOL_ID=$(aws cognito-idp create-user-pool \
--pool-name "$USER_POOL_NAME" \
--region "$REGION" \
--query 'UserPool.Id' --output text)
echo "USER_POOL_ID=$USER_POOL_ID"
返回结果类似如下(形如 us-east-1_xxxxxxxxx):
USER_POOL_ID=us-east-1_xxxxxxxxx
创建 Cognito 托管登录域名。为简化测试,显式指定 --managed-login-version 1,即使用经典 Hosted UI 版本,无须额外配置 branding style;域名前缀用账号 ID 拼接以保证全局唯一:
aws cognito-idp create-user-pool-domain \
--domain "$COGNITO_DOMAIN_PREFIX" \
--user-pool-id "$USER_POOL_ID" \
--managed-login-version 1 \
--region "$REGION"
命令执行成功后回显所设置的托管登录版本:
{
"ManagedLoginVersion": 1
}
(3) 创建 Cognito 应用
域名创建后需要 3-5 分钟才能生效。创建应用客户端,采用 Authorization Code + PKCE 授权流,回调地址使用不常见端口 38123 以规避端口冲突:
CLIENT_ID=$(aws cognito-idp create-user-pool-client \
--user-pool-id "$USER_POOL_ID" \
--client-name "kiro-managed-kb-authcode-client" \
--no-generate-secret \
--allowed-o-auth-flows code \
--allowed-o-auth-scopes openid \
--allowed-o-auth-flows-user-pool-client \
--callback-urls "http://localhost:38123/oauth/callback" \
--supported-identity-providers COGNITO \
--prevent-user-existence-errors ENABLED \
--region "$REGION" \
--query 'UserPoolClient.ClientId' --output text)
echo "CLIENT_ID=$CLIENT_ID"
返回结果类似如下:
CLIENT_ID=xxxxxxxxxxxxxxxxxx
(4) 创建 Cognito 用户名和密码
以管理员身份创建测试用户 user01 并设置永久密码,密码需满足用户池的密码策略:
TEST_USERNAME="user01"
TEST_PASSWORD="<自定义一个满足密码策略的强密码>"
aws cognito-idp admin-create-user \
--user-pool-id "$USER_POOL_ID" \
--username "$TEST_USERNAME" \
--user-attributes Name=email,Value="kb-tester@example.com" Name=email_verified,Value=true \
--message-action SUPPRESS \
--region "$REGION"
aws cognito-idp admin-set-user-password \
--user-pool-id "$USER_POOL_ID" \
--username "$TEST_USERNAME" \
--password "$TEST_PASSWORD" \
--permanent \
--region "$REGION"
至此 Cognito 认证服务创建完毕,其中 USER_POOL_ID 与 CLIENT_ID 将在下一步配置 Gateway 的 JWT Authorizer 时使用。接下来创建 Gateway。
(5) 创建 AgentCore Gateway 需要的 IAM Policy 和 Role
创建 Gateway 执行角色。信任策略仅允许 bedrock-agentcore.amazonaws.com 代入该角色,并用 aws:SourceAccount 与 aws:SourceArn 限定到本账号的 Gateway:
cat > /tmp/managed-kb-gateway-trust.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAgentCoreToAssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "bedrock-agentcore.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "${ACCOUNT_ID}"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:bedrock-agentcore:${REGION}:${ACCOUNT_ID}:gateway/*"
}
}
}
]
}
JSON
aws iam create-role \
--role-name "$KB_GATEWAY_ROLE_NAME" \
--assume-role-policy-document file:///tmp/managed-kb-gateway-trust.json \
--description "Service role for the Managed Knowledge Base MCP gateway"
返回结果类似如下(部分字段节选):
{
"Role": {
"RoleName": "ManagedKbGatewayRole",
"Arn": "arn:aws:iam::123456789012:role/ManagedKbGatewayRole"
}
}
为该角色写入检索知识库所需的权限策略,内容与第 1 节一致:
cat > /tmp/managed-kb-gateway-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ValidateKnowledgeBase",
"Effect": "Allow",
"Action": "bedrock:GetKnowledgeBase",
"Resource": "arn:aws:bedrock:${REGION}:${ACCOUNT_ID}:knowledge-base/${KB_ID}"
},
{
"Sid": "RetrieveFromKnowledgeBase",
"Effect": "Allow",
"Action": "bedrock:Retrieve",
"Resource": "arn:aws:bedrock:${REGION}:${ACCOUNT_ID}:knowledge-base/${KB_ID}"
},
{
"Sid": "AgenticRetrieveStream",
"Effect": "Allow",
"Action": "bedrock:AgenticRetrieveStream",
"Resource": "*"
}
]
}
JSON
aws iam put-role-policy \
--role-name "$KB_GATEWAY_ROLE_NAME" \
--policy-name "ManagedKbRetrievePolicy" \
--policy-document file:///tmp/managed-kb-gateway-policy.json
(6) 创建使用 CUSTOM_JWT 认证的 AgentCore Gateway
新建的 IAM 角色需要数秒钟才能完全生效,建议等待 1 分钟左右后再创建 Gateway,以降低 PassRole 校验失败的概率。
随后创建 CUSTOM_JWT 认证的 Gateway,其 JWT Authorizer 指向上一小节用户池的 Discovery URL,allowedClients 填入上一小节的应用客户端 ID:
KB_GATEWAY_ROLE_ARN=$(aws iam get-role \
--role-name "$KB_GATEWAY_ROLE_NAME" \
--query Role.Arn --output text)
DISCOVERY_URL="https://cognito-idp.${REGION}.amazonaws.com/${USER_POOL_ID}/.well-known/openid-configuration"
aws bedrock-agentcore-control create-gateway \
--name "$KB_GATEWAY_NAME" \
--role-arn "$KB_GATEWAY_ROLE_ARN" \
--protocol-type MCP \
--authorizer-type CUSTOM_JWT \
--authorizer-configuration "{
\"customJWTAuthorizer\": {
\"discoveryUrl\": \"${DISCOVERY_URL}\",
\"allowedClients\": [\"${CLIENT_ID}\"],
\"allowedScopes\": [\"openid\"]
}
}" \
--description "Managed Knowledge Base MCP gateway (CUSTOM_JWT inbound auth)" \
--region "$REGION"
获取 Gateway ID 与状态,等待 status 变为 READY:
GATEWAY_ID=$(aws bedrock-agentcore-control list-gateways \
--region "$REGION" \
--query "items[?name=='${KB_GATEWAY_NAME}'].gatewayId | [0]" \
--output text)
aws bedrock-agentcore-control get-gateway \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query '{status:status, gatewayUrl:gatewayUrl}'
返回结果类似如下:
{
"status": "READY",
"gatewayUrl": "https://managed-kb-mcp-gateway-xxxxxxxxxx.gateway.bedrock-agentcore.us-east-1.amazonaws.com/mcp"
}
(7) 将知识库挂载到 AgentCore Gateway
Gateway 就绪后,挂载知识库 Target。连接器配置与第 1 节相同,同时暴露 AgenticRetrieveStream 与 Retrieve 两个工具:
cat > /tmp/managed-kb-gateway-target.json <<JSON
{
"mcp": {
"connector": {
"source": {
"connectorId": "bedrock-knowledge-bases"
},
"configurations": [
{
"name": "AgenticRetrieveStream",
"description": "对 S3 PDF 知识库执行多步骤代理式检索:自动拆解复杂问题、多轮检索并按需展开全文,流式返回带引用的综合答案。适用于跨章节归纳、多条件分析等需要引用的复杂问答。",
"parameterValues": {
"retrievers": [
{
"description": "S3 PDF 文档知识库",
"configuration": {
"knowledgeBase": {
"knowledgeBaseId": "${KB_ID}"
}
}
}
],
"agenticRetrieveConfiguration": {
"foundationModelType": "MANAGED",
"rerankingModelType": "MANAGED"
}
}
},
{
"name": "Retrieve",
"description": "对 S3 PDF 知识库执行单次混合检索,返回与查询最相关的原始文本片段、相关性分数及 S3 来源,不生成答案。适用于关键词搜索和单一事实查询。",
"parameterValues": {
"knowledgeBaseId": "${KB_ID}"
}
}
]
}
}
}
JSON
TARGET_ID=$(aws bedrock-agentcore-control create-gateway-target \
--gateway-identifier "$GATEWAY_ID" \
--name "managed-kb" \
--target-configuration file:///tmp/managed-kb-gateway-target.json \
--credential-provider-configurations '[{"credentialProviderType":"GATEWAY_IAM_ROLE"}]' \
--region "$REGION" \
--query targetId --output text)
echo "TARGET_ID=$TARGET_ID"
返回结果类似如下:
TARGET_ID=XXXXXXXXXX
查询 Target 状态,等待其变为 READY:
aws bedrock-agentcore-control list-gateway-targets \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query "items[?name=='managed-kb'].{targetId:targetId,status:status}"
返回结果如下:
[
{
"targetId": "XXXXXXXXXX",
"status": "READY"
}
]
(8) 应用系统使用 MCP 协议挂载 Gateway 并测试
Target 就绪后,在 MCP 客户端中挂载该 Gateway。以 Kiro 为例,在 ~/.kiro/settings/mcp.json 中新增一个远程 MCP Server 条目,url 填入本小节 get-gateway 返回的 gatewayUrl,clientId 填入上一小节创建的 CLIENT_ID:
{
"mcpServers": {
"managed-kb-gateway": {
"type": "http",
"url": "<本节创建的 Gateway URL>",
"oauth": {
"clientId": "<上一小节创建的 CLIENT_ID>",
"redirectUri": "localhost:38123",
"oauthScopes": ["openid"]
}
}
}
}
首次连接时,Kiro 会提示对该 MCP 进行认证,触发浏览器跳转到 Cognito 的 Hosted UI 登录页,使用 user01 及其密码登录后即可完成认证;Token 过期后由 Refresh Token 自动静默续期。认证成功后,执行 /mcp 即可看到 Retrieve 与 AgenticRetrieveStream 两个知识库工具,随后在对话中提问即可触发检索。
备注:AgentCore Gateway 本身空闲时不产生额外费用,实际计费发生在调用知识库检索时。
至此完成将知识库封装为 MCP 的两种配置路径。下面列出本文引用的官方文档。
六、参考文档
AWS 官方说明:
Create a managed knowledge base
Create a service role for managed Amazon Bedrock Knowledge Bases
CreateKnowledgeBase API reference
Connect Amazon S3 to a managed knowledge base
Sync a managed knowledge base data source
Use agentic retrieval to query a knowledge base
AgenticRetrieveStream API reference
Connect to your knowledge base through AgentCore Gateway
Amazon Bedrock Managed Knowledge Bases as Connector Target
七、删除实验资源
实验验证结束后,应删除本文创建的资源,避免 Managed Knowledge Base 的托管存储及相关组件继续产生费用或占用配额。本文创建的资源分布在两处:第二章创建的知识库、数据源与服务角色;第五章创建的 AgentCore Gateway 相关资源。删除顺序上,建议先删除第五章的 Gateway 相关资源(其中 Gateway Target 引用了知识库),再删除第二章的知识库资源。
需要特别注意:如果第五章采用的是第 1 节“复用现有 Gateway”的路径,则清理时只删除新挂载的知识库 Target,绝不能删除被复用的 Gateway、执行角色和 Cognito 用户池;只有采用第 2 节“全新创建 Gateway”的路径时,才删除 Gateway、执行角色与 Cognito。请根据第五章实际采用的路径,选择第 1 节对应的小节执行。
bedrock-managed-kb-demo-us-east-1 是本文开始前已经准备好的 S3 存储桶,不属于本实验创建的资源,因此本章不会删除该存储桶及其中的 PDF 文件。
注意:删除操作不可逆。执行前请确认相关资源没有被其他工作负载复用。
1、删除第五章创建的 AgentCore Gateway 资源
第五章提供了两条路径,本节对应给出两种清理方式,按第五章实际采用的路径二选一执行。
(1) 复用现有 Gateway 的情形(对应第五章第 1 节)
如果第五章采用第 1 节复用现有 Gateway,则只需删除新挂载的知识库 Target。被复用的 Gateway、执行角色和 Cognito 用户池是先前已存在的资源(例如《kiro-integration.md》创建的 Web Search Gateway),删除它们会影响其他工作负载,因此本情形不删除这些资源。
先按 Gateway 名称查出 Gateway ID,再查出知识库 Target 的 ID。GATEWAY_NAME 替换为第五章第 1 节实际使用的 Gateway 名称:
REGION="us-east-1"
GATEWAY_NAME="websearch-kiro-jwt-gateway"
GATEWAY_ID=$(aws bedrock-agentcore-control list-gateways \
--region "$REGION" \
--query "items[?name=='${GATEWAY_NAME}'].gatewayId | [0]" \
--output text)
TARGET_ID=$(aws bedrock-agentcore-control list-gateway-targets \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query "items[?name=='managed-kb'].targetId | [0]" \
--output text)
echo "GATEWAY_ID=$GATEWAY_ID"
echo "TARGET_ID=$TARGET_ID"
删除该知识库 Target:
aws bedrock-agentcore-control delete-gateway-target \
--gateway-identifier "$GATEWAY_ID" \
--target-id "$TARGET_ID" \
--region "$REGION"
删除请求返回的状态通常为 DELETING。执行如下循环,等待 get-gateway-target 返回资源不存在:
while aws bedrock-agentcore-control get-gateway-target \
--gateway-identifier "$GATEWAY_ID" \
--target-id "$TARGET_ID" \
--region "$REGION" >/dev/null 2>&1; do
sleep 3
done
删除 Target 后,第五章第 1 节曾向被复用的执行角色追加过一条名为 ManagedKbRetrievePolicy 的内联策略。可选择将其一并摘除,使该角色恢复到挂载知识库之前的状态。此操作只删除这一条知识库专用的内联策略,不会删除角色本身,也不影响该角色原有的其他权限(例如 Web Search 调用权限):
KB_GATEWAY_ROLE_ARN=$(aws bedrock-agentcore-control get-gateway \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query 'roleArn' \
--output text)
KB_GATEWAY_ROLE_NAME="${KB_GATEWAY_ROLE_ARN##*/}"
aws iam delete-role-policy \
--role-name "$KB_GATEWAY_ROLE_NAME" \
--policy-name "ManagedKbRetrievePolicy"
注意:本情形到此为止。不要对被复用的 Gateway 执行 delete-gateway,也不要删除其执行角色(delete-role)或 Cognito 用户池,否则会影响挂载在同一 Gateway 上的其他工具及其认证。
(2) 全新创建 Gateway 的情形(对应第五章第 2 节)
如果第五章采用第 2 节从零创建 Gateway,则需要删除全部新建资源,删除顺序为:Gateway Target → Gateway → 执行角色 → Cognito 托管域名与用户池。先设置第五章第 2 节使用的资源名称:
REGION="us-east-1"
KB_GATEWAY_NAME="managed-kb-mcp-gateway"
KB_GATEWAY_ROLE_NAME="ManagedKbGatewayRole"
USER_POOL_NAME="managed-kb-pool"
按名称查出 Gateway ID:
GATEWAY_ID=$(aws bedrock-agentcore-control list-gateways \
--region "$REGION" \
--query "items[?name=='${KB_GATEWAY_NAME}'].gatewayId | [0]" \
--output text)
echo "GATEWAY_ID=$GATEWAY_ID"
如果 Gateway 存在,删除其下全部 Target,等待 Target 删除完成后再删除 Gateway:
if [[ -n "$GATEWAY_ID" && "$GATEWAY_ID" != "None" ]]; then
TARGET_IDS=$(aws bedrock-agentcore-control list-gateway-targets \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query 'items[].targetId' \
--output text)
if [[ -n "$TARGET_IDS" && "$TARGET_IDS" != "None" ]]; then
for TARGET_ID in $TARGET_IDS; do
aws bedrock-agentcore-control delete-gateway-target \
--gateway-identifier "$GATEWAY_ID" \
--target-id "$TARGET_ID" \
--region "$REGION"
done
while [[ "$(aws bedrock-agentcore-control list-gateway-targets \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query 'length(items)' \
--output text)" != "0" ]]; do
sleep 3
done
fi
aws bedrock-agentcore-control delete-gateway \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION"
while [[ "$(aws bedrock-agentcore-control list-gateways \
--region "$REGION" \
--query "length(items[?gatewayId=='${GATEWAY_ID}'])" \
--output text)" != "0" ]]; do
sleep 3
done
fi
Gateway 删除完成后,删除其专用执行角色的内联策略和角色本身:
aws iam delete-role-policy \
--role-name "$KB_GATEWAY_ROLE_NAME" \
--policy-name "ManagedKbRetrievePolicy"
aws iam delete-role \
--role-name "$KB_GATEWAY_ROLE_NAME"
最后删除第五章第 2 节创建的 Cognito 资源。先删除托管域名,再删除用户池:
USER_POOL_ID=$(aws cognito-idp list-user-pools \
--max-results 60 \
--region "$REGION" \
--query "UserPools[?Name=='${USER_POOL_NAME}'].Id | [0]" \
--output text)
echo "USER_POOL_ID=$USER_POOL_ID"
if [[ -n "$USER_POOL_ID" && "$USER_POOL_ID" != "None" ]]; then
COGNITO_DOMAIN=$(aws cognito-idp describe-user-pool \
--user-pool-id "$USER_POOL_ID" \
--region "$REGION" \
--query 'UserPool.Domain' \
--output text)
if [[ -n "$COGNITO_DOMAIN" && "$COGNITO_DOMAIN" != "None" ]]; then
aws cognito-idp delete-user-pool-domain \
--domain "$COGNITO_DOMAIN" \
--user-pool-id "$USER_POOL_ID" \
--region "$REGION"
fi
aws cognito-idp delete-user-pool \
--user-pool-id "$USER_POOL_ID" \
--region "$REGION"
fi
删除用户池会同时删除其中的应用客户端与 user01 测试用户,无须分别执行删除命令。注意:如果该 Cognito 用户池实际上是复用了《kiro-integration.md》创建的既有用户池,而非第五章第 2 节全新创建,则不应在此删除,请改用第 (1) 小节的思路,仅删除知识库 Target。
2、删除第二章创建的知识库资源
本节删除第二章创建的资源,按“数据源 → 知识库 → IAM 角色”的依赖顺序进行。如果已经退出第二章使用的 Shell 会话,应先重新设置区域、资源 ID 和 IAM 角色名称。KB_ID 与 DATA_SOURCE_ID 必须替换为第二章实际返回的值:
REGION="us-east-1"
KB_ID="<第二章创建的 Knowledge Base ID>"
DATA_SOURCE_ID="<第二章创建的 Data Source ID>"
KB_ROLE_NAME="BedrockManagedKbPdfDemoRole"
先删除 S3 Managed Connector 数据源:
aws bedrock-agent delete-data-source \
--knowledge-base-id "$KB_ID" \
--data-source-id "$DATA_SOURCE_ID" \
--region "$REGION"
删除请求受理后通常没有终端回显。执行如下循环,等待 get-data-source 返回 ResourceNotFound:
while aws bedrock-agent get-data-source \
--knowledge-base-id "$KB_ID" \
--data-source-id "$DATA_SOURCE_ID" \
--region "$REGION" >/dev/null 2>&1; do
sleep 5
done
数据源删除完成后,删除 Managed Knowledge Base:
aws bedrock-agent delete-knowledge-base \
--knowledge-base-id "$KB_ID" \
--region "$REGION"
执行如下循环,等待 get-knowledge-base 返回 ResourceNotFound:
while aws bedrock-agent get-knowledge-base \
--knowledge-base-id "$KB_ID" \
--region "$REGION" >/dev/null 2>&1; do
sleep 5
done
知识库删除完成后,删除服务角色的内联策略和 IAM 角色:
aws iam delete-role-policy \
--role-name "$KB_ROLE_NAME" \
--policy-name "ReadManagedKbSource"
aws iam delete-role \
--role-name "$KB_ROLE_NAME"
3、删除本机临时配置文件
删除前述操作过程中在本机 /tmp 目录下生成的临时配置文件,其中前四个来自第二章,后三个来自第五章(managed-kb-gateway-trust.json 仅在第五章第 2 节创建):
rm -f \
/tmp/managed-kb-trust-policy.json \
/tmp/managed-kb-s3-policy.json \
/tmp/managed-kb-config.json \
/tmp/managed-kb-s3-connector.json \
/tmp/managed-kb-gateway-policy.json \
/tmp/managed-kb-gateway-target.json \
/tmp/managed-kb-gateway-trust.json
注意:本章不执行 aws s3 rm 或 aws s3api delete-bucket。如需删除 S3 中的测试 PDF,应单独确认对象路径后再进行处理,避免误删该存储桶中的其他数据。
至此实验全部完成。
最后修改于 2026-07-22