标准检索增强生成遵循可预测的线性路径:接收查询,检索相关文档,然后生成响应。在许多情况下,这可能足以解决特定问题。在最糟糕的情况下,你的 LLM 会因为上下文没有提供足够的信息而决定不回答问题。

另一方面,我们有智能体。这些系统被赋予了更大的行动自由,可以采取多个非线性步骤来实现某个目标。智能体的定义并不单一,但一般来说,它是一个使用 LLM 并通常使用一些工具与外部世界通信的应用程序。LLM 被用作决策者,决定下一步采取什么行动。行动可以是任何事情,但它们通常是明确定义并限制在一定范围内的可能性。其中一个行动可能是查询向量数据库(如 Qdrant)以检索相关文档,如果上下文不足以做出决策。然而,RAG 只是智能体工具库中的一个工具。

Agentic RAG:将 RAG 与智能体结合
由于智能体的定义是模糊的,所以Agentic RAG的概念也未明确定义。一般来说,它指的是 RAG 与智能体的结合。这使得智能体可以使用外部知识源来做出决策,并且主要是决定何时需要外部知识。如果一个系统打破了标准 RAG 系统的线性流程,并赋予智能体采取多个步骤来达到目标的能力,我们就可以将其描述为 Agentic RAG。
一个简单的路由器,选择要遵循的路径,通常被描述为智能体最简单的形式。这样的系统有多个路径,带有描述何时走某条路径的条件。在 Agentic RAG 的背景下,如果上下文不足以回答问题,智能体可以决定查询向量数据库;如果足够,或者问题涉及常识,则跳过查询。或者,可能有多个集合存储不同类型的信息,智能体可以根据上下文决定查询哪个集合。关键因素是选择路径的决策由 LLM 做出,而 LLM 是智能体的核心。路由智能体从不回到上一步,所以它最终只是一个条件决策系统。

然而,路由仅仅是个开始。智能体可以复杂得多,而极端形式的智能体可以拥有完全的行动自由。在这种情况下,智能体被赋予一套工具,并可以自主决定使用哪些工具、如何使用它们以及以何种顺序使用。LLM 被要求规划和执行行动,智能体可以采取多个步骤来实现目标,包括在需要时回溯。这样的系统不必遵循有向无环图(DAG)结构,可以有循环来帮助自我纠正过去的决策。以这种方式构建的 Agentic RAG 系统不仅可以拥有查询向量数据库的工具,还可以操作查询、总结结果,甚至生成新数据来回答问题。选择是无限的,但我们可以观察到一些常见的模式。

使用 LLM 解决信息检索问题
一般来说,Agentic RAG 系统中公开的工具用于解决信息检索问题,这些问题对搜索社区来说并不陌生。LLM 改变了我们处理这些问题的方式,但问题的核心保持不变。在 Agentic RAG 中可以考虑使用哪些工具?以下是一些示例:
- 查询向量数据库 - Agentic RAG 系统中最常用的工具。它允许智能体根据查询检索相关文档。
- 查询扩展 - 可用于改进查询的工具。它可以用于添加同义词、纠正错别字,甚至根据原始查询生成新查询。

- 提取过滤器 - 仅凭向量搜索有时是不够的。在许多情况下,你可能希望根据特定参数缩小结果范围。此提取过程可以自动从查询中识别相关条件。否则,你的用户将不得不手动定义这些搜索限制。

- 质量判断 - 了解给定查询结果的质量可以用来决定它们是否足以回答问题,或者智能体是否应该采取另一步来以某种方式改进它们。或者,它也可以承认未能提供好的响应。

