从零开始搭建AI智能体 4:Langchain框架 - 基础智能体
LangChain 是最快速入门构建基于 LLM 的智能代理和应用的方法。下面会先整理langchain的依赖,然后通过实践来逐步了解langchain的使用方法。下面举例的代码还未涉及智能体高级功能(记忆功能、中间件、mcp等)并且知识点整理得也不是很全面,主要整理太细也记不住,打算先学会基础功能再深入,有问题可以查看langchain官网doc。
依赖
核心库
pip install langchain langchain-core langchain-community
Langchain-core
langchain-core是langchain的核心库,包含 LangChain 生态系统中使用到的核心接口和抽象。大多数用户主要与langchain包进行交互,该包建立在langchain-core之上,并为所有核心接口提供实现。
Langchain
主包,包含核心功能模块,一般直接与langchain包交互。
Langchain-community
社区维护的通用集成,包含大部分模型 / 工具的基础适配。
扩展库
扩展库是对接外部服务的专用插件,按需安装,核心作用是让 LangChain 能调用具体的模型、工具、数据源。下面会分类例举部分扩展库。
模型接口类
| 扩展库 | 对接的模型 / 服务 | 适用场景 |
|---|---|---|
| langchain-openai | OpenAI/GPT-3.5/4、通义千问(OpenAI 兼容)、DeepSeek 等 | 用 OpenAI 兼容接口的模型 |
| langchain-anthropic | Anthropic Claude | 对接 Claude 系列模型 |
| langchain-dashscope | 通义千问(阿里原生接口) | 不用 OpenAI 兼容,直接对接通义千问 |
| langchain-google-vertexai | Google Gemini/PaLM | 对接谷歌大模型 |
工具类
| 扩展库 | 对接的工具 / 数据源 | 适用场景 |
|---|---|---|
| langchain-mysql | MySQL 数据库 | 从 MySQL 查数据 |
|
langchain-pinecone langchain-chroma |
Pinecone、chroma 向量数据库 | 存储 / 检索向量(RAG 场景) |
| langchain-serpapi | Google 搜索引擎 | 联网搜索信息 |
| langchain-requests | HTTP/API 调用 | 调用第三方 API |
进阶功能类
| 扩展库 | 核心功能 | 适用场景 |
|---|---|---|
| langchain-experimental | 实验性功能(如高级 Agent、多模态) | 尝新功能(非生产环境) |
| langchain-text-splitters | 文本分割工具(如按字符 / 按语义分割) | RAG 场景拆分长文本 |
分组安装
# 多个扩展:装 OpenAI + 向量数据库 + 搜索引擎 扩展
pip install "langchain[openai,pinecone,serpapi]"
# 装所有常用扩展(不推荐,体积大)
pip install "langchain[all]"
Langchain调用大模型
“从零开始搭建AI智能体 3”中通过OpenAI库调用了千问大模型,现在用langchain框架实现。
首先下载langchain-openai库(也可以用阿里原生接口langchain-dashscope) ,确保配置好环境变量,确定base_url,采用流式输出,暂不考虑temperature等其他属性。最简单的大模型调用代码如下:
pip install langchain langchain-openai
from langchain_openai import ChatOpenAI
from langchain.messages import HumanMessage
import os
model = ChatOpenAI(
model="qwen3.5-plus",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
streaming=True
)
messages = [HumanMessage(content="你是谁")]
print("\n" + "=" * 20 + "完整回复" + "=" * 20)
for chunk in model.stream(messages):
if chunk.content:
print(chunk.content, end="", flush=True)

