使用 LangGraph 和 Elasticsearch 构建强大的 RAG 工作流

article/2025/8/24 14:52:10

作者:来自 Elastic  Neha Saini

在这篇博客中,我们将向你展示如何配置和自定义 LangGraph Retrieval Agent 模板与 Elasticsearch,以构建一个强大的 RAG 工作流,实现高效的数据检索和由 AI 驱动的响应。

Elasticsearch 原生集成了行业领先的生成式 AI 工具和提供商。查看我们关于超越 RAG 基础知识或构建可投入生产的应用程序 Elastic Vector Database 的网络研讨会。

要为你的用例构建最佳搜索解决方案,现在就开始免费云试用,或在本地机器上尝试 Elastic。


LangGraph Retrieval Agent Template 是由 LangChain 开发的入门项目,旨在通过 LangGraph Studio 使用 LangGraph 构建基于检索的问题解答系统。该模板预先配置,可与 Elasticsearch 无缝集成,使开发者能够快速构建能够高效索引和检索文档的智能体。

本博客重点介绍如何使用 LangGraph Studio 和 LangGraph CLI 运行并自定义 LangChain Retrieval Agent Template。该模板为构建检索增强生成(RAG)应用提供了框架,并支持多种检索后端,如 Elasticsearch。

我们将带你逐步完成设置、配置环境,以及如何高效结合 Elastic 执行该模板,并自定义智能体流程。

先决条件

在继续之前,请确保你已安装以下内容:

  • Elasticsearch Cloud 部署或本地 Elasticsearch 部署(也可以在 Elastic Cloud 上创建一个 14 天免费试用)——版本需为 8.0.0 或更高

  • Python 3.9 及以上版本

  • 一个 LLM 提供商的访问权限,如 Cohere(本指南使用)、 OpenAI 或 Anthropic / Claude

创建 LangGraph 应用

1. 安装 LangGraph CLI

pip install --upgrade "langgraph-cli[inmem]"

2. 从 retrieval-agent-template 创建 LangGraph 应用

mkdir lg-agent-demo
cd lg-agent-demo
langgraph new lg-agent-demo 

你会看到一个交互式菜单,可以从中选择可用的模板列表。选择 4 表示 Retrieval Agent,选择 1 表示 Python,如下所示:

故障排除:如果遇到错误 “urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)>”

请运行 Python 的安装证书命令来解决此问题,如下所示。

3. 安装依赖项

在新建的 LangGraph 应用根目录下,创建一个虚拟环境并以 edit 模式安装依赖项,这样你的本地更改将被服务器使用:

#For Mac
python3 -m venv lg-demo
source lg-demo/bin/activate 
pip install -e .#For Windows
python3 -m venv lg-demo
lg-demo\Scripts\activate 
pip install -e .

设置环境

1. 创建一个 .env 文件

.env 文件保存 API 密钥和配置,以便应用可以连接到你选择的 LLM 和检索提供者。通过复制示例配置生成一个新的 .env 文件:

cp .env.example .env

2. 配置 .env 文件

.env 文件自带一组默认配置。你可以根据你的设置添加必要的 API 密钥和值来更新它。对于与你的使用场景无关的键,可以保持不变或者删除。

# To separate your traces from other applications
LANGSMITH_PROJECT=retrieval-agent# LLM choice (set the API key for your selected provider):
ANTHROPIC_API_KEY=your_anthropic_api_key
FIREWORKS_API_KEY=your_fireworks_api_key
OPENAI_API_KEY=your_openai_api_key# Retrieval provider (configure based on your chosen service):## Elastic Cloud:
ELASTICSEARCH_URL=https://your_elastic_cloud_url
ELASTICSEARCH_API_KEY=your_elastic_api_key## Elastic Local:
ELASTICSEARCH_URL=http://host.docker.internal:9200
ELASTICSEARCH_USER=elastic
ELASTICSEARCH_PASSWORD=changeme## Pinecone:
PINECONE_API_KEY=your_pinecone_api_key
PINECONE_INDEX_NAME=your_pinecone_index_name## MongoDB Atlas:
MONGODB_URI=your_mongodb_connection_string# Cohere API key:
COHERE_API_KEY=your_cohere_api_key

Elastic Cloud 和 Cohere 示例 .env 文件

