使用 LangChain 和 Elasticsearch 开发一个 agentic RAG 助手

作者:来自 Elastic Kirti Sodhi

学习如何使用 LangChain 和 Elasticsearch 构建一个 agentic rag 新闻助手,通过自适应路由来回答关于文章的查询。

Agent Builder 现在作为技术预览提供。通过 Elastic Cloud Trial 开始使用,并在这里查看 Agent Builder 的文档。


这篇博客深入探讨了 agentic RAG 工作流,解释了它们的关键特性和常见设计模式。它进一步展示了如何通过一个使用 Elasticsearch 作为向量存储、使用 LangChain 构建 agentic RAG 框架的实践示例来实现这些工作流。最后,文章简要讨论了设计和实现此类架构的最佳实践和相关挑战。你可以通过这个 Jupyter notebook 跟着一起创建一个简单的 agentic RAG 管道。

Agentic RAG 简介

检索增强生成(RAG)已成为基于 LLM 的应用程序的基石,它通过根据用户查询检索相关上下文,使模型能够提供最佳答案。RAG 系统通过利用来自 API 或数据存储的外部信息来增强 LLM 响应的准确性和上下文,而不是受限于预训练 LLM 的知识。另一方面,AI agents 能够自主运行,做出决策并采取行动以实现其既定目标。

Agentic RAG 是一个将检索增强生成和 agentic 推理优势统一起来的框架。它将 RAG 集成到 agent 的决策过程中,使系统能够动态选择数据源、优化查询以获得更好的上下文检索、生成更准确的响应,并应用反馈循环来持续改进输出质量。

Agentic RAG 的关键特性

Agentic RAG 框架是对传统 RAG 系统的一次重大提升。它不是遵循固定的检索流程,而是利用能够实时规划、执行和优化结果的动态 agents。

下面来看一些使 agentic RAG 管道与众不同的关键特性:

  • 动态决策:agentic RAG 使用推理机制来理解用户意图,并将每个查询路由到最相关的数据源,从而生成准确且具有上下文意识的响应。
  • 全面的查询分析:agentic RAG 深入分析用户查询,包括子问题及其整体意图。它评估查询的复杂性,并动态选择最相关的数据源来检索信息,以确保响应准确且完整。
  • 多阶段协作:该框架通过一个专业 agents 网络实现多阶段协作。每个 agent 处理一个更大目标中的特定部分,可以顺序或同时工作,以实现统一的结果。
  • 自我评估机制:agentic RAG 管道使用自我反思来评估检索到的文档和生成的响应。它可以检查检索的信息是否完全回答了查询,然后审核输出的准确性、完整性和事实一致性。
  • 与外部工具集成:该工作流可以与外部 API、数据库和实时信息源交互,整合最新信息并根据不断变化的数据动态适应。

Agentic RAG 的工作流模式

这些工作流模式定义了 agentic AI 如何以可靠且高效的方式构建、管理和编排基于 LLM 的应用程序。LangChainLangGraphCrewAILlamaIndex 等多个框架和平台都可以用来实现这些 agentic 工作流。

  • 顺序检索链:顺序工作流将复杂任务拆分为简单且有序的步骤。每一步都会改进下一步的输入,从而得到更好的结果。例如,在创建客户档案时,一个 agent 可能从 CRM 中提取基本信息,另一个从交易数据库中检索购买历史,最后一个 agent 将这些信息合并,生成用于推荐或报告的完整档案。
  • 路由检索链:在这种工作流模式中,一个路由 agent 会分析输入并将其指向最合适的流程或数据源。当存在多个彼此重叠很少的不同数据源时,这种方法特别有效。例如,在客户服务系统中,路由 agent 会对接收到的请求进行分类,如技术问题、退款或投诉,并将其路由到适当的部门以高效处理。
  • 并行检索链:在这种工作流模式中,多个独立的子任务会同时执行,随后它们的输出会被聚合来生成最终响应。这种方法能显著减少处理时间并提高工作流效率。例如,在客户服务的并行工作流中,一个 agent 检索类似的历史请求,另一个咨询相关的知识库文章。一个聚合器随后将这些输出合并,以生成全面的解决方案。
  • 编排者---工作者链:这种工作流由于利用了独立子任务,与并行化相似。然而一个关键区别在于其引入了一个编排者 agent。这个 agent 负责分析用户查询,在运行时动态地将其分解为子任务,并识别生成准确响应所需的合适流程或工具。

