上一篇我们创建了 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、用户等级)。

步骤:

  1. 使用 TypedDict 定义上下文数据结构:
    class AgentContext(TypedDict):
        query_type: str
        # user_id: int  # 可扩展
    
  2. 在 create_agent 时通过 context_schema=AgentContext 告知 Agent 上下文结构。
  3. 调用 agent.invoke 时,通过 context 参数传入符合该结构的实际数据:
    agent.invoke(
        {"messages": [...]},
        context={"query_type": "vip"}
    )
    

四、避坑指南

  1. system_prompt 可以是字符串或 SystemMessage
    两者效果基本一致,按个人习惯选择。

  2. 动态提示词中间件必须用 @dynamic_prompt 装饰
    不要和 @wrap_model_call 混淆,后者用于动态选择模型。

  3. context_schema 是 TypedDict
    定义清楚字段类型,调用时传入的 context 必须符合该结构。

  4. request.runtime.context 获取上下文
    在动态提示词函数中,通过 request.runtime.context.get(...) 读取传入的数据。

  5. 工具函数的 docstring 不能省
    Agent 依赖工具描述决定是否调用,描述清晰能显著提升准确率。

  6. 动态提示词在每个推理步骤前都会触发
    和 wrap_model_call 类似,注意不要写太重的逻辑。


五、总结

这篇我们讲完了 LangChain Agent 的提示词设置:

  1. 基础提示词:create_agent 时传入 system_prompt,支持字符串和 SystemMessage;
  2. 动态提示词:通过 @dynamic_prompt 中间件,根据运行时上下文实时生成提示词;
  3. 上下文定义:用 TypedDict 定义 context_schema,调用时通过 context 传入数据;
  4. 实战案例:电商客服 Agent,普通用户和 VIP 用户获得不同风格的回答。

一句话记住:

基础提示词定义“你是谁”,动态提示词决定“你面对谁时该怎么说话”。


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