标签: AI

  • RAG 中的混合搜索对决!OpenSearch Serverless VS Aurora Serverless

    RAG 中的混合搜索对决!OpenSearch Serverless VS Aurora Serverless

    前言

    今天我要对可作为 Amazon Bedrock Knowledge Bases 向量数据库(搜索引擎)的工具进行对比。

    目前,Bedrock Knowledge Base 中支持混合搜索的向量数据库如下:

    • OpenSearch Serverless
    • OpenSearch Managed Cluster(OpenSearch 托管集群)
    • Aurora Serverless V2(PostgreSQL)
    • MongoDB Atlas

    本次,我将针对其中使用率较高的OpenSearch ServerlessAurora Serverless V2(PostgreSQL) ,对比二者在混合搜索中的精度表现。

    概述

    混合搜索是一种结合向量(语义)搜索关键词(全文)搜索来查找相关文档的搜索方式。这种方式既能通过向量搜索实现基于语义的检索,又能通过关键词搜索,在检索过程中纳入指定关键词的考量。

    OpenSearch Serverless 与 Aurora Serverless V2(PostgreSQL)的对比

    下面我将对本次作为数据存储使用的 OpenSearch Serverless 和 Aurora Serverless V2(PostgreSQL)进行简单对比。

    对比维度OpenSearch ServerlessAurora Serverless V2(PostgreSQL)
    混合搜索(Bedrock Knowledge Bases)支持支持
    中文支持可使用 Kuromoji 等中文形态素分析PostgreSQL 标准全文搜索(目前不支持中文形态素分析)
    向量存储格式支持浮点数 / 二进制两种格式浮点数(基于 pgvector 插件)
    计费单位OCU / 小时(最小 1 个 OCU,含 0.5 计算 OCU+0.5 存储 OCU)ACU / 小时(最小 0.5 个 ACU)
    最小配置计费示例175.22 美元(1 个 OCU:175.2 美元,存储:0.02 美元)87.83 美元(1 个 ACU:87.60 美元,I/O:0.13 美元)

    (参考链接:aws.amazon.comaws.amazon.com

    OpenSearch Serverless 支持中文形态素分析,因此即便使用中文,也能高精度地进行关键词搜索。另一方面,Aurora Serverless V2(PostgreSQL)在最小配置下的费用更具优势,但由于其默认不支持中文形态素分析,因此在中文混合搜索的精度方面存在不确定性。

    精度对比实验

    为对比 OpenSearch Serverless 与 Aurora Serverless V2(PostgreSQL)的精度,本次将开展以下两类实验:

    1. 英文数据集的搜索精度对比
    2. 中文数据集的搜索精度对比

    尤其对于中文数据集,由于 Aurora Serverless V2(PostgreSQL)不支持中文形态素分析,预计 OpenSearch Serverless 在精度上会更具优势。

    1. 实验设置

    以下是本次实验使用的基本设置。首先,Bedrock Knowledge Base 的基础设置如下,仅向量存储工具为两者的差异点。

    嵌入模型(Embedding Model)嵌入类型(Embedding Type)分块策略(Chunking Strategy)
    Titan Text Embeddings V21024 维浮点数向量嵌入分层分块(父块:2000 字符,子块:500 字符,重叠:50 字符)

    精度对比将通过 Bedrock Evaluations 完成。

    (参考链接:docs.aws.amazon.com

    本次对比将采用以下两项指标,指标取值范围均为 0~1,数值越大表示对问题的回答质量越高:

    • Context relevance(上下文相关性):衡量获取的文本与问题在上下文层面的关联程度
    • Context coverage(上下文覆盖率):衡量获取的文本对正确数据中全部信息的覆盖程度

    2. 混合搜索对比(英文数据集)

    1. 数据集

    本次实验使用的数据集如下:Amazon Reviews 2023(2023 年亚马逊评论数据集)

    (参考链接:amazon-reviews-2023.github.io

    该数据集包含约 2.8 万组 “产品 ID – 评论” 数据,示例如下:

    product/productId: B000GKXY4S
    product/title: Crazy Shape Scissor Set
    product/price: unknown
    review/userId: A1QA985ULVCQOB
    review/profileName: Carleen M. Amadio "Lady Dragonfly"
    review/helpfulness: 2/2
    review/score: 5.0
    review/time: 1314057600
    review/summary: Fun for adults too!
    review/text: I really enjoy these scissors for my inspiration books that I am making (like collage, but in books) and using these different textures these give is just wonderful, makes a great statement with the pictures and sayings. Want more, perfect for any need you have even for gifts as well. Pretty cool!
    

    2. 结果(英文)

    对比结果如下,
    数值越高,评估结果越好。

    指标类型OpenSearch无服务器Aurora Serverless V2(PostgreSQL)
    上下文相关性0.060.07
    上下文覆盖0.190.18

    3. 混合搜索对比(中文数据集)

    那么,接下来将对核心中文数据集的(检索)精度展开比较分析。​

    1. OpenSearch(中文分词设置示例)

    由于 OpenSearch Serverless 可使用 Kuromoji 形态素分析(中文分词工具),因此需进行相关配置。

    通过该配置,中文文本能被正确分割,进而有望提升关键词搜索的精度。

    配置示例

    PUT bedrock-knowledge-base-hybrid-index
    {
      "mappings": {
        "properties": {
          "AMAZON_BEDROCK_METADATA": {
            "type": "text",
            "index": false
          },
          "AMAZON_BEDROCK_TEXT_CHUNK": {
            "type": "text",
            "analyzer": "custom_kuromoji_analyzer"
          },
          "bedrock-knowledge-base-default-vector": {
            "type": "knn_vector",
            "dimension": 1024,
            "method": {
              "name": "hnsw",
              "engine": "faiss",
              "space_type": "cosinesimil"
            }
          },
          "id": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      },
      "settings": {
        "index": {
          "knn.algo_param": {
            "ef_search": "512"
          },
          "knn": "true",
          "analysis": {
            "analyzer": {
              "custom_kuromoji_analyzer": {
                "tokenizer": "kuromoji_tokenizer",
                "filter": [
                  "kuromoji_baseform",
                  "ja_stop"
                ],
                "char_filter": [
                  "icu_normalizer"
                ]
              }
            }
          }
        }
      }
    }
    
    

    2. 插入的中文文档

    本次使用的数据集,是让 ChatGPT 输出的,具体如下。
    在混合检索时,我们期望能以 “张居正生平” 作为关键词,检索到相关信息。

    张居正像(现藏于中国国家博物馆)

    时代 明朝中后期(嘉靖、隆庆、万历年间)

    生诞 嘉靖四年五月初三日(1525 年 5 月 24 日)

    死没 万历十年六月二十日(1582 年 7 月 9 日)(58 岁卒)

    改名 无(一直以 “张居正” 为名,字叔大,号太岳)

    字:叔大

    号:太岳

    谥号:文忠(万历朝初赠,后被追夺,天启朝恢复)

    墓所:湖北省荆州市沙市区张居正墓

    官职:吏部左侍郎兼东阁大学士、礼部尚书兼武英殿大学士、少师兼太子太师、吏部尚书、中极殿大学士(内阁首辅)

    主要事迹 1. 推行 “一条鞭法”,将田赋、徭役和杂税合并,按田亩折算银两征收,简化税制,增加财政收入;2. 实施 “考成法”,考核各级官吏政绩,整顿吏治,提高行政效率;3. 重用戚继光、李成梁等将领,加强北方边防,抵御蒙古部落侵扰,稳定边疆局势;4. 主持治理黄河、淮河,任用潘季驯负责河工,疏通河道,减少水患,保障农业生产。

    评估用数据集示例

    • 问题:请告知张居正被任命为吏部尚书的年份
    • 答案:张居正于明万历元年(公元 1573 年) 正式被任命为吏部尚书。

    3. 结果(中文)

    以下是中文数据集的精度对比结果。数值越大,代表评价结果越好。

    Metric typeOpenSearch ServerlessAurora Serverless V2(PostgreSQL)
    Context relevance0.450.43
    Context coverage1.000.93

    如上表所示,尽管优势微弱,但 OpenSearch Serverless 在两项指标上均超过 Aurora Serverless V2(PostgreSQL)。尤其在衡量 “问题回答覆盖度” 的上下文覆盖率(Context coverage)指标上,OpenSearch Serverless 的优势更为明显。

    我们认为,这一差异源于 OpenSearch Serverless 通过 Kuromoji 实现了中文形态素分析支持,进而在混合搜索的关键词搜索精度上形成了优势。

    此外,我们也对比了两者的搜索速度,结果如下:我们连续执行 5 种不同查询,去除最大值与最小值后计算 “截尾平均值”(Trimmed Mean)进行对比。

    OpenSearch Serverless(秒)Aurora Serverless V2(PostgreSQL)(秒)
    0.48 秒0.55 秒

    从搜索速度来看,OpenSearch Serverless 同样具备更快的检索表现。

    总结

    本次实验对比了在 Bedrock 知识库中,分别使用 OpenSearch Serverless 与 Aurora Serverless V2(PostgreSQL)实现混合搜索的效果。结果显示,在中文搜索的精度与速度上,OpenSearch Serverless 均优于 Aurora Serverless V2(PostgreSQL)。

    需要说明的是,本次验证基于 “数据量较少” 的场景,因此两者的差距并不显著;若后续数据量增加,结果可能会发生变化。不过,从整体来看,两款工具在精度与速度上均具备较高性能,建议根据实际使用场景数据量选择合适的工具。

  • 借助 StrandsAgents+AgentCore Memory 实现符合个人偏好的智能体

    借助 StrandsAgents+AgentCore Memory 实现符合个人偏好的智能体

    近年来,随着对话式 AI 的应用不断深入,为每位用户提供个性化体验变得愈发重要。当前所需的智能体,已不再是简单的一问一答模式,而是能够理解 “用户是谁、拥有怎样的关注点与目标” 后再进行响应的智能体。

    在本文中,我们将结合 Strands Agents 与 Bedrock AgentCore,对可记忆并活用用户对话历史的个性化智能体进行实现与验证。

    1. 引言

    首先,我们将对各个构成要素进行简单介绍。

    1.1 什么是 Strands Agents

    Strands Agents 是一套能够灵活设计并构建对话式智能体行为及对话流程的机制。通过组合多个工具,可在对话过程中实现所需的处理(如 API 调用、数据检索、记忆查询等)。

    相关内容也可参考 GitHub 链接:github.com

    1.1.1 Strands Agents 工具

    在 Strands Agents 中,“工具” 指的是智能体所使用的外部功能。本文将重点介绍用于处理对话记忆的 “Agent Core Memory” 工具。

    相关参考链接:github.com

    1.2 什么是 Bedrock AgentCore

    Bedrock AgentCore 是一项托管服务,为智能体的开发与运行提供所需功能。它具备以下功能,可助力智能体的顺畅构建:

    • 提供运行环境
    • 与各类工具联动
    • 认证与授权功能
    • 按用户管理记忆等

    官方参考链接:aws.amazon.com

    1.2.1 AgentCore 记忆功能(AgentCore Memory)

    AgentCore 具备 “Memory(记忆)” 功能,可让智能体拥有短期记忆与长期记忆。

    其中,长期记忆尤为重要,它能够记录通过与用户对话获取的事实信息,并在后续对话中加以活用。例如,通过记忆用户 “擅长 Python”“喜欢旅行” 等偏好与特征,智能体在之后的对话中,就能给出更贴合用户需求的响应与建议。

    需要注意的是,并非所有已记忆的内容都会被调用,系统会动态检索并使用与当前对话相关的信息。

    ChatGPT 也具备记忆功能,能够记住用户的个人信息与偏好,而通过 Bedrock AgentCore,我们可以自行实现同等功能,从而达成自然的个性化体验。

    官方文档参考链接:docs.aws.amazon.com

    2. 验证

    我们将实际创建智能体,验证其能否在保存、检索记忆的同时进行对话。

    由于短期记忆可通过 StrandsAgents 的 ConversationManager 进行管理,因此本次验证将重点关注长期记忆。

    我们已通过 AgentCore 的控制台,创建了启用 “用户偏好” 策略的记忆模块。

    2.1 结构图

    2.2 实现过程

    以下为智能体的实现代码。为了获取与特定用户的对话记录,我们设置了可通过参数接收 “与谁对话” 这一信息的功能。

    class MemoryAgent:
        PROMPT = dedent("""\
            请你扮演一个能为用户提供个性化服务、贴合用户需求的助手。
            请利用与用户过往的交互信息,理解用户想要做的事情。
    
            以下内容仅需在你内部处理,不得告知用户。
            请自然地进行互动。
            - 对于用户的输入内容,不得修改,需全部通过agent_core_memory的record工具进行记录。
            - 在对话过程中,若话题发生变化或开启新话题,请通过agent_core_memory的retrieve工具,从过往交互记录中获取与用户相关的信息。
            以上内容仅需在你内部处理,不得告知用户。
        """)
    
        def __init__(self, actor_id: str, session_id: str):
            model = BedrockModel(
                model_id='us.anthropic.claude-sonnet-4-20250514-v1:0',
                streaming=True,
                additional_request_fields={
                    'thinking': {'type': 'enabled', 'budget_tokens': 4000},
                    'anthropic_beta': ['interleaved-thinking-2025-05-14'],
                },
                region_name='us-west-2',
            )
    
            # 此处准备AgentCore Memory
            # 可指定使用的记忆模块以及长期记忆的整理策略
            provider = AgentCoreMemoryToolProvider(
                memory_id=MEMORY_ID,
                actor_id=actor_id,
                session_id=session_id,
                namespace=f'/strategies/{STRATEGY_ID}/actors/{actor_id}',
                region='us-west-2',
            )
    
            self.agent = Agent(
                model=model,
                system_prompt=self.PROMPT,
                tools=provider.tools,
            )
    
        async def stream(self, prompt):
            async for event in self.agent.stream_async(prompt):
                if text := event.get('event', {}).get('contentBlockDelta', {}).get('delta', {}).get('text', ''):
                    yield text
                for content in event.get('message', {}).get('content', []):
                    if isinstance(content, dict) and (tool_use := content.get('toolUse', '')):
                        logger.info('## 工具使用:%s', tool_use)
    

    2.3 尝试对话

    我平时习惯使用 “Python+Angular” 的组合开发应用。如果智能体生成的应用也采用这种技术组合,我不仅更容易理解,还能直接将其投入实际应用。

    本次验证中,我首先明确告知智能体需用 Python+Angular 实现,随后在不额外说明的情况下让其开发应用,以此检验它是否会主动使用 Angular。若智能体在未明确告知的情况下仍能选择 Angular,就说明它理解了我的偏好,实现了个性化,称得上是贴心的智能体。

    2.3.1 未理解用户偏好的情况

    我们先确认未设置 Strands Agents Tools、不使用记忆功能时的智能体表现。

    首次对话:明确告知所用框架并让智能体实现

    “请用 Python+Angular 开发一个 LLM 聊天 GUI 应用。”

    智能体按照需求,使用 Python+Angular 实现了应用:

    “将为您开发 LLM 聊天应用。我们将以 Python(FastAPI)作为后端,Angular 作为前端进行构建。”(其余省略)

    另起线程:不告知框架,让智能体实现

    若让同一个智能体开发,它有可能从对话历史中推断出需使用 Angular。为避免这种情况,我先停止了智能体应用,重新初始化一个新的智能体,再发出以下请求:“开发一个 RAG 聊天 GUI 应用。”

    由于新智能体未保留之前的对话记忆,不记得上次使用 Angular 作为前端框架的情况。因此,它并未采用我习惯使用的 Angular,而是生成了基于 Streamlit 的代码:

    “将为您开发 RAG 聊天 GUI 应用。我们将使用 Streamlit,构建一个包含文档上传、向量检索、聊天功能的完整应用。”(其余省略)

    2.3.2 已理解用户偏好的情况

    接下来,我们启用 Strands Agents Tools 的 Memory(记忆)工具,通过使用 AgentCore Memory,验证智能体是否能记住过往对话,从而成为具备个性化能力的智能体。

    首次对话:明确告知所用框架并让智能体实现

    “请用 Python+Angular 开发一个 LLM 聊天 GUI 应用。”

    智能体同样按照需求完成了开发:

    “好的,我们来用 Python + Angular 开发 LLM 聊天 GUI 应用!将采用全栈架构,打造一个实用的聊天应用。”(其余省略)

    另起线程:不告知框架,让智能体实现

    此处我们同样先创建一个新的智能体,再发起请求:“开发一个 RAG 聊天 GUI 应用。”

    智能体回复:

    “参考过往的交互记录,发现您对用 Python 和 Angular 开发 LLM 聊天应用很感兴趣!本次我们来开发一个集成了 RAG(检索增强生成)功能的聊天 GUI 应用吧。

    以下为您建议的技术架构:

    技术栈

    • 后端:Python(FastAPI)
    • 前端:Angular
    • RAG:LangChain + 向量数据库(Chroma/FAISS)
    • LLM:OpenAI API 或 Hugging Face

    (其余省略)”

    可见,智能体记住了此前用户使用 Python+Angular 开发 GUI 应用的偏好,因此主动提议采用相同技术架构进行开发。

    这表明 AgentCore Memory 实现了预期功能,能够输出符合用户偏好的响应。

    2.4 查看 Memory的内容

    由于无法从 AWS 控制台直接查看 Memory 的内容,我们通过 AWS 命令行工具(AWSCLI)获取相关数据。

    从获取的结果中可以看出,智能体已将 “对开发 LLM 应用感兴趣”“使用 Python+Angular 开发应用” 识别为用户的偏好。

    $ aws bedrock-agentcore list-memory-records \
        --memory-id $memoryId \
        --namespace /strategies/memory_preference/actors/sy
    {
        "memoryRecordSummaries": [
            {
                "memoryRecordId": "mem-cacf3145-324f-4f30-8e83-dade742bc2e0",
                "content": {
                    "text": "{\"context\":\"对开发LLM(大型语言模型)聊天应用表现出兴趣\",\"preference\":\"对基于LLM的聊天应用感兴趣\",\"categories\":[\"人工智能\",\"技术\",\"应用开发\"]}"
                },
                "memoryStrategyId": "memory_preference",
                "namespaces": ["/strategies/memory_preference/actors/sy"]
            },
            {
                "memoryRecordId": "mem-77a9f50f-8589-4229-874b-2dcac251708f",
                "content": {
                    "text": "{\"context\":\"用户要求使用Python+Angular开发LLM聊天GUI应用\",\"preference\":\"对使用Python和Angular开发应用感兴趣\",\"categories\":[\"编程\",\"软件开发\",\"技术\"]}"
                },
                "memoryStrategyId": "memory_preference",
                "namespaces": ["/strategies/memory_preference/actors/sy"]
            }
        ]
    }
    

    当 Strands Agents 的智能体调用该 Memory 时,可通过向量检索获取匹配度高的内容作为相关记忆。

    以下是第二次运行智能体时,Strands Agents 实际执行的工具调用内容,从中可看出其利用了向量检索的分数来获取相关记忆:

    agent.agent.tool.agent_core_memory(
        action='retrieve',
        query='RAG 聊天 GUI 应用 开发 编程',
    )
    {
        "memoryRecordSummaries": [
            {
                "content": {
                    "text": "{\"context\":\"用户要求使用Python+Angular开发LLM聊天GUI应用\",\"preference\":\"对使用Python和Angular开发应用感兴趣\",\"categories\":[\"编程\",\"软件开发\",\"技术\"]}"
                },
                "namespaces": ["/strategies/memory_preference/actors/sy"],
                "score": 0.49530885
            }
        ]
    }
    

    3. 应用示例

    通过将 Strands Agents Tools 与 AgentCore Memory 相结合,智能体能够记住对话上下文,并根据用户的偏好和目标提供个性化服务。

    此处将介绍几个在实际业务或服务中的应用场景。

    客户支持

    将用户过往的咨询内容及问题处理记录存储在长期记忆中,用户无需每次都从基础情况开始说明。例如,在处理错误问题时,智能体可实现 “上次出现的是XX错误,这次看起来是△△错误呢” 这类理解上下文的支持服务。

    持续学习支持

    作为教育类应用或企业内部培训的辅助工具,智能体可记录学习者的进度及薄弱领域,并据此调整出题内容和讲解方式。用户能获得 “以前你对这个问题不太擅长,这次已经能解出来了呢” 这类反馈,从而得到更具持续性的学习支持。

    个性化推荐系统

    在提供产品推荐或内容建议的应用中,智能体可结合用户的偏好及过往选择进行推荐。例如,旅行方案推荐智能体可实现 “上次您更喜欢安静的温泉胜地,这次为您推荐氛围相似的〇〇地区” 这类响应。

    4. 总结

    通过将 Strands Agents 与 Bedrock AgentCore 的 Memory 功能相结合,能够实现传统对话式 AI 难以做到的 “保持上下文”“结合个人偏好提供服务” 等能力。

    本文通过一个简单的聊天应用,对 AgentCore Memory 的功能进行了验证。

    结果表明,利用 Memory 工具能够为用户提供更自然、更具连贯性的体验。

    未来,还需要应对更复杂的应用场景,例如提升记忆的准确性、实现记忆的删除与修改控制、支持多用户使用等。可以说,让智能体具备 “记忆” 能力,是未来 AI 应用发展中的关键功能之一。

  • 在OSS 的 Open Deep Research 中实现 Deep Research

    在OSS 的 Open Deep Research 中实现 Deep Research

    前言

    这次我想实际运行由 Hugging Face 公开的开源 AI 代理(AI Agent)——Open Deep Research。

    huggingface.co

    1. 概要

    Deep Research 指的是在进行网络搜索的同时,自主收集信息并输出详细报告的服务。目前,带有 “Deep Research” 名称的代表性服务如下。

    服务名称OpenAI Deep ResearchGoogle Gemini Deep ResearchPerplexity Deep ResearchOpen Deep Research
    提供商OpenAIGooglePerplexity AIHugging Face
    价格ChatGPT Pro(月费 200 美元),ChatGPT Plus(月费 20 美元)可有限次数使用Gemini Advanced(月费 20 美元)免费(未注册用户每日限 5 次)免费(开源)
    精度GAIA 基准测试 67%、Humanity’s Last Exam 26.6%(采用 GPT-4 系列 “o3” 模型)无官方基准测试,被评价为可生成高精度医疗、市场调查报告Humanity’s Last Exam 21.1%,检索与解读性能强,但存在部分错误取决于开源模型性能(使用 o1 模型时,GAIA 55%、Humanity’s Last Exam 8.5%)
    特点在 ChatGPT 内运行,结合检索与推理,5-30 分钟生成详细调查报告从 50 余个网站收集信息,支持计划编辑、进度可视化、Google 文档输出通过反复检索与推理,短时间生成全面报告,具备检索对象指定及导出功能仅需开源大语言模型即可运行,适合完全离线部署及隐私保护

    在以上服务中,本次我想重点介绍由 Hugging Face 开发的开源项目 ——Open Deep Research。该服务以复现 OpenAI 的 Deep Research 为目标,与 OpenAI Deep Research 类似,可结合大规模语言模型(LLM)与代理框架进行信息检索和推理。

    huggingface.co

    openai.com

    OpenAI 的 Deep Research 是一款利用网络检索来应对复杂问题的工具,但其代理框架的详细信息未公开。与之相对,Hugging Face 团队开发了这款 “Open Deep Research” 作为开源替代方案,构建了任何人都可使用、改良的系统。

    Open Deep Research 的工作机制

    Open Deep Research 通过以下两种代理协同工作,实现信息检索与推理。

    CodeAgent

    • 接收用户的问题,制定检索计划
    • 将检索任务交给其他代理(SearchAgent)

    SearchAgent

    • 负责实际执行网络检索、收集并整理信息的工作。

    具体流程如下。

    尤其值得注意的是,CodeAgent 向 SearchAgent 下达指令的方式基于以下代码形式,通过这种方式,Agent 能够将更复杂的操作作为指令传递出去。

    Open Deep Research 的请求示例

    search_results = search_agent(task="请在互联网上搜索关于『Open Deep Research』的信息,调查其属于何种组织或具体活动内容。")
    print(search_results)
    

    2. 运行 Open Deep Research

    接下来,我们马上开始实际运行 Open Deep Research。

    准备工作

    需获取以下 3 个 API 密钥:

    此外,本次将使用 o1 模型进行 Deep Research。

    搭建方法

    按照以下步骤搭建环境:

    git clone https://github.com/huggingface/smolagents.git
    cd smolagents/examples/open_deep_research
    
    pip install -r requirements.txt
    pip install smolagents[litellm]
    
    export OPENAI_API_KEY="填入获取的密钥"
    export HF_TOKEN="填入获取的Hugging Face令牌"
    export SERPAPI_API_KEY="填入SERPAPI的密钥"
    

    执行搜索

    使用以下命令执行搜索:

    python run.py --model-id "o1" "请介绍一下Open Deep Research。"
    

    执行过程(中途进展)

    启动搜索后,内部会执行如下处理:

    以下是我为解决该任务将遵循的行动方案: 1. 审视任务“请介绍一下Open Deep Research。”及已知事实。 2. 调用search_agent获取关于“Open Deep Research”的信息。 3. 总结搜索结果中的关键信息,例如背景、目标或重要成果。 4. 使用final_answer呈现调查结果。

    ━━━━━━━━━━━━━━━━━━━━━━━━━ 步骤 1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    大语言模型(LLM)的输出信息: ──────────────────────────────

    思考:我需要查找关于 “Open Deep Research” 的信息。我会让 search_agent 用中文进行网络搜索以获取相关信息。

    代码:

    py

    search_results = search_agent(task="请在互联网上搜索关于『Open Deep
    Research』的信息,调查其属于何种组织或具体活动内容。")
    print(search_results)
    

    ─ 执行解析后的代码: ──────────────────────────────search_results = search_agent (task=” 请在互联网上搜索关于『Open DeepResearch』的信息,调查其属于何种组织或具体活动内容。”)

    print(search_results)

    ──────────────────────────────

    可以看出,CodeAgent 通过 Python 代码形式向 SearchAgent 发送请求,SearchAgent 则根据该请求执行搜索操作。

    回答结果

    获取到的回答:以下是关于『Open Deep Research』的概要总结。

    【概要】

    『Open Deep Research』是一个开源项目,旨在运用 AI 技术及网络搜索功能获取大量信息,为摘要撰写、报告生成及研究工作提供支持。GitHub 上存在多个相关仓库,目前该项目正以开源形式推进开发与改进。此外,其官方网站及演示版本等也已公开,任何人都可进行部署与扩展。

    【背景・特点】

    • 其核心特点是基于 OpenAI 最初发布的 “Deep Research”,由社区主导实现了 “开源化”。
    • 具备 AI 代理(AI Agent)检索、分析互联网上的大规模文本数据,并自动生成摘要与报告的功能。
    • 也能看到其采用结合 Firecrawl 等爬虫技术以提升搜索精度的实现方式。

    【应用案例】

    • 预计可用于需高效处理网络上海量信息的场景,例如自动生成研究资料、整理信息等。
    • 由于属于非营利性社区项目,开发者与用户正通过协作扩充、改进功能,推动项目发展。

    【注意事项】

    • 搜索到的信息多汇总于 2025 年前后,该项目可能尚未形成固定的正式企业组织。实际使用时,建议确认 GitHub 仓库及官方网站(如https://opendeepresearch.vercel.app 等)。
    • 关于许可证形式及持续开发状况,也建议提前核查最新信息。

    以上即为关于『Open Deep Research』的主要信息。

    系统已根据最新信息,生成了关于搜索对象的报告。

    与 OpenAI Deep Research 的对比

    向 OpenAI Deep Research 提出相同问题后,得到的结果如下。

    OpenAI Deep Research 的回答结果:

    明白了。我将对 “Open Deep Research” 的概况进行调查,并汇总其目的、活动内容、相关组织及项目等信息。调查完成后会通知您。

    Open Deep Research 概况

    一、概述

    Open Deep Research(开放深度研究)是一个旨在为 OpenAI 开发的高级调查代理(AI Agent)“Deep Research” 提供开源替代方案的项目。该项目以 Hugging Face 联合创始人托马斯・沃尔夫(Thomas Wolf)等人为核心,目标是让任何人都能结合自己偏好的语言模型,在本地环境中使用高级调查代理。具体而言,其公开了 OpenAI 未披露的代理控制部分(即指示网络浏览、工具使用的框架)并自行实现相关功能,肩负着推动封闭性尖端 AI 功能民主化的使命。

    二、主要研究领域与活动内容

    Open Deep Research 的核心焦点是实现与 Deep Research 同等的网络研究功能。针对用户的问题,它能自动从互联网收集、分析信息,进行逻辑推理并生成长篇回答。其特色功能可归纳为以下 3 点:

    • 内容发现:通过网络搜索收集与用户问题相关的信息(自动生成搜索查询,探寻最新信息)。
    • 内容整合:汇总、整合来自多个信息源的内容,提取关键要点。
    • 信息推理:基于收集到的信息进行层层逻辑推理,得出针对问题的结论及详细解释。

    通过上述流程,该项目据称可在数分钟至数十分钟内完成人类需耗时数小时的调查工作,并生成专业级的详细报告。

    从技术层面看,Open Deep Research 通过组合以下要素实现功能:

    1. 搜索引擎:借助外部搜索服务检索相关信息,获取对应页面的 URL(例如 DuckDuckGo API 等)。
    2. 解析器(网页内容提取):从搜索结果的 URL 中提取页面正文,并转换为文本数据的模块。
    3. 大规模语言模型(LLM):基于提取的文本执行摘要生成、问答及推理的 AI 模型(目前主要使用 OpenAI 的 o1 等模型)。
    4. 代理控制逻辑:指示 LLM 使用网络浏览、文件读取等工具,并管理多步骤操作的框架。在 Hugging Face 版本中,该逻辑通过 Python 轻量级代理库 “smolagents” 实现,并结合 OpenAI 的 LLM(o1 模型)API,复现了与 Deep Research 相当的运行效果。

    三、相关组织与项目

    Open Deep Research 是由Hugging Face 公司的研究团队推进的项目。尤其是托马斯・沃尔夫(Hugging Face 联合创始人)、艾美瑞・鲁歇尔(Aymeric Roucher)等人通过 24 小时黑客马拉松式的努力搭建了原型,并公开了成果。该项目受 OpenAI 的 Deep Research(原始封闭代理)启发,以开源社区的协作支持为显著特征。

    目前存在多个具有类似目标的相关项目。例如,Jina AI 公司开发了基于 TypeScript/Node.js 实现的开源代理 “node-DeepResearch”,采用以 Google 的 PaLM 2、Gemini 模型为后端的技术路径。此外,个人开发者开发的复刻版本也陆续出现,据 Hugging Face 报告,dzhngnickscamara等开发者已各自公开了 Deep Research 的开源版本。这些尝试相互促进,为整个代理 AI 领域的发展做出了贡献。

    四、官方网站与信息来源

    Open Deep Research 的官方信息及资源如下:

    • 官方博客文章(Hugging Face 博客):Hugging Face 于 2025 年 2 月 4 日公开的文章《Open-source DeepResearch – Freeing our search agents》(开源 DeepResearch—— 解放我们的搜索代理),详细解读了 Open Deep Research 的背景、实现方式及成果。
    • 演示网站(Hugging Face Spaces):在 Hugging Face 提供的演示页面可试用 Open Deep Research。从浏览器输入问题后,代理会自动执行搜索并给出回答。目前该演示收到了来自全球的大量请求,可能会出现响应等待时间较长的情况。
    • 源代码(GitHub):Open Deep Research 的实现代码已在GitHub公开,可在 Hugging Face 的smolagents仓库内的open_deep_research示例中查看。任何人都可浏览、使用代码,同时也欢迎通过 Issue(问题反馈)和 Pull Request(代码提交)提供反馈与贡献。

    此外,TechCrunch、Ars Technica 等科技媒体也已针对该项目发布详细报道;日语信息方面,Qiita、GIGAZINE 等平台介绍了项目背景及搭建方法。

    五、最新研究成果与发布动态

    Open Deep Research 自公开以来便展现出较高性能,据报道其成果已接近 OpenAI 官方的 Deep Research。具体而言,在测试通用 AI 助手能力的GAIA 基准测试中,Deep Research 官方版本的平均正确率达到67.36% ,而 Open Deep Research 的得分已达到54% 左右。仅用约 1 天时间便复现核心功能,并实现了官方版本约 80% 的性能,这无疑是一项重大成果。Hugging Face 团队表示 “这仅仅是开始,仍有许多需要改进的地方”,并明确表达了将持续推进开发以提升性能的意向。

    此后,Open Deep Research 持续稳步更新。例如,截至 2025 年 3 月,项目已新增 “Visual Flow”(可视化流程)功能,可将代理的探索过程以视觉形式呈现,便于用户理解多阶段深度调查的流程。此外,作为未来计划,团队还将致力于开发可与 OpenAI 发布的浏览器操作代理 “Operator” 相媲美的GUI 操作兼容代理(通过视觉识别画面,使用鼠标、键盘进行操作的代理)。从这些最新动态可以看出,Open Deep Research 项目正与社区协作不断进化,站在拓展开源 AI 代理可能性的最前沿。

    以下是简单的对比。

    对比项目Open Deep ResearchOpenAI Deep Research
    参考网站数量8 个网站17 个网站
    回答所需时间约 2 分钟约 16 分钟
    报告质量反映了搜索结果,但内容较为简洁能触及搜索结果的细节之处

    结果来看,果然还是 OpenAI Deep Research 参考了更多网站,生成的报告内容也更充实。

    不过,Hugging Face 的 Open Deep Research 作为开源项目公开,能够结合任意的大语言模型(LLM),还可以嵌入自家服务中使用,这一点是很有优势的。

    总结

    我实际运行了作为开源项目公开的 Open Deep Research。

    能够通过开源(OSS)搭建 Deep Research 功能,这一点让我觉得很有吸引力。

    在精度方面,随着 Operator 等功能的引入,未来还有很大的改善空间,非常期待后续的更新。

  • 基于 Amazon S3 Vectors 的 RAG 性能与精度评估实践

    基于 Amazon S3 Vectors 的 RAG 性能与精度评估实践

    本次想为大家介绍在 2025 年纽约 AWS Summit 上发布的 S3 Vectors,内容将包含其与现有向量存储的对比分析。

    相关参考链接:aws.amazon.com

    什么是 S3 Vectors

    S3 Vectors 是 AWS S3 推出的新功能,本质是一款向量存储服务。由于依托 S3 提供,它与 AWS 此前可用的向量存储(如 OpenSearch Serverless、Aurora 等)不同 —— 无需承担运行成本,仅需根据数据量和 API 请求量支付费用。基于这一特性,在部分使用场景中,可实现大幅成本削减。

    相关参考链接:aws.amazon.com

    1. 与其他向量存储的成本对比

    假设每月使用 1GB 存储容量、执行 30000 次检索,以下为 S3 Vectors 与其他向量存储的成本对比示例。※AWS 区域按美国弗吉尼亚北部计算。

    向量存储名称每月总成本成本明细
    S3 Vectors$2.06存储:$2.00,请求:$0.06
    OpenSearch Serverless$175.221 个 OCU:$175.2,存储:$0.02
    Aurora Serverless v2$87.831 个 ACU:$87.60,存储:$0.10,I/O:$0.13
    Pinecone$0(入门版)/$50(标准版)使用 5 个及以上索引时,必须选择标准版

    由此可见,与其他向量存储相比,S3 Vectors 的成本具有压倒性优势。

    2. 功能层面的限制事项

    S3 Vectors 虽能以低成本使用,但在以下功能上存在限制。

    向量存储名称元数据过滤检索功能块大小(Chunk Size)限制分层分块(Hierarchical Chunking)
    S3 Vectors仅支持完全匹配检索、范围检索500 tokens△(默认设置下不可用)
    OpenSearch Serverless支持部分匹配检索等灵活检索方式无限制○(可用)

    元数据过滤检索功能

    进行元数据过滤检索时,无法像 OpenSearch Serverless 那样实现部分匹配等灵活检索,仅支持完全匹配、范围检索等基础方式。

    相关参考链接:docs.aws.amazon.com

    块大小限制

    可创建的最大块大小限制为 500 tokens。

    相关参考链接:docs.aws.amazon.com

    借助 Bedrock 知识库使用分层分块

    在 Bedrock 知识库的默认设置下,同步时会出现以下错误,导致无法使用分层分块功能:

    Filterable metadata must have at most 2048 bytes (Service: S3Vectors, Status Code: 400, Request ID:XXXXXX)

    若要从 Bedrock 知识库使用分层分块,需先在 S3 Vectors 中创建以下配置的索引:

    aws s3vectors create-index \
      --vector-bucket-name "bucket-name" \
      --index-name "index-name" \
      --data-type "float32" \
      --dimension 256 \
      --distance-metric "cosine" \
      --metadata-configuration '{"nonFilterableMetadataKeys":["AMAZON_BEDROCK_METADATA"]}'
    

    出现该限制的原因是,分层分块的父块所存储的元数据,在默认设置下仅能容纳 2048 字节以内的内容。因此,需通过上述命令,将存储父块的元数据指定为 “不可过滤元数据”。

    相关参考链接:docs.aws.amazon.com

    除上述之外,由于 S3 Vectors 仅支持向量检索,因此自然无法实现 OpenSearch Serverless 等服务所支持的混合检索功能。

    3. S3 Vectors 的最佳实践

    官方文档中介绍了以下最佳实践:

    最佳实践核心要点
    重试处理为避免系统过载,推荐采用带退避策略(Backoff)的重试机制
    通过索引拆分实现扩展按租户或用途分别使用多个索引,可提升系统吞吐量
    元数据设计将仅用于参考的文本等设置为不可过滤元数据,以优化性能
    访问控制可通过索引级别的 IAM 权限控制,灵活设计租户级访问限制等权限管理规则

    参考链接:docs.aws.amazon.com

    其中,在访问控制方面,官方特别推荐使用 IAM 角色进行配置,这一点在实际运维中也颇具参考价值。

    与其他向量存储的速度对比

    接下来,我们针对实际使用中最受关注的检索速度,将 S3 Vectors 与 OpenSearch Serverless 进行对比。本次对比基于 Bedrock 知识库的检索场景,具体检索条件如下:

    • 数据源:包含以下 IPA PDF 在内,共约 800MB、1000 个文件
      • 《面向安全网站运营》
      • 《软件开发数据白皮书 2018-2019》
      • 《软件开发数据白皮书 2018-2019 金融保险业篇》
      • 《软件开发数据白皮书 2018-2019 信息通信业篇》
    • 嵌入模型(Embedding Model):Titan Text Embeddings v2
    • 嵌入类型(Embedding Type):1024 维浮点向量嵌入
    • 分块策略(Chunking Strategy):固定分块
    • 分块大小(Chunk Size):300 tokens

    为覆盖缓存生效的场景,我们共设计了 100 种不同的查询语句作为测试请求。

    查询示例

    • “制造业中新开发项目的工时与工期关系”
    • “制造业改良开发中 FP(功能点)规模与工时的关系”

    对比结果

    向量存储名称平均时间(秒)最大时间(秒)最小时间(秒)
    S3 Vectors0.6881.5990.553
    OpenSearch Serverless0.4330.5070.383

    结果显示,S3 Vectors 的平均检索速度比 OpenSearch Serverless 慢 0.2 秒左右,最大延迟甚至相差 1 秒。不过,结合官方文档中 “检索响应时间需控制在 1 秒以内” 的标准来看,S3 Vectors 基本能满足大多数 RAG 场景的速度要求。

    参考链接:docs.aws.amazon.com

    与其他向量存储的精度对比

    接下来,我们从精度维度进行对比,分别测试 S3 Vectors 的 “仅向量检索” 与 OpenSearch Serverless 的 “混合检索” 效果。

    本次精度验证采用 Bedrock Evaluations 工具完成。

    参考链接:aws.amazon.com

    1. 基于向量检索的精度对比

    首先,仅针对向量检索的精度进行验证。我们沿用上述相同的知识库配置进行测试,采用以下两项指标评估精度:

    • 上下文相关性:衡量检索到的文本与查询问题在上下文层面的关联程度
    • 上下文覆盖率:衡量检索到的文本对正确答案全部信息的覆盖程度

    对比结果

    S3 Vectors 的精度

    OpenSearch Serverless 的精度

    由于两者采用相同的检索方式,因此精度水平基本相当。这表明,在仅使用向量检索的场景下,S3 Vectors 的精度与 OpenSearch Serverless 等现有向量存储相比并无明显差距。

    2. 与混合检索的精度对比

    接下来,我们使用包含产品 ID 等信息的数据集,对比 S3 Vectors 的向量检索与 OpenSearch Serverless 的混合检索精度。

    本次测试采用新数据集 —— 按用户整理的 Amazon 评论数据。

    混合检索验证数据集

    1. 2023年亚马逊评论

    https://amazon-reviews-2023.github.io

    该数据集包含约 2.8 万组

    product/productId: B000GKXY4S product/title: Crazy Shape Scissor Set product/price: unknown review/userId: A1QA985ULVCQOB review/profileName: Carleen M. Amadio “Lady Dragonfly” review/helpfulness: 2/2 review/score: 5.0 review/time: 1314057600 review/summary: Fun for adults too! review/text: I really enjoy these scissors for my inspiration books that I am making (like collage, but in books) and using these different textures these give is just wonderful, makes a great statement with the pictures and sayings. Want more, perfect for any need you have even for gifts as well. Pretty cool!

    在精度验证时,我们准备了如下所示的 “问题 – 答案” 配对,并重点围绕混合检索的核心特征 —— 关键词检索精度展开评估。

    评估用数据集示例

    问题:请告知商品 ID 为 B000GKXY4S 的评论摘要。

    答案:Fun for adults too!

    测试时,知识库配置保持不变,仅将 OpenSearch Serverless 的检索方式指定为 “混合检索”。

    精度验证结果

    S3 Vectors 的精度

    OpenSearch Serverless 的精度

    结果显示,在 “上下文相关性” 和 “上下文覆盖率” 两项指标上,采用混合检索的 OpenSearch Serverless 精度均优于仅支持向量检索的 S3 Vectors。

    以下为 “混合检索可成功匹配,但 S3 Vectors 向量检索未匹配成功” 的查询示例:

    查询示例

    请告诉我商品 ID 为 B000GKXY4S 的评论摘要。

    S3 Vectors(向量检索)结果:未检索到查询中包含的 ID :B000GKXY4S

    返回结果为 “product/productId: B000FP553C product/title: Kinesio Scissors

    OpenSearch Serverless(混合检索)结果:成功检索到查询中包含的 ID :B000GKXY4S

    返回结果为 “product/productId: B000GKXY4S product/title: Crazy Shape Scissor Set

    由此可见,由于 S3 Vectors 仅支持向量检索,在需指定 ID、特定单词等关键词的检索场景中,其精度会出现下降。

    总结

    本文结合与现有向量存储的对比,介绍了 S3 的新功能 ——S3 Vectors。尽管 S3 Vectors 在功能上存在一定限制,但对于仅需向量检索的场景,其功能已足够满足需求;加之其成本极低,非常值得尝试应用。

  • 尝试用 Cline × Amazon Bedrock 进行 CRUD 应用的全栈开发

    最近,Cline 作为一款开发辅助 AI 智能体备受关注。

    相关参考链接:github.com

    Cline 是 Visual Studio Code(VSCode)的扩展插件,其特点不仅限于生成代码,还能连贯完成命令执行、运行验证及调试等一系列操作。

    Cline 支持指定任意生成式 AI 模型来生成代码。因此,将其与安全性高、可在实际开发场景中运用的 Amazon Bedrock 结合,便能在业务场景中发挥作用。本次,我们将以 Bedrock 作为大语言模型(LLM),围绕 “能否开发具备 CRUD 功能的应用” 这一目标,以开发 TODO 应用为主题展开尝试。

    概述

    什么是 Cline?

    Cline 是一款以 VSCode 扩展插件形式提供的 AI 智能体,只需简单指令,就能生成整个应用的代码。

    其核心特点如下:

    • 可完成命令执行(例如:创建 / 删除文件或目录、安装依赖库、启动已开发的应用等);
    • 可自动完成运行验证与调试;
    • 数据不会发送至 Cline 服务器(因支持配置任意生成式 AI 模型的 API,并通过该 API 生成内容)。

    使用 Amazon Bedrock 的优势

    如前所述,Cline 可与多种生成式 AI 模型联动,本次我们选择使用 Amazon Bedrock。使用 Bedrock 的优势如下:

    • 输入数据不会被用于模型训练,安全性更有保障;
    • 只需通过配置,即可切换使用多个模型。

    基于以上原因,在业务场景中使用 Cline 时,Amazon Bedrock 会成为极具竞争力的选择。接下来,我们就实际尝试用 Cline × Amazon Bedrock 开发具备 CRUD 功能的 Web 应用。

    TODO 应用的概述

    本次开发的 TODO 应用,最终实现效果如下:

    该 TODO 应用支持填写标题、截止日期和说明来添加任务,同时会记录任务的 “是否完成” 状态,还具备删除功能。下面我们开始为开发这款 TODO 应用做准备。

    开发前的准备工作

    创建 IAM 用户

    我们创建了供 Cline 调用 Bedrock 时使用的 IAM 用户,并为其配置了以下权限。实际场景中应进一步缩小权限范围,本次为简化操作,暂赋予 Bedrock 全访问权限。此外,由于 Cline 需要会话令牌,因此还为该用户配置了获取会话令牌的权限。

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowBedrockAll",
          "Effect": "Allow",
          "Action": "bedrock:*",
          "Resource": "*"
        },
        {
          "Sid": "AllowStsGetSessionToken",
          "Effect": "Allow",
          "Action": "sts:GetSessionToken",
          "Resource": "*"
        }
      ]
    }
    

    Cline 的配置

    我们对 Cline 进行了调用 Bedrock 所需的配置。在配置界面中,填入了上一节创建的 IAM 用户的访问密钥、密钥和会话令牌。

    本次选用的模型是 Claude 3.7 Sonnet。此前曾尝试用成本更低的 Claude 3.5 Haiku 开发应用,但模型精度不稳定,例如明明需要显示 “Task Completed”,但应包含 Docker 文件的文件夹中却未生成任何文件等问题。虽然 Cline 在调试阶段会尝试修复这些问题,但过程中需要反复试错修改,既耗费时间,也产生了不必要的成本。因此,若要开发的不是简单脚本,而是像 CRUD 应用这样具备一定复杂度的完整系统,从一开始就使用 Claude 3.7 Sonnet,模型精度会更稳定。

    搭建 Linux 命令执行环境

    Cline 的一大核心特点是支持执行命令,但它默认倾向于执行 Linux 命令。

    而本次我们在 Windows 环境下进行验证,VSCode 的默认终端是 Powershell。若不做调整,Cline 会尝试执行 Linux 命令,导致命令全部报错。

    因此,为了在 Windows 环境下也能执行 Linux 命令,我们按以下步骤进行了设置:

    1. 安装 Git Bash;
    2. 将 Git Bash 设置为 VSCode 的默认终端。

    开发 TODO 应用

    提示词

    本次传递给 Cline 的任务提示词如下:

    请开发一个 TODO 应用
    
    #需求
    
    -支持将任务以带复选框(Checkbox)的项目形式进行添加和删除。
    
    -已完成的任务,通过勾选复选框,文字需变为浅色并添加删除线。
    
    -支持为每个任务输入截止日期(非必填项)。
    
    #约束条件
    
    -采用 PostgreSQL 实现 CRUD(创建、读取、更新、删除)操作。
    
    -通过 Docker 搭建数据库(DB)。
    
    -后端与前端不使用 Docker,直接在运行环境中启动。
    
    -开发完成后,需完成应用的启动操作。
    
    -界面需设计得现代且美观。

    此外,我们在 Cline 的设置界面中,按以下内容配置了 “Custom Instructions”。

    Custom Instructions 是用于编写通用规则等内容的部分,会在每次向 AI 发送请求时,自动追加到提示词的末尾。

    #运行环境信息
    
    -运行环境为 Windows。
    
    -Docker 环境由 Rancher Desktop 提供。
    
    #实现规则
    ##通用规则
    
    -为每个代码块添加中文注释。
    
    -按合理的文件夹结构创建项目
    
    ##后端
    
    -按 Google 风格编写文档字符串(docstring)。
    
    -使用 Python 实现。
    
    -通过 pyenv、Poetry 创建虚拟环境(pyenv 与 Poetry 已提前在环境中安装完成)。
    
    ##前端
    
    -使用 React 实现。
    
    -通过 npm 进行包管理。

    在 Custom Instructions 中,我们指定 “环境搭建工具使用已提前安装的版本”。若未做此指定,Cline 会尝试从安装这些工具开始操作,过程中会出现大量试错,额外耗费时间与成本。因此,开发环境的准备工作由人工完成会更高效。

    使用 Cline 的开发结果

    根据上一节的提示词向 Cline 下达指令后,Cline 自动完成了以下一系列操作:

    1. 创建文件夹结构
    2. 安装所需依赖库
    3. 设计数据库 schema(表结构)
    4. 通过 Docker 搭建数据库
    5. 实现并启动前端与后端
    6. 运行验证与调试

    最终生成的成果如下

    本次仅使用简单提示词,未过多指定细节,但 Cline 仍以接近人工开发的水平完成了项目,例如:

    • 前端使用 Material-UI(Material Design 组件库)
    • 后端使用 FastAPI,并创建了模型类
    • 数据库 schema 中包含 “创建时间”“更新时间” 字段

    此外,本次开发的代码量约为 0.5KL,耗费成本约 5.2 美元。与人工完成 “从开发到运行验证” 所需的人力成本相比,成本大幅降低。

    试用应用

    接下来,我们实际试用一下这款应用。下图展示了 “添加任务后,将其中 1 个任务标记为已完成” 的效果

    我们尝试直接访问数据库,发现操作结果已实时同步到数据库中

    另外,当我们从界面中删除已完成的任务时,数据库中也执行了物理删除操作

    总结

    通过 “Cline×Amazon Bedrock” 的组合,我们借助安全的生成式 AI 模型,完成了 CRUD 应用从 “界面开发” 到 “数据库实现” 的全流程开发与运行验证。

    同时,我们也得出了以下几点感受:

    1. 开发环境的准备工作,由人工提前完成效率更高;
    2. 若要稳定且精准地开发 “CRUD 应用” 这类具备一定复杂度的项目,需使用 Claude 3.7 Sonnet 模型。

    借助 Amazon Bedrock,Cline 在业务场景中的实用性大幅提升,未来我们将积极推动其应用。

  • 活用 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 系统。

  • Amazon Bedrock 的多智能体协作(Multi Agent Collaboration):实现高级智能体联动

    Amazon Bedrock 的多智能体协作(Multi Agent Collaboration):实现高级智能体联动

    前言

    今天我将结合实际运行的示例代码,为大家讲解 2024 年 12 月发布的 Amazon Bedrock 新功能 ——“多智能体协作(Multi Agent Collaboration)”。

    什么是多智能体协作(Multi Agent Collaboration)

    1. 概述

    多智能体协作(Multi Agent Collaboration)是 Amazon Bedrock 推出的新功能,支持多个 AI 智能体(Agent)协同完成任务。AWS 官方博客中以社交媒体营销活动为例,介绍了其应用模式:

    1. 由管理智能体(Supervisor Agent)接收用户的请求;
    2. 委托专门负责内容创作的智能体撰写帖子;
    3. 委托专门负责互动量预测的智能体确定发帖时机;
    4. 将各智能体返回的结果整合后,向用户反馈最终响应。

    通过管理智能体为各专业智能体分配相应任务,实现了多智能体协同生成输出的能力。

    2. 与其他智能体服务的对比

    在涉及多智能体管理的服务中,与多智能体协作(Multi Agent Collaboration)功能相似的是多智能体编排器(Multi Agent Orchestrator)。下表总结了普通智能体、多智能体协作(Multi Agent Collaboration)及多智能体编排器(Multi Agent Orchestrator)各自的特点与适用范围。

    特征普通的智能体(通常Agent)多智能体协作(Multi Agent Collaboration)多智能体编排器(Multi Agent Orchestrator)
    目的由单个智能体负责所有处理,完成简单任务。多个智能体联动分工,高效处理复杂任务。集中管理多个智能体,将任务分配给最优智能体。
    结构单个智能体接收用户请求,独立完成所有处理流程。管理智能体拆分任务、分配给各智能体,并整合结果。管理角色分析请求,选择合适的智能体执行任务。
    主要功能1. 简单任务处理2. 一致性响应1. 多智能体高效分工2. 发挥各智能体专业性开展处理1. 依据请求灵活选择智能体2. 动态分配任务
    优点1. 结构简单,易于实现2. 适用于小规模任务1. 可高效处理复杂任务2. 最大限度发挥各智能体的专业能力1. 设计简洁,便于新增和修改2. 可灵活适配各类任务
    缺点1. 单个智能体承担所有处理,可扩展性低2. 难以应对复杂任务1. 需实现智能体间联动,管理难度大2. 需进行复杂的系统设计1. 智能体间协作性弱,不适用于复杂任务2. 处理过程高度依赖中央管理

    github.com

    相较于使用普通智能体或多智能体编排器,借助多智能体协作(Multi Agent Collaboration)似乎能够应对更为复杂的任务。

    运行示例场景

    接下来,让我们实际操作使用多智能体协作(Multi Agent Collaboration)功能。本次将基于 AWS 官方提供的资源,搭建一个股票分析助手。

    github.com

    1. 股票分析助手概述

    我们将要搭建的股票分析助手如下所示:

    通过运行示例代码,将创建以下 4 个智能体:

    • Stock Analysis(管理智能体 / Supervisor Agent)接收用户的股票相关请求,分析股价数据与新闻数据;将处理工作委托给各专业智能体,最终生成汇总报告。
    • Stock Data Researcher(股价数据研究智能体)获取股价历史数据,分析价格波动;通过 Lambda 函数获取实时市场数据。
    • News Researcher(新闻研究智能体)获取指定股票代码(Ticker)的相关新闻,分析市场情绪与趋势;通过 Lambda 函数调用网络搜索 API,收集最新新闻。
    • Financial Analyst(金融分析师智能体)整合股价分析与新闻分析的结果,提供投资判断建议;生成最终推荐内容及面向用户的报告。

    流程上,用户输入股票相关信息后,上述 2-4 号智能体将围绕请求的股票信息开展收集与解析工作,再由 1 号 Stock Analysis 智能体对结果进行整合。

    2. 搭建方法

    在 Bedrock Agent 中搭建多智能体协作(Multi Agent Collaboration)非常简便,仅需完成以下设置:

    1. 创建需要参与多智能体协作的各智能体;
    2. 按照以下配置创建用于统筹的管理智能体(Supervisor Agent):
      • 创建管理智能体时,开启 “Enable multi-agent collaboration”(启用多智能体协作)选项;
      • 按以下形式设置由 Supervisor Agent(主管代理)进行统括的 Collaborator Agent(协作代理)。

    本次将通过运行以下示例代码,实现基于 boto3 的多智能体系统搭建。

    github.com

    我们将按照 README 文档的说明逐步搭建系统。

    1. 执行以下命令搭建环境

    git clone https://github.com/awslabs/amazon-bedrock-agent-samples
    
    cd amazon-bedrock-agent-samples
    
    python3 -m venv .venv
    
    source .venv/bin/activate
    
    pip3 install -r src/requirements.txt
    

    2. 执行以下命令创建示例智能体

    python3 examples/multi_agent_collaboration/portfolio_assistant_agent/main.py --recreate_agents "true"
    

    3. 生成的智能体列表

    执行上述命令后,将创建以下智能体:

    生成的智能体概要

    系统将 portfolio_assistant 智能体设置为管理智能体(Supervisor Agent),并将其他智能体注册为协作智能体(Collaborator Agent)。

    Stock Analysis(管理智能体 / Supervisor Agent)

    通过执行以下代码创建管理智能体:

    portfolio_assistant = SupervisorAgent.direct_create(
        "portfolio_assistant",
        role="Portfolio Assistant",
        goal="分析特定的潜在股票投资标的,提供包含一系列投资考量因素的报告",
        collaboration_type="SUPERVISOR",
        instructions="""
                 请以分析特定股票潜在投资价值的资深专家身份开展工作。
                 为掌握最新股价走势及相关新闻动态,需进行调研分析。
                 提交内容详实、论证充分且兼顾潜在投资者需求的报告。
                 借助分析师协作智能体完成最终分析,并将新闻与股价数据作为输入传递给分析师。
                 对协作智能体的调用需按顺序进行,不可并行调用。
                 最终输出内容需全部以日语呈现。""",
        collaborator_agents=[
            {
                "agent": "news_agent",
                "instructions": """
                 如需查找特定股票的相关新闻,请调用此协作智能体。""",
            },
            {
                "agent": "stock_data_agent",
                "instructions": """
                 如需查询特定股票的价格历史,请调用此协作智能体。""",
            },
            {
                "agent": "analyst_agent",
                "instructions": """
                 如需获取原始调研数据,并生成详细报告及投资考量建议,请调用此协作智能体。""",
            },
        ],
        collaborator_objects=[news_agent, stock_data_agent, analyst_agent],
        guardrail=no_bitcoin_guardrail,
        llm="us.anthropic.claude-3-5-sonnet-20241022-v2:0",
        verbose=False,
    )
    

    github.com

    上述代码中的核心配置项说明如下:

    • goal:设置智能体整体预期输出目标。
    • instructions:定义对管理智能体的操作指引,包括如何与协作智能体协同工作。
    • collaborator_agents:定义各协作智能体的配置,确保管理智能体可正常调用协作智能体。

    在 AWS 控制台中也可确认:portfolio_assistant 已被设为管理智能体,其余 3 个智能体均已注册为协作智能体。

    此外,通过以下提示词指令,要求管理智能体与其他协作智能体协同完成股票分析任务。(原始提示词为英文,为实现日语输出已进行修正)。本次通过提示词指定智能体按顺序执行任务,但协作智能体也支持并行执行模式。

    请以分析特定股票潜在投资价值的资深专家身份开展工作。为掌握最新股价走势及相关新闻动态,需进行调研分析。

    提交内容详实、论证充分且兼顾潜在投资者需求的报告。借助分析师协作智能体完成最终分析,并将新闻与股价数据作为输入传递给分析师。

    对协作智能体的调用需按顺序进行,不可并行调用。最终输出内容需全部以中文呈现。

    stock_data_agent(股价数据研究智能体)

    如图所示,该智能体将用于获取股票价格信息的 Lambda 函数配置为行动组。通过此行动组获取股票价格信息,是该智能体的核心职责。

    以下代码定义了该智能体的功能:通过从管理智能体传递的提示词中提取 tool_defs 里定义的参数,实现股价信息的获取。

    # Define Stock Data Agent
    stock_data_agent = Agent.direct_create(
        name="stock_data_agent",
        role="财务数据采集员",
        goal="获取特定股票代码(Ticker)的准确股价趋势",
        instructions="实时财务数据提取专家",
        tool_code=f"arn:aws:lambda:{region}:{account_id}:function:stock_data_lookup",
        tool_defs=[
            {  # lambda_layers: yfinance_layer.zip, numpy_layer.zip
                "name": "stock_data_lookup",
                "description": "获取指定股票代码的1个月股价历史,返回格式为JSON",
                "parameters": {
                    "ticker": {
                        "description": "The ticker to retrieve price history for",
                        "type": "string",
                        "required": True,
                    }
                },
            }
        ],
    )
    

    github.com

    news_agent(新闻研究智能体)

    如图所示,该智能体将用于搜索和获取股票相关新闻的 Lambda 函数配置为行动组。通过此行动组获取股票相关新闻,是该智能体的核心职责。

    analyst_agent(金融分析师智能体)

    通过以下提示词配置,该智能体可根据输入的股价信息与新闻内容开展分析工作:

    角色:财务分析师

    目标:通过分析股价趋势与市场新闻获取洞察

    操作说明:作为资深分析师提供战略性建议。接收新闻摘要与股价摘要作为输入。无可用工具,仅可依赖自身知识开展工作。

    3. 运行示例场景

    接下来,我们立即运行已搭建的智能体系统。本次将通过 AWS 控制台进行操作。

    我们向作为管理智能体创建的 portfolio_assistant 智能体发送以下请求,查询亚马逊股票相关信息:

    请求

    ticker:Amazon

    回答

    在本次案例中,大约 30 秒左右就收到了回复。尽管执行时间会因所运行的智能体(Agent)而异,但如果要执行多个像搜索这类耗时的操作,整体花费的时间也会相应增加。

    此外,我们能够通过以下形式查看协作智能体(Collaborator Agent)是如何开展处理工作的。可以看到,news_agent、stock_data_agent、analyst_agent 这几个智能体相互协作,成功回答了问题。

    接下来,让我们看看管理智能体(Supervisor Agent)是如何向协作智能体下达指令的。通过跟踪步骤,能够查看各个智能体的运行情况,具体如下:

    从以下内容可以看出,协作智能体能够从管理智能体传递的提示词中提取出参数。

    管理智能体向协作智能体(stock_data_agent)发送的提示词

    [{text = 请提供股票代码为 ‘Amazon’ 的股票价格历史。}]

    协作智能体执行行动组的输入

    "invocationInput": [
    {
    "actionGroupInvocationInput": {
    "actionGroupName": "actions_stock_data_agent",
    "executionType": "LAMBDA",
    "function": "stock_data_lookup",
    "parameters": [
    {
    "name": "ticker",
    "type": "string",
    "value": "Amazon"
    }
    ]
    },
    "invocationType": "ACTION_GROUP",
    "traceId": "1f373c5c-12b9-4d07-8a24-1317d66f5115-0"
    }
    ]
    

    对于管理智能体接收到的请求,我们可以轻松构建出向各个协作智能体分配任务的流程。在将任务拆分给多个专业智能体来解决时,多智能体协作(Multi Agent Collaboration)的优势有望得到充分发挥。

    总结

    本次我们对 2024 年 12 月发布的 Amazon Bedrock 多智能体协作(Multi Agent Collaboration)功能进行了讲解。特别令人欣喜的是,仅通过 Bedrock Agent 就能构建出专业智能体以及对其进行统筹的管理智能体。鉴于该功能在各类应用场景中都有潜在的使用可能,我打算今后继续进行更多尝试。

  • 借助 Azure MCP Server 与 GitHub Copilot,尽可能简化 Azure 应用搭建流程

    借助 Azure MCP Server 与 GitHub Copilot,尽可能简化 Azure 应用搭建流程

    Model Context Protocol(MCP)问世已有一段时间,在此期间,支持 MCP 的服务不断增多,其作为大语言模型(LLM)工具的应用范围也在逐步扩大。无论是工具提供方还是客户端的服务数量都在增加,预计今后支持 MCP 的场景还将进一步拓展。

    在这样的背景下,微软推出了 Azure MCP Server—— 一款可通过 MCP 操作 Azure 资源的 MCP 服务器。(相关链接:github.com

    目前,该服务器可操作的资源虽有限,但已能实现 CosmosDB、Blob Storage 等数据的查询功能。本文将先简要介绍 MCP,随后讲解如何从 GitHub Copilot 调用 Azure MCP Server,从而轻松搭建使用 Azure 资源的 Web 应用。

    MCP 是什么

    MCP 是 Model Context Protocol 的缩写,顾名思义,它指的是一种协议(即标准规范)。具体而言,这是一种针对 “使用 LLM 模型的应用在调用工具时,如何获取上下文并调用工具” 这一流程所制定的标准规范。

    提到工具调用,大家可能会想到 Function Calling(函数调用),但 MCP 与它属于不同层面的概念,具体区别如下:

    • Function Calling(函数调用):输入用户提示词与各工具的信息后,选择并调用对应工具的功能。
    • MCP:规定了 LLM 应用应如何选择工具、工具方应如何提供工具的标准规范。

    在 Model Context Protocol 中,定义了 “MCP Server”(MCP 服务器)与 “MCP Client”(MCP 客户端)两种角色:

    • 宿主(Host):指使用 MCP 的 LLM 应用。
    • MCP Server(MCP 服务器):提供工具,负责提供工具信息并执行工具调用。
    • MCP Client(MCP 客户端):从 MCP Server 获取工具信息,决定调用哪个工具并执行调用操作。
    https://modelcontextprotocol.io/docs/concepts/architecture

    严格来说,MCP Server 还可提供提示词模板等其他功能,本文在此暂不展开说明。

    例如,Claude Desktop、GitHub Copilot 等属于工具调用方服务,对应上述的 “宿主”,其内部包含了 MCP 客户端。

    本文将按照以下架构开展操作:通过由 NodeJS 启动的 MCP Server 来操作 Azure 资源。

    关于 Azure MCP Server

    这是微软发布的 MCP 服务器,可通过工具提供 Azure 资源的操作能力,支持标准输入与 HTTP 两种通信方式。

    可操作的内容示例如下:

    • 获取 CosmosDB 容器列表
    • 向 CosmosDB 容器执行 SQL 查询
    • 获取 Blob Storage 容器列表

    搭建使用 Azure 资源的 Web 应用

    本次我们将搭建一个简易 Web 应用,实现文件的上传、下载与删除功能,并记录 “谁在何时上传了文件”。后端将采用 Blob Storage 作为文件存储,CosmosDB 用于管理上传历史。

    开发环境如下:

    • VS Code Insiders
    • GitHub Copilot
    • Python 3.10.11

    启动 Azure MCP Server

    启动 Azure MCP Server 十分简单。

    https://github.com/Azure/azure-mcp

    执行以下命令启动服务器

    bashnpx -y @azure/mcp@latest server start --transport sse

    若出现如下输出,则表示启动成功

    plaintextinfo: Microsoft.Hosting.Lifetime[14]

    Now listening on: http://localhost:5008

    配置 VS Code 中的 GitHub Copilot,使其适配 Azure MCP Server

    仅启动 MCP Server 无法让客户端识别,需完成注册操作以确保 LLM 应用能正常识别。由于本次使用 GitHub Copilot,具体操作可参考链接code.visualstudio.com

    核心步骤为在 .vscode/mcp.json 文件中写入以下内容即可:

    json

    {
        "servers": {
            "azure-mcp-dev": {
                "url": "http://localhost:5008"
            }
        }
    }
    

    通过 GitHub Copilot 搭建应用

    首先,需预先在 Azure 中手动创建以下资源组及资源:

    • 资源组:mcp-dev
    • CosmosDB:ssk-mcp-cosmos-dev
    • 存储账户:sskmcpblobdev

    理论上,我们希望让 Azure MCP Server 完成资源创建的全过程,但将资源创建操作完全交给 LLM 存在一定风险,因此本次仅手动完成这部分工作。

    完成上述准备后,向已关联 Azure MCP Server 的 GitHub Copilot 输入以下提示词:

    “我想在名为 mcp-dev 的资源组中,使用 Blob Storage 和 CosmosDB 搭建一个文件上传管理系统。

    • 支持用户各自上传、下载、删除文件。
    • 通过 CosmosDB 记录每个用户何时更新了哪个文件。
    • 使用 Python 的 FastAPI 进行开发。

    请基于上述条件完成以下操作:

    • 修改 Azure 资源配置。
    • 输出展示数据库与存储配置的文档。”

    此时,Copilot 会先检查现有资源状态,如下所示:

    其中显示 “Ran azmcp-group-list” 的部分,即为正在执行 Azure MCP Server 操作的过程,能看出它正在确认资源组、存储及 CosmosDB 的状态。

    Copilot 在首次回复中会告知所需的设计方案,之后我们可进一步指令其输出代码。

    需要注意的是,Copilot 会生成源代码,但不会主动创建容器。由于若不明确指示,它通常不会执行修改资源的操作,因此需补充相关指令。

    补充指令后,资源所需的各个容器便会分别创建完成。

    至此,源代码与后端资源的搭建就全部完成了。

    实际使用体验

    下面我们来运行一下这个应用。界面是通过向 GitHub Copilot 输入提示词生成的。

    由于没有对外观做任何指定,所以界面处于最基础的状态。这里展示的是已上传 schema.json 文件后的状态,Azure 资源中也同步了上传的文件及相关操作历史。

    像这样,借助 Azure MCP Server 与 GitHub Copilot,从 Azure 资源配置到应用创建的全过程,都可以通过提示词一次性完成。在 Azure 上搭建简单应用时,这一组合应该会非常实用。

    总结

    本文借助 Azure MCP Server 与 GitHub Copilot,轻松验证了 Azure 资源配置与应用开发的全流程。

    除了 GitHub Copilot 原本就具备的应用创建能力外,现在连适配应用的资源配置都能通过提示词一站式完成,非常便捷。

    未来,MCP Server 的工具扩展功能还将进一步完善,想必能为我们带来更高效的开发体验。

    那么,我们下次再见。

  • 使用 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,并不能移除通过快速创建功能生成的向量数据库等其他关联资源。若不再需要这些资源,请务必手动删除,避免遗漏。

  • 借助 Amazon Nova 模型与 Bedrock Knowledge Base 实现视频检索

    借助 Amazon Nova 模型与 Bedrock Knowledge Base 实现视频检索

    不知您是否有过想要检索视频的经历?

    比如,只依稀记得视频里提到过某些内容,但这些内容并未体现在视频标题中,导致无论如何都找不到对应的视频。

    或许如果能像使用 Google 搜索那样检索就好了,但对于公司内部的视频或工作中使用的视频而言,事情往往没那么简单。

    为了解决这类困扰,我们尝试利用 Amazon Nova 模型与 Amazon Bedrock Knowledge Base 开发了一款工具。

    通过使用 Bedrock Knowledge Base,无需自行开发文档导入与检索功能,只需将视频的摘要结果存入 S3,即可轻松实现联动。

    也就是说,能够在最大限度降低开发成本的同时,开发出高性能的应用程序。

    构成图

    1. 视频检索想要实现的目标

    如果视频标题中包含目标语句,那么通过标题就能进行检索,但对于仅在视频部分内容中提及的信息等,很难通过字符串进行检索。

    此外,有时用户并非对某一特定视频感兴趣,而是希望广泛检索主题相同的视频。

    在本次视频检索项目中,为实现此类模糊检索,我们考虑通过 Bedrock Knowledge Base 进行向量检索。

    2. 实现方法

    大致步骤如下:

    1. 使 Amazon Nova 模型可对视频进行摘要处理
    2. 使摘要结果可导入 Bedrock Knowledge Base
    3. 实现视频检索处理
    4. 制作检索界面

    下面分别进行详细说明。

    2.1. 使 Amazon Nova 模型可对视频进行摘要处理

    通过模型生成摘要

    Amazon Nova 模型除了可接收文本、图像输入外,还能接收视频输入。

    我们将视频及其文字稿与下述提示词一同输入模型,让模型生成摘要文本。

    本次我们从 YouTube 频道视频中,选取了时长 1 分钟以内的视频,并上传至 S3。

    视频上传至 S3 后,Lambda 会接收事件触发,调用 Amazon Nova Lite 为这些视频生成说明文本,并将文本文件上传至 S3。

    该文本文件随后将成为 Knowledge Base 的导入对象。

    system_prompt = [
        {
            "text": dedent("""\
                您的任务是分析给定的视频,并说明视频中呈现的内容。
                视频的文字稿结果已记载在「文字稿:xxx」部分,请将其作为说明的依据。
                您的回复必须严格仅由视频的说明文本构成。
                请尽可能详细地进行说明。
                摘要请以中文呈现。
            """)
        }
    ]
    use_messages = [
        {
            "role": "user",
            "content": [
                {"text": f"视频名: {filename}"},
                {
                    "video": {
                        "format": "mp4",
                        "source": {"bytes": b64_content},
                    },
                },
                {"text": f"文字稿: {transcript}"},
                {"text": "请用中文说明此视频。"},
            ],
        }
    ]
    config = {"temperature": 0}
    body = {
        "schemaVersion": "messages-v1",
        "system": system_prompt,
        "messages": use_messages,
        "inferenceConfig": config,
    }
    
    response = bedrock_agent.invoke_model(
        modelId=MODEL_ID,
        body=json.dumps(body),
        contentType="application/json",
    )
    model_response = json.loads(response["body"].read())
    content = model_response["output"]["message"]["content"][0]["text"]
    

    模型会返回如下响应:

    此外,由于本次仅针对短时长视频,因此采用了直接向 API 提交视频的方式,但如果文件体积较大,则需要采取诸如读取上传至 S3 的文件、将视频分段传输后再合并等方法。

    2.2. 使摘要结果可导入 Bedrock Knowledge Base

    导入 Knowledge Base

    接下来需要通过 Knowledge Base 进行同步,以导入上述说明文本。但如果直接导入,无法实现原始视频与上传的文本文件之间的关联。

    为解决这一问题,我们使用了 Knowledge Base 的 metadata.json 功能。

    在此 JSON 文件中记载的内容,会在 Knowledge Base 同步时作为元数据保存到 OpenSearch Serverless 中,可供检索时获取。

    本次我们在元数据中指定了视频的 URL,用于检索后的界面显示。

    {
      "metadataAttributes": {
        "original_path": "s3://bucket/path/to/video.mp4"
      }
    }
    

    当视频的说明文本与对应的 metadata.json 配置完成后,即可对 Knowledge Base 进行同步。

    2.3. 实现视频检索处理

    执行检索

    检索时使用了 Knowledge Base 的 Retrieve API。

    此外,通过在检索后设置分数下限作为阈值,可确保经重排序后被判定为相关性较低的视频不纳入检索结果。

    const input = {
      knowledgeBaseId,
      retrievalQuery: {
        text: query.trim(),
      }
      retrievalConfiguration: {
        vectorSearchConfiguration: {
          numberOfResults: 20,
          overrideSearchType: "HYBRID",
          rerankingConfiguration: {
            bedrockRerankingConfiguration: {
              modelConfiguration: {
                modelArn: AMAZON_RERANK_MODEL,
              },
              numberOfRerankedResults: 10,
            },
            type: "BEDROCK_RERANKING_MODEL",
          },
        },
      },
    };
    const command = new RetrieveCommand(input);
    return client.send(command);
    

    可按如下方式获取视频的概要及视频文件路径:

    {
      "retrievalResults": [{
        "content": {
          "text": "该视频介绍了远程办公中的 IT 工程师想吃的豆沙包排名……",
          "type": "TEXT"
        },
        "location": {
          "s3Location": {
            "uri": "s3://bucket/path/to/summary.txt"
          },
          "type": "S3"
        },
        "metadata": {
          "original_path": "s3://bucket/path/to/video.mp4"
        }
      }]
    }
    

    2.4. 制作检索界面

    本次使用 bolt.new 制作了执行上述检索的界面。

    虽然我不太擅长前端开发,但只需用中文下达指令,就能制作出非常不错的应用,这一点让我很惊喜。

    制作的检索应用
    检索结果

    3. 结果

    3.1. 尝试用视频中包含的语句进行检索

    首先,我们尝试使用既包含在视频标题中、也包含在生成式 AI 生成的摘要文本中的关键词进行检索。

    经确认,目标视频会显示在检索结果的第一位。

    当遇到 “想再看那个视频,但用传统检索方式搜不到” 的情况时,使用这款应用就能立即找到想看的视频。

    “美味的豆沙包”

    3.2. 尝试用视频中不包含的语句进行检索

    接下来,我们尝试用未出现在标题和摘要文本中,但凭借向量检索可能捕捉到相关内容的语句进行了检索。

    此次检索也成功命中了一段视频,内容是 2018 年参加在美国旧金山举办的 “Elastic {ON}” 大会时的场景。

    虽然本次知识库中仅导入了 Elastic {ON} 相关的视频,但如果预先导入其他海外大会的视频,就能实现 “并非想找某一特定视频,而是希望广泛获取同类视频” 的需求。

    海外大会的场景

    总结

    目前,Bedrock Knowledge Base 尚无法直接输入视频,但通过使用 Amazon Nova 生成视频说明文本,我们间接实现了视频检索功能。

    虽然通过自行对视频进行嵌入处理也能实现相同功能,但 Bedrock Knowledge Base 的优势在于可轻松集成内容导入与检索能力。

    内容导入仅需将文件放入 S3 并执行 “同步” 操作即可,检索也只需调用 Retrieve API。借助 Retrieve API,还能通过重排序功能轻松优化检索结果。