从零构建一个 agentic RAG 管道

为了说明 agentic RAG 的原理,我们来设计一个使用 LangChain 和 Elasticsearch 的工作流。该工作流采用基于路由的架构,多个 agents 协同工作来分析查询、检索相关信息、评估结果并生成连贯的响应。你可以参考这个 Jupyter notebook 跟着示例操作。

工作流从 router agent 开始,该 agent 分析用户的查询以选择最优的检索方法,即使用 vectorstore 、 websearch 或 composite 方法。 vectorstore 负责传统基于 RAG 的文档检索, websearch 获取未存储在 vectorstore 中的最新信息,而 composite 方法在需要来自多个来源的信息时将两者结合。

如果文档被认为合适, summarization agent 会生成清晰且符合上下文的响应。然而,如果文档不足或不相关, query rewriting agent 会重写查询以改进搜索。然后该修订后的查询会重新启动路由流程,使系统能够改进搜索并提升最终输出质量。

先决条件

此工作流依赖以下核心组件来有效执行示例:

在继续之前,你会被提示为此示例配置以下所需的环境变量。

复制代码
AZURE_OPENAI_ENDPOINT="Add your azure openai endpoint"
AZURE_OPENAI_KEY="Add your azure openai key"
AZURE_OPENAI_DEPLOYMENT="gpt-4.1"
AZURE_OPENAI_API_VERSION="Add your azure openai api version"

ES_ENDPOINT = "Add your Elasticsearch ENDPOINT"
ES_API_KEY = "Add your Elasticsearch API KEY"

数据源

此工作流使用 AG News 数据集的一个子集进行演示。该数据集包含来自多个类别的新闻文章,如 International、Sports、Business 和 Science/Technology。

复制代码
dataset = load_dataset("ag_news", split="train[:1000]")
docs = [
    Document(
        page_content=sample["text"],
        metadata={"category": sample["label"]}
    )
    for sample in dataset
]

我们使用 langchain_elasticsearch 的 ElasticsearchStore 模块作为向量存储。在检索时,我们实现了 SparseVectorStrategy ,使用 ELSER,这是 Elastic 的专有嵌入模型。在启动向量存储之前,必须确认 ELSER 模型已在你的 Elasticsearch 环境中正确安装和部署。

复制代码
elastic_vectorstore = ElasticsearchStore.from_documents(
    docs,
    es_url=ES_ENDPOINT,
    es_api_key=ES_API_KEY,
    index_name=index_name,
    strategy=SparseVectorStrategy(model_id=".elser_model_2"),
)

elastic_vectorstore.client.indices.refresh(index=index_name)

Web 搜索功能使用 LangChain 社区工具中的 DuckDuckGoSearchRun 实现,它允许系统高效地从网络检索实时信息。你也可以考虑使用其他可能提供更相关结果的搜索 API。选择此工具的原因是它允许无需 API key 即可进行搜索。

复制代码
duckduckgo = DuckDuckGoSearchRun(description= "A custom DuckDuckGo search tool for finding latest news stories.", verbose=True)
def websearch_retriever(query):
    results = duckduckgo.run(f"{query}")
    return results

Composite retriever 设计用于需要组合多种来源的查询。它通过同时从网络检索实时数据和从向量存储查询历史新闻,提供全面且符合上下文的准确响应。

复制代码
def composite_retriever(query):
    related_docs = vectorstore_retriever(query)
    related_docs += websearch_retriever(query)
    return related_docs

设置 agents

下一步,定义 LLM agents,以在该工作流中提供推理和决策能力。我们将创建的 LLM chains 包括: router_chain 、 grade_docs_chain 、 rewrite_query_chain 和 summary_chain 。