下面是一个示例 .env 配置,使用 Elastic Cloud 作为检索提供者,Cohere 作为 LLM,正如本博客中演示的:

# To separate your traces from other applications
LANGSMITH_PROJECT=retrieval-agent
#Retrieval Provider
# Elasticsearch configuration
ELASTICSEARCH_URL=elastic-url:443
ELASTICSEARCH_API_KEY=elastic_api_key
# Cohere API key
COHERE_API_KEY=cohere_api_key

注意:虽然本指南使用 Cohere 进行响应生成和向量生成,但你也可以根据自己的用例选择其他 LLM 提供商,比如 OpenAIClaude,或者本地的 LLM 模型。请确保你要使用的每个 key 都已经在 .env 文件中正确设置。

3. 更新配置文件 - configuration.py

在 .env 文件中设置好相应的 API key 后,下一步是更新应用程序的默认模型配置。更新配置可以确保系统使用你在 .env 文件中指定的服务和模型。

导航到配置文件:

 cd src/retrieval_graph

configuration.py 文件包含检索代理执行以下三项主要任务时使用的默认模型设置:

  • 嵌入模型(Embedding model)—— 将文档转换为向量表示

  • 查询模型(Query model)—— 将用户查询处理为向量

  • 响应模型(Response model)—— 生成最终回答

默认情况下,代码使用的是 OpenAI(如 openai/text-embedding-3-small)和 Anthropic(如 anthropic/claude-3-5-sonnet-20240620 和 anthropic/claude-3-haiku-20240307)提供的模型。

在本博客中,我们切换为使用 Cohere 模型。如果你已经在使用 OpenAI 或 Anthropic,则无需更改。

使用 Cohere 的示例更改:

打开 configuration.py 并按如下方式修改默认模型设置:

