Ohhnews

分类导航

$ cd ..
foojay原文

MongoDB作为AI Agent的向量数据库

#人工智能代理#向量数据库#mongodb#检索增强生成#多智能体系统

目录

现代人工智能系统正在不断演进。大型语言模型(LLM)已成为现代应用的支柱,帮助构建从 GPS 到更集成内容的对话界面。然而,LLM 缺乏记忆和跨交互保留内容的能力,因为它们是无状态的。这些局限性催生了 AI 智能体的构建。这些 AI 智能体超越了简单的提示-响应交互,转向更自主、面向任务的工作流程。

这些智能体不仅仅是模型调用,而是一个编排层,将推理与检索、记忆和工具执行等能力相结合。在开发这些智能体时,需要一个能够存储和检索语义有意义数据的数据库,这正是向量数据库的用武之地。

向量数据库将数据存储为文本、图像或非结构化数据的密集数值表示。这些嵌入(embeddings)捕获语义含义,能够实现相似性搜索而非精确匹配。借助 MongoDB Atlas,开发者可以生成嵌入、将其与应用数据一起存储,并在 MongoDB Atlas 中执行向量搜索,从而使 AI 智能体能够无缝结合操作数据与语义检索,简化架构的同时提升性能。

本文中,我们将使用 Java 构建一个 AI 智能体,以 MongoDB 作为数据库,将用户查询、文档、智能体记忆和嵌入统一存储在同一位置。我们将了解 MongoDB 如何简化检索增强生成(RAG)和持久记忆系统的实现。

为什么你应该使用 MongoDB 构建 AI 智能体?

  1. 向量存储与 Voyage AI 支持——MongoDB Atlas 基础设施为你提供了开发者友好的生态系统。你可以在平台上直接存储向量嵌入、创建向量嵌入并执行向量搜索。这减少了构建企业应用所需的不同系统数量。
  2. 混合搜索——借助 MongoDB Atlas 基础设施,你可以在向量搜索查询中添加过滤器,并为查询结果增加额外条件。与专门的向量存储不同,MongoDB 可以同时执行语义(向量)和经典结构化(关键词)查询。
  3. 开发者生态系统——MongoDB 始终是开发者优先的数据库,它让你的应用能够高效集成。
  4. 运维效率——如果你已经在使用 MongoDB,添加向量搜索功能可以避免引入新基础设施,简化模式、事务和运维。

理解 AI 智能体

构建 AI 智能体时,理解嵌入、检索增强生成(RAG)和智能体架构的核心原则至关重要。

向量嵌入(简称嵌入)是从文本、音频、视频或任何非结构化数据中导出的数字数据的密集向量表示。这些向量位于高维空间中,语义相似性得以保留,这意味着语义相似的输入基于余弦相似度或点积等距离度量而彼此靠近。

这种向量表示有助于检索最相似的前 K 个向量,通过向量搜索实现语义检索而非精确匹配。这对于处理同义改写、歧义和上下文查询至关重要。

检索增强生成(RAG)将检索步骤构建到管道中。模型利用语义搜索能力生成响应。标准 LLM 最常见的挑战之一是幻觉(hallucination),即仅依赖存储在模型权重中的参数知识时生成错误或虚构信息。RAG 通过将响应基于检索到的文档而非仅依赖内部权重来解决这一问题,从而提升事实一致性、可追溯性和响应新鲜度。

随着这些变化,智能体的概念应运而生。在这些智能体架构中,向量搜索成为实现记忆系统的核心抽象:

  1. 短期记忆:最近的交互历史被嵌入并检索,以保持对话连续性。
  2. 长期记忆:过去交互、文档和工具输出的嵌入被持久化。
  3. 语义回忆:基于相似性而非固定键动态检索上下文。

在这些架构中,向量数据库同时作为这些系统的检索层和存储层。因此,向量搜索不再仅仅用于语义搜索,而是成为智能体系统的基础构建块。它支撑着智能体如何检索知识、维护记忆,并在真实应用中以低幻觉输出响应。

使用 MongoDB 构建多智能体应用

