如何使用 Mastra 和 Elasticsearch 构建具备代理能力的 AI 应用
作者来自 Elastic Enrico Zimuel通过一个实际示例学习如何使用 Mastra 和 Elasticsearch 构建具备代理能力的 AI 应用。Agent Builder 现已正式发布。通过 Elastic Cloud Trial开始使用并在此查看 Agent Builder 文档。在本文中我们将介绍如何使用 Mastra TypeScript 框架构建与 Elasticsearch 交互的具备代理能力的应用。我们最近为 mastra-ai/mastra 开源项目做出了贡献新增了将 Elasticsearch 作为向量数据库的支持。通过这一新功能你可以在 Mastra 中原生使用 Elasticsearch 来存储 embedding。除了向量之外Elasticsearch 还提供了一整套高级功能来满足所有上下文工程需求例如 hybrid search 和 reranking。本文详细介绍了如何创建一个 agent 来实现基于 Elasticsearch 的检索增强生成RAG架构。我们将展示一个演示项目其中使用 agentic 方法与存储在 Elasticsearch 中的科幻电影数据语料进行交互。该项目可在 elastic/mastra-elasticsearch-example 获取。MastraMastra 是一个用于创建具备代理能力的 AI 应用的 TypeScript 框架。Mastra 中的项目结构如下所示src/ ├── mastra/ │ ├── agents/ │ │ └── weather-agent.ts │ ├── tools/ │ │ └── weather-tool.ts │ ├── workflows/ │ │ └── weather-workflow.ts │ ├── scorers/ │ │ └── weather-scorer.ts │ └── index.ts ├── .env.example ├── package.json └── tsconfig.json在 Mastra 中你可以构建 agents、tools、workflows 和 scores。Agent 是一个类接收输入消息并生成输出响应。agent 可以使用 tools、大型语言模型LLMs和 memory见图 1。图 1展示 agent 在 Mastra 中工作原理的示意图。Agent 的tools使其能够与 “外部世界” 交互例如与 web API 通信或执行内部操作如查询 Elasticsearch。memory组件对于存储对话历史至关重要包括过去的输入和输出。存储的上下文使 agent 能够利用过去的交互为未来的问题提供更有信息量和更相关的响应。Workflows 允许你使用清晰、结构化的步骤定义复杂任务序列而不是依赖单个 agent 的推理见图 2。它们让你完全控制任务如何拆分、数据如何在任务间流动以及何时执行。Workflows 默认使用内置执行引擎运行也可以部署到 workflow runners。图 2Mastra 中 workflow 的示例。在 Mastra 中你还可以定义 scores它们是使用模型评分、规则和统计方法评估 agent 输出的自动化测试。Scorers 返回分数数值通常在 0 到 1 之间用于量化输出满足评估标准的程度。这些分数使你能够客观地跟踪性能、比较不同方法并识别 AI 系统中需要改进的部分。Scorers 可以使用你自己的 prompts 和评分函数进行自定义。Elasticsearch运行演示项目时需要有一个运行中的 Elasticsearch 实例。你可以在 Elastic Cloud 激活免费试用或使用 start-local 脚本在本地安装curl -fsSL https://elastic.co/start-local | sh这将在你的计算机上安装 Elasticsearch 和 Kibana并生成用于配置 Mastra 集成的 API key。API key 会作为上一个命令的输出显示并存储在 elastic-start-local 文件夹中的 .env 文件中。安装并配置演示我们创建了一个 elastic/mastra-elasticsearch-example 仓库其中包含演示项目的源代码。仓库中的示例展示了如何在 Mastra 中创建一个 agent实现基于 RAG 架构从 Elasticsearch 检索文档。我们为演示提供了一个关于科幻电影的数据集。从 Kaggle 上的 IMDb 数据集中提取了 500 部电影。第一步是使用 npm 安装项目依赖命令如下npm install接下来需要配置.env文件其中包含设置。可以通过复制.env.example文件的结构来生成该文件命令如下cp .env.example .env现在可以编辑 .env添加缺失的信息OPENAI_API_KEY ELASTICSEARCH_URL ELASTICSEARCH_API_KEY ELASTICSEARCH_INDEX_NAMEscifi-moviesElasticsearch 索引的名称是 scifi-movies。如果需要可以使用 .env 变量 ELASTICSEARCH_INDEX_NAME 修改它。我们使用 OpenAI 作为 embedding 服务这意味着你需要在 OPENAI_API_KEY env 变量中提供 OpenAI 的 API key。示例中使用的 embedding 模型是 openai/text-embedding-3-smallembedding 维度为 1536。为了生成最终答案我们使用了 openai/gpt-5-nano 模型以降低成本。RAG 架构允许使用较低性能通常也更便宜的最终 LLM 模型因为答案的基础事实由检索组件此例中为 Elasticsearch处理。较小的 LLM 主要负责两个任务重述/embedding 查询将用户的自然语言问题转换为向量 embedding以进行语义搜索。综合答案将高度相关的检索上下文块文档/电影整合为连贯的、最终的、人类可读答案遵循提供的 prompt 指令。由于 RAG 流程提供了答案所需的精确事实上下文最终 LLM 不需要庞大或复杂也不必在自身参数中拥有所有知识这是大型、高成本模型的优势。它本质上充当 Elasticsearch 提供的上下文的高级文本总结器和格式化器而非完整的知识库。这使得使用 gpt-5-nano 等模型在成本和延迟上得到优化成为可能。配置完 .env 文件后可以使用以下命令将电影数据摄取到 Elasticsearchnpx tsx src/utility/store.ts你应该会看到如下输出 Starting ingestion of 500 movies from 500_scifi_movies.jsonl... Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 1/500 (0%) | ok:1 | fail:0 | chunks:1 | eta:19m 33s | current:Capricorn One Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 2/500 (0%) | ok:2 | fail:0 | chunks:2 | eta:10m 32s | current:Doghouse Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 3/500 (1%) | ok:3 | fail:0 | chunks:3 | eta:7m 33s | current:Dinocroc Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 4/500 (1%) | ok:4 | fail:0 | chunks:7 | eta:6m 10s | current:Back to the Future Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 5/500 (1%) | ok:5 | fail:0 | chunks:9 | eta:5m 14s | current:The Projected Man Ingesting ░░░░░░░░░░░░░░░░░░░░░░░░ 6/500 (1%) | ok:6 | fail:0 | chunks:11 | eta:4m 41s | current:I, Robot ... ✅ Ingestion complete in 1m 46s. Success: 500, Failed: 0, Chunks: 693.scifi-movies 索引的 mapping 包含以下字段embeddingdense_vector1536 维使用 cosine similarity。descriptiontext包含电影描述。directortext包含导演姓名。titletext包含电影标题。我们使用 title description 生成 embedding。由于 title 和 description 是两个独立字段将二者拼接可确保生成的 embedding 向量同时捕获电影的特定唯一身份title和丰富的描述性上下文description从而获得更准确、全面的语义搜索结果。这个组合输入为 embedding 模型提供了更好的文档内容单一表示以进行相似性匹配。运行演示可以使用以下命令运行演示npm run dev该命令将在 localhost:4111 启动一个 Web 应用以访问 Mastra Studio见图 3。图 3Mastra Studio 截图展示了 Elasticsearch Agent 示例。Mastra Studio 提供一个交互式 UI 用于构建和测试你的 agents同时提供一个 REST API将你的 Mastra 应用作为本地服务暴露出来。这让你可以立即开始构建而无需担心集成问题。我们提供了一个 Elasticsearch Agent使用 Mastra 的 createVectorQueryTool 作为工具通过 Elasticsearch 执行语义搜索。这个 agent 使用 RAG 方法搜索相关文档即 movies来回答用户的问题。这个 agent 使用以下 promptYou are a helpful assistant that answers questions based on the provided context. Follow these steps for each response: 1. First, carefully analyze the retrieved context chunks and identify key information. 2. Break down your thinking process about how the retrieved information relates to the query. 3. Draw conclusions based only on the evidence in the retrieved context. 4. If the retrieved chunks dont contain enough information, explicitly state whats missing. Format your response as: THOUGHT PROCESS: - Step 1: [Initial analysis of retrieved chunks] - Step 2: [Reasoning based on chunks] FINAL ANSWER: [Your concise answer based on the retrieved context] Important: When asked to answer a question, please base your answer only on the context provided in the tool. If the context doesnt contain enough information to fully answer the question, please state that explicitly and stop it. Do not add more information than what is present in the retrieved chunks. Remember: Explain how youre using the retrieved information to reach your conclusions.如果你点击 Mastra Studio Agents 菜单并选择Elasticsearch Agent你可以使用聊天系统测试这个 agent。例如你可以用以下问题询问有关 sci-fi movies 的信息Find 5 movies or TV series about UFOs.你会注意到agent 会执行 vectorQueryTool。你可以点击被调用的工具查看输入和输出。在执行结束时LLM 会根据来自 Elasticsearch 的 scifi-movies 索引的上下文回答你的问题图 4。图 4使用 Elasticsearch Agent 的 LLM 响应。Mastra 内部执行以下步骤向量转换用户的问题 “Find 5 movies or TV series about UFOs” 被转换为向量 embedding使用 OpenAI 的 openai/text-embedding-3-small 模型。向量搜索该 embedding 随后用于通过向量搜索查询 Elasticsearch。结果检索Elasticsearch 返回与查询高度相关的 10 部 movies即向量最接近用户查询向量的那些。答案生成检索到的 movies 和原始用户问题被发送给 LLM具体为 openai/gpt-5-nano。LLM 处理这些信息并生成最终答案确保满足用户要求的五个结果。Elasticsearch Agent这里报告了 Elasticsearch Agent 的源代码。import { Agent } from mastra/core/agent; import { ElasticSearchVector } from mastra/elasticsearch; import { createVectorQueryTool } from mastra/rag; import { ModelRouterEmbeddingModel } from mastra/core/llm; import { Memory } from mastra/memory; const es_url process.env.ELASTICSEARCH_URL; const es_apikey process.env.ELASTICSEARCH_API_KEY; const es_index_name process.env.ELASTICSEARCH_INDEX_NAME; const prompt insert here the previous prompt; const esVector new ElasticSearchVector({ id: elasticsearch-vector, url: es_url, auth: { apiKey : es_apikey } }); const vectorQueryTool createVectorQueryTool({ vectorStore: esVector, indexName: es_index_name, model: new ModelRouterEmbeddingModel(openai/text-embedding-3-small) }); export const elasticsearchAgent new Agent({ id: elasticsearch-agent, name: Elasticsearch Agent, instructions: prompt, model: openai/gpt-5-nano, tools: { vectorQueryTool }, memory: new Memory(), });vectorQueryTool 是用于实现 RAG 示例中检索部分的工具。它使用 Elastic 为 Mastra 提供的 ElasticSearchVector 实现。这个 agent 是 agent 类的一个对象使用 vectorQueryTool、prompt 和 memory。如你所见为了将 Elasticsearch 连接到 agent我们需要的代码非常少。结论本文展示了将 Elasticsearch 与 Mastra 框架集成以构建复杂 agentic AI 应用的简单性和强大功能。具体来说我们演示了如何创建一个 RAG agent能够对索引在 Elasticsearch 中的 sci-fi movie 数据语料库执行语义搜索。一个关键要点是 Elastic 对 Mastra 开源项目的直接贡献为 Elasticsearch 作为向量存储提供原生支持。这种集成显著降低了入门门槛如Elasticsearch Agent源代码所示。使用 ElasticSearchVector 和 createVectorQueryTool将 Elasticsearch 连接到你的 agent 的完整设置只需要极少的配置代码行数。Elasticsearch 提供了多种高级功能以增强结果相关性。例如hybrid search 通过结合词汇搜索和向量搜索显著提升准确性。另一个有趣的功能是在 hybrid search 结束时使用最新 Jina 模型进行 reranking。要了解更多这些技术请参考 Elasticsearch Labs 的以下文章Elasticsearch hybrid search — Valentin CrettazJina 模型简介、功能及在 Elasticsearch 中的应用 — Scott Martens我们还鼓励你探索提供的示例并开始使用 Mastra 和 Elasticsearch 构建你自己的数据驱动 agents。有关 Mastra 的更多信息你可以查看官方文档。原文https://www.elastic.co/search-labs/blog/build-agentic-ai-applications-mastra-elasticsearch