

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Amazon Bedrock 知识库构建 RAG 应用程序
<a name="tutorial-build-rag-with-bedrock"></a>

许多企业在其 NFS 和 SMB 文件共享中积累了大量文档存储库，包括产品手册、政策文档、合同、研究报告、工程规格和用户生成的内容。

通过连接到 FSx for ONTAP 卷的 Amazon S3 接入点，Amazon Bedrock 知识库可以直接从该卷中提取内容。 Foundation-model 回复以您的团队通过 NFS 或 SMB 保存的文档为基础。作者在共享上更新的内容将在下次同步时提供给知识库。

在本教程中，您将通过 Amazon S3 接入点将一小组示例 PDF 上传到 FSx for ONTAP 卷，创建指向接入点的 Amazon Bedrock 知识库，提取文档，然后通过 API 提问。`RetrieveAndGenerate`

**注意**  
本教程大约需要 **35 到 45 分钟**才能完成。 AWS 服务 使用者会对您创建的资源产生费用。如果您及时完成所有步骤，包括**清理**部分，则美国东部（弗吉尼亚北部）的预期费用将低于 **1美元** AWS 区域。该估算值不包括 FSx 对 ONTAP 容量本身的持续费用。

## 先决条件
<a name="tutorial-bedrock-kb-prerequisites"></a>

在开始之前，请确保您具有以下各项：
+ 连接了 Amazon S3 接入点的 ONTAP 卷的 FSx。接入点必须具有**互联网**网络来源，这样 Amazon Bedrock 服务才能访问它。有关创建接入点的说明，请参阅[创建接入点](fsxn-creating-access-points.md)。
+ 为 Amazon Bedrock 知识库支持的嵌入模型启用模型访问权限，并在其中创建知识库的至少一个文本生成模型（例如`amazon.nova-lite-v1:0`）。 AWS 区域 本教程使用`amazon.titan-embed-text-v2:0`（1024 个维度）作为嵌入模型；还支持 Cohere 嵌入模型。如果您选择其他嵌入模型，请在步骤 2 中调整向量索引维度以匹配模型的输出维度。在 Amazon Bedrock 控制台的 “模型访问权限” 下启用了**模型访问权限**。有关更多信息，请参阅《[亚马逊 Bedrock *用户指南》中的 Amazon Bedrock* 基础模型](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html)。
+ AWS CLI 安装了版本 2，并配置了可以创建 IAM 角色的证书、Amazon S3 Vectors 资源和 Amazon Bedrock 知识库。

## 步骤 1：将示例文档上传到接入点
<a name="tutorial-bedrock-kb-upload"></a>

下载一些公共 PDF 作为示例语料库，然后使用 Amazon S3 接入点别名将其上传到您的接入点。

1. 创建本地目录并下载示例 PDF。

   ```
   $ mkdir -p ~/kb-pdfs && cd ~/kb-pdfs
   curl -sSL -o aws-overview.pdf https://d1.awsstatic.com/whitepapers/aws-overview.pdf
   curl -sSL -o wellarchitected-framework.pdf https://docs.aws.amazon.com/pdfs/wellarchitected/latest/framework/wellarchitected-framework.pdf
   curl -sSL -o s3-userguide.pdf https://docs.aws.amazon.com/pdfs/AmazonS3/latest/userguide/s3-userguide.pdf
   ```

1. 将每个文件上传到接入点。{{access-point-alias}}替换为您的接入点别名（例如，`my-kb-ap-a1b2c3d4e5f6g7h8i9j0kl1mnop2uuse1a-ext-s3alias`）。您可以在 Amazon FSx 控制台的 “已**连接的 Amazon S3 接入点**” 下找到该别名，也可以通过运行来找到该别名。`aws fsx describe-s3-access-point-attachments`

   ```
   $ for f in *.pdf; do
       aws s3 cp "$f" "s3://{{access-point-alias}}/$f"
   done
   ```

1. 验证文件已存放在卷上。

   ```
   $ aws s3 ls s3://{{access-point-alias}}/
   ```

**注意**  
Amazon Bedrock 知识库规定每个文档的最大文件大小为 50 MB。摄取期间会跳过大于 50 MB 的文件。

## 第 2 步：创建矢量存储
<a name="tutorial-bedrock-kb-vector-store"></a>