router agent 使用 LLM assistant 来在运行时确定给定查询的最合适数据源。grading agent 评估检索到的文档的相关性。如果文档被认为相关,它们会被传递给 summary agent 生成摘要。否则,rewrite query agent 会重写查询并将其发送回路由流程进行另一轮检索。你可以在 notebook 的 LLM chains 部分找到所有 agents 的说明。

复制代码
class RouteQuery(BaseModel):
    datasource: Literal["vectorstore", "websearch", "composite"] = Field(
        ...,
        description="Choose to route the query to web search, vectorstore or composite."
    )

router_prompt = ChatPromptTemplate.from_template("""You are an assistant that decides the best data source for questions based on news articles.
Choose one of the following options:
- 'vectorstore': for general, background, or historical news articles.
- 'websearch': for recent discoveries, 'latest', 'current', or '2025' type queries.
- 'composite': when the question needs both historical and current knowledge on news articles.

Question: {query}

Return one word: 'vectorstore', 'websearch', or 'composite'.
""")
router_structured = llm.with_structured_output(RouteQuery)
router_chain: RunnableSequence = router_prompt | router_structured

llm.with_structured_output 将模型的输出限制为遵循 RouteQuery 类下 BaseModel 定义的预定义 schema,确保结果的一致性。第二行通过将 router_prompt 与 router_structured 连接,组成一个 RunnableSequence ,形成一个管道,其中输入的 prompt 会被语言模型处理,以生成结构化、符合 schema 的结果。

定义图节点

这一部分涉及定义图的状态,这些状态表示系统不同组件之间流动的数据。清晰地指定这些状态可以确保工作流中的每个节点都知道它可以访问和更新哪些信息。

复制代码
class RAGState(TypedDict):
    query: str
    docs: List[Document]
    router: str
    summary: str
    self_reflection: bool
    retry_count: int = 0

在定义状态之后,下一步是定义图的节点。节点就像图的功能单元,对数据执行特定操作。我们的管道中有 7 个不同的节点。

复制代码
def router(state: RAGState):
   router = router_chain.invoke({'query': state["query"]})
   logger.info(f"Router selected the datasource: {router.datasource}")
   logger.info(f"User query: {state['query']}")
   return {"router": router.datasource}

def vectorstore(state: RAGState):
   return {"docs": vectorstore_retriever(state["query"])}

def websearch(state: RAGState):
   return {"docs": websearch_retriever(state["query"])}

def composite(state: RAGState):
   return {"docs": composite_retriever(state["query"])}

def self_reflection(state: RAGState):
   evaluation = grade_docs_chain.invoke(
       {"query": state["query"], "docs": state["docs"]}
   )
   if evaluation.binary_score:
       logger.info(f"Self-reflection passed -- binary_score={evaluation.binary_score}")
   else:
       logger.info(f"Self-reflection failed -- binary_score={evaluation.binary_score}")

   return {
       "self_reflection": evaluation.binary_score,
   }

def query_rewriter(state: RAGState):
   retry_count = state.get("retry_count", 0) + 1
   new_query = rewrite_query_chain.invoke({"query": state["query"]})
   logger.info(f"Query rewritten: {new_query}, retry_count: {retry_count}")
   return {
       "query": new_query,
       "retry_count": retry_count,
   }

def summarize(state: RAGState):
   summary = summarize_chain.run(
       query=state["query"],
       docs=state["docs"],
   )
   return {"summary": summary}

query_rewriter 节点在工作流中有两个作用。首先,当 self-reflection agent 评估的文档被认为不足或不相关时,它使用 rewrite_query_chain 重写用户查询以改进检索。其次,它作为一个计数器,跟踪查询被重写的次数。

每次调用该节点时,会增加存储在工作流状态中的 retry_count 。此机制防止工作流进入无限循环。如果 retry_count 超过预定义阈值,系统可以回退到错误状态、默认响应或你选择的任何其他预定义条件。

编译图

