【LangChain组件02】—— create_agent函数详解

LangChain create_agent() 函数详解:从 Agent 原理到可运行的实战代码

搞 LLM 应用开发的人大概都有一段"配 Agent 配到头皮发麻"的经历:自己拼模型调用、工具循环、记忆、判断分支......代码越写越长,还容易各有各的写法。LangChain 的 create_agent() 就是为了终结这种混乱------它是 LangChain 现在最核心的 Agent 工厂函数,一个函数就能搭出一个完整的 Agent 图(StateGraph),把模型调用、工具执行、循环控制、状态管理全包在里面。

这篇文章带你从头把它搞懂:先厘清"Agent 到底是什么",再逐参数拆解 create_agent(),最后给出一套能直接跑起来的示例和进阶玩法。文中所有参数与用法以 LangChain 官方文档为准,标注来源,便于你对照查阅。

说明:写作时当前环境访问外部文档受限,本文参数细节以 LangChain 官方 Agents 文档与菜鸟教程 create_agent() 参考页为准(来源见文末),如有新版差异请以官方 reference 为准。


一、先搞懂:Agent 到底是什么

1.1 Agent 的本质:Model + Harness

LangChain 官方对 Agent 的定义很精炼:

An agent is a model calling tools in a loop until a given task is complete. (Agent 是模型在一个循环里反复调用工具,直到某个任务完成。)

拆开看是两件事:

  • Model(模型):负责"想",理解任务、决定下一步做什么。
  • Harness(装配层/控制层):循环本身之外的一切------提示词、工具、中间件,以及决定"在什么时机给模型喂什么上下文"的逻辑。

所以官方一句话公式是:

ini 复制代码
Agent = Model + Harness

Agent 的真正核心不是模型,而是 Harness。 模型再聪明,如果拿不到正确的上下文、不会用工具,也只是一块"会说话的 GPU"。

1.2 核心循环:Agent Loop

一个 Agent 的运行是一个循环,每一圈大致是:

markdown 复制代码
模型思考 → 决定要不要调工具 → 调用工具拿到结果 → 把结果喂回模型 → 再思考......
                          ↓
                直到任务完成(或到达终止条件)

关键点在于:模型不是"一次回答"就结束,而是在循环里不断迭代 ,直到它判断任务完成。这个循环 + 状态管理,正是 create_agent() 帮你搭好的东西。

1.3 为什么需要 Harness

有人会问:我直接 bind 工具给模型调不行吗?可以,但只是"能用"。Harness 解决的问题是------在正确的时间,给模型送对上下文

举个例子:一个带搜索、带记忆的 Agent,需要保证------

  • 每轮调用前把历史对话 + 工具结果组装好送给模型;
  • 工具返回后能解析并更新状态;
  • 多轮之间能持久化,让 Agent 记得上下文;
  • 该中断让人类审批的地方停下

这些琐事如果手写,分散在各处很难维护。create_agent() 就是把这些"装配"逻辑一次打包。

1.4 一句话定位 create_agent()

create_agent() 是一个高度可配置的 Harness 工厂。它的最小用法只三行,却能生成一个完整的、带状态管理的可运行 Agent:

python 复制代码
from langchain.agents import create_agent

agent = create_agent(model="google_genai:gemini-3.6-flash", tools=tools)

它返回一个编译好的图(CompiledStateGraph) ,你可以 invokestream、挂接 checkpointer,本质上是用 LangGraph 帮你搭好了 Agent 的骨架。


二、create_agent():一个函数搞定 Agent

2.1 函数签名与参数总览

create_agent() 的完整签名如下(基于 LangChain 官方 Agents 文档与菜鸟教程整理):

python 复制代码
from langchain.agents import create_agent

