标签: RAG

  • 活用 Amazon Bedrock 的 Rerank API 提升 RAG 精度

    活用 Amazon Bedrock 的 Rerank API 提升 RAG 精度

    在 RAG(检索增强生成:Retrieval-Augmented Generation)为用户提供准确信息的过程中,检索精度尤为关键。

    而提升检索精度的方法之一便是 “重排序(Rerank)”。

    通过执行重排序操作,将检索得到的结果按相关度重新排序,能更轻松地针对用户所需信息给出回答。

    如今,Amazon Bedrock 已新增支持重排序的模型,且可与 Bedrock Knowledge Base 搭配使用。

    以往,实现这一功能需要自行托管模型等,颇为繁琐;而现在,只需在向 Knowledge Base 发起的检索请求中添加相关设置,即可一并执行检索与重排序操作,且仅能获取重排序后的结果。

    本次我们将实际使用重排序模型,验证检索结果会发生怎样的变化。

    1. 前言

    1.1 什么是重排序(Rerank)

    在包含 Bedrock Knowledge Base 在内的 RAG 检索中,向量检索的应用十分广泛。

    然而,仅依靠向量检索往往无法达到足够的检索精度,难以给出恰当的回答。

    因此,对通过向量检索获取的文档进行重排序处理,可使相关度更高的文档出现在检索结果的靠前位置。

    重新排序的图像

    1.2 以往的实现方式

    此前,要在 RAG 系统中集成重排序处理,需搭建 SageMaker 实例、托管重排序专用模型并执行推理。

    例如,在 2024 年 8 月时,若要使用 Cohere Rerank 3,就需按照下述文章的说明创建 SageMaker 实例。

    aws.amazon.com

    这种方式存在诸多问题,如需要投入精力准备 SageMaker 实例与重排序模型,且会产生运营成本。

    1.3 Bedrock 支持的重排序模型

    自 2024 年 12 月起,可通过 Bedrock 使用重排序模型。

    借助该重排序模型,无需自行托管模型,仅通过调用 API 即可执行重排序操作。

    这不仅省去了运营管理的繁琐工作,还无需一直启动服务器,只需根据使用量付费,让用户能轻松开启重排序功能的使用。

    除了可通过 Bedrock 的 InvokeModel API 调用外,还支持通过 Bedrock Knowledge Base 的 Rerank API、Retrieve API、RetrieveAndGenerate API、RetrieveAndGenerateStream API 进行调用。

    截至 2025 年 1 月,提供的模型有 Amazon Rerank 1.0(以下简称 Amazon Rerank 模型)和 Cohere Rerank 3.5(以下简称 Cohere Rerank 模型)。

    2. 尝试应用重排序模型

    本次验证将使用本文中已采用的、模拟酒店评论检索的数据。

    此次以 “烤肉好吃的酒店” 为检索词,期望 “使用本地产蔬菜和肉类制作的烤肉料理” 的第 10 条评论以及 “炭火烤制的牛排” 的第 7 条评论能出现在检索结果的靠前位置。

    重排序模型选用 Amazon Rerank 模型。

    序号内容
    1这家酒店的温泉堪称顶级疗愈。源泉直供的温泉水格外柔和,泡完后肌肤感觉滑溜溜的。从露天温泉能眺望到美丽的群山,夜晚还能一边泡澡一边欣赏满天繁星。这是一家让人想反复前往的温泉酒店。
    2酒店的温泉非常舒服,能让人彻底放松。室内温泉和露天温泉各具特色,尤其是从露天温泉看到的庭院景色美不胜收,可欣赏到四季不同的美景。水温也恰到好处,长时间浸泡也不会觉得疲惫。
    3早就听闻这是一家以温泉为特色的酒店,实际体验远超预期。因直接使用天然温泉源泉,水质极佳,泡完后身体持续暖暖的。我们还预约了私人温泉,在专属空间里度过了惬意的时光。
    4温泉区域宽敞开阔,视野极佳。从露天温泉能一览大海,可伴着海浪声悠闲度日。水温也不会过高,能慢慢暖遍全身,非常满意。此外,还支持当日往返使用,让人能轻松前来,这点很贴心。
    5温泉散发着令人舒心的硫磺香气,让人真切感受到来到了温泉胜地。温泉水功效显著,能明显感觉到肌肤变得光滑。这里有多个温泉池,有时特定时段还能独享,让人体验到奢华感。另外,泡完温泉后提供的冰镇饮品也是个惊喜服务。
    6酒店的餐食宛如艺术品。大量使用本地新鲜食材制作的怀石料理,不仅外观精美,每一道菜都能让人感受到制作的用心。尤其是用当季海鲜制作的刺身,堪称绝品,仅凭这一点就想再次前来。
    7晚餐有很多本地特色菜,非常满意。特别是炭火烤制的牛排,入口即化,美味得让人想一再续盘。早餐种类也很丰富,用本地蔬菜制作的沙拉和手工豆腐都很美味。
    8晚餐是套餐形式,每道菜都很好吃,其中最令人印象深刻的是用本地采摘的蔬菜制作的前菜和自制甜点。采用凸显食材本味的简单烹饪方式,充分展现了食材的优良品质。早餐营养均衡,刚出炉的面包尤其美味。
    9酒店的餐食超出预期。因靠近海边,大量使用新鲜海鲜,刺身和煮鱼都非常好吃。晚餐分量充足,每道菜的调味都饱含心意。早餐的日式料理也很美味,尤其是温泉蛋堪称绝品。
    10晚餐是大量使用本地食材制作的创意料理,每道菜都能感受到巧思。特别是用本地产蔬菜和肉类制作的烤肉料理,堪称绝品,充分凸显了食材本身的味道。早餐也很用心,有手工果酱和刚出炉的面包等,非常满意。

    2.1 通过 Bedrock 的 InvokeModel API 使用

    InvokeModel API 是用于调用 Bedrock 所提供模型的 API。

    在请求体(body)中输入想要进行重排序的文档列表以及用户的查询语句后,就能在响应结果中获取到按与用户查询语句相关度从高到低重新排序的文档,以及各自的相关度(分数)。

    代码

    query = "烤肉好吃的酒店"
    documents = [
        "这家酒店的温泉堪称顶级疗愈。源泉直供的温泉水格外柔和,泡完后肌肤感觉滑溜溜的。从露天温泉能眺望到美丽的群山,夜晚还能一边泡澡一边欣赏满天繁星。这是一家让人想反复前往的温泉酒店。",
        # (省略)
    ]
    
    response = bedrock.invoke_model(
        modelId="amazon.rerank-v1:0",
        body=json.dumps({
            "query": query,
            "documents": documents,
            "top_n": 3,
        }),
    )
    
    body = json.loads(response["body"].read())
    pprint.pprint(body["results"])
    

    输出

    [{'index': 9, 'relevance_score': 0.001466458403084568},
     {'index': 6, 'relevance_score': 0.0005013742398679934},
     {'index': 8, 'relevance_score': 0.0003640086870995012}]
    

    ※重排序结果中包含的索引(index)以 0 为起始,为了与上方表格保持一致,需在索引数值上加 1。

    结果

    序号内容
    10晚餐是大量使用本地食材制作的创意料理,每道菜都能感受到巧思。特别是用本地产蔬菜和肉类制作的烤肉料理,堪称绝品,充分凸显了食材本身的味道。早餐也很用心,有手工果酱和刚出炉的面包等,非常满意。
    7晚餐有很多本地特色菜,非常满意。特别是炭火烤制的牛排,入口即化,美味得让人想一再续盘。早餐种类也很丰富,用本地蔬菜制作的沙拉和手工豆腐都很美味。
    9酒店的餐食超出预期。因靠近海边,大量使用新鲜海鲜,刺身和煮鱼都非常好吃。晚餐分量充足,每道菜的调味都饱含心意。早餐的日式料理也很美味,尤其是温泉蛋堪称绝品。

    可以确认,正如预期的那样,第 10 条和第 7 条评论内容排在了靠前位置。

    2.2 通过 Bedrock Knowledge Base 的 Rerank API 使用

    Rerank API 是作为 Knowledge Base 的功能提供的,但其本质与上述的 InvokeModel 相同,输入文档列表和用户查询语句后,就能得到重排序后的文档列表。

    代码

    region = boto3.Session().region_name
    amazon_rerank_arn = f"arn:aws:bedrock:{region}::foundation-model/amazon.rerank-v1:0"
    
    response = bedrock_agent.rerank(
        queries=[
            {
                "type": "TEXT",
                "textQuery": {
                    "text": query,
                },
            },
        ],
        sources=[
            {
                "inlineDocumentSource": {
                    "textDocument": {
                        "text": document,
                    },
                    "type": "TEXT",
                },
                "type": "INLINE",
            } for document in documents
        ],
        rerankingConfiguration={
            "type": "BEDROCK_RERANKING_MODEL",
            "bedrockRerankingConfiguration": {
                "numberOfResults": 3,
                "modelConfiguration": {
                    "modelArn": amazon_rerank_arn,
                },
            },
        },
    )
    
    pprint.pprint(response["results"])
    

    输出

    [{'index': 9, 'relevanceScore': 0.0014664584305137396},
     {'index': 6, 'relevanceScore': 0.0005013742484152317},
     {'index': 8, 'relevanceScore': 0.0003640086797531694}]
    

    可以确认,得到了与使用 InvokeModel 时完全相同的结果。

    2.3 通过 Bedrock Knowledge Base 的 Retrieve API 使用

    与 InvokeModel、Rerank API 不同,在 Retrieve API 中,无需传入文档列表作为输入。

    该 API 以用户的查询语句为输入,先通过用户查询语句检索向量数据库,再将检索结果作为文档列表进行重排序。

    为了使用 Retrieve API,我们先创建了知识库,并将上述内容逐条作为一个数据块进行存储。

    首先确认不进行重排序时的结果。

    代码

    response = bedrock_agent.retrieve(
        knowledgeBaseId=knowledgebase_id,
        retrievalConfiguration={
            "vectorSearchConfiguration": {
                "numberOfResults": 3,
                "overrideSearchType": "SEMANTIC",
            },
        },
        retrievalQuery={
            "text": query,
        },
    )
    
    pprint.pprint(response["retrievalResults"])
    

    输出

    [{'content': {'text': '酒店的餐食宛如艺术品。大量使用本地新鲜食材制作的怀石料理,不仅外观精美,每一道菜都能让人感受到制作的用心。尤其是用当季海鲜制作的刺身,堪称绝品,仅凭这一点就想再次前来。',
                  'type': 'TEXT'},
      'location': {'s3Location': {'uri': 's3://xxx/006.txt'},
                   'type': 'S3'},
      'score': 0.43565163},
     {'content': {'text': '酒店的餐食超出预期。因靠近海边,大量使用新鲜海鲜,刺身和煮鱼都非常好吃。晚餐分量充足,每道菜的调味都饱含心意。早餐的日式料理也很美味,尤其是温泉蛋堪称绝品。',
                  'type': 'TEXT'},
      'location': {'s3Location': {'uri': 's3://xxx/009.txt'},
                   'type': 'S3'},
      'score': 0.435101},
     {'content': {'text': '晚餐是大量使用本地食材制作的创意料理,每道菜都能感受到巧思。特别是用本地产蔬菜和肉类制作的烤肉料理,堪称绝品,充分凸显了食材本身的味道。早餐也很用心,有手工果酱和刚出炉的面包等,非常满意。',
                  'type': 'TEXT'},
      'location': {'s3Location': {'uri': 's3://xxx/010.txt'},
                   'type': 'S3'},
      'score': 0.4281698}]
    

    结果

    序号内容
    6酒店的餐食宛如艺术品。大量使用本地新鲜食材制作的怀石料理,不仅外观精美,每一道菜都能让人感受到制作的用心。尤其是用当季海鲜制作的刺身,堪称绝品,仅凭这一点就想再次前来。
    9酒店的餐食超出预期。因靠近海边,大量使用新鲜海鲜,刺身和煮鱼都非常好吃。晚餐分量充足,每道菜的调味都饱含心意。早餐的日式料理也很美味,尤其是温泉蛋堪称绝品。
    10晚餐是大量使用本地食材制作的创意料理,每道菜都能感受到巧思。特别是用本地产蔬菜和肉类制作的烤肉料理,堪称绝品,充分凸显了食材本身的味道。早餐也很用心,有手工果酱和刚出炉的面包等,非常满意。

    当获取前 3 条结果时,第 10 条评论排在第 3 位,而第 7 条评论未出现在检索结果中。

    若使用这样的检索结果进行 RAG,恐怕难以得到高精度的回答。

    接下来,在 Retrieve API 中指定重排序模型,确认检索结果会发生怎样的变化。

    代码

    response = bedrock_agent.retrieve(
        knowledgeBaseId=knowledgebase_id,
        retrievalConfiguration={
            "vectorSearchConfiguration": {
                # (1) 首次检索时获取 10 条结果
                "numberOfResults": 10,
                "overrideSearchType": "SEMANTIC",
                "rerankingConfiguration": {
                    "bedrockRerankingConfiguration": {
                        "modelConfiguration": {
                            "modelArn": amazon_rerank_arn,
                        },
                        # (2) 对检索得到的 10 条结果进行重排序,并返回前 3 条
                        "numberOfRerankedResults": 3,
                    },
                    "type": "BEDROCK_RERANKING_MODEL",
                },
            },
        },
        retrievalQuery={
            "text": query,
        },
    )
    
    pprint.pprint(response)
    

    输出

    [{'content': {'text': '晚餐是大量使用本地食材制作的创意料理,每道菜都能感受到巧思。特别是用本地产蔬菜和肉类制作的烤肉料理,堪称绝品,充分凸显了食材本身的味道。早餐也很用心,有手工果酱和刚出炉的面包等,非常满意。',
                  'type': 'TEXT'},
      'location': {'s3Location': {'uri': 's3://xxx/010.txt'},
                   'type': 'S3'},
      'score': 0.0014721895568072796},
     {'content': {'text': '晚餐有很多本地特色菜,非常满意。特别是炭火烤制的牛排,入口即化,美味得让人想一再续盘。早餐种类也很丰富,用本地蔬菜制作的沙拉和手工豆腐都很美味。',
                  'type': 'TEXT'},
      'location': {'s3Location': {'uri': 's3://xxx/007.txt'},
                   'type': 'S3'},
      'score': 0.0004994205664843321},
     {'content': {'text': '酒店的餐食超出预期。因靠近海边,大量使用新鲜海鲜,刺身和煮鱼都非常好吃。晚餐分量充足,每道菜的调味都饱含心意。早餐的日式料理也很美味,尤其是温泉蛋堪称绝品。',
                  'type': 'TEXT'},
      'location': {'s3Location': {'uri': 's3://xxx/009.txt'},
                   'type': 'S3'},
      'score': 0.0003640086797531694}]
    

    结果

    序号内容
    10晚餐是大量使用本地食材制作的创意料理,每道菜都能感受到巧思。特别是用本地产蔬菜和肉类制作的烤肉料理,堪称绝品,充分凸显了食材本身的味道。早餐也很用心,有手工果酱和刚出炉的面包等,非常满意。
    7晚餐有很多本地特色菜,非常满意。特别是炭火烤制的牛排,入口即化,美味得让人想一再续盘。早餐种类也很丰富,用本地蔬菜制作的沙拉和手工豆腐都很美味。
    9酒店的餐食超出预期。因靠近海边,大量使用新鲜海鲜,刺身和煮鱼都非常好吃。晚餐分量充足,每道菜的调味都饱含心意。早餐的日式料理也很美味,尤其是温泉蛋堪称绝品。

    通过执行重排序,第 10 条和第 7 条内容占据了前 2 位。

    这样一来,就能为用户提供更多其所需的信息了。

    3. Amazon Rerank 模型与 Cohere Rerank 模型的对比

    接下来,我们使用同样可在 Bedrock 上使用的 Cohere Rerank 模型对相同内容进行测试。

    只需将 modelArn 替换为 Cohere Rerank 模型对应的 ARN,就能切换所使用的重排序模型。

    操作起来非常简便。

    代码

    cohere_rerank_arn = f"arn:aws:bedrock:{region}::foundation-model/cohere.rerank-v3-5:0"
    # (省略)
    

    输出

    [{'content': {'text': '晚餐是大量使用本地食材制作的创意料理,每道菜都能感受到巧思。特别是用本地产蔬菜和肉类制作的烤肉料理,堪称绝品,充分凸显了食材本身的味道。早餐也很用心,有手工果酱和刚出炉的面包等,非常满意。',
                  'type': 'TEXT'},
      'location': {'s3Location': {'uri': 's3://xxx/010.txt'},
                   'type': 'S3'},
      'score': 0.3279808461666107},
     {'content': {'text': '酒店的餐食宛如艺术品。大量使用本地新鲜食材制作的怀石料理,不仅外观精美,每一道菜都能让人感受到制作的用心。尤其是用当季海鲜制作的刺身,堪称绝品,仅凭这一点就想再次前来。',
                  'type': 'TEXT'},
      'location': {'s3Location': {'uri': 's3://xxx/006.txt'},
                   'type': 'S3'},
      'score': 0.1456373631954193},
     {'content': {'text': '晚餐有很多本地特色菜,非常满意。特别是炭火烤制的和牛牛排,入口即化,美味得让人想一再续盘。早餐种类也很丰富,用本地蔬菜制作的沙拉和手工豆腐都很美味。',
                  'type': 'TEXT'},
      'location': {'s3Location': {'uri': 's3://xxx/007.txt'},
                   'type': 'S3'},
      'score': 0.11919290572404861}]
    

    结果

    序号内容
    10晚餐是大量使用本地食材制作的创意料理,每道菜都能感受到巧思。特别是用本地产蔬菜和肉类制作的烤肉料理,堪称绝品,充分凸显了食材本身的味道。早餐也很用心,有手工果酱和刚出炉的面包等,非常满意。
    6酒店的餐食宛如艺术品。大量使用本地新鲜食材制作的怀石料理,不仅外观精美,每一道菜都能让人感受到制作的用心。尤其是用当季海鲜制作的刺身,堪称绝品,仅凭这一点就想再次前来。
    7晚餐有很多本地特色菜,非常满意。特别是炭火烤制的和牛牛排,入口即化,美味得让人想一再续盘。早餐种类也很丰富,用本地蔬菜制作的沙拉和手工豆腐都很美味。

    与使用 Amazon Rerank 模型时相比,第 7 条的排名下降了一位,但仍在前三之列。

    第 6 条内容虽然是关于海鲜料理而非肉类料理的评论,但它是关于美味料理的评论,而非温泉相关,因此我认为其得分较高。

    这样一来,在 RAG 生成回答时,也能在不缺失信息的情况下进行内容生成了。

    4. 其他

    4.1 调用速度

    我们对 Amazon Rerank 模型与 Cohere Rerank 模型的响应速度是否存在差异进行了验证。

    针对俄勒冈区域的模型,我们分别对相同请求各执行 5 次,通过比较响应时间的平均值来分析差异。

    Amazon Rerank 模型

    序号响应时间(秒)
    10.895
    20.687
    30.734
    40.828
    50.775
    平均0.784

    Cohere Rerank 模型

    序号响应时间(秒)
    10.454
    20.508
    30.533
    40.495
    50.453
    平均0.489

    对比结果显示,Cohere Rerank 模型的速度约为 Amazon Rerank 模型的 1.5 倍。

    4.2 费用

    本次使用的模型费用如下表所示。

    虽然相较于非重排序模型(例如 Amazon Nova Lite 为每 1000 个输出令牌 0.00024 美元),这些重排序模型的费用略显偏高,但这也意味着仅通过 API 调用就能使用到如此复杂的功能。

    序号模型费用
    1Amazon Rerank 模型1 美元 / 1000 次查询
    2Cohere Rerank 模型2 美元 / 1000 次查询

    总结

    我们对 Bedrock 新增的重排序模型进行了验证,确认其对改善检索结果具有实际作用。

    实验表明,通过执行重排序操作,能够使更贴合用户输入的内容出现在检索结果的靠前位置。

    此外,Bedrock Knowledge Base 的优势在于,无需自行开发实现,仅通过修改设置就能实现检索效果的大幅提升。

    本次验证仅进行到检索(retrieve)阶段,而若使用 retrieve_and_generate 功能,还可将回答生成的过程也交由 Bedrock 完成。

    未来,我希望活用 Bedrock 的重排序功能,开发出更贴合用户意图的 RAG 系统。

  • 使用 Aurora Serverless v2 作为 Amazon Bedrock Knowledge Bases 的向量数据库

    使用 Aurora Serverless v2 作为 Amazon Bedrock Knowledge Bases 的向量数据库

    今天我尝试了使用 Amazon Bedrock Knowledge Bases,并将 Amazon Aurora PostgreSQL 用作向量数据库。

    去年 12 月,Amazon Bedrock Knowledge Bases 新增了可快速创建 Aurora PostgreSQL 作为向量数据库的功能,大幅简化了设置流程。

    本次我也将利用这一快速创建功能进行设置。

    aws.amazon.com

    1. 将 Aurora PostgreSQL 配置为向量存储

    事前准备

    本次将 S3 用作 RAG(检索增强生成)的外部数据源。之后,我们会确认 LLM(大语言模型)的回答是否参考了存储在 S3 中的资料。

    Knowledge Bases 的创建

    在 AWS 管理控制台中,进入 Bedrock 页面,仅通过 GUI 操作即可轻松创建 Knowledge Bases。

    点击 “Knowledge Base with vector store”(带向量存储的知识库),即可跳转至 Knowledge Bases 创建页面。

    在 “步骤 2 配置数据源” 中,指定事前准备好的 S3 的 URI。而 “步骤 3 选择嵌入模型并配置向量数据库” 则是本次的核心内容。

    向量数据库的选项中新增了 “Amazon Aurora PostgreSQL Serverless” 这一项目,请选择此项。

    ※向量数据库的可选范围因区域而异,本文中测试使用的是东京区域。

    之后点击 “下一步”,确认创建内容后即可完成设置。仅需通过 GUI 操作即可完成,直观又简单!

    在 RDS 控制台中可以确认已创建的数据库。

    数据库表的创建情况如下所示。

    Bedrock_Knowledge_Base_Cluster=> \d bedrock_knowledge_base
            Table "bedrock_integration.bedrock_knowledge_base"
      Column   |        Type         | Collation | Nullable | Default
    -----------+---------------------+-----------+----------+---------
     id        | uuid                |           | not null |
     embedding | public.vector(1536) |           |          |
     chunks    | text                |           |          |
     metadata  | jsonb               |           |          |
    Indexes:
        "bedrock_knowledge_base_pkey" PRIMARY KEY, btree (id)
        "bedrock_knowledge_base_embedding_idx" hnsw (embedding public.vector_l2_ops)
    

    Knowledge Bases 的测试

    选择已创建的 Knowledge Bases 后,会出现 “测试知识库”页面。在此处向 LLM 提问,测试是否能返回预期的回答。

    本次我提出了 “敏捷开发的优势是什么?“ 这一问题。结果如预期般返回了参考了事前准备并存储在 S3 中的资料的回答,看起来运行正常。

    2. 与 OpenSearch Serverless 的对比

    OpenSearch Serverless 是被广泛用作向量数据库的代表性服务。此处将整理其与 Aurora Serverless v2 在实际使用中的差异。

    功能

    当使用 Aurora PostgreSQL 作为向量数据库时,仅支持语义搜索这一种检索类型。

    而使用 OpenSearch Serverless 时,则可在混合搜索与语义搜索之间进行选择。

    • 语义搜索:并非简单的关键词匹配,而是检索语义上相关的信息。
    • 混合搜索:将关键词检索与语义搜索相结合进行信息检索。

    从检索功能性来看,OpenSearch Serverless 更具优势。若需融入关键词检索功能,建议选择 OpenSearch Serverless。

    成本

    OpenSearch Serverless 的计算费用采用计时收费模式,即便处于未使用状态,仍会产生每小时的费用。以美国东部(弗吉尼亚北部)区域为例,每个单位的费用为 0.24 美元 / 小时。根据文档说明,至少会按 2 个单位计费,因此每月的费用约为 0.24 美元 / 小时 × 720 小时 × 2 = 345 美元。

    相比之下,Aurora Serverless v2 不仅单价低廉(0.12 美元 / 单位 / 小时),还支持缩容至 0 个单位。因此,能够有效控制未使用状态下的成本。

    aws.amazon.com

    查看此前通过快速创建功能搭建的 Aurora PostgreSQL 实例配置,确认其确实支持缩容至 0 个单位,与预期一致。

    在 CloudWatch 中查看单位使用率(ACU),可以确认实例在未使用时会自动缩容至 0 个单位。

    3. 检索速度确认

    最后,我们将验证文档数量增加时的检索速度及 ACU(Aurora 计算单位)变化情况。数据源采用 Kaggle 上的 “BBC News Summary” 数据集,将约 9000 条数据存储至 S3 中。

    参照 “1. 将 Aurora PostgreSQL 配置为 Bedrock Knowledge Bases 的向量数据库” 中的方法,向 LLM 发起提问。结果显示,与文档数量较少时相同,回答在数十毫秒内即可返回。对于本次使用的数据集规模而言,检索速度似乎不存在明显问题。

    查看 ACU 数据可知:文档导入时的 ACU 使用率约为 30%(16(最大扩容单位数)× 0.3 = 5 个单位),LLM 生成回答时的 ACU 使用率约为 15%(16 × 0.15 = 2.5 个单位)。

    向量数据库的 ReadLatency(读取延迟)控制在 0.01 秒以内,使用体验较为流畅。

    4. 总结

    本次尝试了在 Bedrock Knowledge Bases 中使用 Aurora Serverless v2 作为向量数据库。

    借助快速创建功能,仅需几次 GUI 点击操作,即可轻松完成向量数据库的搭建。对于 “控制未使用状态下成本” 这一需求,也能够轻松实现。

    最后提醒

    仅删除 Bedrock Knowledge Bases,并不能移除通过快速创建功能生成的向量数据库等其他关联资源。若不再需要这些资源,请务必手动删除,避免遗漏。

  • 使用 GraphRAG Toolkit 在 Amazon Bedrock 中构建 GraphRAG

    使用 GraphRAG Toolkit 在 Amazon Bedrock 中构建 GraphRAG

    此次,我想借助 AWS 提供的开源工具 GraphRAG Toolkit,入门 GraphRAG 技术。

    使用 GraphRAG Toolkit,能够以低代码方式实现基于 Amazon Neptune 和 Amazon OpenSearch Serverless 的 GraphRAG 系统。

    另外,请注意,它与 2024 年 12 月起可在 Bedrock Knowledge Base 中使用的 GraphRAG 是不同的工具,请勿混淆。

    1. 前言

    1.1. 什么是 GraphRAG?

    传统的 RAG(检索增强生成)采用关键词检索或向量检索来获取相关信息,而 GraphRAG 则利用知识图谱,更深入地理解检索结果的上下文,从而提取相关性更高的信息。

    在传统 RAG 中,只有通过关键词检索或向量检索命中的信息才能用于回答生成;而在 GraphRAG 中,以关键词检索或向量检索得到的结果为起点,对图谱进行遍历,即便未在检索中命中但与上下文相关的信息也能被获取,并用于回答生成。

    也就是说,GraphRAG 利用结构化的实体间关系,实现了精度更高的信息检索与上下文理解。

    1.2. 什么是 GraphRAG Toolkit?

    GraphRAG Toolkit 是 AWS 提供的开源 GraphRAG 库,提供了诸多简化基于 GraphRAG 的系统构建的功能。(参考链接:github.com

    该工具可将 Amazon Neptune Database 用作图数据库,将 Amazon OpenSearch Serverless 用作向量数据库。

    通过使用此工具包,能够从非结构化数据中提取实体及其关系,将其作为知识图谱存储;并通过针对该知识图谱查询用户问题,构建可提供相关性更高信息的应用程序。本次我们将使用该工具包来尝试 GraphRAG 技术。

    GraphRAG Toolkit 中知识图谱的基本结构

    知识图谱是一种将数据构建为实体(实际存在的事物)及其关系(关联性)的结构化数据模型,用于表达数据间的语义关联。

    通过将信息整理为 “实体” 与 “关系” 的网络,能够实现考虑关联性的检索以及逻辑性的推理。

    在 GraphRAG Toolkit 中,知识图谱通过以下术语和结构构建。(自上而下,概念从抽象宏观逐渐过渡到具体微观。)

    序号项目概述示例
    1文档(Source)表示原始文档的属性https://docs.aws.amazon.com/neptune/latest/userguide/intro.html
    2片段(Chunk)文档分割后的小单位Amazon Neptune is a fast, reliable, fully managed graph database service that makes it easy to build and run applications that work with highly connected datasets. The core of Neptune is…
    3主题(Topic)片段中记载的核心主题Amazon Neptune
    4语句(Statement)片段中书写的句子或语句The core of Neptune is a purpose-built, high-performance graph database engine.
    5事实(Fact)从语句中提炼出的事实Amazon Neptune HAS high-performance
    6实体事实的主语、宾语,对应现实世界的 “事物” 或 “概念”Amazon Neptune

    知识图谱示意图(链接:https://github.com/awslabs/graphrag-toolkit/blob/main/images/lexical-graph.png

    1.3. 什么是 Amazon Neptune?

    Amazon Neptune 是 AWS 提供的全托管型图数据库服务,能够高效管理和操作数据间的关系。

    Neptune 支持多种图模型,可实现灵活的数据操作。它不仅可用于构建知识图谱,还在社交网络分析、推荐系统等多种场景中得到应用。

    此外,其一大优势在于能够控制成本 —— 可在不使用的时段 “停止” 服务,在开发环境中还能选用 T3 实例等相对经济的实例类型。

    2. 构建环境

    本次将通过 GraphRAG Toolkit 提供的 CloudFormation 模板来搭建环境。

    架构图
    序号项目概述
    1Amazon Neptune存储知识图谱并提供检索功能
    2Amazon OpenSearch Service配合图检索使用,用于向量检索
    3Amazon Bedrock从片段中提取主题、语句、事实、实体;生成用于存入向量数据库的向量・提取模型:Claude-3-Sonnet・向量化模型:Titan Text Embedding V2
    4Notebook(笔记本)操作 GraphRAG Toolkit,执行文档导入与检索操作

    3. 导入数据

    使用上述 CloudFormation 模板搭建环境后,系统会提供多个示例笔记本。数据导入可选择以下两种笔记本之一:

    • 01-Combined-Extract-and-Build.ipynb:一站式完成从文档中提取实体等信息及构建图谱的操作
    • 02-Separate-Extract-and-Build.ipynb:将实体等信息的提取与图谱构建拆分为独立步骤执行

    文档导入按以下流程进行:

    1. 文档分割(Chunking):将文档拆分为细小的单元
    2. 提取命题(Proposition):将片段传入大语言模型(LLM),提取命题命题是为提取构建知识图谱所需的 6 类要素而生成的预处理结果,会对原始文档进行清洗,例如将复杂句子拆分为简单易懂的句子、展开代词和缩写等。
    3. 提取核心要素:将命题传入 LLM,提取主题、语句、事实、实体
    4. 构建并导入知识图谱:根据提取的实体等信息构建知识图谱,存入图数据库
    5. 向量化并导入向量数据库:将语句传入 LLM 进行嵌入(Embedding)处理,生成向量后存入向量数据库

    使用 GraphRAG Toolkit 时,只需调用 extract 方法,即可一键执行上述所有流程,上手非常简单。

    3.1. 确认待导入的数据

    本次将使用 02-Separate-Extract-and-Build.ipynb 笔记本,确认提取模型如何处理原始文档,使其转化为可导入图数据库的格式。

    执行笔记本中的 “Extract(提取)” 阶段后,LLM 会解析文档,提取实体、属性以及各类关系。提取结果将保存至 extracted/ 目录下。

    通过修改配置,也可将提取结果保存至 S3。这样一来,可将已处理的数据存储在 S3 中,当新增数据需要重新构建知识图谱、或需在其他数据库中构建相同知识图谱时,无需重复执行提取操作,既能规避 LLM 的调用限制,又能节省成本。

    实际输出到 extracted/ 目录的 JSON 文件内容如下(因篇幅有限,已大幅省略)。从中可以看出,前文所述的命题、主题、语句、事实、实体均以嵌套形式存储。

    {
      "id_": "aws:xxxx",
      "metadata": {
        "url": "https://docs.aws.amazon.com/neptune-analytics/latest/userguide/what-is-neptune-analytics.html",
        "aws::graph::propositions": [
          // 命题
          "Neptune Analytics is a memory-optimized graph database engine for analytics",
          "Neptune Analytics allows getting insights and finding trends by processing large amounts of graph data in seconds"
        ],
        "aws::graph::topics": {
          "topics": [
            {
              // 主题
              "value": "Neptune Analytics",
              "entities": [
                {
                  // 实体
                  "value": "Neptune Analytics",
                  "classification": "Software"
                }
              ],
              "statements": [
                {
                  // 语句
                  "value": "Neptune Analytics is a memory-optimized graph database engine for analytics",
                  "facts": [
                    // 事实
                    {
                      "subject": {
                        "value": "Neptune Analytics",
                        "classification": "Software"
                      },
                      "predicate": {
                        "value": "OPTIMIZED FOR"
                      },
                      "complement": "memory"
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    }
    

    此外,对于中文文档,它也能很好地完成信息提取。

    {
      "id_": "aws:xxxx",
      "metadata": {
        "aws::graph::propositions": [
          // 命题
          "知识表示的方法",
          "知识图谱将数据表现为实体与关系的网络",
          "知识图谱是一种易于捕捉信息语义的强大方法"
        ],
        "aws::graph::topics": {
          "topics": [
            {
              // 主题
              "value": "Knowledge Representation",
              "entities": [
                {
                  // 实体
                  "value": "知识图谱(知识图谱)",
                  "classification": "Concept(概念)"
                }
              ],
              "statements": [
                {
                  // 语句
                  "value": "知识图谱将数据表现为实体与关系的网络",
                  "facts": [
                    // 事实
                    {
                      "subject": {
                        "value": "知识图谱(知识图谱)",
                        "classification": "Concept(概念)"
                      },
                      "predicate": {
                        "value": "REPRESENTS(表示)"
                      },
                      "object": {
                        "value": "数据(数据)",
                        "classification": "Concept(概念)"
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    }
    

    3.2. 确认已导入的数据

    通过 CloudFormation 部署 Notebook 时,图探索器(Graph Explorer)会同时完成部署。打开该图探索器,即可直观查看已构建的知识图谱。

    图探索器的打开方式

    下图展示了使用 GraphRAG Toolkit 导入 Amazon Neptune 文档后构建的知识图谱的部分内容。

    如前文所述,可以看到知识图谱分为文档、片段、主题、语句、事实、实体等层级,且各层级之间的关系均有明确标注。

    实际构建的知识图谱(部分)

    4. 检索

    在 GraphRAG 中,首先通过向量检索找到作为起点的节点,随后遍历知识图谱,最终返回检索结果。

    GraphRAG Toolkit 主要提供两种检索方法,具体如下表所示:

    序号检索方法优点缺点用途
    1TraversalBasedRetriever・处理轻量化・结果可重复性高・对未知词汇及专有名词的适配性强・灵活性较低・检索精度偏低按类别整理的 FAQ 等场景
    2SemanticGuidedRetriever・可探索符合问题意图的信息・能考虑复杂关联性・可确保检索结果的多样性・计算成本高,处理负载重需要灵活、高级的信息检索场景(如匹配问题意图、需多样化信息等)

    4.1. TraversalBasedRetriever(基于遍历的检索器)

    TraversalBasedRetriever 是通过按顺序遍历图谱结构来扩展信息的检索方法。由于它会按固定顺序遍历知识图谱,因此处理过程较为轻量化。

    TraversalBasedRetriever 包含两种具体实现方式,可单独使用其中一种,也可组合使用两种。默认设置下,返回的是两种方式组合后的结果。

    1. EntityBasedSearch(基于实体的检索)

    从查询字符串中提取关键词,在图谱中查找匹配的实体(自下而上,Bottom up)。找到匹配的实体后,从该实体出发,向事实、命题、主题等更宏观的概念层级遍历,从而完成检索。

    其特点是,即便面对未知词汇或专有名词,也能依据预先构建的知识图谱收集相关信息。由于检索从实体出发,往往能广泛获取与该实体相关的信息。

    2. ChunkBasedSearch(基于片段的检索)

    利用查询与片段间的向量相似度进行检索(自上而下,Top down)。从检索命中的片段出发,向主题、命题、事实等更微观的概念层级遍历,从而完成检索。

    由于检索从与查询语义相近的片段开始,往往能精准获取关联性更强的信息。

    4.2. SemanticGuidedRetriever(基于语义引导的检索器)

    SemanticGuidedRetriever 对语句(Statement)进行向量化处理后执行检索。针对通过向量检索获取的语句,采用波束搜索(Beam Search)与路径解析技术,从邻近节点开始探索,筛选出关联性强的信息。

    此外,该检索器还集成了多种为回答生成筛选所需信息的机制,例如:通过重排序(Rerank)筛选符合问题意图的检索结果;通过多样性过滤器确保回答信息不仅局限于相似内容,而是具备多样性。

    通过结合向量检索与图谱检索的混合模式,SemanticGuidedRetriever 既能保持较高的信息关联性,又能返回范围更广的检索结果,但相应地会增加处理负载。

    4.3. 确认检索结果

    可使用 GraphRAG Toolkit 中包含的 04-Querying.ipynb 笔记本,测试上述两种检索方法。

    我们针对每个检索器提出了 “Neptune Database 与 Neptune Analytics 有什么区别?” 的问题,并确认了大语言模型(LLM)的回答及回答所使用的文档。

    TraversalBasedRetriever

    Neptune Database 与 Neptune Analytics 呈互补关系。

    Neptune Database 是托管型图数据库服务,提供数据的持久化存储、备份、复制等功能。[https://docs.aws.amazon.com/neptune/latest/userguide/intro.html]

    而 Neptune Analytics 是用于高速分析大规模图数据的内存引擎,可从 Neptune Database 或 S3 读取图数据,通过执行预构建的图算法或自定义查询进行分析。

    [https://docs.aws.amazon.com/neptune-analytics/latest/userguide/what-is-neptune-analytics.html]

    也就是说,Neptune Database 负责图数据的持久化存储与管理,Neptune Analytics 则是实现该数据高速分析处理的服务。通过将数据存储与分析分离,可使两者各自实现专注于自身功能的性能优化。[https://docs.aws.amazon.com/neptune-analytics/latest/userguide/neptune-analytics-features.html]

    ■ 文档

    [
      {
        "source": "https://docs.aws.amazon.com/neptune-analytics/latest/userguide/what-is-neptune-analytics.html",
        "topic": "Neptune Analytics",
        "statements": [
          "Neptune Analytics can load data from a Neptune Database graph",
          "Neptune Analytics complements Amazon Neptune Database, a popular managed graph database",
          "Neptune Analytics can load data from a Neptune Database snapshot",
          "The Neptune Analytics vs Neptune Database page explains when to use Neptune Analytics and when to use Neptune Database",
          "Neptune Analytics can load graph data stored in Amazon S3"
        ]
      },
      {
        "source": "https://docs.aws.amazon.com/neptune/latest/userguide/intro.html",
        "topic": "Amazon Neptune",
        "statements": [
          "Neptune Analytics is an analytics database engine.",
          "Neptune Analytics complements Neptune database.",
          "The Neptune database has continuous backup to Amazon S3",
          "Amazon Neptune automatically detects database crashes and restarts",
          "Amazon Neptune increases database performance and availability"
        ]
      }
    ]
    

    4.3.1. SemanticGuidedRetriever(基于语义引导的检索器)

    Neptune Database 与 Neptune Analytics 是不同的产品,主要区别如下:

    Neptune Database 是托管型图数据库服务,可实现数据的持久化存储与低延迟的查询执行。[https://docs.aws.amazon.com/neptune/latest/userguide/intro.html]

    而 Neptune Analytics 是用于在内存中分析图数据的引擎,可将大规模图数据集加载到内存中,高速执行预先准备的高级分析算法及自定义 Cypher 查询。

    [https://docs.aws.amazon.com/neptune-analytics/latest/userguide/what-is-neptune-analytics.html]

    Neptune Analytics 适用于数据分析、数据科学及探索性工作负载。

    也就是说,Neptune Database 的主要目的是数据的持久化存储与低延迟查询执行,而 Neptune Analytics 的主要目的是在内存中实现大规模图数据的高速分析。此外,Neptune Analytics 也可从 Neptune Database 读取数据并进行分析。[https://docs.aws.amazon.com/neptune-analytics/latest/userguide/what-is-neptune-analytics.html]

    ■ 文档

    <sources>
      <source_1>
        <source_1_metadata>
          <url>https://docs.aws.amazon.com/neptune-analytics/latest/userguide/what-is-neptune-analytics.html</url>
        </source_1_metadata>
        <statement_1.1>Neptune Analytics is a memory-optimized graph database engine for analytics</statement_1.1>
        <statement_1.2>Neptune Analytics is a memory-optimized graph database engine for analytics</statement_1.2>
        <statement_1.3>Neptune Analytics can load data from a Neptune Database graph</statement_1.3>
        <statement_1.4>Neptune Analytics can load data from a Neptune Database snapshot</statement_1.4>
        <statement_1.5>Neptune Analytics is an ideal choice for data-science workloads that require fast iteration for data, analytical and algorithmic processing, or vector search on graph data</statement_1.5>
      </source_1>
      <source_2>
        <source_2_metadata>
          <url>https://docs.aws.amazon.com/neptune/latest/userguide/intro.html</url>
        </source_2_metadata>
        <statement_2.1>Neptune Analytics is an analytics database engine.</statement_2.1>
        <statement_2.2>Neptune Analytics is a solution for quickly analyzing existing graph databases.</statement_2.2>
        <statement_2.3>Neptune Analytics is a solution for quickly analyzing graph datasets stored in a data lake.</statement_2.3>
        <statement_2.4>Amazon Neptune is a fully managed graph database service</statement_2.4>
        <statement_2.5>Amazon Neptune is a fully managed graph database service</statement_2.5>
      </source_2>
    </sources>
    

    直观来看,使用 SemanticGuidedRetriever 得到的回答似乎更准确,但不同检索方法在检索精度上的差异等问题,我们将留作后续的验证课题。

    此外,TraversalBasedRetriever 与 SemanticGuidedRetriever 返回结果中包含的文档格式存在差异,不过据了解,该问题将在后续更新中实现统一。

    总结

    本次我们通过 GraphRAG Toolkit,了解了 GraphRAG 处理数据的具体流程。通过实际运行并确认内部机制,我认为已经理解了 GraphRAG 的特性。

    同时,我们也发现,借助 GraphRAG Toolkit 能够非常轻松地构建 GraphRAG 系统。该工具包封装了将数据导入图数据库前的繁琐处理流程,这一点十分令人满意。