最后一步是定义图的边并在编译之前添加必要的条件。每个图必须从指定的起始节点开始,该节点作为工作流的入口点。图中的边表示节点之间的数据流,可以分为两种类型:

  • 直线边:定义从一个节点到另一个节点的直接、无条件流。当第一个节点完成任务后,工作流会沿着直线边自动继续到下一个节点。

  • 条件边:允许工作流根据当前状态或节点计算结果进行分支。下一个节点会根据条件动态选择,例如评估结果、路由决策或重试次数。

    graph.add_edge(START, "router")

    def after_router(state: RAGState):
    route = state.get("router", None)
    if route == "vectorstore":
    return "vectorstore"
    elif route == "websearch":
    return "websearch"
    else:
    return "composite"

    def after_self_reflection(state: RAGState):
    if state["self_reflection"]:
    return "summarize"
    return "query_rewriter"

    def after_query_rewriter(state: RAGState):
    while state['retry_count'] <= 3:
    return "router"
    raise RuntimeError("Maximum retries (3) reached -- evaluation failed.")

    graph.add_conditional_edges(
    "router",
    after_router,
    {
    "vectorstore": "vectorstore",
    "websearch": "websearch",
    "composite": "composite"
    }
    )

    graph.add_edge("vectorstore", "self_reflection")
    graph.add_edge("websearch", "self_reflection")
    graph.add_edge("composite", "self_reflection")
    graph.add_conditional_edges(
    "self_reflection",
    after_self_reflection,
    {
    "summarize": "summarize",
    "query_rewriter": "query_rewriter"
    }
    )
    graph.add_conditional_edges("query_rewriter", after_query_rewriter, {"router": "router"})
    graph.add_edge("summarize", END)
    agent=graph.compile()

至此,你的第一个 agentic RAG 管道已准备就绪,可以使用已编译的 agent 进行测试。

复制代码
result = agent.invoke({"query": query1})
logger.info(f"\nFinal Summary:\n: {result['summary']}")

测试 agentic RAG 管道

我们现在将使用以下三种不同类型的查询来测试此管道。注意,结果可能会有所不同,下列示例仅展示一种可能的结果。

复制代码
query1="What are the latest AI models released this month?"
query2="What technological innovations are discussed in Sci/Tech news?"
query3="Compare a Sci/Tech article from the dataset with a current web article about AI trends."

对于第一个查询,router 选择 websearch 作为数据源。该查询未通过 self-reflection 评估,随后被重定向到 query rewriting 阶段,如输出所示。

复制代码
INFO     | __main__:router:11 - Router selected the datasource: websearch
INFO     | __main__:router:12 - User query: What are the latest AI models released this month?
INFO     | __main__:self_reflection:31 - Self-reflection failed -- binary_score=False
INFO     | __main__:query_rewriter:40 - Query rewritten: query='Which AI models have been officially released in June 2024?', retry_count: 1
INFO     | __main__:router:11 - Router selected the datasource: websearch
INFO     | __main__:router:12 - User query: query='Which AI models have been officially released in June 2024?'
Dream Machine is a text-to-video model created by Luma Labs and launched in June 2024 . It generates video output based on user prompts or still images. Dream Machine has been noted for its ability to realistically capture motion... Released in June 2023. In June 2024 , Baidu announced Ernie 4.0 Turbo. In April 2025, Ernie 4.5 Turbo and X1 Turbo were released . These models are optimized for faster response times and lower operational costs.[28][29]. The meaning of QUERY is question, inquiry. How to use query in a sentence. Synonym Discussion of Query. QUERY definition: 1. a question, often expressing doubt about something or looking for an answer from an authority.... Learn more. Query definition: a question; an inquiry.. See examples of QUERY used in a sentence.
INFO     | __main__:self_reflection:29 - Self-reflection passed -- binary_score=True
INFO     | __main__:<module>:2 - 
Final Summary:
: In June 2024, two AI models were officially released: Dream Machine, a text-to-video model launched by Luma Labs, and Ernie 4.0 Turbo, announced by Baidu, which is optimized for faster response times and lower operational costs.