这些只是其中一些示例,但列表并不详尽。例如,您的 LLM 可能会操作 Qdrant 搜索参数或选择不同的查询方法。举个例子?如果您的用户使用某些特定关键字进行搜索,您可能更喜欢稀疏向量而不是密集向量,因为在这种情况下它们更高效。在这种情况下,您必须为您的智能体配备工具,以决定何时使用稀疏向量以及何时使用密集向量。了解集合结构的智能体可以轻松做出此类决策。
这些工具中的每一个本身都可能是一个独立的智能体,多智能体系统并不少见。在这种情况下,智能体可以相互通信,一个智能体可以决定使用另一个智能体来解决特定问题。Agentic RAG 中一个非常有用的组成部分是人工参与,它可以用来纠正智能体的决策,或者将其引导到正确的方向。
智能体在何处使用?
智能体是一个有趣的概念,但由于它们严重依赖 LLM,因此并非适用于所有问题。使用大型语言模型成本高昂且速度往往很慢,在许多情况下,不值得付出成本。标准 RAG 只涉及一次 LLM 调用,并且响应以可预测的方式生成。另一方面,智能体可以采取多个步骤,用户体验到的延迟会累积。在许多情况下,这是不可接受的。Agentic RAG 可能不广泛适用于电子商务搜索,用户期望快速响应;但可能适用于客户支持,用户愿意等待更长时间以获得更好的答案。
哪个框架最好?
有许多可用于构建智能体的框架,选择最好的一个并非易事。这取决于你现有的技术栈或你熟悉的工具。一些最流行的 LLM 库已经转向了智能体范式,并提供了构建它们的工具。然而,也有一些工具主要是为智能体开发而构建的,所以让我们重点关注它们。
LangGraph
由 LangChain 团队开发的 LangGraph,对于那些已经使用 LangChain 构建 RAG 系统并希望开始使用 Agentic RAG 的人来说,似乎是一个自然的扩展。
令人惊讶的是,LangGraph 本身与大型语言模型毫无关系。它是一个用于构建基于图的应用程序的框架,其中每个节点都是工作流的一个步骤。每个节点都以应用程序状态作为输入,并产生一个修改后的状态作为输出。然后该状态被传递到下一个节点,依此类推。节点之间的边可以是条件性的,这使得分支成为可能。与某些基于 DAG 的工具(例如 Apache Airflow)不同,LangGraph 允许图中存在循环,这使得实现循环工作流成为可能,因此智能体可以实现自我反思和自我纠正。理论上,LangGraph 可以用于以基于图的方式构建任何类型的应用程序,而不仅仅是 LLM 智能体。
LangGraph 的一些优点包括:
- 持久性 - 工作流图的状态作为检查点存储。这发生在每个所谓的超级步骤(即图的单个顺序节点)中。它支持重播工作流的某些步骤、容错以及包括人工交互。此机制还充当短期内存,可在特定工作流执行的上下文中访问。
- 长期记忆 - LangGraph 也有记忆的概念,这些记忆在不同的工作流运行之间共享。然而,这种机制必须由我们的节点明确处理。Qdrant 及其语义搜索能力常被用作长期记忆层。
- 多智能体支持 - 尽管 LangGraph 中没有单独的多智能体系统概念,但可以通过构建一个包含多个智能体和某种协调器(它决定在给定情况下使用哪个智能体)的图来创建这样的架构。如果一个节点可以是任何东西,那么它也可以是另一个智能体。
LangGraph 的其他一些有趣功能包括可视化图表、自动化失败步骤的重试以及包含人工交互的能力。
Agentic RAG 的一个最小示例可以改进用户查询,例如通过修复拼写错误、使用同义词扩展它,甚至根据原始查询生成新查询。然后,智能体可以根据改进后的查询从向量数据库中检索文档,并生成响应。实现此方法的 LangGraph 应用程序可能如下所示:
from typing import Sequence
from typing_extensions import TypedDict, Annotated
from langchain_core.messages import BaseMessage
from langgraph.constants import START, END
from langgraph.graph import add_messages, StateGraph
class AgentState(TypedDict):
# The state of the agent includes at least the messages exchanged between the agent(s)
# and the user. It is, however, possible to include other information in the state, as
# it depends on the specific agent.
messages: Annotated[Sequence[BaseMessage], add_messages]
def improve_query(state: AgentState):
...
def retrieve_documents(state: AgentState):
...
def generate_response(state: AgentState):
...
# Building a graph requires defining nodes and building the flow between them with edges.
builder = StateGraph(AgentState)
builder.add_node("improve_query", improve_query)
builder.add_node("retrieve_documents", retrieve_documents)
builder.add_node("generate_response", generate_response)
builder.add_edge(START, "improve_query")
builder.add_edge("improve_query", "retrieve_documents")
builder.add_edge("retrieve_documents", "generate_response")
builder.add_edge("generate_response", END)
# Compiling the graph performs some checks and prepares the graph for execution.
compiled_graph = builder.compile()
# Compiled graph might be invoked with the initial state to start.
compiled_graph.invoke({
"messages": [
("user", "Why Qdrant is the best vector database out there?"),
]
})
过程的每个节点都只是一个执行特定操作的 Python 函数。如果你愿意,可以在其中调用你选择的 LLM,但它不假设消息是由任何 AI 创建的。LangGraph 更像一个运行时,它以特定顺序启动这些函数,并在它们之间传递状态。虽然LangGraph与 LangChain 生态系统集成良好,但它可以独立使用。对于寻求额外支持和功能的团队,还有一个名为 LangGraph Platform 的商业产品。该框架适用于 Python 和 JavaScript 环境,因此可以在不同的技术栈中使用。
CrewAI
CrewAI 是构建智能体(包括 Agentic RAG)的另一个热门选择。它是一个高级框架,假定有一些基于 LLM 的智能体协同工作以实现共同目标。CrewAI 中的“crew”一词便来源于此。CrewAI 的设计考虑了多智能体系统。与 LangGraph 不同,开发者不创建处理图,而是定义智能体及其在团队中的角色。
CrewAI 的一些核心概念包括
- 智能体 - 一个由 LLM 控制,具有特定角色和目标的单元。它可以选择使用一些外部工具与外部世界通信,但通常由我们提供给 LLM 的提示引导。
- 流程 - 目前分为顺序或分层。它定义了智能体如何执行任务。在顺序流程中,智能体一个接一个地执行;而在分层流程中,智能体由管理者智能体选择,管理者智能体负责决定在给定情况下使用哪个智能体。
- 角色与目标 - 每个智能体在团队中都有特定的角色,以及它应该努力实现的目标。这些是在我们定义智能体时设置的,并用于决定在给定情况下使用哪个智能体。
- 记忆 - 一个广泛的记忆系统,包括短期记忆、长期记忆、实体记忆和结合了其他三种记忆的上下文记忆。还有用于偏好和个性化的用户记忆。这就是 Qdrant 发挥作用的地方,因为它可以用作长期记忆层。
CrewAI 提供了一套丰富且集成到框架中的工具。对于那些希望将 RAG 与例如代码执行或图像生成结合的人来说,这可能是一个巨大的优势。生态系统非常丰富,但引入自己的工具也不是什么大问题,因为 CrewAI 的设计是可扩展的。
一个用 CrewAI 实现的简单 Agentic RAG 应用可能看起来像这样:
from crewai import Crew, Agent, Task
from crewai.memory.entity.entity_memory import EntityMemory
from crewai.memory.short_term.short_term_memory import ShortTermMemory
from crewai.memory.storage.rag_storage import RAGStorage
class QdrantStorage(RAGStorage):
...
response_generator_agent = Agent(
role="Generate response based on the conversation",
goal="Provide the best response, or admit when the response is not available.",
backstory=(
"I am a response generator agent. I generate "
"responses based on the conversation."
),
verbose=True,
)
query_reformulation_agent = Agent(
role="Reformulate the query",
goal="Rewrite the query to get better results. Fix typos, grammar, word choice, etc.",
backstory=(
"I am a query reformulation agent. I reformulate the "
"query to get better results."
),
verbose=True,
)
task = Task(
description="Let me know why Qdrant is the best vector database out there.",
expected_output="3 bullet points",
agent=response_generator_agent,
)
crew = Crew(
agents=[response_generator_agent, query_reformulation_agent],
tasks=[task],
memory=True,
entity_memory=EntityMemory(storage=QdrantStorage("entity")),
short_term_memory=ShortTermMemory(storage=QdrantStorage("short-term")),
)
crew.kickoff()
免责声明:QdrantStorage 不是 CrewAI 框架的一部分,但它取自 Qdrant 文档中关于如何将 Qdrant 与 CrewAI 集成的部分。
尽管它不是一个技术优势,但 CrewAI 拥有出色的文档。该框架适用于 Python,并且易于上手。CrewAI 还提供商业产品 CrewAI Enterprise,它提供了一个平台,用于大规模构建和部署智能体。
AutoGen
AutoGen 强调多智能体架构作为其基本设计原则。该框架要求任何系统中至少有两个智能体才能真正称之为智能体应用程序——通常是助手和用户代理交换消息以实现共同目标。还支持两个以上智能体的顺序聊天,以及用于内部对话的群聊和嵌套聊天。然而,AutoGen 不假定智能体之间存在结构化状态传递,聊天对话是它们之间通信的唯一方式。
该框架中有许多有趣的概念,其中一些甚至相当独特
- 工具/函数 - 智能体可用于与外部世界通信的外部组件。它们被定义为 Python 可调用对象,可用于我们希望智能体执行的任何外部交互。类型注解用于定义工具的输入和输出,并支持 Pydantic 模型以实现更复杂的类型模式。AutoGen 目前仅支持 OpenAI 兼容的工具调用 API。
- 代码执行器 - 内置代码执行器包括本地命令、Docker 命令和 Jupyter。智能体可以编写和启动代码,因此理论上智能体可以完成任何 Python 可以完成的事情。其他框架都没有使代码生成和执行如此突出。代码执行在 AutoGen 中作为一等公民是一个有趣的概念。
每个 AutoGen 智能体至少使用以下组件之一:人工参与、代码执行器、工具执行器或 LLM。一个简单的 Agentic RAG,基于两个智能体的对话,它们可以从向量数据库中检索文档,或改进查询,可能看起来像这样:
from os import environ
from autogen import ConversableAgent
from autogen.agentchat.contrib.retrieve_user_proxy_agent import RetrieveUserProxyAgent
from qdrant_client import QdrantClient
client = QdrantClient(...)
response_generator_agent = ConversableAgent(
name="response_generator_agent",
system_message=(
"You answer user questions based solely on the provided context. You ask to retrieve relevant documents for "
"your query, or reformulate the query, if it is incorrect in some way."
),
description="A response generator agent that can answer your queries.",
llm_config={"config_list": [{"model": "gpt-4", "api_key": environ.get("OPENAI_API_KEY")}]},
human_input_mode="NEVER",
)
user_proxy = RetrieveUserProxyAgent(
name="retrieval_user",
llm_config={"config_list": [{"model": "gpt-4", "api_key": environ.get("OPENAI_API_KEY")}]},
human_input_mode="NEVER",
retrieve_config={
"task": "qa",
"chunk_token_size": 2000,
"vector_db": "qdrant",
"db_config": {"client": client},
"get_or_create": True,
"overwrite": True,
},
)
result = user_proxy.initiate_chat(
response_generator_agent,
message=user_proxy.message_generator,
problem="Why Qdrant is the best vector database out there?",
max_turns=10,
)
对于刚接触智能体开发的人来说,AutoGen 提供了 AutoGen Studio,一个用于原型化智能体的低代码界面。虽然不打算用于生产,但它大大降低了尝试智能体架构的门槛。