在深入构建智能体的实际代码之前,我们先了解构建应用的一些基本前提。

  1. 一个免费层的 MongoDB Atlas 集群。
  2. 创建免费的 Voyage AI API 密钥,用于在数据库中生成嵌入。
  3. 使用 Spring Initializr 设置 Spring Boot 项目以与 MongoDB 配合使用。
  4. 安装最新的 Java 和 Gradle/Maven 版本。

为了构建多智能体系统,我们以旅行重新规划系统为例。

为了更好地理解该系统,假设以下场景:你从多伦多飞往旧金山,在纽约中转。然后现实发生了:纽约到旧金山的航班延误了 9 小时。由于你有一个重要的客户会议需要展示产品,因此需要更好的计划。

此时,我们需要的不仅仅是一个告知其他路线的系统,而是一个能够重新规划整个行程的系统。这正是多智能体重规划系统的用武之地。该系统主要完成以下工作:

  • 监控智能体检测中断
  • 规划智能体编排决策
  • 预订智能体寻找替代路线
  • 预算智能体基于成本进行筛选
  • 偏好智能体与用户选择对齐
  • 记忆智能体回忆类似的过往情况

每个智能体单独看都很简单,但组合在一起就像一个协调的系统。

使该系统强大的关键是将 MongoDB 作为数据库使用。MongoDB 将实时数据存储在数据库中;每个事件都被记录在系统中;Voyage AI 和 MongoDB 的向量搜索功能存储过往旅行事件的嵌入,并在重新规划期间检索相似案例。

为了构建该系统,我们将使用四个不同的集合:trip_stateeventagent_decisionincident_memorytrip_state 存储行程的当前状态;所有中断事件被复制到 events 中;每个智能体将其推理记录在 agent_decision 中;incident_memory 存储过往事件。

让我们逐步进行。

步骤 1:创建向量搜索索引

在构建系统之前,我们需要一个向量搜索索引。本项目的嵌入由 Voyage AI 的 voyage-3-large 模型生成。

前往 MongoDB Atlas,创建一个名为 incident_memory 的集合,并使用以下 JSON 创建向量搜索索引。

$ cat
{
  "fields": [
    {
      "numDimensions": 1024,
      "path": "embedding",
      "similarity": "cosine",
      "type": "vector"
    }
  ]
}

步骤 2:创建行程

通过以下 API 调用创建行程。该请求到达控制器。由于请求体是可选的,当没有提供时,我们使用默认的 CreateTripRequest,并将规范化后的请求传递给服务层。因此,规范化后的对象要么是传入的请求,要么是客户端省略请求体时的默认占位符。

$ java
@PostMapping("/create")
public TripState createTrip(@RequestBody(required = false) CreateTripRequest request) {
    CreateTripRequest normalized = request == null
            ? new CreateTripRequest("demo-user", null, null)
            : request;
    return tripService.createTrip(normalized);
}

服务层创建行程。例如:

$ bash
curl -X POST "http://localhost:8080/trip/create" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "traveler-001",
    "preferences": {
      "airlinePreference": "SkyJet",
      "avoidRedEye": true,
      "maxAdditionalBudget": 250
    }
  }'

结果如下:

$ cat
{
  "id": "69dd6111674d2228e4db4b25",
  "userId": "traveler-001",
  "itinerary": [
    {
      "segmentId": "SEG-1",
      "type": "FLIGHT",
      "provider": "SkyJet",
      "fromLocation": "JFK",
      "toLocation": "SFO",
      "cost": 420.0
    }
  ],
  "status": "ON_TRACK"
}

该行程存储在 trip_state 中。此时一切正常。

步骤 3:触发中断

在此步骤中,我们将在数据库中添加一个延迟状态。这通过另一个 POST 方法完成:

$ bash
curl -X POST "http://localhost:8080/event/simulate-delay" \
  -H "Content-Type: application/json" \
  -d '{
    "tripId": "69dd6111674d2228e4db4b25",
    "delayMinutes": 180,
    "severity": "HIGH"
  }'

控制器中的另一个代码块处理该请求:

$ java
@PostMapping("/simulate-delay")
public TravelEvent simulateDelay(@RequestBody SimulateDelayRequest request)