知识库将文档嵌入存储在矢量存储中。Amazon Bedrock 知识库支持多个矢量存储；本教程使用 Amazon S3 矢量作为默认存储库，因为它针对 RAG 工作负载进行了成本优化，并且只需最少的设置。还支持 Amazon OpenSearch Serverless；有关这些说明，请参阅本步骤末尾的可折叠部分。

### 使用控制台创建矢量存储
<a name="tutorial-bedrock-kb-vector-store-console"></a>

如果您使用控制台在中创建知识库[步骤 4：创建知识库和数据源](#tutorial-bedrock-kb-create-kb)，请在矢量**数据库步骤中选择**快速创建新的矢量存储**，然后选择 Amazon S3 矢量****图（推荐）或 Amazon S OpenSearch ** **erverless**。Amazon Bedrock 会自动创建矢量存储和所有必需的配置。向前跳至 [步骤 3：为知识库创建 IAM 角色](#tutorial-bedrock-kb-iam-role)。

### 要创建 Amazon S3 矢量存储，请使用 AWS CLI
<a name="tutorial-bedrock-kb-vector-store-cli"></a>

1. 创建 Amazon S3 矢量存储桶。矢量存储桶名称遵循与标准 Amazon S3 存储桶相同的全局唯一性规则。本教程使用`fsxn-kb-vectors`; 替换为唯一的名称。

   ```
   $ aws s3vectors create-vector-bucket --vector-bucket-name fsxn-kb-vectors
   ```

1. 在存储桶中创建向量索引。索引维度必须与嵌入模型的输出维度匹配；Titan Text Embeddings v2 输出 1024 个维度。该`nonFilterableMetadataKeys`设置将 Bedrock 元数据字段标记为不可筛选，这使它们不受每向量 2 KB 可筛选元数据的限制。

   ```
   $ aws s3vectors create-index --vector-bucket-name fsxn-kb-vectors \
       --index-name bedrock-kb-index \
       --dimension 1024 --distance-metric cosine --data-type float32 \
       --metadata-configuration '{"nonFilterableMetadataKeys":["AMAZON_BEDROCK_METADATA","AMAZON_BEDROCK_TEXT"]}'
   ```

   请注意响应`indexArn`中的；你在中使用它[步骤 4：创建知识库和数据源](#tutorial-bedrock-kb-create-kb)。

### 替代方案：使用创建 OpenSearch 服务无服务器矢量存储 AWS CLI
<a name="tutorial-bedrock-kb-vector-store-oss"></a>

如果您更喜欢无服务器 OpenSearch 服务（用于更高的每秒查询量、高级搜索功能或熟悉现有操作），请使用以下步骤代替上面的 Amazon S3 Vectors 程序。

1. 为集合创建加密和网络安全策略。

   ```
   $ aws opensearchserverless create-security-policy --name kb-enc --type encryption \
       --policy '{"Rules":[{"ResourceType":"collection","Resource":["collection/fsxn-kb"]}],"AWSOwnedKey":true}'
   aws opensearchserverless create-security-policy --name kb-net --type network \
       --policy '[{"Rules":[{"ResourceType":"collection","Resource":["collection/fsxn-kb"]},{"ResourceType":"dashboard","Resource":["collection/fsxn-kb"]}],"AllowFromPublic":true}]'
   ```

1. 创建数据访问策略，向知识库角色和您的当前用户授予读写集合的权限。将 {{account-id}} 和 {{current-user}} 替换为您自己的值。

   ```
   $ aws opensearchserverless create-access-policy --name kb-data --type data --policy '[{
       "Rules":[
           {"ResourceType":"index","Resource":["index/fsxn-kb/*"],"Permission":["aoss:*"]},
           {"ResourceType":"collection","Resource":["collection/fsxn-kb"],"Permission":["aoss:*"]}
       ],
       "Principal":[
           "arn:aws:iam::{{account-id}}:role/fsxn-kb-role",
           "arn:aws:iam::{{account-id}}:user/{{current-user}}"
       ]
   }]'
   ```

1. 创建收藏并等待它变成`ACTIVE`。

   ```
   $ aws opensearchserverless create-collection --name fsxn-kb --type VECTORSEARCH
   aws opensearchserverless batch-get-collection --names fsxn-kb \
       --query 'collectionDetails[0].{status:status,endpoint:collectionEndpoint}'
   ```

1. 使用带有签名请求的 Python 脚本在集合上创建向量索引。索引必须使用维度 1024（适用于 Titan Text Embeddings v2）和亚马逊 Bedrock 知识库期望的字段名称。有关完整脚本和后续配置步骤，请参阅 *Amazon Bedrock 用户*[指南中的使用无服务器 OpenSearch 服务的先决条件](https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base-setup-oss.html)。使用步骤 4 中生成的集合 ARN 和索引名称，类型`storage-configuration`为。`OPENSEARCH_SERVERLESS`

## 步骤 3：为知识库创建 IAM 角色
<a name="tutorial-bedrock-kb-iam-role"></a>

知识库需要一个可以代入的 IAM 角色来调用嵌入模型、通过 Amazon S3 接入点读取对象以及访问矢量存储。下方显示的策略授予对 Amazon S3 Vectors 矢量存储的访问权限。如果您改用无服务器 OpenSearch 服务，请将该`S3Vectors`语句替换为对集合 ARN 授予`aoss:APIAccessAll`权限的语句。

### 使用控制台创建角色
<a name="tutorial-bedrock-kb-iam-role-console"></a>

在中使用 Amazon Bedrock 控制台创建知识库时[步骤 4：创建知识库和数据源](#tutorial-bedrock-kb-create-kb)，选择**创建并使用新的服务角色**。Amazon Bedrock 创建了一个具有所需信任和权限的角色，其范围仅限于您的知识库、嵌入模型、矢量存储和数据源。向前跳至 [步骤 4：创建知识库和数据源](#tutorial-bedrock-kb-create-kb)。

### 要创建角色，请使用 AWS CLI
<a name="tutorial-bedrock-kb-iam-role-cli"></a>

1. 将以下信任策略另存为`kb-trust-policy.json`。它允许 Amazon Bedrock 担任这个角色。{{account-id}}用您的 AWS 账户 身份证替换。

   ```
   {
       "Version": "2012-10-17", 		 	 	 
       "Statement": [{
           "Effect": "Allow",
           "Principal": {"Service": "bedrock.amazonaws.com"},
           "Action": "sts:AssumeRole",
           "Condition": {"StringEquals": {"aws:SourceAccount": "{{account-id}}"}}
       }]
   }
   ```

1. 将以下权限策略另存为`kb-permissions.json`。它允许访问嵌入模型、Amazon S3 接入点和矢量存储。用您的值替换占位符。

   ```
   {
       "Version": "2012-10-17", 		 	 	 
       "Statement": [
           {
               "Sid": "FoundationModel",
               "Effect": "Allow",
               "Action": ["bedrock:InvokeModel"],
               "Resource": ["arn:aws:bedrock:{{region}}::foundation-model/amazon.titan-embed-text-v2:0"]
           },
           {
               "Sid": "S3AccessPoint",
               "Effect": "Allow",
               "Action": ["s3:GetObject", "s3:ListBucket"],
               "Resource": [
                   "arn:aws:s3:{{region}}:{{account-id}}:accesspoint/{{access-point-name}}",
                   "arn:aws:s3:{{region}}:{{account-id}}:accesspoint/{{access-point-name}}/object/*"
               ]
           },
           {
               "Sid": "S3Vectors",
               "Effect": "Allow",
               "Action": [
                   "s3vectors:GetIndex",
                   "s3vectors:PutVectors",
                   "s3vectors:GetVectors",
                   "s3vectors:ListVectors",
                   "s3vectors:DeleteVectors",
                   "s3vectors:QueryVectors"
               ],
               "Resource": [
                   "arn:aws:s3vectors:{{region}}:{{account-id}}:bucket/fsxn-kb-vectors",
                   "arn:aws:s3vectors:{{region}}:{{account-id}}:bucket/fsxn-kb-vectors/index/*"
               ]
           }
       ]
   }
   ```

1. 创建角色并附加权限策略。

   ```
   $ aws iam create-role --role-name fsxn-kb-role \
       --assume-role-policy-document file://kb-trust-policy.json
   aws iam put-role-policy --role-name fsxn-kb-role --policy-name kb-access \
       --policy-document file://kb-permissions.json
   ```

## 步骤 4：创建知识库和数据源
<a name="tutorial-bedrock-kb-create-kb"></a>

数据源指向您的 Amazon S3 接入点别名。Amazon Bedrock 知识库接受接入点别名代替存储桶名称。

### 使用控制台创建知识库
<a name="tutorial-bedrock-kb-create-kb-console"></a>

1. 打开 Amazon Bedrock 控制台，网址为[https://console.aws.amazon.com/bedrock/](https://console.aws.amazon.com/bedrock/)。

1. 在左侧导航窗格中，选择**知识库**，然后选择**创建知识库**。

1. 在**知识库详细信息**下，输入名称（例如`fsxn-kb`）和描述。

1. 在 **IAM 权限**下，选择**创建并使用新的服务角色**。

1. 对于**数据源**，选择 **Amazon S3**，然后选择**下一步**。

1. 输入数据源名称（例如，`fsxn-s3ap-source`）。

1. 例如，对于 **S3 URI**，请在`s3://`接入点别名后输入`s3://my-kb-ap-a1b2c3d4e5f6g7h8i9j0kl1mnop2uuse1a-ext-s3alias`。控制台在此字段中不区分存储桶名称和接入点别名；接入点别名按原样接受。

1. 选择**下一步**。

1. 在 “**嵌入” 模型**下，选择 **Titan 文本嵌入 v2**。

1. 在 “**矢量数据库**” 下，选择 “**快速创建新的矢量存储**”，然后选择 **Amazon S3 矢量图**。选择**下一步**。

1. 查看配置并选择**创建知识库**。创建知识库可能需要几分钟。

### 要使用创建知识库 AWS CLI
<a name="tutorial-bedrock-kb-create-kb-cli"></a>

1. 创建知识库。用您的值替换占位符。`indexArn`是您在步骤 2 中创建的 Amazon S3 向量索引的 ARN。

   ```
   $ aws bedrock-agent create-knowledge-base --name fsxn-kb \
       --role-arn arn:aws:iam::{{account-id}}:role/fsxn-kb-role \
       --knowledge-base-configuration '{
           "type":"VECTOR",
           "vectorKnowledgeBaseConfiguration":{
               "embeddingModelArn":"arn:aws:bedrock:{{region}}::foundation-model/amazon.titan-embed-text-v2:0"
           }
       }' \
       --storage-configuration '{
           "type":"S3_VECTORS",
           "s3VectorsConfiguration":{
               "indexArn":"{{index-arn}}"
           }
       }'
   ```

   记下响应中的 `knowledgeBaseId`。

1. 创建数据源。使用表单将 Amazon S3 接入点别名作为存储桶名称传递到`bucketArn`字段中`arn:aws:s3:::{{access-point-alias}}`。

   ```
   $ aws bedrock-agent create-data-source \
       --knowledge-base-id {{knowledge-base-id}} \
       --name fsxn-s3ap-source \
       --data-source-configuration '{
           "type":"S3",
           "s3Configuration":{"bucketArn":"arn:aws:s3:::{{access-point-alias}}"}
       }'
   ```

   记下响应中的 `dataSourceId`。

## 第 5 步：收录文档
<a name="tutorial-bedrock-kb-ingest"></a>

运行摄取作业，通过接入点对文档进行爬网，生成嵌入内容，并在矢量存储中为它们编制索引。

### 使用控制台运行摄取
<a name="tutorial-bedrock-kb-ingest-console"></a>

1. 在 Amazon Bedrock 控制台中，打开您的知识库。

1. 在**数据源**部分，选择您的数据源，然后选择**同步**。

1. 等待 **“同步” 状态显示为 “****就绪**”。

### 要使用运行摄取 AWS CLI
<a name="tutorial-bedrock-kb-ingest-cli"></a>

1. 启动摄取作业。

   ```
   $ aws bedrock-agent start-ingestion-job \
       --knowledge-base-id {{knowledge-base-id}} \
       --data-source-id {{data-source-id}}
   ```

   记下响应中的 `ingestionJobId`。

1. 轮询作业直到其完成。

   ```
   $ aws bedrock-agent get-ingestion-job \
       --knowledge-base-id {{knowledge-base-id}} \
       --data-source-id {{data-source-id}} \
       --ingestion-job-id {{ingestion-job-id}}
   ```

   该`status`字段从过渡`IN_PROGRESS`到`COMPLETE`。该`statistics`字段显示扫描和索引了多少文档。

## 步骤 6：查询知识库
<a name="tutorial-bedrock-kb-query"></a>

向知识库询问一个以摄取的文档为基础的问题。该响应包括通过 Amazon S3 接入点别名引用源文档的引文。

### 使用控制台进行查询
<a name="tutorial-bedrock-kb-query-console"></a>

1. 在 Amazon Bedrock 控制台中，打开您的知识库。

1. 选择**测试知识库**。

1. 在 “**生成响应**” 下，选择文本生成模型（例如 **Nova Lite**）。

1. 输入诸如之类的问题，`What are the pillars of the AWS Well-Architected Framework?`然后选择 “**运行**”。答案中显示的引文引用链接到 Amazon S3 接入点中的源文档。

### 要使用进行查询 AWS CLI
<a name="tutorial-bedrock-kb-query-cli"></a>

使用 `retrieve-and-generate` 命令。用您的值替换占位符。`modelArn`必须参考您有权访问的文本生成模型的推理配置文件。

```
$ aws bedrock-agent-runtime retrieve-and-generate \
    --input '{"text":"What are the pillars of the AWS Well-Architected Framework?"}' \
    --retrieve-and-generate-configuration '{
        "type":"KNOWLEDGE_BASE",
        "knowledgeBaseConfiguration":{
            "knowledgeBaseId":"{{knowledge-base-id}}",
            "modelArn":"arn:aws:bedrock:{{region}}:{{account-id}}:inference-profile/us.amazon.nova-lite-v1:0"
        }
    }'
```

响应中包含生成的答案`output.text`和`citations`数组中的引文列表。每份引文都包含一个`s3Location.uri`字段，该字段通过表`s3://{{access-point-alias}}/{{file.pdf}}`单中的接入点别名指向源文档。

## 问题排查
<a name="tutorial-bedrock-kb-troubleshooting"></a>

摄取任务报告文件被忽略  
Amazon Bedrock 知识库规定每个文档的最大文件大小为 50 MB。大于 50 MB 的文件将在中列出`failureReasons`并跳过。在上传之前对大型文档进行拆分或压缩。

`ValidationException`: 标记为 Legacy 的型号  
您的账户已弃用您指定的文本生成模型。选择有效的推理配置文件，例如`us.amazon.nova-lite-v1:0`或其他当前支持的模型。运行列`aws bedrock list-inference-profiles`出可用的配置文件。

`AccessDeniedException`摄入期间  
确认知识库 IAM 角色`s3:ListBucket`在接入点 ARN（而不是底层卷上）上有`s3:GetObject`和，并且接入点是否有互联网网络来源，以便 Amazon Bedrock 服务可以访问它。如果您在步骤 2 中选择了 Serv OpenSearch ice Serverless 替代方案，还要验证数据访问策略是否将该角色列为委托人。

摄取任务成功但查询未返回任何相关段落  
确认矢量索引是使用`dimension: 1024`（适用于 Titan Text Embeddings v2）创建的，并且索引映射中的字段名称与知识库中配置的字段名称相匹配。

## 清理
<a name="tutorial-bedrock-kb-clean-up"></a>

为避免持续产生费用，请删除您创建的资源：
+ Amazon Bedrock 知识库和数据源
+ Amazon S3 向量索引和矢量存储桶（如果您在步骤 2 中使用了替代方案，则为无 OpenSearch 服务服务器集合）
+ IAM 角色和内联策略
+ 上传到接入点的对象（如果不再需要）

```
$ aws bedrock-agent delete-data-source --knowledge-base-id {{knowledge-base-id}} --data-source-id {{data-source-id}}
aws bedrock-agent delete-knowledge-base --knowledge-base-id {{knowledge-base-id}}
aws s3vectors delete-index --vector-bucket-name fsxn-kb-vectors --index-name bedrock-kb-index
aws s3vectors delete-vector-bucket --vector-bucket-name fsxn-kb-vectors
aws iam delete-role-policy --role-name fsxn-kb-role --policy-name kb-access
aws iam delete-role --role-name fsxn-kb-role
```

### 替代方案：清理 OpenSearch 服务无服务器资源
<a name="tutorial-bedrock-kb-clean-up-oss"></a>

如果您在步骤 2 中选择了 Serv OpenSearch ice Serverless 替代方案，请将上述`s3vectors`命令替换为以下命令。Idle Serv OpenSearch ice Service Serverless 集合会产生 OCU-hour 费用，因此在完成本教程后请立即将其删除。

```
$ # Get the collection ID (required by delete-collection; the name is not accepted)
COLLECTION_ID=$(aws opensearchserverless batch-get-collection --names fsxn-kb \
    --query 'collectionDetails[0].id' --output text)

# Delete the collection, then the policies
aws opensearchserverless delete-collection --id "$COLLECTION_ID"
aws opensearchserverless delete-access-policy --name kb-data --type data
aws opensearchserverless delete-security-policy --name kb-net --type network
aws opensearchserverless delete-security-policy --name kb-enc --type encryption
```