值得注意的是,AutoGen 目前正在进行重大更新,正在开发的 0.4.x 版本与稳定的 0.2.x 版本相比引入了大量 API 更改。虽然该框架目前内置的持久性和状态管理功能有限,但这些功能可能会在未来的版本中发展。
OpenAI Swarm
与本文描述的其他框架不同,OpenAI Swarm 是一个教育项目,尚未准备好用于生产。不过,值得一提的是,它非常轻巧且易于上手。OpenAI Swarm 是一个实验性框架,用于编排多智能体工作流,侧重于通过直接交接而不是复杂的编排模式来实现智能体协调。
通过这种设置,智能体只是在聊天中交换消息,可选择调用一些 Python 函数与外部服务通信,或在另一个智能体看起来更适合回答问题时,将对话移交给该智能体。每个智能体都有一个特定的角色,由我们必须定义的指令定义。我们必须决定特定智能体将使用哪个 LLM,以及它可以调用的一组函数。例如,检索智能体可以使用向量数据库来检索文档,并将结果返回给下一个智能体。这意味着应该有一个函数代表它执行语义搜索,但模型将决定查询应该如何。
以下是使用 OpenAI Swarm 实现的类似 Agentic RAG 应用程序的外观:
from swarm import Swarm, Agent
client = Swarm()
def retrieve_documents(query: str) -> list[str]:
"""
Retrieve documents based on the query.
"""
...
def transfer_to_query_improve_agent():
return query_improve_agent
query_improve_agent = Agent(
name="Query Improve Agent",
instructions=(
"You are a search expert that takes user queries and improves them to get better results. You fix typos and "
"extend queries with synonyms, if needed. You never ask the user for more information."
),
)
response_generation_agent = Agent(
name="Response Generation Agent",
instructions=(
"You take the whole conversation and generate a final response based on the chat history. "
"If you don't have enough information, you can retrieve the documents from the knowledge base or "
"reformulate the query by transferring to other agent. You never ask the user for more information. "
"You have to always be the last participant of each conversation."
),
functions=[retrieve_documents, transfer_to_query_improve_agent],
)
response = client.run(
agent=response_generation_agent,
messages=[
{
"role": "user",
"content": "Why Qdrant is the best vector database out there?"
}
],
)
即使我们没有明确定义处理图,智能体仍然可以决定将处理移交给不同的智能体。没有状态的概念,所以一切都依赖于不同组件之间交换的消息。
OpenAI Swarm 不专注于与外部工具的集成,如果想将语义搜索与 Qdrant 集成,则必须完全自己实现。显然,该库与 OpenAI 模型紧密耦合,虽然可以使用其他模型,但需要额外的工作,例如设置代理以调整接口以适应 OpenAI API。
赢家?
为您的 Agentic RAG 系统选择最佳框架取决于您现有的技术栈、团队专业知识以及项目的具体要求。所有描述的工具都是强有力的竞争者,并且它们正在快速发展。密切关注它们是值得的,因为它们可能会随着时间的推移而发展和改进。最终,您应该能够使用它们中的任何一个来构建相同的流程,但其中一些可能更适合您希望您的智能体与之交互的特定工具生态系统。
然而,在为您的 Agentic RAG 系统选择框架时,有一些重要因素需要考虑
- 人工参与 - 即使我们旨在构建自主智能体,通常也需要纳入人类的反馈,以防止我们的智能体执行恶意操作。
- 可观测性 - 调试系统以及理解内部发生的事情的难易程度。尤其重要,因为我们正在处理大量的 LLM 提示。
不过,选择合适的工具包取决于您项目的状态和您的具体要求。如果您希望将您的智能体与许多外部工具集成,CrewAI 可能是最佳选择,因为其开箱即用的集成集最大。然而,LangGraph 与 LangChain 集成良好,因此如果您熟悉该生态系统,它可能更适合您。
所有框架在构建智能体方面都有不同的方法,因此值得尝试所有这些框架,看看哪一个最适合您的需求。LangGraph 和 CrewAI 更成熟,功能更多,而 AutoGen 和 OpenAI Swarm 更轻量级,更具实验性。然而,现有框架均未解决所有提及的信息检索问题,因此您仍然需要构建自己的工具来填补空白。
使用 Qdrant 构建 Agentic RAG
无论您选择哪种框架,Qdrant 都是构建 Agentic RAG 系统的绝佳工具。请查看我们的集成,选择最适合您用例和偏好的集成。开始使用 Qdrant 最简单的方法是使用我们的托管服务 Qdrant Cloud。我们提供免费的 1GB 集群,因此您可以在几分钟内开始构建您的 Agentic RAG 系统。
延伸阅读
查看 Qdrant 如何与
