使用 LangChain 构建 Agent 时非常简单,只需要调用函数 create_agent() 即可创建一个 Agent。
按最简单的情况,我们仅需传入 model、tools 和 system_prompt 这些参数,然而,要创建更复杂、更自定义的 Agent,我们还需要深入理解 create_agent() 函数以及它的用法。
同样,在指定模型时,既可以直接写模型字符串,如 "openai:gpt-5.5",也可以先通过 init_chat_model() 创建模型对象,再传入 create_agent()。两种写法看起来都能运行,但适合的场景并不完全相同。
本文从 create_agent() 开始,把 Agent 的运行过程和 Model 的创建方式逐一详细陈明。
一、create_agent 的作用
LangChain 当前提供:
from langchain.agents import create_agent
create_agent() 用于创建一个能够在模型调用和工具执行之间循环运行的 Agent。
官方当前的函数签名中,主要参数包括:
create_agent(
model,
tools=None,
*,
system_prompt=None,
middleware=(),
response_format=None,
state_schema=None,
context_schema=None,
checkpointer=None,
store=None,
interrupt_before=None,
interrupt_after=None,
debug=False,
name=None,
cache=None,
)
实际开发时,并不需要一开始就掌握所有参数。最常使用的是:
model
tools
system_prompt
middleware
response_format
checkpointer
其中最重要的是前三项。
model 决定 Agent 使用哪个大模型进行推理;tools 决定模型可以调用哪些外部能力;system_prompt 则负责告诉模型它应该扮演什么角色、遵守什么规则。
LangChain 的 Agent 底层建立在 LangGraph Runtime 之上,因此 create_agent() 返回的并不是一个普通 Python 函数,而是一个已经编译好的图运行对象。
这也是为什么后面可以直接调用:
agent.invoke(...)
agent.stream(...)
从使用者角度看,我们不必自己定义图;从运行机制看,它仍然是一个由多个节点组成的 Agent 图。
二、Agent 的运行机制
先看一个简单示例:
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"{city}:晴天,25℃"
agent = create_agent(
model="openai:gpt-5.5",
tools=[get_weather],
system_prompt="你是一个天气助手。",
)
result = agent.invoke(
{
"messages": [
{
"role": "user",
"content": "上海天气怎么样?"
}
]
}
)
print(result["messages"][-1].content)
运行结果
示例输出:
上海今天是晴天,气温约 25℃。
Agent 的执行过程如下:
用户消息
↓
模型判断
↓
调用 get_weather
↓
工具返回天气数据
↓
结果加入 messages
↓
再次调用模型
↓
生成最终回答
模型产生 tool_calls 后,Agent 会执行对应工具,并把结果加入消息状态,再重新调用模型。
直到模型不再请求工具,而是生成最终答案,循环才结束。
所以,create_agent() 真正帮开发者省掉的是这部分控制逻辑。
如果自己实现,需要检查模型是否产生工具调用、解析参数、找到工具、执行工具、保存结果,再决定是否继续调用模型。LangChain 已经把这些步骤放进 Agent Runtime。
三、model 参数的两种写法
create_agent() 的第一个参数 model 非常重要。
它可以接收两类值:
str
或者:
BaseChatModel
也就是既可以直接传模型名称,也可以传一个已经创建好的 LangChain Chat Model 对象。
直接传模型名称
最简单的方式是:
agent = create_agent(
model="openai:gpt-5.5",
tools=[get_weather],
)
这里采用:
provider:model
格式。
例如:
openai:gpt-5.5
anthropic:claude-sonnet-4-6
google_genai:gemini-2.5-flash-lite
LangChain 会根据 Provider 找到对应的模型集成。不同 Provider 最终都会暴露统一的 Chat Model 接口,因此在很多情况下,切换模型并不需要修改 Agent 主体逻辑。
如果模型名称本身足够明确,有些情况下 Provider 也可以省略,例如:
model="gpt-5.5"
不过实际项目中,更建议明确写出 Provider。这样阅读配置时,可以直接知道模型来自哪个提供商,也能减少模型名称产生歧义的可能。
除了上述方式指定模型外,还可以使用 init_chat_model() 函数创建模型,并对模型提供更灵活的控制。
四、使用 init_chat_model
LangChain 提供了统一的模型初始化入口:
from langchain.chat_models import init_chat_model
例如:
from langchain.chat_models import init_chat_model
model = init_chat_model(
"openai:gpt-5.5",
temperature=0,
timeout=30,
max_tokens=2000,
max_retries=6,
)
然后把模型对象交给 Agent:
agent = create_agent(
model=model,
tools=[get_weather],
)
这时候职责就比较清楚:
init_chat_model
↓
负责模型配置
create_agent
↓
负责 Agent 运行逻辑
Agent 的主体代码基本不需要改变。
OpenAI 兼容模型
实际开发中,还有一类模型非常常见:提供 OpenAI Compatible API,也就是 OpenAI 兼容接口的模型服务。
它们不一定由 OpenAI 提供,但接口格式兼容 OpenAI Chat Completions API。
LangChain 可以将这类接口按照 OpenAI Provider 处理,只需要额外指定:
model
base_url
api_key
例如:
from langchain.chat_models import init_chat_model
model = init_chat_model(
model="your-model-name",
model_provider="openai",
base_url="https://your-provider.com/v1",
api_key="your-api-key",
)
LangChain 官方文档明确支持通过 model_provider="openai" 配合自定义 base_url 接入实现 OpenAI Chat Completions API 的服务。
这个方式对于私有部署模型、统一模型网关以及一些第三方模型平台尤其有用。
五、模型参数怎么理解
创建 Model 时,经常会看到:
model = init_chat_model(
"openai:gpt-5.5",
temperature=0.2,
max_tokens=2000,
timeout=30,
max_retries=6,
)
主要参数及其作用如下:
| 参数 | 主要作用 | 常见配置 | 需要注意 |
|---|---|---|---|
model | 指定模型 | "gpt-5.5" | 名称由 Provider 决定 |
temperature | 控制生成随机程度 | 0、0.2、0.7 | 不同模型支持情况可能不同 |
max_tokens | 限制单次输出长度 | 1000、2000 | 不是上下文窗口大小 |
timeout | 单次模型请求超时 | 30、60 | Agent 可能产生多轮调用 |
max_retries | 请求失败后的自动重试 | 2、6 | 不是 Agent 重新推理次数 |
base_url | 指定模型 API 地址 | Provider API 地址 | OpenAI 兼容接口常用 |
api_key | API 身份认证 | 环境变量读取 | 不建议硬编码到代码中 |
| Provider 参数 | 控制厂商特有能力 | 因 Provider 而异 | 并非所有模型通用 |
需要注意的是,不同 Integration 对参数的支持并不完全一致。Provider 特有能力仍然应该以对应 Integration 的文档为准。
temperature
temperature 控制生成结果的随机程度。
例如:
temperature=0
更适合信息抽取、分类、工具选择等希望结果相对稳定的任务。
而内容生成类任务可能使用更高的值:
temperature=0.7
但具体支持范围和行为仍取决于模型提供商和具体模型,不应该假设所有模型都完全一致。
max_tokens
它用于限制一次模型输出允许使用的 Token 数量。
例如:
max_tokens=2000
它控制的是单次输出长度上限,并不是整个上下文窗口大小。
Agent 尤其需要注意这一点,因为一次 Agent 执行可能产生多轮模型调用:
Model
↓
Tool
↓
Model
↓
Tool
↓
Model
因此 Agent 的总 Token 消耗,并不能简单理解成某一次 max_tokens。
另外,对于 OpenAI Integration,OpenAI 已经逐步从 max_tokens 转向 max_completion_tokens。当前 ChatOpenAI 仍会对旧参数进行兼容处理,但在具体模型上仍应以 Provider 当前接口为准。
timeout
timeout=30
表示等待一次模型请求的超时时间。
Agent 往往比普通聊天请求执行时间更长,因为它可能连续调用模型和工具,所以生产环境通常需要明确考虑超时策略。
max_retries
max_retries=6
用于控制请求失败后的最大重试次数。
因此,max_retries 解决的是临时性请求故障,并不是 Agent 逻辑执行失败后的“重新思考次数”。
这两个概念不要混在一起。
base_url
对于 OpenAI 官方 API,通常不需要自己设置 base_url。
但是使用 OpenAI 兼容服务时,它就非常重要:
base_url="https://your-provider.com/v1"
它告诉 LangChain:
模型请求应该发送到哪里
例如:
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="your-model-name",
base_url="https://your-provider.com/v1",
api_key="your-api-key",
)
这也是 LangChain 官方推荐的 OpenAI Compatible Endpoint 接入方式之一。
api_key
api_key 用于模型服务的身份认证。
最直接的方式当然可以写:
model = ChatOpenAI(
model="your-model-name",
api_key="sk-xxxxxxxx",
)
但实际项目中并不建议这样做。
API Key 属于敏感信息,不应该直接写入源代码,更不应该提交到 Git 仓库。
更常见的方式是通过环境变量保存:
OPENAI_API_KEY
DEEPSEEK_API_KEY
DASHSCOPE_API_KEY
MODEL_API_KEY
然后在 Python 中读取:
import os
api_key = os.getenv("MODEL_API_KEY")
例如:
import os
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="your-model-name",
base_url=os.getenv("MODEL_BASE_URL"),
api_key=os.getenv("MODEL_API_KEY"),
)
这样模型配置和敏感凭证就可以与代码分离。
在实际项目中,可以简单遵循:
普通配置
model
base_url
temperature
timeout
敏感配置
api_key
普通配置可以放在配置文件中,而 API Key 更适合放在环境变量、部署平台 Secret 或专门的 Secret Manager 中。
六、直接使用模型类
init_chat_model() 并不是唯一方式。
如果项目明确绑定某个 Provider,也可以直接创建具体模型类。
例如 OpenAI:
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="gpt-5.5",
temperature=0,
timeout=30,
)
agent = create_agent(
model=model,
tools=[get_weather],
)
如果使用千问,可以安装:
pip install -U langchain-qwq
然后使用:
from langchain_qwq import ChatQwen
model = ChatQwen(
model="qwen-flash",
max_tokens=3000,
)
agent = create_agent(
model=model,
tools=[get_weather],
)
LangChain 当前的 ChatQwen Integration 支持 Tool Calling 和 Structured Output,因此可以作为 create_agent() 的模型使用。
DeepSeek 也有对应的 Integration:
pip install -U langchain-deepseek
然后:
from langchain_deepseek import ChatDeepSeek
model = ChatDeepSeek(
model="deepseek-chat",
temperature=0,
)
agent = create_agent(
model=model,
tools=[get_weather],
)
这里需要注意模型本身的能力差异。
当前 deepseek-chat 支持 Tool Calling 和 Structured Output,而 deepseek-reasoner 不支持这两项能力。因此,对于本文这种需要模型主动调用工具的 Agent,更适合使用 deepseek-chat。
如果某个平台没有使用专门的 LangChain Integration,但提供了 OpenAI 兼容接口,也可以直接使用 ChatOpenAI:
import os
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="your-model-name",
base_url=os.getenv("MODEL_BASE_URL"),
api_key=os.getenv("MODEL_API_KEY"),
)
因此,实际项目中常见的模型创建方式可以归纳为:
| 创建方式 | 示例 | 特点 | 适合场景 |
|---|---|---|---|
| 直接传字符串 | "openai:gpt-5.5" | 最简单 | 配置较少的 Agent |
init_chat_model() | init_chat_model(...) | Provider 抽象统一 | 需要切换多个模型 |
ChatOpenAI | ChatOpenAI(...) | OpenAI 参数直接 | OpenAI 模型 |
ChatQwen | ChatQwen(...) | 千问专用 Integration | 千问模型 |
ChatDeepSeek | ChatDeepSeek(...) | DeepSeek 专用 Integration | DeepSeek 模型 |
ChatOpenAI + base_url | 自定义 API 地址 | 兼容范围广 | OpenAI Compatible API |
其中,init_chat_model() 更像 LangChain 提供的统一模型入口:
init_chat_model
↓
统一模型抽象
↓
具体 Provider Integration
而:
ChatOpenAI(...)
ChatQwen(...)
ChatDeepSeek(...)
则直接使用对应 Provider 的 LangChain Integration。
如果项目需要方便地切换 OpenAI、Anthropic、Gemini 等模型,init_chat_model() 会更自然。
如果项目已经明确绑定某个 Provider,并且需要大量 Provider 特有参数,直接使用对应模型类通常更加清晰。
如果使用的是企业内部模型、模型网关或者其他提供 OpenAI Compatible API 的服务,则:
ChatOpenAI(
base_url=...,
api_key=...,
model=...
)
往往是最简单的接入方式。
LangChain 官方同时提醒,如果 Provider 存在专门的 Integration,而项目又依赖它的非标准特性,则应优先使用对应 Integration。
因此,不存在一种始终更好的创建方式。
选择依据是项目需要多少 Provider 无关性,以及是否需要使用具体 Provider 的特有能力。
七、create_agent 的重要参数
理解 Model 后,再看 create_agent() 的其他参数会简单很多。
示例代码:
agent = create_agent(
model=model,
tools=[get_weather],
system_prompt="你是一个天气助手,只根据工具返回的数据回答。",
)
tools
tools 是 Agent 可以调用的外部能力。
可以直接使用普通 Python 函数:
def get_weather(city: str) -> str:
"""Get weather for a city."""
return f"{city}:晴天,25℃"
也可以使用:
from langchain.tools import tool
定义更加明确的工具。
需要特别注意:工具的函数名、参数类型以及描述都会帮助模型理解“什么时候应该调用它”。
所以 Tool 并不只是一个 Python 函数,它同时也是提供给模型的一份能力说明。
如果未设置工具,或工具列表为空,如下:
tools=[]
Agent 仍然可以创建,但此时基本只剩模型节点,没有工具调用循环。
system_prompt
system_prompt 用于定义 Agent 的基础行为:
system_prompt="""
你是一个天气助手。
要求:
1. 天气问题必须调用工具获取数据。
2. 不允许自行编造天气信息。
3. 回答保持简洁。
"""
它既可以是字符串,也可以传入 SystemMessage。
Agent 每次调用模型时,会把这部分系统指令放入模型上下文。
response_format
如果下游程序需要的不是自然语言,而是确定的数据结构,可以使用:
response_format=SomeSchema
例如:
from pydantic import BaseModel
class WeatherResult(BaseModel):
city: str
temperature: int
condition: str
然后:
agent = create_agent(
model=model,
tools=[get_weather],
response_format=WeatherResult,
)
最终结构化结果可以从:
result["structured_response"]
读取。
LangChain 会根据模型能力选择相应的结构化输出方式。
这里同样需要注意模型能力差异。
不是所有模型都支持完全相同的 Structured Output 或 Tool Calling 能力,因此切换模型时,不能只替换模型名称,还应该检查目标模型是否支持当前 Agent 使用的能力。比如当前 deepseek-chat 支持 Tool Calling,而 deepseek-reasoner 则存在相应限制。
middleware
当简单的:
Model + Tools + Prompt
已经不能满足需求时,通常就会开始用 Middleware。
Middleware 可以介入 Agent 生命周期,例如:
调用模型前
调用模型后
调用工具前后
整个 Agent 执行前后
因此,动态 Prompt、动态选择模型、工具权限控制、日志、重试、Guardrail、上下文压缩等能力,都可以通过 Middleware 实现。
这也是 LangChain Agent 扩展机制中很重要的一部分。
八、实际项目中的选择
理解 create_agent() 后,可以把整个关系整理成:
Model
负责推理
Tool
负责访问外部能力
System Prompt
负责基础行为约束
Middleware
负责动态控制 Agent 生命周期
State
保存当前执行过程中的数据
create_agent
把这些组件组装成 Agent Runtime
其中 Model 和 Agent 应该明确区分。
下面:
model = init_chat_model("openai:gpt-5.5")
创建的是模型对象。
下面:
model = ChatQwen(
model="qwen-flash"
)
创建的仍然只是模型对象。
下面:
model = ChatDeepSeek(
model="deepseek-chat"
)
同样只是模型对象。
甚至:
model = ChatOpenAI(
model="your-model",
base_url="https://your-provider.com/v1",
api_key="..."
)
本质上仍然只是创建一个符合 LangChain Chat Model 接口的对象。
而:
agent = create_agent(
model=model,
tools=[get_weather]
)
创建的才是Agent。
Model 本身可以:
model.invoke("你好")
它只是一次模型调用。
Agent 则可以:
理解问题
↓
决定调用工具
↓
执行工具
↓
读取结果
↓
继续推理
↓
再次调用工具
↓
最终回答
这也是理解 create_agent() 最重要的一点。
实际开发时,如果只是做一次文本生成、翻译、分类或者结构化抽取,没有工具循环和 Agent 决策需求,直接使用 Model 往往更简单。
如果任务需要模型根据当前状态自主选择工具,并可能连续执行多个步骤,再使用 create_agent()。
整个选择过程可以进一步整理为:
| 需求 | 更适合的方式 |
|---|---|
| 快速创建简单 Agent | create_agent(model="provider:model") |
| 希望统一切换不同 Provider | init_chat_model() |
| 深度使用某个 Provider | 对应 Chat Model 类 |
| 使用 OpenAI 兼容接口 | ChatOpenAI + base_url + api_key |
| 使用企业内部模型网关 | OpenAI Compatible API |
| 需要 Tool Calling | 检查模型是否支持工具调用 |
| 需要结构化结果 | 检查 Structured Output 支持 |
| API Key 管理 | 环境变量或 Secret Manager |
| 需要复杂 Agent 控制 | Model + Tools + Middleware |
Model 配置较简单时,可以直接:
create_agent(
model="openai:gpt-5.5",
...
)
当需要控制 temperature、超时、重试、Provider 参数,或者多个地方复用同一个模型时,更适合先创建:
model = init_chat_model(...)
或者直接创建具体的 Model:
ChatOpenAI(...)
ChatQwen(...)
ChatDeepSeek(...)
如果使用 OpenAI 兼容服务,则通常进一步配置:
ChatOpenAI(
model=...,
base_url=...,
api_key=...
)
最后再统一传给:
create_agent(
model=model,
...
)
这样 Model 的创建与 Agent 的创建就被明确分离开来。
九、总结
本文从 create_agent() 入手,介绍了 LangChain Agent 的运行机制,以及 Model、Tool、System Prompt 和 Middleware 之间的关系。模型既可以通过字符串直接指定,也可以使用 init_chat_model()、ChatOpenAI、ChatQwen、ChatDeepSeek 等方式创建,还可以通过 base_url 和 api_key 接入 OpenAI 兼容模型。
实际开发时,简单 Agent 可以直接指定模型;需要参数控制、模型复用、Provider 切换或自定义 API 地址时,更适合先创建 Model 对象。API Key 应与代码分离,通过环境变量或 Secret Manager 管理。理解 Model 与 Agent 的边界,是继续学习 Middleware、Memory、State 和复杂 Agent 架构的基础。
社区讨论
参与讨论
有问题或想法?欢迎继续讨论。