尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

LangChain实战:构建具备RAG与计算能力的AI Agent

LangChain实战:构建具备RAG与计算能力的AI Agent
📅 发布时间:2026/7/4 19:19:00

1. 从零构建AI Agent:LangChain实战指南

最近在开发一个需要结合知识检索和数学计算的智能助手项目时,我深入研究了LangChain框架的Agent机制。与普通聊天机器人不同,Agent能够自主调用工具、进行多轮决策,真正实现"会思考"的AI系统。下面分享我的实战经验,手把手教你构建一个具备RAG知识库查询和精确计算能力的智能Agent。

2. AI Agent核心架构解析

2.1 Agent的四大核心组件

一个完整的AI Agent需要具备以下能力:

  • 大脑(LLM):使用通义千问(qwen-plus)作为推理引擎
  • 记忆系统:
    • 短期记忆:维护对话历史(message数组)
    • 长期记忆:基于FAISS构建的RAG知识库
  • 规划能力:通过多轮工具调用实现复杂任务分解
  • 工具集:本例包含两个关键工具:
    • 公司知识检索(rag_search)
    • 数学计算器(calculator)

2.2 工具调用机制详解

LangChain的工具调用流程遵循以下范式:

  1. 用户输入查询(HumanMessage)
  2. LLM判断是否需要调用工具
  3. 若需调用,返回工具名称和参数(tool_calls)
  4. 执行具体工具函数
  5. 将结果封装为ToolMessage返回对话历史
  6. LLM基于工具结果生成最终回复

这个过程中最精妙的是第5步——通过ToolMessage将工具执行结果重新注入对话流,使得LLM能基于工具输出进行后续推理。

3. 实战开发步骤

3.1 环境准备与依赖安装

首先确保已安装必要库:

pip install langchain-core langchain-community faiss-cpu dashscope

注意:FAISS在不同平台可能有兼容性问题,Mac用户建议使用conda安装:

conda install -c conda-forge faiss-cpu

3.2 工具函数实现

3.2.1 知识检索工具
@tool def rag_search(query: str) -> str: """ 从RAG知识库检索公司内部信息,包括: - 项目计划(名称/代号) - 技术方案 - 预算信息 - 截止日期 示例查询: - "深蓝计划的预算是多少" - "项目截止日期是什么时候" """ # 初始化向量数据库(具体实现见下文) ...

关键点:

  • 使用@tool装饰器声明工具函数
  • 文档字符串必须详细说明功能、参数和返回示例
  • 返回类型必须为字符串
3.2.2 数学计算工具
@tool def calculator(expression: str) -> str: """ 执行精确数学计算,支持: - 四则运算(+ - * /) - 百分比计算 - 括号优先级 示例: - "2 + 3 * 5" → "17.0" - "500 * 0.8" → "400.0" """ # 安全计算实现见3.4节 ...

3.3 多轮对话引擎实现

核心循环逻辑:

def run_agent(query: str, max_turns=5): tool_maps = {"rag_search": rag_search, "calculator": calculator} llm = ChatTongyi(model_name="qwen-plus") tool_llm = llm.bind_tools(tools=list(tool_maps.values())) messages = [HumanMessage(content=query)] for turn in range(max_turns): # 获取LLM响应 response = tool_llm.invoke(messages) messages.append(response) if not response.tool_calls: return response.content # 处理工具调用 for tool_call in response.tool_calls: tool_name = tool_call["name"] if tool_name in tool_maps: tool_output = tool_maps[tool_name](**tool_call["args"]) messages.append( ToolMessage( content=tool_output, tool_call_id=tool_call["id"], name=tool_name ) ) return "超过最大对话轮数"

关键设计:通过max_turns参数防止无限循环,实测表明复杂任务通常3轮内可完成。

4. 安全增强方案

4.1 eval函数的安全隐患

原始计算器实现直接使用eval()存在严重风险:

# 危险实现! return str(eval(expression)) # 可能执行恶意代码

4.2 三种加固方案

