大模型Agent开发实战:用LangChain从零构建一个能自主决策的AI助手
前言
今年年初我开始接触AI Agent,第一个感觉就是:大模型本身像一个知识渊博的专家,但它只会动嘴,不会动手。而Agent不一样,它不仅能说,还能调用工具、查阅资料、执行操作,像一个真正的助理。
举个例子:你问大模型“明天北京飞上海的机票多少钱”,它只能告诉你“请去携程查询”。但如果你问一个Agent,它会自己去查航班信息、比价、甚至帮你下单。
这篇文章就是我学习Agent开发过程中的笔记和总结,从最基础的概念开始,到最终搭建一个可运行的Agent应用。全程代码可复制运行。
一、什么是AI Agent?
1.1 大模型 vs Agent
先区分两个概念:
| 大模型(LLM) | AI Agent(智能体) | |
|---|---|---|
| 能力 | 理解和生成文本 | 理解+推理+行动 |
| 工具使用 | 不支持 | 可调用外部工具(搜索、计算器、API等) |
| 记忆 | 单次对话 | 可拥有长期记忆 |
| 自主性 | 被动回答 | 可主动规划和执行任务 |
| 典型例子 | ChatGPT网页版 | AutoGPT、Manus、Devin |
一句话概括:大模型是大脑,Agent是大脑+手脚。
1.2 Agent的核心组成
一个完整的Agent包含三个部分:
-
大模型(LLM):负责理解任务、制定计划、生成输出
-
工具(Tools):Agent可以调用的外部能力,如搜索引擎、计算器、数据库、API接口等
-
编排层(Orchestration):决定Agent什么时候思考、什么时候调用工具、什么时候给出最终答案
1.3 Agent的工作流程
text
用户提问
↓
【思考】大模型理解问题,决定需要什么工具
↓
【行动】调用工具获取信息(如搜索、计算)
↓
【观察】接收工具返回的结果
↓
【循环】重复思考→行动→观察,直到信息足够
↓
【回答】给出最终答案
这个过程叫做 ReAct(Reasoning + Acting) 模式,即推理与行动交替进行。
二、环境搭建
2.1 安装依赖
bash
# 创建虚拟环境 conda create -n agent python=3.10 -y conda activate agent # 安装LangChain及相关组件 pip install langchain==0.1.0 pip install langchain-community==0.1.0 pip install langchain-openai==0.0.5 pip install openai==1.12.0 pip install python-dotenv pip install duckduckgo-search # 搜索引擎工具 pip install arxiv # 学术论文搜索 pip install numexpr # 数学表达式计算
2.2 配置API Key
在项目根目录创建 .env 文件:
bash
OPENAI_API_KEY=你的OpenAI密钥 # 如果用DeepSeek,填写DeepSeek的密钥 DEEPSEEK_API_KEY=你的DeepSeek密钥
或者直接使用本地Ollama模型(无需API Key),本文会展示两种方式。
三、你的第一个Agent
3.1 最简单的Agent
python
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain.tools import tool
load_dotenv()
# 初始化大模型
llm = ChatOpenAI(
model="gpt-3.5-turbo",
api_key=os.getenv("OPENAI_API_KEY"),
temperature=0
)
# ==================== 定义工具 ====================
@tool
def add(a: int, b: int) -> int:
"""计算两个数字的和"""
return a + b
@tool
def multiply(a: int, b: int) -> int:
"""计算两个数字的乘积"""
return a * b
# 工具列表
tools = [add, multiply]
# ==================== 创建Agent ====================
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个数学助手,擅长使用工具解决数学问题。"),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# ==================== 运行 ====================
if __name__ == "__main__":
result = agent_executor.invoke({"input": "计算 23 乘以 17 加上 45 的结果"})
print(f"最终答案: {result['output']}")
3.2 运行效果
text
> Entering new AgentExecutor chain...
Invoking: multiply with {'a': 23, 'b': 17}
返回: 391
Invoking: add with {'a': 391, 'b': 45}
返回: 436
> Finished chain.
最终答案: 436
Agent自动完成了两步操作:先乘后加。这就是Agent的核心能力——自主规划和执行。
四、给Agent装上更多工具
4.1 常用工具集合
python
from langchain.tools import DuckDuckGoSearchRun
from langchain_community.tools import ArxivQueryRun
from langchain.tools import WikipediaQueryRun
from langchain.utilities import WikipediaAPIWrapper
import requests
import json
# 1. 网络搜索工具
search = DuckDuckGoSearchRun()
# 2. 维基百科工具
wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
# 3. 学术论文搜索
arxiv = ArxivQueryRun()
# 4. 当前时间工具
@tool
def get_current_time() -> str:
"""获取当前日期和时间"""
from datetime import datetime
return datetime.now().strftime("%Y年%m月%d日 %H:%M:%S")
# 5. 天气查询工具(调用免费API)
@tool
def get_weather(city: str) -> str:
"""查询城市天气,输入城市名称"""
try:
url = f"https://wttr.in/{city}?format=%C+%t"
response = requests.get(url, timeout=5)
return f"{city}天气:{response.text.strip()}"
except:
return "天气查询失败,请稍后重试"
# 所有工具
tools = [
search,
wikipedia,
arxiv,
get_current_time,
get_weather
]
4.2 使用工具的完整Agent
python
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
prompt = ChatPromptTemplate.from_messages([
("system", """你是一个全能的AI助手,可以使用以下工具来帮助用户:
- 搜索工具:查询最新的网络信息
- 维基百科:查询百科知识
- 学术论文:搜索学术文献
- 时间工具:获取当前时间
- 天气工具:查询城市天气
请根据用户的问题选择合适的工具,如果工具无法回答,请诚实告知。
"""),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
max_iterations=5 # 防止死循环
)
# 测试
questions = [
"现在几点了?",
"北京今天天气怎么样?",
"帮我搜索一下什么是Transformer模型",
]
for q in questions:
print(f"\n问题:{q}")
result = agent_executor.invoke({"input": q})
print(f"回答:{result['output']}")
print("-" * 60)
五、ReAct原理详解
5.1 什么是ReAct?
ReAct = Reasoning(推理) + Acting(行动)
这是一种让大模型交替进行"思考"和"行动"的框架。每一步,模型会输出:
-
Thought(思考):分析当前状态,决定下一步做什么
-
Action(行动):调用某个工具,传入参数
-
Observation(观察):工具返回的结果
然后带着观察结果进入下一步思考,直到得出最终答案。
5.2 ReAct vs 普通调用
| 普通调用 | ReAct Agent | |
|---|---|---|
| 过程 | 一次生成 | 多轮思考+行动 |
| 准确性 | 依赖模型内部知识 | 可查证外部信息 |
| 可解释性 | 黑盒 | 每一步都可追溯 |
| 幻觉风险 | 较高 | 较低(有事实依据) |
5.3 手动实现ReAct(简化版)
python
import re
def react_agent(question, max_steps=5):
"""手动实现ReAct流程"""
context = f"问题:{question}\n"
for step in range(max_steps):
print(f"\n--- 第 {step+1} 轮 ---")
# 1. 让模型生成思考+行动
prompt = f"""
你是一个AI助手,可以使用以下工具:
- search(query):搜索网络信息
- calculate(expression):计算数学表达式
当前已知信息:
{context}
请按照以下格式输出:
思考:<你的分析>
行动:<工具名(参数)>
"""
# 模拟模型响应(实际使用中会调用LLM)
# 这里为了演示,直接手动构造响应
if "天气" in question and step == 0:
# 模拟思考+行动
print("思考:用户询问天气,需要调用搜索工具")
print("行动:search(北京天气)")
observation = "北京今天晴,气温15-25度"
context += f"搜索结果显示:{observation}\n"
elif step == 0:
# 默认搜索
print("思考:需要搜索相关信息")
print("行动:search(" + question + ")")
observation = "找到了相关信息..."
context += f"搜索结果:{observation}\n"
else:
# 最终回答
print("思考:已有足够信息,可以回答用户")
print(f"最终回答:根据搜索结果,{question}的答案是...")
break
return "回答完成"
# 测试
react_agent("北京今天天气怎么样?")
六、带记忆的Agent
默认情况下,Agent每次调用都是独立的,不记得之前的对话。如果需要多轮对话记忆,需要添加记忆组件。
python
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
# 创建带记忆的Agent
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="output" # 重要:指定输出字段
)
# 创建Agent时传入memory
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
memory=memory,
verbose=True,
handle_parsing_errors=True
)
# 多轮对话
print("带记忆的Agent,输入 'quit' 退出")
while True:
user_input = input("\n你: ")
if user_input.lower() == 'quit':
break
result = agent_executor.invoke({"input": user_input})
print(f"AI: {result['output']}")
运行效果:
text
你: 我叫张三 AI: 你好张三!很高兴认识你。 你: 我叫什么名字? AI: 你刚才说你叫张三。
七、使用本地模型替代OpenAI
如果你不想用OpenAI的API,可以用Ollama的本地模型:
bash
# 先确保Ollama在运行 ollama run deepseek-r1:7b
python
from langchain_community.llms import Ollama
# 使用本地模型
llm = Ollama(
model="deepseek-r1:7b",
base_url="http://localhost:11434",
temperature=0.7
)
# 其余代码不变
# 直接用llm替换之前的ChatOpenAI
注意:本地模型在工具调用能力上可能不如GPT-4,但对于简单的工具调用(如搜索、计算),7B级别的模型已经够用。
八、实际项目:一个智能科研助手
下面是一个完整的示例,构建一个可以帮助研究人员完成文献检索和数据分析的Agent。
python
import os
import json
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.tools import tool
from langchain_community.tools import ArxivQueryRun
from dotenv import load_dotenv
import requests
load_dotenv()
# ==================== 初始化 ====================
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0,
api_key=os.getenv("OPENAI_API_KEY")
)
# ==================== 定义工具 ====================
@tool
def search_paper(topic: str) -> str:
"""搜索学术论文,输入研究主题"""
arxiv = ArxivQueryRun()
return arxiv.run(topic)
@tool
def get_paper_citation(title: str) -> str:
"""获取论文引用信息,输入论文标题"""
# 简化版:模拟获取引用
return f"论文《{title}》已被引用约45次"
@tool
def analyze_sentiment(text: str) -> str:
"""分析文本的情感倾向,返回正面/负面/中性"""
# 简化版:模拟情感分析
positive_words = ["好", "优秀", "创新", "显著", "有效"]
negative_words = ["差", "问题", "不足", "局限"]
score = 0
for word in positive_words:
if word in text:
score += 1
for word in negative_words:
if word in text:
score -= 1
if score > 0:
return "正面"
elif score < 0:
return "负面"
else:
return "中性"
@tool
def get_current_time() -> str:
"""获取当前时间"""
from datetime import datetime
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
tools = [search_paper, get_paper_citation, analyze_sentiment, get_current_time]
# ==================== 创建Agent ====================
prompt = ChatPromptTemplate.from_messages([
("system", """你是一个科研助手,帮助研究人员完成以下任务:
1. 搜索和查找学术论文
2. 获取论文引用信息
3. 分析研究文本的情感倾向
请根据用户需求选择合适工具,用专业、简洁的语言回答。
"""),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=False,
max_iterations=6,
handle_parsing_errors=True
)
# ==================== 运行 ====================
if __name__ == "__main__":
print("🤖 科研助手已启动")
print("=" * 50)
tasks = [
"搜索关于Transformer模型的论文",
"分析这段文本的情感:这项研究提出了一种创新的方法,显著提升了模型性能",
]
for task in tasks:
print(f"\n任务: {task}")
result = agent_executor.invoke({"input": task})
print(f"结果: {result['output']}")
print("-" * 50)
九、常见问题与排错
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Agent陷入死循环 | 思考-行动循环无法终止 | 设置 max_iterations=5 限制循环次数 |
| 工具调用失败 | 工具参数格式不对 | 检查工具函数的参数定义,添加类型注解 |
| API Key无效 | 密钥过期或填错 | 重新生成并配置环境变量 |
| 模型不支持工具调用 | 模型版本太旧 | 使用支持函数调用的模型(GPT-3.5-turbo-0613+) |
| 本地模型无法调用工具 | Ollama版本不支持 | 升级Ollama到最新版,或使用支持工具的模型 |
| 中文搜索结果不理想 | 搜索引擎对中文支持有限 | 添加中文搜索引擎工具(如Bing搜索) |
| 记忆混乱 | memory配置不当 | 检查 output_key 是否匹配 |
我遇到过的几个问题
问题一:本地DeepSeek模型调用工具时报错,说模型不支持function calling。解决方法是升级Ollama到最新版本,或使用 deepseek-r1:7b 的最新版镜像。
问题二:Agent在搜索工具返回大量文本后,处理速度变慢。解决方法是减少 max_iterations,并在工具返回时限制结果长度。
十、总结
本文完整介绍了AI Agent的开发过程:
| 内容 | 核心要点 |
|---|---|
| Agent概念 | 大模型+工具+编排,能自主决策和行动 |
| ReAct模式 | 思考→行动→观察→循环→回答 |
| 工具定义 | 使用 @tool 装饰器,添加类型注解和文档 |
| 记忆机制 | ConversationBufferMemory实现多轮对话记忆 |
| 本地部署 | 用Ollama替代OpenAI,本地运行 |
| 实际案例 | 科研助手、天气查询、数学计算等 |
几个核心认知:
-
Agent的本质是大模型+工具调用,关键是把"做什么"和"怎么做"分开
-
工具的定义要清晰,包括功能描述和参数说明,这直接影响Agent调用工具的准确性
-
必须设置循环上限,否则Agent可能陷入无限推理
-
本地模型(如DeepSeek 7B)已经可以做简单的工具调用,但复杂任务仍需要更强的模型
下一步可以做什么:
-
接入更多工具(数据库查询、文件读写、邮件发送等)
-
使用多Agent协作(多个Agent分工完成复杂任务)
-
给Agent加上记忆增强(长期记忆、向量检索)
-
部署为Web API服务
📌 本文所有代码已整合在文中,复制即可运行。如遇问题欢迎评论区交流。
如果本文对你有帮助,欢迎点赞、收藏、转发!
参考资料
-
LangChain官方文档:https://python.langchain.com
-
ReAct原论文:[2210.03629] ReAct: Synergizing Reasoning and Acting in Language Models
-
OpenAI Function Calling文档:https://platform.openai.com/docs/guides/function-calling
-
Ollama官方文档:https://github.com/ollama/ollama
-
智谱AI Agent相关文档:Z.ai - Inspiring AGI to Benefit Humanity
推荐标签
AI Agent LangChain 大模型 Agent开发 ReAct
更多推荐
所有评论(0)