接下来,我们来看一个使用 vectorstore 检索的示例,通过第二个查询演示。

复制代码
INFO     | __main__:router:11 - Router selected the datasource: vectorstore
INFO     | __main__:router:12 - User query: What technological innovations are discussed in Sci/Tech news?
INFO     | __main__:self_reflection:29 - Self-reflection passed -- binary_score=True
INFO     | __main__:<module>:2 - 
Final Summary:
: Recent Sci/Tech news highlights several technological innovations: NASA is collaborating with Silicon Valley firms to build a powerful Linux-based supercomputer to support theoretical research and shuttle engineering; new chromatin transfer techniques have enabled the cloning of cats; cybersecurity advancements are being discussed in relation to protecting personal technology; Princeton University scientists assert that existing technologies can be used immediately to stabilize global warming; and a set of GameBoy micro-games has been recognized for innovation in game design.

最后的查询被引导到 composite retrieval,该方法同时使用 vectorstore 和 web search。

复制代码
INFO     | __main__:router:11 - Router selected the datasource: composite
INFO     | __main__:router:12 - User query: Compare a Sci/Tech article from the dataset with a current web article about AI trends.
Atlas currently only available on macOS, built on Chromium with planned features like ad-blocking still in development. OpenAI's Atlas browser launched with bold promises of AI -powered web browsing, but early real-world testing reveals a different story. Career-long data are updated to end-of-2024 and single recent year data pertain to citations received during calendar year 2024. The selection is based on the top 100,000 scientists by c-score (with and without self-citations) or a percentile rank of 2% or above in the sub-field. In this article I list 45 AI tools across 21 different categories. After exploring all the available options in each category, I've carefully selected the best tools based on my personal experience. Reading a complex technical article ? Simply highlight confusing terminology and ask "what's this?" to receive instant explanations. compare browsers. Comparison showing traditional browser navigation versus OpenAI Atlas AI -powered workflows. After putting Gemini, ChatGPT, Grok, and DeepSeek through rigorous testing in October 2025, it's clear that there isn't one AI that reigns supreme across all categories.
INFO     | __main__:self_reflection:29 - Self-reflection passed -- binary_score=True
INFO     | __main__:<module>:2 - 
Final Summary:
: A Sci/Tech article from the dataset highlights NASA's development of robust artificial intelligence software for planetary rovers, aiming to make them more self-reliant and capable of decision-making during missions. In contrast, a current web article about AI trends focuses on the proliferation of AI-powered tools across various categories, including browsers like OpenAI Atlas, and compares leading models such as Gemini, ChatGPT, Grok, and DeepSeek, noting that no single AI currently excels in all areas. While the NASA article emphasizes specialized AI applications for autonomous robotics in space exploration, the current trends article showcases the broadening impact of AI across consumer and professional technologies, with ongoing competition and rapid innovation among major AI platforms.

在上述工作流中,agentic RAG 能智能地确定在检索用户查询信息时使用哪个数据源,从而提高响应的准确性和相关性。你可以创建更多示例来测试 agent 并查看输出,以判断是否产生有趣的结果。

构建 agentic RAG 工作流的最佳实践

现在我们了解了 agentic RAG 的工作原理,让我们来看一些构建这些工作流的最佳实践。遵循这些指南可以帮助系统保持高效并易于维护。

  • 准备回退方案:提前为工作流中任何步骤失败的场景规划回退策略。这些策略可以包括返回默认答案、触发错误状态或使用替代工具。这样可以确保系统在遇到故障时仍能优雅处理,不破坏整体工作流。
  • 实现全面日志记录:尝试在工作流的每个阶段实现日志记录,例如重试、生成输出、路由选择和查询重写。这些日志有助于提高透明度、便于调试,并随着时间推移优化 prompts、agent 行为和检索策略。
  • 选择合适的工作流模式:根据你的用例选择最适合的工作流模式。顺序工作流适用于逐步推理, 并行工作流适用于独立数据源,编排者---工作者模式适用于多工具或复杂查询。
  • 纳入评估策略:在工作流的不同阶段整合评估机制。这可以包括 self-reflection agents、对检索文档的评分或自动质量检查。评估有助于验证检索文档的相关性、响应的准确性以及复杂查询的各个部分是否被覆盖。