同时,有一个关键操作:

$ java
tripState.setStatus(TripStatus.DISRUPTED);
tripService.saveTrip(tripState);

这是你的第一个智能体,它检测到问题、更新状态并记录决策。

模拟的延迟如下:

$ cat
{
  "id": "69dd6160674d2228e4db4b26",
  "tripId": "69dd6111674d2228e4db4b25",
  "type": "FLIGHT_DELAY",
  "severity": "HIGH",
  "metadata": {
    "from": "JFK",
    "to": "SFO",
    "delayMinutes": 180
  }
}

步骤 4:重新规划

要触发重新规划,规划智能体(PlannerAgent)编排其他智能体。它向记忆智能体(MemoryAgent)询问类似事件(利用 MongoDB 向量搜索),向预订智能体(BookingAgent)询问替代路线;然后预算智能体(BudgetAgent)和偏好智能体(PreferenceAgent)优化这些选项,最终规划智能体提交最终行程。

这进入以下端点:

$ java
@PostMapping("/plan/replan")
public TripState replan(@RequestBody ReplanRequest request)

规划智能体接管工作。例如:

$ bash
curl -X POST http://localhost:8080/plan/replan \
  -H "Content-Type: application/json" \
  -d '{
    "tripId": "69dd6111674d2228e4db4b25"
  }'

响应如下:

$ cat
{
  "id": "69dd6111674d2228e4db4b25",
  "status": "REPLANNED",
  "itinerary": [
    {
      "segmentId": "OPT-CHI-1",
      "fromLocation": "JFK",
      "toLocation": "ORD",
      "cost": 320.0
    },
    {
      "segmentId": "OPT-CHI-2",
      "fromLocation": "ORD",
      "toLocation": "SFO",
      "cost": 320.0
    }
  ]
}

此时,系统开始建议从芝加哥转机。

步骤 5:记忆智能体利用向量搜索

首先,规划智能体会检查:“我们是否见过类似情况?”如果是,则从 incident_memory 中检索并建议可能的操作。

$ java
List<IncidentMemory> results = vectorSearchService.findSimilar(query);

步骤 6:预订智能体生成选项

当未找到响应时,智能体开始生成自己的选项。为此:

$ java
List<AlternativeRoute> options =
    bookingAgent.generateOptions(tripState, latestEvent, memories);

预算智能体也开始筛选选项:

$ java
List<AlternativeRoute> budgeted =
    budgetAgent.filterOptions(tripState, options);

步骤 7:系统最终做出决策

最后,行程被更新,系统记录做出该决策的原因。此时,当你调用:

$ bash
curl http://localhost:8080/trip/69dd6111674d2228e4db4b25

会得到如下响应:

$ cat
{
  "status": "REPLANNED",
  "itinerary": [
    {
      "fromLocation": "JFK",
      "toLocation": "ORD"
    },
    {
      "fromLocation": "ORD",
      "toLocation": "SFO"
    }
  ]
}

最终,系统不仅检测到了延迟,还利用了记忆、协调了多个智能体,并生成了一个更好的规划,同时所有决策历史完全可追溯地存储在 MongoDB 中。

该多智能体系统的完整代码可在 GitHub 仓库 中找到。

结论

本文中,我们尝试使用 MongoDB 构建了一个自适应、有状态且智能的多智能体系统。

从一个简单的旅行行程开始,我们看到了中断如何触发跨多个智能体的协调行动链:监控智能体检测到问题,记忆智能体利用向量搜索回忆类似过往事件,规划智能体编排预订、预算和偏好智能体以得出更好的替代方案。最重要的是,该过程的每一步都被持久化,使得系统不仅智能,而且可解释。

使这一架构强大的是 MongoDB 作为统一数据平台的角色。MongoDB 将操作数据和 AI 记忆整合在一起,而不是分离到不同系统中,使智能体能够超越无状态执行,并根据上下文和经验进行操作。

MongoDB 的向量搜索能力使系统能够检索类似的过往情况,并将该知识应用于新问题,减少猜测并提高决策质量。

文章 MongoDB 作为 AI 智能体的向量数据库 首次出现在 foojay 上。