agent = create_agent(
    model,                     # str | BaseChatModel:语言模型
    tools=None,                # Sequence:工具列表
    *,
    system_prompt=None,        # str | SystemMessage:系统提示
    middleware=(),             # Sequence[AgentMiddleware]:中间件列表
    response_format=None,      # ResponseFormat | type:结构化输出配置
    state_schema=None,         # type[AgentState]:自定义状态结构
    context_schema=None,       # type:运行时上下文结构
    checkpointer=None,         # Checkpointer:对话持久化
    store=None,                # BaseStore:跨会话存储
    interrupt_before=None,     # list[str]:在哪些节点前暂停
    interrupt_after=None,      # list[str]:在哪些节点后暂停
    debug=False,               # bool:是否输出详细日志
    name=None,                 # str:Agent 名称
    cache=None,                # BaseCache:缓存配置
)
参数 类型 作用
model `str BaseChatModel`
tools Sequence 工具列表,可空
system_prompt `str SystemMessage`
middleware Sequence[AgentMiddleware] 中间件,扩展 Harness 能力
response_format `ResponseFormat type`
state_schema type[AgentState] 自定义运行状态结构
context_schema type 每次调用的运行时上下文结构
checkpointer Checkpointer 会话/对话持久化
store BaseStore 跨会话长期存储
interrupt_before list[str] 在哪些节点前暂停
interrupt_after list[str] 在哪些节点后暂停
debug bool 是否输出详细日志
name str Agent 标识名
cache BaseCache 缓存配置

2.2 返回值:CompiledStateGraph

create_agent() 返回一个 CompiledStateGraph(LangGraph 编译后的图对象)。它不是一个"函数",而是一个可执行的状态图,提供了多种运行方式:

方法 说明 适用场景
invoke(input, config) 同步运行,等待完整结果 脚本、简单接口
ainvoke(input, config) 异步运行,等待完整结果 Web 服务
stream(input, config, stream_mode) 同步流式运行 实时展示中间步骤
astream(input, config, stream_mode) 异步流式运行 WebSocket、SSE
get_state(config) 获取当前状态 查看/恢复对话状态
update_state(config, values) 更新状态 手动修改对话状态

(注:官方文档还介绍了 stream_events,用于逐步展示工具调用与中间消息。)


三、核心参数逐个拆解

3.1 model:选模型

model 是三处必填参数中最关键的一个,接受两种形式:

方式 1:传字符串(最常用)

python 复制代码
from langchain.agents import create_agent

agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    system_prompt="你是菜鸟教程 RUNOOB 的助手",
)

create_agent() 内部会自动调用 init_chat_model() 处理字符串,帮你完成模型初始化、工具绑定、结构化输出等逻辑。

方式 2:传已构建好的模型实例

python 复制代码
from langchain.chat_models import init_chat_model

model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0.3, max_tokens=500)
agent = create_agent(
    model=model,
    system_prompt="你是菜鸟教程 RUNOOB 的助手",
)

适合你需要精细控制模型参数(temperature、max_tokens 等),或需要在 Agent 之外复用同一个模型实例的场景。

方式 3:传已绑定工具的模型实例

python 复制代码
model_with_tools = init_chat_model("deepseek:deepseek-v4-flash").bind_tools([...])
agent = create_agent(model=model_with_tools)

这种方式不太常用------通常让 create_agent 自己管理工具绑定更省事。

推荐方式 1(传字符串)。 create_agent() 内部会统一处理初始化、工具绑定、结构化输出等。方式 2 适合"同实例多处复用"的场景。

3.2 tools:工具列表(Agent 的"四肢")

tools 决定 Agent 能做什么。接受三种格式的工具,可混合:

格式 1:@tool 装饰的函数(最常用)

python 复制代码
from langchain.tools import tool

@tool
def search_course(keyword: str) -> str:
    """搜索菜鸟教程课程"""
    return f"搜索结果:{keyword} 相关课程"

格式 2:Pydantic BaseModel 类

python 复制代码
from pydantic import BaseModel, Field

class WeatherQuery(BaseModel):
    """查询天气"""
    city: str = Field(description="城市名称")

