普通模型调用只能"一问一答",智能体(Agent)则要自己想清楚任务、挑工具、执行、再根据结果决定下一步。用 LangChain 搭一个能跑的智能体,实际工作量比想象小得多——核心就是四步:封工具、起模型、建智能体、发指令。下面按顺序走一遍,重点讲那个几乎所有人都会踩的类型选择坑。
先把环境钉住:版本决定接口
LangChain 迭代很快,接口在不同大版本之间不兼容。本文流程基于 0.3 及以上版本验证通过:
pip install "langchain>=0.3.0" langchain-community langchain-core
一个必须知道的版本事实:initialize_agent 属于经典接口,官方已标记为 legacy,后续维护会逐步停止,新项目主推 LangGraph 的 create_react_agent。老接口短期内还能用、适合理解原理,但生产代码要有迁移预期——两者的核心机制(模型决策 + 工具执行 + 结果回传)是一致的,学会一个再切另一个成本很低。
第一步:用 @tool 封装技能库
没有工具的智能体和普通对话没区别。工具就是函数加描述:
from langchain_core.tools import tool
@tool
def add(a: float, b: float) -> float:
"""实现两个数字的加法运算"""
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]
@tool 装饰器会自动把函数签名转成参数 Schema,docstring 就是模型读到的工具说明——说明写得越清楚,模型选错工具的概率越低。
第二步:初始化模型
模型是智能体的大脑,此时不需要绑定工具:
from langchain_community.llms import Tongyi
llm = Tongyi(temperature=0.1)
temperature 压到 0.1 是刻意的:工具调用类任务要的是稳定和精确,不是创意。温度过高时模型可能幻觉出不存在的工具名或拼错参数。
第三步:创建智能体——类型必须选对
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,
)
四步里唯一会让新手当场报错的就是这里。初代 ZERO_SHOT_REACT_DESCRIPTION 只支持单参数工具——它基于文本模板解析 Action Input,天然假定参数是一段整体输入。而 add/subtract/multiply 都有两个入参,用它直接触发参数解析异常。根因不在代码写错,在架构类型与工具签名不匹配。结构化类型会走 JSON 参数解析,多参数、复杂嵌套参数都能正确处理,通用场景统一用它最省心。
参数速查:tools 必须是列表(单个工具也要包一层);llm 要传完整实例;verbose 开发期打开,排查全靠它。
第四步:发自然语言指令
result = agent.run("请计算100加100的结果")
print("最终计算结果:", result)
返回字典里 input 是原始指令,output 是最终结果,业务代码只读 output。
验收:看懂 verbose 日志才算跑通
打开 verbose=True 后,一次成功的执行应呈现完整的闭环日志:
- Thought:模型分析任务,判断需要加法;
- Action:选定 add 工具,传入 100 和 100;
- Observation:拿到 200;
- 下一轮 Thought:结果已足够,输出最终答案。
四段都在、output 数值正确,才算验收通过。只看到答案没看日志,等于没验证工具是否真的被调用过——模型也可能直接口算了,那说明工具链路没接通。这类 ZeroShot 智能体不需要训练和微调,靠上下文里的工具描述现场决策,这也是它能低成本落地办公计算、简单业务调度的原因。
后续要往生产走,重点看 LangGraph:状态图、检查点、人工介入,都是老接口没覆盖的能力。

评论0