方案1:输入过滤
import re def safe_eval(expr: str) -> str: if not re.match(r'^[\d+\-*/(). ]+$', expr): return "非法输入" return str(eval(expr))
方案2:使用ast.literal_eval
import ast def safe_eval(expr: str) -> str: try: node = ast.parse(expr, mode='eval') if not all(isinstance(n, (ast.Num, ast.BinOp, ast.UnaryOp)) for n in ast.walk(node)): raise ValueError return str(eval(expr)) except: return "计算错误"
方案3:自定义解析器(推荐)
from operator import add, sub, mul, truediv ops = {'+': add, '-': sub, '*': mul, '/': truediv} def safe_calculate(expr: str) -> str: try: tokens = expr.split() stack = [] for token in tokens: if token in ops: b, a = stack.pop(), stack.pop() stack.append(ops[token](a, b)) else: stack.append(float(token)) return str(stack[0]) except: return "计算错误"

实测表明方案3安全性最佳,虽然仅支持二元运算,但已满足大多数计算场景。

5. 性能优化技巧

5.1 向量数据库缓存

避免每次调用都重建FAISS索引:

RAG_PATH = "faiss_index" if os.path.exists(RAG_PATH): ragdb = FAISS.load_local(RAG_PATH, embeddings) else: ragdb = FAISS.from_documents(docs, embeddings) ragdb.save_local(RAG_PATH)

5.2 对话历史管理

过长的对话历史会影响性能,建议:

  1. 设置最大历史长度(如最近10条)
  2. 对历史消息进行摘要压缩
  3. 重要信息显式存入知识库

5.3 工具调用优化

通过bind_tools的tool_choice参数可以控制工具调用行为:

# 强制使用特定工具 llm.bind_tools(..., tool_choice={"type": "function", "function": {"name": "calculator"}}) # 禁止工具调用 llm.bind_tools(..., tool_choice="none")

6. 典型问题排查

6.1 工具未被识别

现象:LLM不调用预期工具 排查步骤:

  1. 检查工具描述是否完整(参数、示例缺一不可)
  2. 验证工具是否正确绑定:
    print(tool_llm.tools) # 应显示已绑定的工具
  3. 测试直接工具调用是否正常

6.2 无限循环问题

现象:Agent持续调用同一工具 解决方案:

  1. 检查ToolMessage是否正确返回
  2. 限制最大对话轮数(如前文max_turns)
  3. 在工具描述中明确使用边界条件

6.3 中文处理异常

现象:中文查询结果不准确 优化方案:

  1. 调整文本分块策略:
    text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, # 增大分块大小 chunk_overlap=100, separators=["\n\n", "\n", "。", "!", "?"] # 中文友好分隔符 )
  2. 使用支持中文的embedding模型:
    embeddings = DashScopeEmbeddings(model="text-embedding-v2")

7. 扩展应用场景

基于此框架可轻松扩展更多实用场景:

7.1 电商客服Agent

  • 新增工具:
    • 订单查询
    • 物流跟踪
    • 退换货政策检索

7.2 数据分析Agent

  • 集成:
    • SQL查询
    • 可视化生成
    • 统计计算

7.3 智能家居控制

  • 对接:
    • 设备状态查询
    • 情景模式切换
    • 能耗统计

我在实际项目中发现,当工具数量超过5个时,建议使用ToolExecutor进行统一调度管理,避免工具冲突。另外,为每个工具添加明确的元数据描述(如适用场景、输入输出示例)能显著提升调用准确率。

相关新闻

  • Unity安卓15三键导航栏UI遮挡解决方案
  • Java JWT Token实战:安全存储、刷新机制与黑名单实现
  • Unity脚本模板定制:提升团队协作效率的实用指南

最新新闻

  • Python大模型开发:多模态模型图像生成API封装与参数调优实战
  • 数据库设计 Step by Step (5)——理解用户需求
  • Lerna配置架构解析:构建现代化多包项目管理体系
  • 2026最新2款AI编程平替学生党深度实测
  • Krea-2 Turbo模型深度实践指南:如何在有限硬件资源下实现专业级AI绘图
  • 3个实战技巧:快速掌握PyRadiomics医学影像特征提取的完整指南

日新闻

  • STM32F745VG与MC6470 IMU的高性能姿态控制系统设计
  • 机器不消费,人何以生存
  • AI项目操作手册编写规范与最佳实践

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号