create_agent 的参数表不长,但有几个参数直接影响线上可维护性:name 让 Agent 有身份,system_prompt 决定它的行为边界,response_format 决定它最后交出什么。这一篇一个一个说。
25.1 name:给 Agent 一个运行时身份
agent = create_agent(
model=model,
name="chat_assistant",
)
response = agent.invoke({"messages": ["你好"]})
for msg in response["messages"]:
msg.pretty_print()
================================ Human Message =================================
你好
================================== Ai Message ==================================
Name: chat_assistant
你好!有什么我可以帮你的吗?
设置 name 后,Agent 产生的 AIMessage 会带上这个名字。它在 Multi-Agent 场景里最常被提及,但实际用途更广:
| 场景 | name 解决什么 |
|---|---|
| 流式输出归因 | 标明当前这段输出由哪个 Agent 产生,尤其多 Agent 协作或嵌套调用时 |
| 消息身份标记 | 保存会话、回放执行、建审计日志、前端展示角色时能认出生成者 |
| 调试与 trace | 多个能力相近的 Agent 并存时,靠名字区分执行链路 |
| 组件化封装 | 检索助手、SQL 助手、报告助手作为模块注册、监控、复用时的稳定标识 |
| 前端可观测性 | 面板上显示「当前活跃 Agent」「本轮输出来源」 |
| 运行时身份 ID | 比展示名更稳定,适合日志检索、监控统计、跨模块协作 |
结论很直接:生产环境显式设置 name,不要依赖默认行为。
25.2 system_prompt:写清角色、格式和工具用法
系统提示词为 Agent 提供任务背景、行为准则和操作指南,通过 system_prompt 参数设置,接受 str 或 SystemMessage 两种类型:
from langchain_core.messages import SystemMessage
agent = create_agent(
model=model,
tools=[add_numbers],
# 两种写法等价
system_prompt="你是一个数学助手,解决日常的算术问题",
# system_prompt=SystemMessage(content="你是一个数学助手,解决日常的算术问题"),
)
好提示词的三个必备要素:
- 明确角色:你是天气助手 / 数学助手,别写「你是一个有用的 AI」;
- 定义输出格式:天气场景给「天气状况 / 温度 / 注意事项」三段,比「说清楚点」有效得多;
- 说明何时使用工具:什么情况下必须查工具、什么情况下直接回答。
agent = create_agent(
model=model,
tools=[get_weather],
system_prompt="""你是天气助手。
工作流程:
1. 理解用户的城市查询
2. 使用 get_weather 工具获取数据
3. 简洁清晰地回答
输出格式:
- 天气状况
- 温度
- 注意事项(如有)
""",
)
一个实验能说明提示词的分量:某天气工具前两次返回「天气服务暂时不可用」,提示词里没写重试策略时,Agent 直接就放弃了;把「遇到 TEMP_UNAVAILABLE 前缀要重试,最多 3 次」写进去,它就会连续调三次直到成功(见上一篇 24.5)。
提示词分静态与动态两种设置方式,动态需要中间件,后续章节再讲。
25.3 Agent 的结构化输出:和模型的有什么不同
第 06 章讲的是「模型 + with_structured_output」,Agent 这边叫 response_format,两者差别不小:
| 维度 | 模型的结构化输出 | Agent 的结构化输出 |
|---|---|---|
| 操作对象 | 大模型对象 | Agent |
| 解析时机 | 每次模型调用生成 AIMessage 时解析 | 仅在 Agent 判定「任务结束」输出最终答案时解析 |
| 数据流转 | 模型 → 结构化对象 | 模型 → 工具 → 反思 → … → 结构化对象 |
| 绑定方式 | with_structured_output |
response_format 参数 |
| 适用场景 | 单次、确定性任务(抽字段、翻译、分类) | 多步、复杂推理(查文档后汇总报表) |
关键差别在「解析时机」:模型侧每次调用都要合规;Agent 侧只关心最后那一次,中间的思考过程可以是自然语言、可以是工具调用。
结果存放位置也不一样——不在 messages 里,而在状态字典的 structured_response 键上:
result = agent.invoke({"messages": [{"role": "user", "content": "..."}]})
print(result["structured_response"])
25.4 四种策略:response_format 怎么选
create_agent(
...,
response_format: Union[
ToolStrategy[StructuredResponseT],
ProviderStrategy[StructuredResponseT],
type[StructuredResponseT],
None,
] = None,
)
ProviderStrategy 用供应商原生能力,在模型解码阶段就强制格式,适合 OpenAI、Anthropic Claude、xAI Grok 这类支持的模型:
from langchain.agents.structured_output import ProviderStrategy
class ContactInfo(BaseModel):
"""用户的联系方式"""
name: str = Field(description="用户姓名")
email: str = Field(description="用户邮箱地址")
phone: str = Field(description="用户的手机号")
agent = create_agent(model=model, response_format=ProviderStrategy(ContactInfo))
response = agent.invoke({"messages": [
HumanMessage("从这段话中抽取结构化信息:小明的邮箱地址为 shkstart@atguigu.com,手机号:12345678912")
]})
ToolStrategy 适用于不支持原生结构化输出的模型:它动态创建一个「虚拟工具」,参数就是你期望的结构,然后引导模型去「调用」这个工具,间接产出结构化数据。兼容任何支持工具调用的模型:
from langchain.agents.structured_output import ToolStrategy
agent = create_agent(
model=model,
tools=[search_tool], # 业务工具照常传
response_format=ToolStrategy(ContactInfo),
)
result = agent.invoke({"messages": [
{"role": "user", "content": "联系人信息:John Doe, john@atguigu.com, (010) 56253825"}
]})
print(result["structured_response"])
# name='John Doe' email='john@atguigu.com' phone='(010) 56253825'
直接传 Schema 会被包装成 AutoStrategy:模型支持原生就用 ProviderStrategy,否则回落 ToolStrategy。
agent = create_agent(model=model, response_format=ContactInfo) # 自动选择策略
要注意版本变化:LangChain 1.0 起官方不再推荐直接传模式,要求显式用 ToolStrategy 或 ProviderStrategy;当前 1.2 实测仍可用,但别把这种写法留在生产代码里。
None 是默认值,就是不用结构化输出、正常自然语言回答。
25.5 小结
三个参数各司其职:name 给运行时身份,system_prompt 定行为边界,response_format 定最终产出。Agent 的结构化输出与模型侧最大的不同是「只在任务结束时解析」,结果落在 structured_response 而不是消息列表里。
下一篇进入 ToolStrategy 的三个参数:怎么用 tool_message_content 把数据块换成一句确认、用 handle_errors 控制重试与报错,以及那两类一定会遇到的异常。
上一篇:绑定工具与 ReAct 循环;系列第一篇:为什么需要 LangChain。
本文根据公开课程课件整理,并结合 LangChain 官方文档核对与补充。