格式 3:工具字典(描述远程工具或内置工具)

python 复制代码
mcp_tool = {
    "type": "mcp",
    "server_label": "weather_server",
    "server_url": "https://weather.example.com/sse",
    "allowed_tools": ["get_forecast"],
}

混合使用:

python 复制代码
agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    tools=[search_course, WeatherQuery, mcp_tool],
)

None 或空列表表示 Agent 无工具可用,此时它就是一个纯粹的对话模型(等价于直接调模型)。

python 复制代码
agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    tools=None,
    system_prompt="你是菜鸟教程 RUNOOB 的助手",
)
result = agent.invoke({"messages": [HumanMessage(content="Python 适合零基础学习吗?")]})
print(result["messages"][-1].content)

3.3 system_prompt:系统提示(行为边界)

定义 Agent 的行为角色和约束规则,支持字符串和 SystemMessage 对象。

方式 1:字符串(简单直接)

python 复制代码
agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    system_prompt="你是菜鸟教程 RUNOOB 的学习顾问。回答要简洁,不超过 100 字。",
)

方式 2:SystemMessage 对象(可在多个 Agent 间复用)

python 复制代码
from langchain.messages import SystemMessage

system_msg = SystemMessage(content="你是菜鸟教程 RUNOOB 的学习顾问。回答要简洁,不超过 100 字。")
agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    system_prompt=system_msg,
)

system_prompt 是可选的,但不传的话模型会以"通用助手"角色回答。有明确业务场景的应用,建议始终设置 system_prompt 来约束模型的行为边界。 若需要运行时动态生成提示,用 middleware(见第五节)。

3.4 state_schema / AgentState:自定义运行状态

默认的 AgentState 只包含 messagesjump_to(跳转)和 structured_response 等内置字段。内置字段的关键一个是:

字段 类型 说明
messages list[BaseMessage] 当前线程的完整对话历史,只追加,不替换

AgentState 也是所有中间件钩子(before_modelafter_model 等)的类型签名。钩子接收当前状态,返回要合并回去的更新字典。

如果你需要额外状态字段,可以子类化 AgentState 并通过 state_schema 传入。 下面这个例子给 Agent 加了"学习进度"的字段,并用 InjectedState 让工具直接读写状态:

python 复制代码
from typing import Annotated
from typing_extensions import TypedDict
from langchain.agents import create_agent, AgentState
from langchain.tools import tool, InjectedState
from langchain.messages import HumanMessage

# 扩展 AgentState,添加自定义字段
class LearningAgentState(AgentState):
    """自定义状态,增加学习进度相关字段"""
    user_level: str                 # 用户等级
    completed_topics: list[str]     # 已完成的主题列表

@tool
def track_progress(
    topic: str,
    state: Annotated[dict, InjectedState],
) -> str:
    """记录用户的学习进度。
    Args:
        topic: 刚学完的主题名称
    """
    completed = state.get("completed_topics", [])
    completed.append(topic)
    return f"已记录学习进度。当前已完成 {len(completed)} 个主题:{', '.join(completed)}"

agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    tools=[track_progress],
    state_schema=LearningAgentState,   # 使用自定义状态
    system_prompt="你是菜鸟教程 RUNOOB 的学习助手。",
)

# 运行时需提供自定义状态的初始值
result = agent.invoke({
    "messages": [HumanMessage(content="我学完了 Python 基础,帮我记录一下")],
    "user_level": "入门",
    "completed_topics": ["HTML 基础"],
})

print(f"用户等级: {result.get('user_level')}")
print(f"已完成主题: {result.get('completed_topics')}")
print(f"回复: {result['messages'][-1].content[:100]}")

运行结果:

less 复制代码
用户等级: 入门
已完成主题: ['HTML 基础', 'Python 基础']
回复: 已记录学习进度。当前已完成 2 个主题:HTML 基础, Python 基础

