1. 从聊天机器人到智能代理:LangChain实战入门
最近在开发一个企业级AI应用时,我发现单纯的聊天机器人已经无法满足复杂业务场景的需求。比如需要查询公司内部知识库、进行精确计算、甚至调用外部API完成多步骤任务。这正是AI Agent(智能代理)大显身手的领域。
与普通聊天机器人不同,AI Agent具备环境感知、自主决策和工具调用能力。想象一下,当你问"公司项目预算增加46%后是多少"时,它不仅能从知识库找到原始预算,还能调用计算器完成精确运算——这正是我们要用LangChain实现的核心功能。
2. 智能代理的四大核心组件
2.1 LLM:大脑中枢
大语言模型是Agent的思考核心。在示例中我们使用通义千问(ChatTongyi)作为基础模型,它负责理解用户意图、制定决策流程。选择qwen-plus型号是因为它在中文场景下的优异表现,特别是在工具调用方面的指令跟随能力。
注意:实际部署时应考虑模型响应时间和成本,对于简单任务可以使用轻量级模型如qwen-turbo
2.2 记忆系统:短期与长期
- 短期记忆:通过保存对话历史(message数组)实现,使Agent能理解上下文
- 长期记忆:采用RAG(检索增强生成)技术,示例中使用FAISS向量数据库存储公司内部文档
2.3 规划能力:任务分解
Agent需要将复杂问题拆解为可执行步骤。例如当用户询问"预算增加后的金额"时,它会自动规划为:
- 检索原始预算数据
- 调用计算器进行百分比运算
- 整合结果返回用户
2.4 工具调用:扩展能力边界
示例中实现了两个典型工具:
- 精确计算器(calculator)
- 文档检索(rag_search)
工具调用是Agent区别于普通聊天机器人的关键能力,下面我们重点解析实现细节。
3. 工具调用全流程实现
3.1 工具定义规范
每个工具都需要明确定义:
python复制@tool
def calculator(expression: str) -> str:
"""
计算数学表达式。需要精确计算时使用。
参数:
expression: 数学算式,如 "2 + 2" 或 "500 * 0.8"。
返回:
str: 计算结果,如 "4.0" 或 "400.0"。
"""
try:
return str(eval(expression))
except Exception as e:
return f"计算错误: {e}"
工具定义的三个关键点:
- 使用
@tool装饰器声明 - 文档字符串必须清晰描述功能、参数和返回格式
- 返回值必须是字符串(LLM可理解的格式)
3.2 工具绑定与调用
绑定过程非常简单:
python复制tool_maps = {
"rag_search": rag_search,
"calculator": calculator
}
llm = ChatTongyi(model_name="qwen-plus")
tool_llm = llm.bind_tools(tools=list(tool_maps.values()))
关键点:
- 使用字典管理工具便于扩展
bind_tools方法将工具描述注入模型上下文- 绑定后模型输出会包含
tool_calls字段
3.3 多轮对话控制
核心流程代码:
python复制message = [HumanMessage(content=query)]
for i in range(5): # 防止无限循环
response = tool_llm.invoke(message)
message.append(response)
if not response.tool_calls:
return response.content
for tool_call in response.tool_calls:
tool_output = tool_maps[tool_call["name"]](**tool_call["args"])
message.append(ToolMessage(
content=tool_output,
tool_call_id=tool_call["id"],
name=tool_call["name"]
))
这个循环实现了经典的"思考-行动-观察"模式:
- LLM决定是否需要调用工具
- 执行工具并获取结果
- 将结果反馈给LLM进行下一步决策
重要:必须设置最大循环次数(示例中为5次),避免无限循环消耗资源
4. 安全风险与防御实践
4.1 eval注入风险
示例中的计算器使用eval()存在严重安全隐患:
python复制# 危险实现!
return str(eval(expression)) # 可能执行任意代码
攻击者可能构造如下输入:
code复制"公司计划是什么"; import os; os.system('rm -rf /')
4.2 安全加固方案
方案1:输入过滤
python复制import re
def calculator(expression: str) -> str:
if not re.match(r'^[\d\+\-\*\/\.\(\) ]+$', expression):
return "错误:包含非法字符"
# 后续计算逻辑...
方案2:使用安全计算库
python复制from ast import literal_eval
def calculator(expression: str) -> str:
try:
return str(literal_eval(expression)) # 比eval安全
except:
return "计算错误"
方案3:沙箱环境
python复制import restrictedpython
def calculator(expression: str) -> str:
try:
code = compile_restricted(expression, '<string>', 'eval')
return str(eval(code))
except:
return "计算错误"
4.3 综合防御策略
在实际项目中建议:
- 前端过滤特殊字符
- 后端使用白名单校验
- 关键操作记录审计日志
- 定期进行安全测试
5. 企业级应用扩展建议
5.1 工具管理最佳实践
- 使用工具版本控制
- 实现工具的热加载
- 添加工具使用权限控制
- 监控工具调用频次和耗时
5.2 性能优化技巧
- 并行工具调用:当多个工具无依赖时可并行执行
python复制from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor() as executor:
futures = {
tool_call["id"]: executor.submit(
tool_maps[tool_call["name"]],
**tool_call["args"]
)
for tool_call in response.tool_calls
}
for tool_call in response.tool_calls:
tool_output = futures[tool_call["id"]].result()
# 处理结果...
- 缓存机制:对频繁查询的RAG结果建立缓存
- 流式响应:在工具执行耗时较长时先返回部分结果
5.3 监控与日志
完善的监控体系应包括:
- 工具调用成功率
- 各环节耗时分析
- 异常请求预警
- 用户行为分析
示例日志格式:
json复制{
"timestamp": "2024-03-20T14:30:00Z",
"session_id": "abc123",
"tool_name": "calculator",
"parameters": {"expression": "50*0.8"},
"execution_time": 0.12,
"status": "success"
}
6. 常见问题排查指南
6.1 工具未被调用
可能原因:
- 工具描述不够清晰(改进文档字符串)
- 模型温度参数过高(尝试设置为0)
- 提示词未明确要求工具使用
解决方案:
python复制from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "你必须使用工具回答以下问题。可用的工具:{tool_names}"),
("human", "{input}")
])
6.2 工具调用结果不准确
排查步骤:
- 检查工具输入参数是否符合预期
- 验证工具本身功能是否正常
- 确认LLM是否正确解析了工具输出
调试技巧:
python复制print("原始工具输出:", tool_output)
# 在返回前对结果进行格式化
return f"工具执行成功,结果为:{tool_output}"
6.3 循环次数过多
优化方案:
- 设置更合理的最大循环次数
- 检测重复工具调用(可能是LLM陷入死循环)
- 添加超时机制
实现示例:
python复制from datetime import datetime, timedelta
timeout = datetime.now() + timedelta(seconds=30)
while datetime.now() < timeout:
# 正常处理逻辑
...
在实际项目中,我发现这些AI Agent的开发模式正在改变传统的人机交互方式。通过合理设计工具系统和对话流程,原本需要多个系统协作完成的复杂任务,现在一个智能代理就能优雅地解决。特别是在处理需要结合多种数据源和计算能力的业务场景时,这种技术架构展现出强大的优势。