…embedding_model: Annotated[str,{"__template_metadata__": {"kind": "embeddings"}},] = field(default="cohere/embed-english-v3.0",
…
response_model: Annotated[str, {"__template_metadata__": {"kind": "llm"}}] = field(default="cohere/command-r-08-2024",
…
query_model: Annotated[str, {"__template_metadata__": {"kind": "llm"}}] = field(default="cohere/command-r-08-2024",metadata={

使用 LangGraph CLI 运行检索代理

1. 启动 LangGraph 服务器

cd lg-agent-demo
langgraph dev

这将在本地启动 LangGraph API 服务器。如果运行成功,你应该会看到类似下面的内容:

打开 Studio UI 链接。

这里有两个可用的图表:

  • Retrieval Graph:从 Elasticsearch 检索数据并使用 LLM 响应查询。

  • Indexer Graph:将文档索引到 Elasticsearch 并使用 LLM 生成向量。

2. 配置 Indexer graph

  • 打开 Indexer graph。
  • 点击管理助手 (Manage Assistants)。
    • 点击 “添加新助手” (Add New Assistant),输入指定的用户详情,然后关闭窗口。
{"user_id": "101"}

3. 索引示例文档

索引以下示例文档,这些文档代表组织 NoveTech 的假设季度报告:

[{    "page_content": "NoveTech Solutions Q1 2025 Report - Revenue: $120.5M, Net Profit: $18.2M, EPS: $2.15. Strong AI software launch and $50M government contract secured."},{"page_content": "NoveTech Solutions Business Highlights - AI-driven analytics software gained 15% market share. Expansion into Southeast Asia with two new offices. Cloud security contract secured."},{"page_content": "NoveTech Solutions Financial Overview - Operating expenses at $85.3M, Gross Margin 29.3%. Stock price rose from $72.5 to $78.3. Market Cap reached $5.2B."},{"page_content": "NoveTech Solutions Challenges - Rising supply chain costs impacting hardware production. Regulatory delays slowing European expansion. Competitive pressure in cybersecurity sector."},{"page_content": "NoveTech Solutions Future Outlook - Expected revenue for Q2 2025: $135M. New AI chatbot and blockchain security platform launch planned. Expansion into Latin America."},{"page_content": "NoveTech Solutions Market Performance - Year-over-Year growth at 12.7%. Stock price increase reflects investor confidence. Cybersecurity and AI sectors remain competitive."},{"page_content": "NoveTech Solutions Strategic Moves - Investing in R&D to enhance AI-driven automation. Strengthening partnerships with enterprise cloud providers. Focusing on data privacy solutions."},{"page_content": "NoveTech Solutions CEO Statement - 'NoveTech Solutions continues to innovate in AI and cybersecurity. Our growth strategy remains strong, and we foresee steady expansion in the coming quarters.'"}
]

一旦文档被索引,你将在线程中看到一条删除消息,如下所示。

4. 运行检索图(retrieval graph)

切换到检索图。 输入以下搜索查询:

What was NovaTech Solutions total revenue in Q1 2025?

系统将返回相关文档,并根据已索引的数据提供准确的答案。

自定义检索代理

为了增强用户体验,我们在检索图中引入了一个自定义步骤,用于预测用户可能提出的下三个问题。这个预测基于以下内容:

  • 从检索到的文档中的上下文

  • 之前的用户交互

  • 上一个用户查询

实现查询预测功能需要以下代码更改:

1. 更新 graph.py

添加 predict_query 函数:

async def predict_query(state: State, *, config: RunnableConfig
) -> dict[str, list[BaseMessage]]:logger.info(f"predict_query predict_querypredict_query predict_query predict_query predict_query")  # Log the queryconfiguration = Configuration.from_runnable_config(config)prompt = ChatPromptTemplate.from_messages([("system", configuration.predict_next_question_prompt),("placeholder", "{messages}"),])model = load_chat_model(configuration.response_model)user_query = state.queries[-1] if state.queries else "No prior query available"logger.info(f"user_query: {user_query}")logger.info(f"statemessage: {state.messages}")#human_messages = [msg for msg in state.message if isinstance(msg, HumanMessage)]message_value = await prompt.ainvoke({"messages": state.messages,"user_query": user_query,  # Use the most recent query as primary input"system_time": datetime.now(tz=timezone.utc).isoformat(),},config,)next_question = await model.ainvoke(message_value, config)return {"next_question": [next_question]}

修改 respond 函数以返回 response 对象,而不是消息:

async def respond(state: State, *, config: RunnableConfig
) -> dict[str, list[BaseMessage]]:"""Call the LLM powering our "agent"."""configuration = Configuration.from_runnable_config(config)# Feel free to customize the prompt, model, and other logic!prompt = ChatPromptTemplate.from_messages([("system", configuration.response_system_prompt),("placeholder", "{messages}"),])model = load_chat_model(configuration.response_model)retrieved_docs = format_docs(state.retrieved_docs)message_value = await prompt.ainvoke({"messages": state.messages,"retrieved_docs": retrieved_docs,"system_time": datetime.now(tz=timezone.utc).isoformat(),},config,)response = await model.ainvoke(message_value, config)# We return a list, because this will get added to the existing listreturn {"response": [response]}

更新图结构以添加新的节点和边用于 predict_query

builder.add_node(generate_query)
builder.add_node(retrieve)
builder.add_node(respond)
builder.add_node(predict_query)
builder.add_edge("__start__", "generate_query")
builder.add_edge("generate_query", "retrieve")
builder.add_edge("retrieve", "respond")
builder.add_edge("respond", "predict_query")

2. 更新 prompts.py

为查询预测(Query Prediction)编写 prompt:

PREDICT_NEXT_QUESTION_PROMPT = """Given the user query and the retrieved documents, suggest the most likely next question the user might ask.**Context:**
- Previous Queries:
{previous_queries}- Latest User Query: {user_query}- Retrieved Documents:
{retrieved_docs}**Guidelines:**
1. Do not suggest a question that has already been asked in previous queries.
2. Consider the retrieved documents when predicting the next logical question.
3. If the user's query is already fully answered, suggest a relevant follow-up question.
4. Keep the suggested question natural and conversational.
5. Suggest at least 3 questionSystem time: {system_time}"""

3. 更新 configuration.py

添加 predict_next_question_prompt

predict_next_question_prompt: str = field(default=prompts.PREDICT_NEXT_QUESTION_PROMPT,metadata={"description": "The system prompt used for generating responses."},)

4. 新 state.py

添加以下属性:

response: Annotated[Sequence[AnyMessage], add_messages]
next_question : Annotated[Sequence[AnyMessage], add_messages]

5. 重新运行 Retrieval Graph

再次输入以下搜索查询:

What was NovaTech Solutions total revenue in Q1 2025?

系统将处理输入并预测用户可能会问的三个相关问题,如下所示。

结论

在 LangGraph Studio 和 CLI 中集成 Retrieval Agent 模板提供了几个关键优势:

  • 加速开发:模板和可视化工具简化了检索工作流的创建和调试,减少了开发时间。
  • 无缝部署:内置对 API 和自动扩展的支持,确保在不同环境中的顺利部署。
  • 简易更新:修改工作流、添加新功能和集成额外节点变得简单,便于扩展和增强检索过程。
  • 持久化记忆:系统保留代理的状态和知识,提升一致性和可靠性。
  • 灵活的工作流建模:开发人员可以根据特定用例自定义检索逻辑和通信规则。
  • 实时交互和调试:能够与运行中的代理进行交互,有效进行测试和问题解决。

通过利用这些功能,组织可以构建强大、高效且可扩展的检索系统,增强数据访问性和用户体验。

该项目的完整源代码可在 GitHub 上找到。

原文:Build a powerful RAG workflow using LangGraph and Elasticsearch - Elasticsearch Labs


http://www.hkcw.cn/article/pVmJfwMkQn.shtml

相关文章

OpenEvidence AI临床决策支持工具平台研究报告

平台概述 OpenEvidence是一个专为医疗专业人士设计的临床决策支持工具,旨在通过整合各类临床计算器和先进的人工智能技术,提高医生的诊疗决策效率和准确性。作为一款综合性医疗平台,OpenEvidence将复杂的医学计算流程简化,同时提供个性化的临床建议,使医生能够更快、更准…

Python使用FastMCP开发MCP服务端

MCP简介 Model Context Protocol (MCP) 是一个专门为 LLM&#xff08;大语言模型&#xff09;应用设计的协议&#xff0c;它允许你构建服务器以安全、标准化的方式向 LLM 应用程序公开数据和功能。FastMCP 作为 Python 生态中的一款轻量级框架&#xff0c;利用装饰器来简化路由…

【科研绘图系列】R语言绘制GO term 富集分析图(enrichment barplot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理画图code 2code 3系统信息介绍 本文介绍了使用R语言绘制GO富集分析条形图的方法。通过加载ggplot2等R包,对GO term数据进行预处理,包括p值转换…

利用Flask来实现留言板的基本操作

留言板开发 一、相关技术介绍 本项目基于现代Web开发技术栈构建&#xff0c;采用Python 3.12作为后端开发语言&#xff0c;搭配轻量级Flask 2.3.2框架实现核心功能。数据库层使用Flask-SQLAlchemy ORM框架操作MySQL 8.0数据库&#xff0c;通过对象关系映射简化数据操作。用户…

vue3: tmap (腾讯地图)using typescript

项目结构&#xff1a; <!--* ___-_ _-___* _--^^^#####// \\#####^^^--_* _-^##########// ( ) \\##########^-_* -############// |\^^/| \\############-* _/############// (::) \############\_* …

【Linux】线程概念

&#x1f4dd;前言&#xff1a; 这篇文章我们来讲讲Linux——线程概念&#xff1a; 线程的基本概念线程的优缺点线程与进程 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;Linux &#x1f380;CSDN主页 愚润求学 &#x1f304;其他专栏&am…

技术文档撰写指南:从结构到细节的全流程解析

在技术领域&#xff0c;一份优质的技术文档不仅是项目成果的载体&#xff0c;更是技术思想的可视化表达。本文结合《汽车导航系统电路设计及故障分析》课程设计说明书&#xff0c;拆解技术文档的核心要素&#xff0c;提供可复用的撰写范式&#xff0c;助力技术内容高效传播。 …

如何用AI设计海报,DeepSeek+即梦免费批量生成

大家好&#xff0c;这里是K姐。 一个帮助你把AI真正用起来的女子。 佳节将至&#xff0c;还在为节日海报而苦恼吗&#xff1f; 520刚过&#xff0c;端午节、六一儿童节、618就接踵而至&#xff0c;满街满屏的海报让人眼花缭乱。 做自媒体电商以及实体店的小伙伴现在已经一个…

全国一体化算力体系建设:破解算力困局,赋能数字经济新未来​

在数字经济蓬勃发展的当下&#xff0c;算力作为核心生产力&#xff0c;正面临着前所未有的挑战与机遇。从 GPT3.5 到 GPT4 的升级&#xff0c;算力需求呈现跳跃式增长&#xff0c;需要至少提高 3 到 5 倍的算力&#xff0c;国内算力供应出现断层&#xff0c;难以满足当前需求。…

window安装nginx

步骤1&#xff1a;下载Nginx for Windows​ 访问Nginx官网下载页面&#xff1a;https://nginx.org/en/download.html 在​​Stable version​​&#xff08;稳定版&#xff09;下找到Windows版本&#xff0c;点击下载.zip文件&#xff08;如 nginx-1.28.0.zip&#xff09; 步…

秋招Day11 - JVM - 垃圾回收

讲讲JVM的垃圾回收机制 垃圾回收是指JVM对内存中已经死亡的&#xff0c;不再使用的对象进行清除或回收。 常见的垃圾回收算法有标记-复制&#xff0c;标记-整理&#xff0c;标记-清除&#xff0c;分代收集算法等 一般的垃圾回收。过程是先使用可达性分析算法得出内存中哪些对…

Deepseek应用技巧-Dify安装和踩坑指南

前言&#xff1a;Dify的名号是非常大的&#xff0c;作为私有化AI部署中必不可少的一个组件&#xff0c;他的功能和COZE十分相似&#xff0c;可以进行工作流和智能体的搭建&#xff0c;有非常强大的功能&#xff0c;那本节就将来揭开Dify的神秘的面纱&#xff0c;首先看一下Dify…

[python] argparse怎么指定bool类型?

前述 最近在写脚本的时候想要实现一个if 操作&#xff0c;通过用户输入。确定要不要启用某个语句。 非常自然的就是使用python的argparse包&#xff0c;但是发现了一个陷阱&#xff0c;记录下。 陷阱 argparse.ArgumentParser() 可以指定输入类型&#xff0c;我可以设定为bo…

尚硅谷redis7 86 redis集群分片之3主3从集群搭建

86 redis集群分片之3主集群搭建 3主3从redis集群配置 找3台真实虚拟机,各自新建 mķdir -p /myredis/cluster 新建6个独立的redis实例服务 IP:192.168.111.175端口6381/端口6382 vim /myredis/cluster/redisCluster6381.conf bind 0.0.0.0 daemonize yes protected-mode no …

交集、差集、反选

1.交集&#xff1a;两个ROI相交的部分 dev_open_window (0, 0, 512, 512, black, WindowHandle) read_image (Image, clip) threshold (Image, Region, 0, 128) * 交集 intersection (Circle1, Circle2, RegionIntersection) 最终效果如下图所示&#xff1a; 2.差集&#xff1a…

Flutter GridView网格组件

目录 常用属性 GridView使用配置 GridView.count使用 GridView.extent使用 GridView.count Container 实现列表 GridView.extent Container 实现列表 GridView.builder使用 GridView网格布局在实际项目中用的也是非常多的&#xff0c;当我们想让可以滚动的元素使用矩阵…

The 2020 ICPC Asia Yinchuan Regional Programming Contest

A. Best Player 关于投影到坐标轴上&#xff0c;投影到x轴上&#xff0c;确实如果两个点的y值一样&#xff0c;会导致重影&#xff0c;但不能只看只看y轴的影响&#xff0c;还有要注意输出。 #include<bits/stdc.h> using namespace std; typedef long long ll; const l…

寄存器模型

8.layering sequence &#xff08;1&#xff09;概述 转化&#xff1a;高抽象级item&#xff0c;中间的sequence&#xff0c;低抽象级item。 &#xff08;2&#xff09;寄存器模型的示意图 &#xff08;3&#xff09;示例代码&#xff1a;bus packet sequence &#xff08;4&…

Python训练营打卡Day39

DAY 39 图像数据与显存 知识点回顾 1.图像数据的格式&#xff1a;灰度和彩色数据 2.模型的定义 3.显存占用的4种地方 a.模型参数梯度参数 b.优化器参数 c.数据批量所占显存 d.神经元输出中间状态 4.batchisize和训练的关系 作业&#xff1a;今日代码较少&#xff0c;理解内容…

AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月29日第92弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀6-8个和值&#xff0c;可以做到100-300注左右。 (1)定…