为什么用 InjectedState 它让工具函数能直接拿到并回写运行状态,不用把 state 显式传进工具参数里。这是 LangChain 处理"工具需要访问状态"的标准做法。

3.5 response_format:结构化输出

想让 Agent 返回校验过的结构化数据 ,而不是一段自由文本,就用 response_format 指定一个 Pydantic 模型或 ResponseFormat:

python 复制代码
from pydantic import BaseModel
from langchain.agents import create_agent

class Answer(BaseModel):
    summary: str
    confidence: float

agent = create_agent(
    model="google_genai:gemini-3.6-flash",
    tools=tools,
    response_format=Answer,
)
result = agent.invoke({"messages": [{"role": "user", "content": "Summarize AI trends"}]})
print(result["structured_response"])   # Answer(summary=..., confidence=...)

结果从 result["structured_response"] 取出,是一个校验过的、类型安全的模型实例。做数据管道、接后端接口时特别有用。

3.6 checkpointer / store:持久化与记忆

  • checkpointer(Checkpointer) :对话/会话持久化。配合 thread_id,让 Agent 记住多轮对话、可中断恢复。
python 复制代码
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    model="google_genai:gemini-3.6-flash",
    tools=[],
    checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": str(uuid7())}}

# 第一轮
result = agent.invoke(
    {"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
    config=config,
)

# 第二轮:复用同一 thread_id,延续历史
result = agent.invoke(
    {"messages": [{"role": "user", "content": "What about tomorrow?"}]},
    config=config,
)

thread_id 区分不同会话;复用同一个值即延续同一段历史。持久化历史需要配置 checkpointer ,本地可用 InMemorySaver(),生产环境(如 LangSmith 部署)会自动配置。

  • store(BaseStore):跨会话的长期存储(区别于 checkpointer 的单会话记忆)。用于存用户偏好、长期知识等。

3.7 context_schema:运行时上下文

thread_id 管"会话",context 管"单次运行"。 如果你想给工具/中间件传每次调用才会变的运行时数据(用户 ID、API key、feature flag 等),用 context_schema 定义其结构,用 runtime.context 访问:

python 复制代码
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver

@dataclass
class Context:
    user_id: str

agent = create_agent(
    model="google_genai:gemini-3.6-flash",
    tools=[],
    context_schema=Context,
    checkpointer=InMemorySaver(),
)
result = agent.invoke(
    {"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
    config={"configurable": {"thread_id": str(uuid7())}},
    context=Context(user_id="user-123"),
)

3.8 其余可选参数

  • middleware:中间件列表,扩展 Harness 能力(详见第五节)。
  • interrupt_before / interrupt_after :在指定节点前/后暂停,配合人机协同做审批。也可用 HumanInTheLoopMiddleware
  • debug:输出详细日志,排查问题时开启。
  • name:给 Agent 起名,多 Agent 系统里嵌入为子图时很有用。
  • cache:缓存配置,减少重复调用、提升性能。

四、实战:从 0 到 1 的可运行示例

这一节把上面拆开的参数串成五个渐进场景,从最小可用到完整能力。

4.1 场景一:最小可用 Agent(无工具)

python 复制代码
from langchain.agents import create_agent
from langchain.messages import HumanMessage

agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    tools=None,
    system_prompt="你是菜鸟教程 RUNOOB 的助手。",
)

result = agent.invoke({"messages": [HumanMessage(content="Python 适合零基础学习吗?")]})
print(result["messages"][-1].content)

没有工具,Agent 退化为纯对话模型,适合验证模型和提示词。

4.2 场景二:带工具 + 自定义 system_prompt

python 复制代码
from langchain.agents import create_agent
from langchain.tools import tool

@tool
def search_course(keyword: str) -> str:
    """搜索菜鸟教程课程。"""
    return f"搜索结果:{keyword} 相关课程"

@tool
def weather(city: str) -> str:
    """查询城市天气。"""
    return f"{city} 当前晴,26℃"

agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    tools=[search_course, weather],
    system_prompt="你是学习助手。查课程用 search_course,查天气用 weather。",
)

