LangChain ReAct Agent 核心技术问答

https://github.com/lhh737/LangChain-ReAct-Agent
文章目录
- [LangChain ReAct Agent 核心技术问答](#LangChain ReAct Agent 核心技术问答)
-
- [1. ReAct Agent 实现原理](#1. ReAct Agent 实现原理)
-
- [1.1 什么是 ReAct Agent?](#1.1 什么是 ReAct Agent?)
- [1.2 项目中 ReAct Agent 的实现方式](#1.2 项目中 ReAct Agent 的实现方式)
- [1.3 ReAct Agent 的工作流程](#1.3 ReAct Agent 的工作流程)
- [2. 项目架构和组件关系](#2. 项目架构和组件关系)
-
- [2.1 整体架构](#2.1 整体架构)
- [2.2 组件关系图](#2.2 组件关系图)
- [2.3 核心组件职责](#2.3 核心组件职责)
- [3. 工具调用机制](#3. 工具调用机制)
-
- [3.1 工具定义方式](#3.1 工具定义方式)
- [3.2 工具调用流程](#3.2 工具调用流程)
- [3.3 工具列表](#3.3 工具列表)
- [4. RAG 检索增强实现细节](#4. RAG 检索增强实现细节)
-
- [4.1 RAG 服务架构](#4.1 RAG 服务架构)
- [4.2 检索流程](#4.2 检索流程)
- [4.3 向量存储实现](#4.3 向量存储实现)
- [4.4 文档处理流程](#4.4 文档处理流程)
- [5. 模型配置与使用](#5. 模型配置与使用)
-
- [5.1 模型类型](#5.1 模型类型)
- [5.2 模型工厂实现](#5.2 模型工厂实现)
- [5.3 模型使用场景](#5.3 模型使用场景)
- [6. 中间件机制](#6. 中间件机制)
-
- [6.1 中间件功能](#6.1 中间件功能)
- [6.2 中间件工作原理](#6.2 中间件工作原理)
- [7. 前端实现](#7. 前端实现)
-
- [7.1 前端架构](#7.1 前端架构)
- [7.2 前端与 Agent 交互流程](#7.2 前端与 Agent 交互流程)
- [8. 配置管理](#8. 配置管理)
-
- [8.1 配置文件结构](#8.1 配置文件结构)
- [8.2 配置加载机制](#8.2 配置加载机制)
- [9. 性能优化](#9. 性能优化)
-
- [9.1 向量存储优化](#9.1 向量存储优化)
- [9.2 流式输出](#9.2 流式输出)
- [9.3 缓存机制](#9.3 缓存机制)
- [10. 扩展与定制](#10. 扩展与定制)
-
- [10.1 新增工具](#10.1 新增工具)
- [10.2 自定义中间件](#10.2 自定义中间件)
- [10.3 模型切换](#10.3 模型切换)
- [11. 常见问题与解决方案](#11. 常见问题与解决方案)
-
- [11.1 工具调用失败](#11.1 工具调用失败)
- [11.2 检索结果不准确](#11.2 检索结果不准确)
- [11.3 性能问题](#11.3 性能问题)
- [11.4 内存使用过高](#11.4 内存使用过高)
- [12. 总结](#12. 总结)
1. ReAct Agent 实现原理
1.1 什么是 ReAct Agent?
ReAct Agent 是一种结合了推理(Reasoning)和行动(Acting)能力的智能代理。它通过以下步骤工作:
- 推理:分析用户查询,理解需求
- 决策:决定需要调用哪些工具来获取信息
- 行动:调用相应的工具执行操作
- 观察:获取工具执行结果
- 整合:基于工具返回的信息,生成最终回答
1.2 项目中 ReAct Agent 的实现方式
在项目中,ReAct Agent 通过 LangChain 的 create_agent 函数创建:
python
self.agent = create_agent(
model=chat_model,
system_prompt=load_system_prompts(),
tools=[rag_summarize, get_weather, get_user_location, get_user_id,
get_current_month, fetch_external_data, fill_context_for_report],
middleware=[monitor_tool, log_before_model, report_prompt_switch],
)
1.3 ReAct Agent 的工作流程
- 接收用户输入 :通过
execute_stream方法接收用户查询 - 构建输入字典:将用户查询转换为 LangChain 可处理的格式
- 流式处理 :调用
agent.stream方法流式处理输入 - 工具调用:根据推理结果,调用相应的工具
- 生成响应:基于工具执行结果,生成最终回答
- 返回结果:以流式方式返回回答
2. 项目架构和组件关系
2.1 整体架构
项目采用模块化设计,主要包含以下组件:
- 前端层:Streamlit 应用(app.py)
- Agent 层:ReactAgent 核心实现
- 工具层:各种工具函数(agent_tools.py)
- RAG 层:检索增强生成服务(rag_service.py)
- 存储层:向量存储服务(vector_store.py)
- 模型层:模型工厂(factory.py)
- 工具层:各种工具函数
- 配置层:YAML 配置文件
- 工具层:工具函数和中间件
2.2 组件关系图
┌───────────────┐ ┌───────────────┐ ┌────────────────┐
│ Streamlit │────>│ ReactAgent │────>│ 工具函数集 │
│ 前端应用 │ │ 核心代理 │ │ (agent_tools) │
└───────────────┘ └───────────────┘ └────────────────┘
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐ ┌────────────────┐
│ 配置管理 │<────│ 模型工厂 │<────│ RAG服务 │
│ (config) │ │ (factory) │ │ (rag_service) │
└───────────────┘ └───────────────┘ └────────────────┘
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐ ┌────────────────┐
│ 中间件 │<────│ 向量存储 │<────│ 文件处理 │
│ (middleware) │ │ (vector_store)│ │ (file_handler)│
└───────────────┘ └───────────────┘ └────────────────┘
2.3 核心组件职责
| 组件 | 职责 | 文件位置 |
|---|---|---|
| ReactAgent | 核心代理,协调工具调用和推理过程 | agent/react_agent.py |
| 工具函数 | 提供各种功能,如RAG、天气查询等 | agent/tools/agent_tools.py |
| RAG服务 | 实现检索增强生成功能 | rag/rag_service.py |
| 向量存储 | 管理向量数据库,提供检索功能 | rag/vector_store.py |
| 模型工厂 | 创建和管理LLM和嵌入模型 | model/factory.py |
| 中间件 | 提供监控、日志和提示词切换功能 | agent/tools/middleware.py |
| 配置管理 | 管理项目配置 | utils/config_handler.py |
| 前端应用 | 提供用户交互界面 | app.py |
3. 工具调用机制
3.1 工具定义方式
项目使用 LangChain 的 @tool 装饰器定义工具:
python
@tool(description="从向量存储中检索参考资料")
def rag_summarize(query: str) -> str:
return rag.rag_summarize(query)
3.2 工具调用流程
- 工具注册 :在创建 Agent 时,将工具列表传递给
create_agent函数 - 推理决策:Agent 根据用户查询和系统提示,决定是否调用工具
- 参数解析:Agent 解析工具所需的参数
- 工具执行:调用相应的工具函数
- 结果处理:将工具执行结果返回给 Agent
- 回答生成:Agent 根据工具结果生成最终回答
3.3 工具列表
项目中定义了以下工具:
| 工具名称 | 描述 | 参数 | 返回值 |
|---|---|---|---|
| rag_summarize | 从向量存储中检索参考资料 | query: str | 检索结果摘要 |
| get_weather | 获取指定城市的天气 | city: str | 天气信息 |
| get_user_location | 获取用户所在城市 | 无 | 城市名称 |
| get_user_id | 获取用户ID | 无 | 用户ID |
| get_current_month | 获取当前月份 | 无 | 月份字符串 |
| fetch_external_data | 获取用户使用记录 | user_id: str, month: str | 使用记录 |
| fill_context_for_report | 为报告生成注入上下文 | 无 | 确认信息 |
4. RAG 检索增强实现细节
4.1 RAG 服务架构
RAG 服务由以下组件组成:
- 向量存储:使用 Chroma 作为向量数据库
- 检索器:将向量存储转换为检索器
- 提示模板:定义 RAG 提示词模板
- LLM:使用通义千问模型生成回答
- 链:将检索、提示和生成连接起来
4.2 检索流程
- 接收查询:RAG 服务接收用户查询
- 文档检索:使用检索器从向量存储中检索相关文档
- 上下文构建:将检索到的文档构建为上下文
- 提示构建:将查询和上下文注入提示模板
- 生成回答:LLM 根据提示生成回答
4.3 向量存储实现
向量存储服务的主要功能:
- 初始化:创建 Chroma 向量存储实例
- 文档加载:从文件系统加载文档
- 文本分割:使用 RecursiveCharacterTextSplitter 分割文本
- 向量存储:将分割后的文本转换为向量并存储
- 检索器创建:将向量存储转换为检索器
4.4 文档处理流程
- 文件扫描:扫描指定目录下的文件
- 文件去重:使用 MD5 哈希值去重
- 文档加载:根据文件类型加载文档
- 文本分割:将文档分割为小块
- 向量存储:将分割后的文本存储到向量数据库
5. 模型配置与使用
5.1 模型类型
项目使用以下模型:
- 聊天模型:通义千问 qwen3-max
- 嵌入模型:text-embedding-v4
5.2 模型工厂实现
模型工厂使用工厂模式创建模型实例:
python
class ChatModelFactory(BaseModelFactory):
def generator(self)->Optional[Embeddings | BaseChatModel]:
return ChatTongyi(model=rag_conf["chat_model_name"])
class EmbeddingsFactory(BaseModelFactory):
def generator(self) -> Optional[Embeddings | BaseChatModel]:
return DashScopeEmbeddings(model=rag_conf["embedding_model_name"])
5.3 模型使用场景
| 模型 | 使用场景 | 实现方式 |
|---|---|---|
| 聊天模型 | 生成回答、推理决策 | ChatTongyi |
| 嵌入模型 | 文本向量化、相似度计算 | DashScopeEmbeddings |
6. 中间件机制
6.1 中间件功能
项目实现了以下中间件:
- monitor_tool:监控工具调用
- log_before_model:在模型调用前记录日志
- report_prompt_switch:实现提示词切换功能
6.2 中间件工作原理
中间件在 Agent 执行过程中插入自定义逻辑,如:
- 监控工具调用的执行时间和结果
- 记录模型调用前的状态
- 根据上下文切换提示词模板
7. 前端实现
7.1 前端架构
前端使用 Streamlit 实现,主要功能:
- 会话管理:维护用户会话状态
- 消息展示:显示用户和助手的消息
- 用户输入:接收用户查询
- 流式输出:实时显示助手的回答
7.2 前端与 Agent 交互流程
- 初始化 Agent:在会话开始时创建 ReactAgent 实例
- 接收用户输入:通过聊天输入框接收用户查询
- 调用 Agent :调用 Agent 的
execute_stream方法 - 流式显示:实时显示 Agent 的回答
- 更新会话:将消息添加到会话历史
8. 配置管理
8.1 配置文件结构
项目使用 YAML 文件管理配置:
| 配置文件 | 用途 | 主要配置项 |
|---|---|---|
| rag.yml | RAG 相关配置 | 聊天模型名称、嵌入模型名称 |
| chroma.yml | 向量存储配置 | 集合名称、持久化目录、分块大小等 |
| agent.yml | Agent 配置 | 外部数据路径等 |
| prompts.yml | 提示词配置 | 系统提示词路径等 |
8.2 配置加载机制
配置通过 config_handler.py 加载,使用单例模式确保配置的一致性。
9. 性能优化
9.1 向量存储优化
- 文档去重:使用 MD5 哈希值避免重复加载文档
- 文本分割:合理设置分块大小和重叠度
- 检索参数:设置合适的检索数量(k值)
9.2 流式输出
使用流式输出提高用户体验:
python
for chunk in self.agent.stream(input_dict, stream_mode="values", context={"report": False}):
latest_message = chunk["messages"][-1]
if latest_message.content:
yield latest_message.content.strip() + "\n"
9.3 缓存机制
外部数据使用内存缓存,避免重复加载:
python
def generate_external_data():
if not external_data:
# 加载外部数据
# ...
10. 扩展与定制
10.1 新增工具
要新增工具,只需:
- 使用
@tool装饰器定义工具函数 - 在创建 Agent 时添加到工具列表
10.2 自定义中间件
要添加自定义中间件:
- 定义中间件函数
- 在创建 Agent 时添加到中间件列表
10.3 模型切换
可以通过修改 rag.yml 配置文件切换模型:
yaml
chat_model_name: qwen3-max
embedding_model_name: text-embedding-v4
11. 常见问题与解决方案
11.1 工具调用失败
问题 :工具调用失败
解决方案:检查工具参数是否正确,查看日志了解具体错误原因
11.2 检索结果不准确
问题 :RAG 检索结果不准确
解决方案:调整文本分割参数,增加检索数量,优化嵌入模型
11.3 性能问题
问题 :Agent 响应缓慢
解决方案:优化向量存储,使用更高效的模型,实现缓存机制
11.4 内存使用过高
问题 :内存使用过高
解决方案:合理设置文本分块大小,定期清理缓存
12. 总结
LangChain ReAct Agent 项目实现了一个功能完整的智能代理系统,主要特点:
- 模块化设计:清晰的组件划分,便于维护和扩展
- ReAct 模式:结合推理和行动能力,提高决策质量
- RAG 增强:通过检索增强生成,提高回答的准确性
- 工具集成:支持多种工具,扩展 Agent 能力
- 流式输出:提供实时响应,改善用户体验
- 中间件机制:支持自定义逻辑,增强系统灵活性
该项目展示了如何使用 LangChain 构建一个完整的 ReAct Agent 系统,为智能客服、助手等应用场景提供了参考实现。