LangChain第八节-Agent 提示词与动态提示词
上一篇我们创建了 Agent,但它的行为是“默认”的。
你想让它更专业、更个性、更听话?
关键就在于:提示词(Prompt)。
写在前面:为什么提示词如此重要?
你可能已经发现:
- 同一个模型,不同的提示词,输出质量天差地别;
- 同一个 Agent,面对普通用户和 VIP 用户,本应给出不同风格的回答;
- 你想让 Agent 专注某个领域,但它总是“跑题”。
在 LangChain 中,提示词为 Agent 提供了任务背景、行为准则和操作指南。
通过 system_prompt 参数设置,它本质上定义了 Agent 的“角色”和“使命”。
提示词设置有两种方式:
- 基础设置:创建 Agent 时传入一个固定的
system_prompt - 动态设置:根据运行时上下文或 Agent 状态,实时生成不同的提示词
本文你会学到:
- 如何用字符串和
SystemMessage设置基础提示词 - 如何用
@dynamic_prompt中间件实现动态提示词 - 如何通过
context_schema定义运行时上下文 - 一个完整的电商客服案例:普通用户 vs VIP 用户
建议先收藏,再跟练。
本文假设你已完成环境搭建,并拥有 DeepSeek API Key。
一、基础提示词设置
基础提示词设置是在 create_agent 时传入一个参数 system_prompt。
这个参数可以是:
- 字符串
str SystemMessage类型
案例:使用字符串和 SystemMessage 设置系统提示词
from langchain.agents import create_agent
from langchain_core.messages import SystemMessage
from langchain_core.tools import tool
from init_llm import deepseek_llm
# 工具:实现两数相加
@tool
def add_numbers(a: int, b: int) -> str:
"""计算并返回两个数的和。"""
return f"和为:{a + b}"
if __name__ == '__main__':
"""创建数学助手 Agent"""
agent = create_agent(
model=deepseek_llm,
tools=[add_numbers],
# 方式一:字符串
# system_prompt="你是一个数学助手,可以实现两数相加。"
# 方式二:SystemMessage
system_prompt=SystemMessage(content="你是一个数学助手,可以实现两数相加。")
)
resp = agent.invoke(
{"messages": [{"role": "user", "content": "10加上20再加上30是多少?"}]}
)
print("resp:", resp)
result = resp["messages"][-1].content
print(result)
运行结果:
10加上20再加上30的和是60。
基础提示词适合角色固定、行为稳定的场景。
二、动态提示词设置
对于需要根据运行时上下文或 Agent 状态调整提示词的高级场景,可以使用中间件(Middleware)实现动态提示词。
通过 @dynamic_prompt 装饰器创建中间件,可以根据用户角色生成不同的系统提示。
案例:电商客服 Agent,普通用户 vs VIP 用户
1. 定义两个工具
from langchain.agents import create_agent
from langchain.agents.middleware import dynamic_prompt, ModelRequest
from langchain_core.tools import tool
from typing import TypedDict
import json
from my_llm import deepseek_llm
# 工具1:模拟查询订单信息
@tool
def query_order_info(order_id: str) -> str:
"""根据订单ID查询订单的详细信息,包括状态、商品列表和创建时间。"""
order_database = {
"ORD123456": {"status": "已发货", "items": ["手机X1"], "create_time": "2025-01-15"},
"ORD654321": {"status": "待付款", "items": ["耳机Y1"], "create_time": "2025-01-18"}
}
order_data = order_database.get(order_id)
if order_data:
return json.dumps(order_data, ensure_ascii=False)
else:
return f"错误:未找到订单 {order_id}。"
# 工具2:模拟检索常见问题解答
@tool
def search_faq(keyword: str) -> str:
"""根据关键词从知识库中检索相关的政策条款或解决方案。"""
faq_knowledge_base = {
"退货": "支持7天无理由退货,商品需完好且包装齐全。",
"保修": "电子产品享受1年免费保修服务。",
"发货": "下单后48小时内发货,偏远地区可能延迟。"
}
for topic, answer in faq_knowledge_base.items():
if topic in keyword:
return answer
return f"未找到与'{keyword}'直接相关的政策,请尝试其他关键词或联系人工客服。"
2. 定义运行时上下文的数据结构
class AgentContext(TypedDict):
query_type: str # 'normal'(普通用户) 或 'vip'(VIP用户)
3. 定义动态提示词中间件
@dynamic_prompt
def dynamic_support_prompt(request: ModelRequest) -> str:
"""
根据 query_type 生成不同的系统提示词。
"""
query_type = request.runtime.context.get("query_type", "normal")
base_instruction = "你是一名专业的电商客服助手。请根据工具查询结果,准确、清晰地回答用户问题。"
if query_type == "vip":
return f"""{base_instruction}
当前角色:高级支持专员
工作要求:
1.深度分析:仔细分析用户描述,识别潜在的根本问题。
2.精准分类:将问题明确归类(如“物流问题”、“产品质量”、“售后申请”)。
3.方案规划:若工具能解决,提供具体步骤;若需人工,明确告知后续流程。
请使用更专业、严谨的语言。
"""
else:
return f"""{base_instruction}
当前角色:一线客服助手
工作要求:
1.快速响应:优先使用工具获取订单/政策信息。
2.直接解答:对于明确问题(如退货、物流),直接给出基于知识的答案。
3.简洁友好:回复要简单明了,避免复杂术语。
保持友好和高效的沟通风格。
"""
4. 创建 Agent 并演示
if __name__ == "__main__":
agent = create_agent(
model=deepseek_llm,
tools=[query_order_info, search_faq],
middleware=[dynamic_support_prompt], # 挂载动态提示词中间件
context_schema=AgentContext # 关联上下文 schema
)
user_query = "我的订单ORD654321已签收,但是物品坏了怎么办?"
print(f"用户问题:{user_query}\n")
print("场景一:普通客服模式 (query_type: 'normal')")
result_normal = agent.invoke(
{"messages": [{"role": "user", "content": user_query}]},
context={"query_type": "normal"}
)
final_response_normal = result_normal["messages"][-1].content
print(final_response_normal)
print("\n" + "=" * 50)
print("场景二:VIP模式 (query_type: 'vip')")
result_vip = agent.invoke(
{"messages": [{"role": "user", "content": user_query}]},
context={"query_type": "vip"}
)
final_response_vip = result_vip["messages"][-1].content
print(final_response_vip)
运行结果对比(精简)
普通客服模式:
根据查询到的信息,我为您提供以下建议:
1. 订单状态显示"待付款",但您已签收商品且发现损坏……
2. 建议立即拍照取证,联系人工客服……
(语言简洁友好)
VIP 模式:
基于目前的信息,我为您提供以下专业分析和建议:
## 问题分类:产品质量问题
### 当前情况分析:
1. 订单状态异常……
### 建议处理方案:
第一步:核实订单信息……
(语言专业严谨,有分析框架)
可以看到,同一个 Agent,根据 query_type 的不同,自动切换了角色和回答风格。
三、关键点解析
1. 两个工具的作用
query_order_info:根据订单 ID 查询订单基本信息(状态、商品、创建时间)。search_faq:从知识库中检索与用户问题相关的政策或解决方案(退货流程、保修期限)。
2. 动态提示词如何工作?
动态提示词能根据运行时上下文(如用户身份、问题类型)实时生成最合适的系统提示词,实现精准化、个性化回复。
通过 create_agent 时传入自定义中间件函数(@dynamic_prompt 装饰)来挂载。
3. context_schema 与 context 参数
create_agent 中的 context_schema 参数作用是定义运行时上下文有哪些数据。
它是一个 TypedDict 类型,用于指定执行单次任务时可能需要的动态数据(如用户 ID、用户等级)。
步骤:
- 使用
TypedDict定义上下文数据结构:class AgentContext(TypedDict): query_type: str # user_id: int # 可扩展 - 在
create_agent时通过context_schema=AgentContext告知 Agent 上下文结构。 - 调用
agent.invoke时,通过context参数传入符合该结构的实际数据:agent.invoke( {"messages": [...]}, context={"query_type": "vip"} )
四、避坑指南
-
system_prompt可以是字符串或SystemMessage
两者效果基本一致,按个人习惯选择。 -
动态提示词中间件必须用
@dynamic_prompt装饰
不要和@wrap_model_call混淆,后者用于动态选择模型。 -
context_schema是 TypedDict
定义清楚字段类型,调用时传入的context必须符合该结构。 -
request.runtime.context获取上下文
在动态提示词函数中,通过request.runtime.context.get(...)读取传入的数据。 -
工具函数的 docstring 不能省
Agent 依赖工具描述决定是否调用,描述清晰能显著提升准确率。 -
动态提示词在每个推理步骤前都会触发
和wrap_model_call类似,注意不要写太重的逻辑。
五、总结
这篇我们讲完了 LangChain Agent 的提示词设置:
- 基础提示词:
create_agent时传入system_prompt,支持字符串和SystemMessage; - 动态提示词:通过
@dynamic_prompt中间件,根据运行时上下文实时生成提示词; - 上下文定义:用
TypedDict定义context_schema,调用时通过context传入数据; - 实战案例:电商客服 Agent,普通用户和 VIP 用户获得不同风格的回答。
一句话记住:
基础提示词定义“你是谁”,动态提示词决定“你面对谁时该怎么说话”。
更多推荐
所有评论(0)