result = agent.invoke({"messages": [HumanMessage(content="北京今天天气如何?")]})
print(result["messages"][-1].content)

成功标志 :Agent 自动选择了 weather 工具并返回对应结果。

4.3 场景三:自定义状态(扩展 AgentState)

复用第三节 3.4 的 LearningAgentState 例子,重点在于用 state_schema 注入自定义状态、用 InjectedState 让工具回写状态。

4.4 场景四:结构化输出

python 复制代码
from pydantic import BaseModel
from langchain.agents import create_agent

class Summary(BaseModel):
    topic: str
    key_points: list[str]
    confidence: float

agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    tools=None,
    response_format=Summary,
    system_prompt="把用户输入总结为结构化摘要。",
)

result = agent.invoke({"messages": [{"role": "user", "content": "介绍下分页查询"}]})
print(result["structured_response"])   # Summary(...)

成功标志structured_response 返回一个 Summary 实例,字段齐全且类型正确。

4.5 场景五:会话持久化

python 复制代码
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    tools=[],
    checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": str(uuid7())}}

agent.invoke({"messages": [{"role": "user", "content": "我叫吴彦祖"}]}, config=config)
result = agent.invoke(
    {"messages": [{"role": "user", "content": "我叫什么?"}]},
    config=config,
)
print(result["messages"][-1].content)   # 记得我叫吴彦祖

成功标志:第二轮回答了第一轮的信息------说明历史被正确记住。


五、进阶:中间件(Middleware)怎么用

create_agent 的可定制性主要来自 middleware(中间件) 。每块中间件只负责一个关注点,挂在 Agent 循环的正确时机,且可自由组合------只取当前需求需要的,跳过其余

5.1 常用预制中间件

中间件 作用 典型场景
ModelRetryMiddleware 模型调用自动重试 应对限流、超时、瞬时错误
ToolRetryMiddleware 工具调用自动重试 工具不稳定、偶发失败
HumanInTheLoopMiddleware 人机协同,指定工具前暂停审批 危险写操作、昂贵调用前人工确认
PIIMiddleware 隐私护栏,脱敏/拦截敏感数据 合规要求,强制性策略
SummarizationMiddleware 历史/上下文压缩 长上下文防溢出
MemoryMiddleware 加载持久化指令 跨会话记忆
SkillsMiddleware 按需加载领域知识 避免一次性全量加载
FilesystemMiddleware 文件系统读写 跨轮次的文件工作区
TodoListMiddleware 任务清单规划 多步复杂任务
SubAgentMiddleware 子代理委托 复杂任务并行分解,主上下文保持干净

5.2 示例:重试 + 人机协同

python 复制代码
from langchain.agents import create_agent
from langchain.agents.middleware import (
    ModelRetryMiddleware,
    ToolRetryMiddleware,
    HumanInTheLoopMiddleware,
)
from langchain.tools import tool

@tool
def search(query: str) -> str:
    """搜索并返回简短摘要。"""
    return f"Search results for: {query}"

agent = create_agent(
    model="google_genai:gemini-3.6-flash",
    tools=[search],
    middleware=[
        ModelRetryMiddleware(max_retries=3),
        ToolRetryMiddleware(max_retries=2),
        HumanInTheLoopMiddleware(interrupt_on={"write_file": True}),
    ],
)

5.3 示例:文件系统 + 记忆 + 技能(来自 deepagents)

python 复制代码
from deepagents.backends import StateBackend
from deepagents.middleware import (
    FilesystemMiddleware,
    MemoryMiddleware,
    SkillsMiddleware,
    SummarizationMiddleware,
)

backend = StateBackend()
model = "google_genai:gemini-3.6-flash"

