LangChain智能体开发实战:四个步骤做出能调用工具的AI助手
本文介绍基于LangChain框架构建AI智能体的具体流程。通过工具封装、模型初始化、智能体配置及自然语言调用四个步骤,实现具备自主执行能力的AI应用。重点解析多参数工具适配及ReAct运行机制,提供可复用的Python代码示例,适用于办公自动化及轻量级业务场景。
什么是 LangChain 智能体
不少开发者头一回听到“智能体”(Agent)这个词,就被一串术语吓退了。“自主决策”“逻辑链路”“工具编排”,听着像是非得有扎实的算法功底才玩得转。可实际上,借助
LangChain 这类框架,搭一个真能干活的智能体,核心思路相当简单。
一般的大模型对话,说白了就是“问什么答什么”。它靠训练数据生成文本,没法主动去查天气、算账,也碰不了数据库。智能体则不一样,它更像一个随身带着工具箱的管家。你交给它一个指令,它会先琢磨:“要办成这件事,我得动用哪个工具?”接着调用工具、拿到结果,再根据结果定下一步,直到任务做完。
LangChain 的作用就在于,它把这套“思考-行动-观察”的循环封装好了。开发者不必自己写状态机,也不用编写复杂的判断逻辑,只要按标准流程把工具和模型配置好,其余交给框架就行。
环境准备与依赖
动手写代码之前,先确认本地装的 LangChain 版本对路。这个框架迭代很快,旧接口在新版里可能已经废弃或重构。眼下建议装 0.3 及以上版本,这样才能用上最新的智能体初始化接口。
pip install langchain>=0.3.0另外,对应大模型的社区包也得装上。本文示例用的是阿里云通义千问,所以要安装langchain-community同时确认相关的 API Key 已经配好。要是换成 OpenAI 或其他模型,只消替换对应的初始化类,整体架构不用动。
新建一个 Python 文件,比如agent_demo.py,所有逻辑都集中在这个文件里,调试和看运行日志都方便。
第一步:封装工具集
智能体比大模型强的地方,就在于它能调用外部工具。没了工具,智能体就退化成普通的聊天机器人。所以开发的头一步,是定义智能体“会哪些技能”。
LangChain 提供了@tool装饰器,能把普通的 Python 函数迅速转成智能体认得的工具。要害在函数的文档字符串(docstring),智能体会读这段描述,判断什么时候该调用这个工具。
下面是一个简单的计算工具集,含加、减、乘三个功能:
from langchain_core.tools import tool
@tool
def add(a: float, b: float) -> float:
"""实现两个数字的加法运算
参数:
a: 第一个运算数字
b: 第二个运算数字
"""
return a + b
@tool
def subtract(a: float, b: float) -> float:
"""实现两个数字的减法运算"""
return a - b
@tool
def multiply(a: float, b: float) -> float:
"""实现两个数字的乘法运算"""
return a * b
# 将工具放入列表,供后续传入智能体
tool_list = [add, subtract, multiply]有个细节得留意:函数参数必须带明确的类型提示(如float),文档字符串也要把用途说清楚。智能体做决策时,主要靠这些信息去匹配用户意图。描述要是含糊,它可能挑错工具,甚至干脆不调用。
第二步:初始化大模型
工具齐了,还得有个“大脑”来指挥工具怎么用。这个大脑就是大语言模型(LLM)。在 LangChain 里初始化模型很简单,实例化对应的类即可。
from langchain_community.llms import Tongyi
# 初始化通义千问模型
# temperature 设为 0.1 以降低随机性,保证执行结果的稳定性
llm = Tongyi(temperature=0.1)temperature参数控制输出的随机程度。聊天创作时,高温度能带来多样性;可智能体要精确执行任务,低温度(如 0.1 或 0)更合适,模型的推理过程会更稳,幻觉也少。
到这一步,模型和工具还是各管各的。模型不知道有哪些工具可用,工具也不知道自己何时被调用。下一步就是把两者接起来。
第三步:创建智能体
这一步最为关键。LangChain 提供了initialize_agent方法,把模型、工具和运行策略打包成一个智能体对象。
from langchain.agents import initialize_agent, AgentType
agent = initialize_agent(
tools=tool_list,
llm=llm,
agent_type=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)配置时有几个参数值得多看一眼。
- tools 填的是前面已经定义好的那组工具。
- llm 接收的是初始化完成的模型实例。
- agent_type 决定智能体按什么架构跑。新手栽跟头最多的地方就在这儿。
- 把 verbose 打开之后,控制台就会把智能体思考的全过程打出来,调试起来方便不少。:设为
True
为什么选 STRUCTURED_CHAT 这种类型?
LangChain 给出的智能体类型不止一种。早先的用起来简单,可它对工具参数的支持比较有限,一般只撑得住单参数工具。一旦我们定义的工具带多个参数(比如前面那个),老类型常常解析不对参数格式,结果就是报错或者执行不下去。ZERO_SHOT_REACT_DESCRIPTIONadd(a, b)相比之下,STRUCTURED_CHAT 属于更新一代的选项。它能接收结构化输入,多参数工具处理起来更顺,复杂的对话上下文也能兼容。绝大多数真实场景里,直接选它就行,能省掉一批本不该出现的参数解析问题。
STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION
还有一点要说明,属于经典接口。LangChain 官方正一步步转向基于 LangGraph 的新架构(比如)。不过用来入门、做轻量应用,经典接口照样稳、照样好上手。等以后真需要更复杂的状态管理和工作流控制,再迁到 LangGraph 也不迟。initialize_agentcreate_react_agent
第四步:调用与执行
智能体建好以后,用自然语言下指令就能驱动它,参数不用手动传,只要说清“做什么”。
result = agent.run("请计算100加100的结果")
print("最终结果:", result)跑这段代码时,要是把打开了,控制台会输出类似下面这样的日志:verbose
Entering new AgentExecutor chain...
Thought: 我需要计算100加100,应该使用add工具。 Action: add Action Input: {"a": 100, "b": 100} Observation: 200.0 Thought: 我现在知道了最终答案。 Final Answer: 100加100的结果是200.0
这就是智能体跑起来的核心机制:ReAct 循环(Reasoning and Acting)。
- Thought(思考):模型先分析用户指令,再定下一步做什么。
- Action(行动):模型挑出工具,并把参数生成出来。
- Observation(观察):工具跑完返回结果,模型把这个结果接住。
- 循环:模型拿到观察结果后再想一轮,如此反复,直到给出最终答案。
这中间,开发者一行判断该调加法还是减法的代码都不用写。[[保留1]]该走哪一步,模型自己看上下文就定了。所谓“零样本”(Zero-Shot),说的就是这个:不用针对具体任务做微调,靠通用推理能力,模型就能应付新任务。if-else
核心机制解析
把 ReAct 机制弄明白,排查问题时心里就有底。智能体跑不通,毛病往往出在下面几处:
- 思考偏差:模型没读懂用户想干什么,挑错了工具。多数情况是工具的文档字符串写得太含糊。
- 参数错误:模型给出的参数格式对不上工具的要求。结构化聊天类型能缓解这个问题,但函数签名还是得写清楚。
- 观察缺失:工具执行时报了错,模型收不到有效反馈。这时该回头看看工具代码本身够不够健壮。
灵活性是智能体的长处。同一个智能体,做数学计算也行,查数据库、发邮件也行,前提是把对应的工具函数备好。这种解耦设计让业务逻辑的扩展变得很省事。
落地场景与建议
四步走通之后,就可以把智能体往真实场景里放了:
- 办公自动化:把文件处理、邮件发送、日历查询这类工具封装起来,让智能体帮着打理日常琐事。
- 数据查询助手:接上数据库查询工具,用户用自然语言就能问业务数据,比如“上个月销售额最高的产品是什么”。