ChatOpenAI
ChatOpenAI是langChain-openai 中创建OpenAI 风格对话模型(包括通义千问、GPT 等兼容接口模型)的标准化客户端类。
- 封装模型初始化参数(model /api_key /base_url /streaming等),统一不同模型的调用方式;
- 提供invoke() / stream() 等方法,直接调用模型;
- 自动处理请求格式转换、响应解析(比如把原生delta 封装成AIMessageChunk)。
invoke() / stream()
这两个方法分别针对大模型的流式输出和非流式输出。
| 方法 | 核心定位 | 返回类型 | 使用场景 | 特点 |
|---|---|---|---|---|
| invoke() | 一次性对话 | 完整的AIMessage对象 | 批量处理、不需要实时展示回复的场景 | 等待模型思考完成后,一次性返回完整回复 |
| stream() | 实时流式对话 | 生成器AIMessageChunk | 聊天机器人、实时展示回复的场景 | 逐字 / 逐段返回回复,有「打字机效果」 |
AIMessage/AIMessageChunk
两者都是大模型回复的标准化载体,区别主要在于,非流式调用得到的AIMessage是完整回复,content是完整文本;流式调用得到的AIMessageChunk是碎片,其中的content是单个字符/词。关键属性有:
- content:模型回复的核心文本;
- role:固定为“assistant” (无需手动设置);
- additional_kwargs:扩展属性;
- response_metadata:原生 API 响应元数据(如模型耗时、token 数)。
AIMessage(
content="J'adore la programmation.",
response_metadata={
"token_usage": {
"completion_tokens": 5,
"prompt_tokens": 31,
"total_tokens": 36,
},
"model_name": "gpt-4o",
"system_fingerprint": "fp_43dfabdef1",
"finish_reason": "stop",
"logprobs": None,
},
id="run-012cffe2-5d3d-424d-83b5-51c6d4a593d1-0",
usage_metadata={"input_tokens": 31, "output_tokens": 5, "total_tokens": 36},
)
HumanMessage
HumanMessage是用户消息的标准化载体,代表用户说的话。关键属性有:
- content:用户输入的核心文本;
- role:固定为“user” ;
- additional_kwargs:扩展属性。
此外,还有系统信息载体:SystemMessage。
多轮对话
基于前面的内容,可以通过循环实现在终端和大模型进行对话。
from langchain_openai import ChatOpenAI
from langchain.messages import HumanMessage, AIMessage
import os
import re
model = ChatOpenAI(
model="qwen3.5-plus",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
temperature=0.2,
streaming=True
)
chat_history = []
while True:
h_msg = input("[请输入]: ").strip()
if re.search(r'exit', h_msg, re.IGNORECASE):
break
chat_history.append(HumanMessage(content=h_msg))
full_text = ""
print("[qwen3.5-plus]: ", end="")
for chunk in model.stream(chat_history):
if chunk.content:
full_text = full_text + chunk.content
print(chunk.content, end="", flush=True)
chat_history.append(AIMessage(content=full_text))
print('/n')
Langchain创建智能体
智能体将语言模型与工具结合,创建能够对任务进行推理、决定使用哪些工具并迭代寻求解决方案的系统。
在大模型的基础上创建要给最简单的智能体(关闭streaming,不考虑流式输出),代码如下:
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from langchain.tools import tool
import os
from langchain.messages import AIMessageChunk
@tool
def check_weather(location: str) -> str:
'''Return the weather forecast for the specified location.'''
return f"It's always sunny in {location}"
model_qwen = ChatOpenAI(
model="qwen3.5-plus",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
temperature=0.2,
streaming=False
)
graph = create_agent(
model=model_qwen,
tools=[check_weather],
system_prompt="You are a helpful assistant"
)
inputs = {
"messages": [{"role": "user", "content": "what is the weather in Hangzhou"}]
}
print(graph.invoke(inputs, stream_mode='values'))
tool
创建工具最简单的方法是通过@tool装饰器;类型提示是必需的,因为它们定义了工具的输入架构;函数的文档字符串(docstring)作为工具的描述,应该信息丰富且简洁,以帮助模型理解工具的用途。
@tool装饰器可以指定工具名和工具描述:@tool("calculator", description="Performs arithmetic calculations. Use this for any math problems.")
create_agent()
create_agent()函数用于快速构建智能体,核心是封装大模型 + 工具 + 系统提示词为 LangGraph 状态机(返回graph对象),部分参数如下:
| 参数名 | 是否必选 | 类型 | 核心作用 |
|---|---|---|---|
| model | 是 | ChatOpenAI/BaseChatModel | 绑定智能体使用的大模型 |
| tools | 是 | List[Tool / Callable] | 智能体可调用的工具列表(支持@tool装饰的函数或普通函数,但最好都用装饰器) |
| system_prompt | 否 | str | 定义智能体角色 / 行为准则(默认无) |
| prompt | 否 | ChatPromptTemplate | 自定义完整提示词模板(覆盖system_prompt) |
| agent_type | 否 | str | 指定智能体类型(如react,默认自动适配) |
input格式
create_agent()生成的智能体,inputs必须是字典,且核心键为messages,格式固定为:
inputs = {
"messages": [
# 消息列表:角色-内容
{"role": "user", "content": "用户的问题"}, # 必选:用户消息
{"role": "system", "content": "覆盖create_agent的 system_prompt"}, # 可选
{"role": "assistant", "content": "历史回复"}, # 可选:对话历史
]
}
input{"message": []} 本质就是会话历史列表,可以包含多轮user/assistant消息,智能体 / 大模型会按时序(列表顺序) 解析上下文。为了防止token过长,在实际使用时注意限制列表长度。
Runnable接口
Runnable 方式定义了一个标准接口,允许 Runnable 组件:
- Invoked:将单个输入转换为输出。
- Batched:多个输入被有效地转换为输出。
- streamed(流式):输出在生成时进行流式处理。
create_agent()返回的是Langchain框架中标准的Runnable对象(graph对象),核心方法有:
- invoke(inputs, stream_mode):一次性执行智能体,返回完整结果(字典);
- stream(inputs, stream_mode)
stream(inputs, stream_mode):流式执行,逐步骤 / 逐字返回结果; - batch(input_list):批量执行多个输入;
- ainvoke()/astream():异步执行(高并发场景)。
stream_mode
invoke和stream方法下都可以设置stream_mode参数。 invoke方法中stream_mode可选'values'和'updates'。steams方法中stream_mode选项更多,常用的有'values'、‘updates'、'message'等,其他的用得少就省略了。
values
values模式下完整记录用户提问→模型决定调用工具→工具返回结果→模型生成最终回复的过程,输出结构是单个大字典,核心键是'message'。
invoke方法仅输出一个完整的大字典,但是stream方法下会流式输出大字典(结构相同),需要通过循环来获取。
{
"messages": [
# 1. 用户消息(HumanMessage)
HumanMessage(
content='what is the weather in Hangzhou', # 用户输入
id='86dc8e29-c7f7-4934-a318-59f7b2f7a525'
),
# 2. 模型第一次回复(AIMessage:工具调用指令)
AIMessage(
content='', # 无文本回复,仅返回工具调用指令
tool_calls=[{ # 核心:智能体决定调用的工具
'name': 'check_weather', # 工具名
'args': {'location': 'Hangzhou'}, # 工具参数
'id': 'call_38f32c149f9944aaa2af7b15' # 工具调用ID(关联后续ToolMessage)
}],
finish_reason='tool_calls', # 回复终止原因:触发工具调用
response_metadata={ # 模型调用元数据
'token_usage': {'completion_tokens': 78, 'prompt_tokens': 283, 'total_tokens': 361},
'reasoning_tokens': 46 # 模型思考消耗的tokens(通义千问特有)
}
),
# 3. 工具返回结果(ToolMessage)
ToolMessage(
content="It's always sunny in Hangzhou", # 工具执行结果
name='check_weather', # 对应调用的工具名
tool_call_id='call_38f32c149f9944aaa2af7b15' # 关联第二步的工具调用ID
),
# 4. 模型第二次回复(AIMessage:最终文本回复)
AIMessage(
content='The weather in Hangzhou is sunny! It looks like you can expect clear skies and sunshine there.', # 最终回复
tool_calls=[], # 无工具调用(已完成回复)
finish_reason='stop', # 回复终止原因:正常结束
response_metadata={
'token_usage': {'completion_tokens': 70, 'prompt_tokens': 335, 'total_tokens': 405},
'reasoning_tokens': 45
}
)
]
}
updates
'updates'模式为分步模式,按模型→工具→模型的执行节点拆分,每个步骤只返回当前节点的结果。节点类型的键为:model(模型节点)/tools(工具节点),智能体的执行路径清晰,适用于调试。输出格式为列表,列表中元素为字典。
invoke方法仅输出一个完整的列表,列表内按照执行节点区分字典,但是stream方法下会流式输出执行节点区分字典(结构相同),需要通过循环来获取。
[
# 步骤1:模型节点(model)- 生成工具调用指令
{
"model": { # 节点类型:模型节点
"messages": [
AIMessage(
content='', # 无文本回复,仅工具调用
tool_calls=[{'name': 'check_weather', 'args': {'location': 'Hangzhou'}}],
finish_reason='tool_calls',
response_metadata={'token_usage': {...}} # 同values模式
)
]
}
},
# 步骤2:工具节点(tools)- 执行工具并返回结果
{
"tools": { # 节点类型:工具节点
"messages": [
ToolMessage(
content="It's always sunny in Hangzhou", # 工具返回结果
tool_call_id='call_86182af1cb124726a4d398cf' # 关联步骤1的工具调用ID
)
]
}
},
# 步骤3:模型节点(model)- 生成最终文本回复
{
"model": { # 节点类型:模型节点
"messages": [
AIMessage(
content="The weather in Hangzhou is sunny! It's always sunny there according to the forecast.", # 最终回复
tool_calls=[],
finish_reason='stop'
)
]
}
}
]
messages
这是stream方法特有的stream_mode,流式返回Tuple,可以理解为,将updates模式返回的AIMessage/ToolMessage结果提取出来,不区分模型节点,只返回message。
更多推荐

所有评论(0)