agent = create_agent(
    model=model,
    tools=[search],
    middleware=[
        FilesystemMiddleware(backend=backend),
        SummarizationMiddleware(model=model, backend=backend),
        MemoryMiddleware(backend=backend, sources=["./AGENTS.md"]),
        SkillsMiddleware(backend=backend, sources=["./skills/"]),
    ],
)

这个示例从 deepagents 包导入,需要先 pip install deepagents

5.4 create_agent() vs create_deep_agent()

  • create_agent :需要你自己配置 Harness,灵活、可控,适合按需组装能力。
  • create_deep_agent :基于 create_agent 构建,已预置常用能力(规划、文件系统工具、子代理、记忆等)。

官方建议:需要深度定制时用 create_agent;想要一个开箱即用、能力齐全的长任务 Agent(coding / research)时用 create_deep_agent


六、总结:你真正需要记住的 N 件事

  1. Agent = Model + Harness。 模型负责思考,Harness 负责在正确时机喂正确上下文;create_agent() 就是帮你组装 Harness 的工厂函数。
  2. create_agent() 返回 CompiledStateGraph ,用 invoke / stream / get_state 等运行和查看状态。
  3. 三件套必配:model + tools + system_prompt model 推荐传字符串;tools 可传 @tool 函数 / Pydantic 类 / 工具字典;system_prompt 建议总是设置。
  4. 自定义状态用 state_schema + 子类化 AgentState + InjectedState,让工具直接读写运行状态。
  5. 结构化输出用 response_format ,从 result["structured_response"] 拿校验过的对象。
  6. 会话记忆用 checkpointer + thread_id ,跨会话长期记忆用 store
  7. 单次运行上下文用 context_schema + context ,它和 thread_id 是两个维度。
  8. 扩展能力靠 middleware:重试、PII 护栏、人机协同、文件系统、子代理、记忆/技能,自由组合、按需取用。
  9. 深度定制用 create_agent,开箱即用选 create_deep_agent

验证清单

  • 能用 from langchain.agents import create_agent 成功导入
  • 最小 Agent(model + system_prompt,无工具)能 invoke 并拿到回复
  • 加入 @tool 工具后,Agent 能在循环中自动调用工具
  • 扩展 AgentState + InjectedState 后,工具能读写自定义状态字段
  • 配置 response_format 后,能从 structured_response 拿到类型安全对象
  • 配置 checkpointer + thread_id 后,第二轮能记住第一轮对话
  • stream(或 stream_events)能实时看到中间步骤 / 工具调用
  • 生产场景下,为关键调用配置了 ModelRetryMiddleware / ToolRetryMiddleware
  • 涉及敏感或破坏性操作时,加了 HumanInTheLoopMiddlewareinterrupt_before/after

参考资源

注:本文撰写时环境中外网访问受限,文中参数与示例主要引用上述 LangChain 官方文档及菜鸟教程页面。为获得最准确的参数与版本信息,请以官方参考为准。

相关推荐
程序员良辰22 分钟前
服务器 JDK 环境变量配置:一键安装和手动配置有什么区别?
开发语言·python
nanawinona25 分钟前
先跑通小流程,再让 AI 和 Python 承接复杂量化
人工智能·python
DeepVisionary27 分钟前
8 月 20 款大模型同台:OpenAI 拆出三档家族,IBM 押注 512K 密集推理,Meta 回头开源 30B
python·自动化
未若君雅裁27 分钟前
自定义中间件:Node-style 与 Wrap-style 钩子全解析
python·中间件·langchain
奈斯先生Vector29 分钟前
本地图片识别怎么接入多模态 AI?用 Python API 理解 GPT-4o Vision 的真实工作流
开发语言·人工智能·windows·python·网络协议·http·aigc
测试老哥36 分钟前
Pytest 之assert断言的使用
自动化测试·软件测试·python·测试工具·测试用例·pytest·接口测试
2601_956319881 小时前
先把交易想法说清,再让 Python 承接
人工智能·python
Swift社区1 小时前
Wi-Fi 6 的核心技术特性
人工智能·python