挑战

虽然 agentic RAG 系统在适应性、精确性和动态推理方面具有显著优势,但在设计和实施阶段也存在需要解决的挑战。一些关键挑战包括:

  • 复杂工作流:随着更多 agent 和决策点的加入,整体工作流变得越来越复杂,这可能导致运行时错误或失败的概率增加。尽可能通过消除冗余 agent 和不必要的决策点来优先简化工作流。
  • 可扩展性:将 agentic RAG 系统扩展以处理大型数据集和高查询量可能具有挑战性。需采用高效的索引、缓存和分布式处理策略以保持规模下的性能。
  • 编排和计算开销:执行包含多个 agent 的工作流需要高级编排,包括仔细的调度、依赖管理和 agent 协作,以防止瓶颈和冲突,这些都会增加系统复杂性。
  • 评估复杂性:评估这些工作流存在固有挑战,每个阶段都需要不同的评估策略。例如,RAG 阶段需评估检索文档的相关性和完整性,而生成的摘要需检查质量和准确性。同样,查询重写的有效性需要单独的评估逻辑来判断重写后的查询是否改进了检索结果。

结论

在这篇博客中,我们介绍了 agentic RAG 的概念,并强调了它通过引入 agentic AI 的自主能力增强了传统 RAG 框架。我们探索了 agentic RAG 的核心特性,并通过一个实践示例展示了这些特性 ------ 使用 Elasticsearch 作为向量存储,并用 LangChain 构建 agentic 框架,创建了一个新闻助手。

此外,我们讨论了设计和实施 agentic RAG 管道时应考虑的最佳实践和关键挑战。这些见解旨在指导开发者创建稳健、可扩展且高效的 agentic 系统,有效结合检索、推理和决策能力。

接下来

我们构建的工作流较为简单,还有很大的改进和实验空间。我们可以通过尝试不同的嵌入模型和优化检索策略来增强它。此外,集成一个 re-ranking agent 来优先排序检索到的文档可能会有帮助。另一个探索方向是为 agentic 框架开发评估策略,特别是识别可在不同类型框架中通用的常用方法。最后,可以在更大和更复杂的数据集上实验这些框架。

与此同时,如果你有类似的实验想分享,我们很乐意了解!欢迎通过我们的社区 Slack 频道讨论论坛提供反馈或交流。

资源

原文:https://www.elastic.co/search-labs/blog/agentic-rag-news-assistant-langchain-elasticsearch

相关推荐
我很哇塞耶38 分钟前
从检索到生成全优化:ACL 2025 新方法 DRAG,复杂查询 RAG 新救星
人工智能·ai·大模型·rag·检索增强生成
YJlio41 分钟前
[鸿蒙2025领航者闯关] 基于鸿蒙 6 的「隐私感知跨设备办公助手」实战:星盾安全 + AI防窥 + 方舟引擎优化全流程复盘
人工智能·安全·harmonyos
ghie909043 分钟前
线性三角波连续调频毫米波雷达目标识别
人工智能·算法·计算机视觉
学习中的数据喵1 小时前
可以看穿事物“本质“的LDA
人工智能·机器学习
j***12151 小时前
Java进阶(ElasticSearch的安装与使用)
java·elasticsearch·jenkins
fj_changing1 小时前
Ubuntu 22.04部署CosyVoice
人工智能·python·深度学习·ubuntu·ai
z***02601 小时前
Python大数据可视化:基于大数据技术的共享单车数据分析与辅助管理系统_flask+hadoop+spider
大数据·python·信息可视化
on_pluto_1 小时前
【debug】解决 conda 和 镜像下载pytorch太慢的问题
人工智能·pytorch·conda
GIS程序媛—椰子1 小时前
从后端到 AI/Agent:那些可迁移的系统思维(未完结)
人工智能·后端