目录
- 前言
- [一、什么是 @dynamic_prompt?](#一、什么是 @dynamic_prompt?)
- 二、工作机制详解
-
- [2.1 执行时机:每次模型调用前](#2.1 执行时机:每次模型调用前)
- [2.2 替换规则:完全覆盖,一次有效](#2.2 替换规则:完全覆盖,一次有效)
- 三、代码示例:基于用户角色动态调整提示词
前言
- 在构建基于 LangChain 的智能 Agent 时,系统提示词(System Prompt)是塑造模型行为和角色定位的关键。通常,我们在创建 Agent 时通过 system_prompt 参数设置一个静态的提示词。但实际应用中,我们往往需要根据不同的用户、上下文或对话阶段动态调整提示词。LangChain 提供的 @dynamic_prompt 中间件正是为此而生。
- 本文将结合 LangChain 官方文档,详细讲解 @dynamic_prompt 的用法、工作机制
一、什么是 @dynamic_prompt?
-
@dynamic_prompt 是 LangChain Agents 中的一个中间件装饰器,钩子(执行时机)本质是
before_model,它允许我们在每次模型调用之前,根据当前的运行时上下文(context、agentstate)动态生成系统提示词。这意味着你可以让同一个 Agent 在面对不同场景时表现出截然不同的行为风格,而无需创建多个 Agent 实例。 -
核心思想:
- 静态提示词:创建 Agent 时设定的固定提示词,作为默认配置。
- 动态提示词:通过
@dynamic_prompt定义的中间件在运行时生成的提示词,每次模型调用前都会重新计算,并完全替换静态提示词(如果存在)。
二、工作机制详解
2.1 执行时机:每次模型调用前
@dynamic_prompt 装饰的中间件是一个包装式 (Wrap-style)中间件,它在 Agent 准备调用底层大语言模型进行推理之前执行。这意味着:
- 如果 Agent 在一次任务中需要多次调用模型(例如 ReAct 循环中的多次推理和工具调用),每一次模型调用前,动态提示词函数都会被触发。
- 这确保了系统提示词可以基于最新的状态(如对话轮次、已执行的工具结果)进行调整。
2.2 替换规则:完全覆盖,一次有效
动态提示词函数返回一个字符串,该字符串会成为本次模型调用实际使用的系统提示词。无论创建 Agent 时是否设置了静态 system_prompt,它都会被这个动态生成的字符串完全替换。
重要的是,这种替换是一次性的:
-
当前模型调用结束后,修改不会持久化到 Agent 的配置中。
-
下一次模型调用如果没有再次经过 @dynamic_prompt 中间件的干预,将恢复使用 Agent 创建时的默认静态提示词(如果设置了的话),或者不使用系统提示词。
python创建 Agent │ ├─ 提供了静态 system_prompt? ── 是 ──→ 存储为默认提示词 │ └─ 否 ──→ 无默认提示词 用户调用 Agent (例如:invoke) │ ├─ 请求进入 @dynamic_prompt 中间件 │ │ │ └─ 执行动态函数,根据当前 context 生成新提示词字符串 │ ├─ 中间件将生成的字符串设置为本次模型调用的 system_prompt │ ├─ 模型使用动态提示词进行推理 │ └─ 本次调用结束,Agent 状态重置(提示词修改不保留) 下一次模型调用(新步骤或新请求) │ └─ 再次触发 @dynamic_prompt,重新生成提示词(可能基于新 context)
三、代码示例:基于用户角色动态调整提示词
以下代码改编自 LangChain 官方文档,演示了如何根据 user_role 上下文动态生成不同的系统提示词
python
from typing import TypedDict
from langchain.agents import create_agent
from langchain.agents.middleware import dynamic_prompt, ModelRequest
from langchain_openai import ChatOpenAI
# 1. 定义上下文结构(用于传入动态信息)
class Context(TypedDict):
user_role: str
# 2. 定义动态提示词中间件
@dynamic_prompt
def user_role_prompt(request: ModelRequest) -> str:
"""根据用户角色生成不同的系统提示词"""
user_role = request.runtime.context.get("user_role", "user")
base_prompt = "You are a helpful assistant."
if user_role == "expert":
return f"{base_prompt} Provide detailed technical responses."
elif user_role == "beginner":
return f"{base_prompt} Explain concepts simply and avoid jargon."
return base_prompt
# 3. 创建 Agent(可以同时设置静态提示词,但会被动态替换)
model = ChatOpenAI(model="gpt-4")
agent = create_agent(
model=model,
tools=[], # 此处省略工具定义
middleware=[user_role_prompt], # 注册动态提示词中间件
system_prompt="You are a default assistant.", # 静态提示词(可选)
context_schema=Context
)
# 4. 调用 Agent,传入不同的 context
# 第一次调用:专家模式
result1 = agent.invoke(
{"messages": [{"role": "user", "content": "Explain transformer architecture."}]},
context={"user_role": "expert"}
)
# 实际使用的系统提示词: "You are a helpful assistant. Provide detailed technical responses."
# 第二次调用:新手模式
result2 = agent.invoke(
{"messages": [{"role": "user", "content": "Explain transformer architecture."}]},
context={"user_role": "beginner"}
)
# 实际使用的系统提示词: "You are a helpful assistant. Explain concepts simply and avoid jargon."
# 第三次调用:未提供 context,使用默认
result3 = agent.invoke(
{"messages": [{"role": "user", "content": "Explain transformer architecture."}]}
)
# 实际使用的系统提示词: "You are a helpful assistant." (由动态函数返回的 base_prompt)