LangChain系列文章目录

提示:LangChain系列文章的所有文章的目录,请查看我的文章目录。

第一章 LangChain 简介与核心包



前言

本文主要整理 LangChain 提示词工程相关内容,包括 PromptTemplate、ChatPromptTemplate、MessagesPlaceholder、提示词拼接、Few-shot Prompt Template、示例选择器等知识点,并配合代码示例和运行结果进行说明。


LangChain提示词工程

一、Prompt templates(提示词模板)

1.prompt(提示词)

  • 大语言模型以文本作为输入:输入的文本通常被称为提示词(prompt)。
  • 在开发过程中,对于提示词通常不能直接硬编码(也就是直接写),不利于提示词管理,而是通过提示词模板进行维护,类似短信模板、邮件模板等。

2.提示词模板

  • 提示词模板类似与邮件模板、短信模板等,就是一个字符串模板。
  • 提示词模板包含一组模板参数,通过模板参数值替换模板对应的参数。

3.提示词模板组成:

  • 发给大语言模型(LLM)的指令。
  • 一组问答示例,以提醒AI以什么格式返回请求。
  • 发给大语言模型的问题。

二、提示词模板操作

1.版本导入方式

  • LangChain 0.1.0 及以上版本(当前主流):
from langchain_core.prompts import PromptTemplate
from langchain_core.prompts import ChatPromptTemplate
  • LangChain 0.0.x 旧版本,只能用
from langchain.prompts import PromptTemplate
from langchain.prompts import ChatPromptTemplate

2.提示词模板(prompt template)

  • 一般的LLM模型以一段内容为输入。
  • 使用PromptTemplate类创建简单的提示词。
  • 提示词模板可以内嵌任意数量的模板参数,然后通过参数值格式化模板内容。
  • 创建提示词模板示例
    • 使用PromptTemplate.from_template()方法创建提示词模板对象
      • 或者直接使用PromptTemplate()对象创建提示词模板
      • 使用from_template()方法,不能有input_variables参数
    • template参数用于定义模板字符串,其中模板内使用{}创建模板变量
    • input_variables参数,指定对应的输入参数。
    • 没有format_messages()方法。
    • 提示词模板对象使用format()将变量输入,并返回字符串
      • 使用format()方法后,返回字符串,不能用在链条上!
        使用PromptTemplate.from_template()代码:
from langchain_core.prompts import PromptTemplate

# 定义一个提示模板,包含adjective和content两个模板变量
prompt_template = PromptTemplate.from_template(
    template="给我讲一个关于{content}的{adjective}笑话。"
)
print(prompt_template)            # prompt_template是个对象

# 通过模板参数格式化提示模板
result = prompt_template.format(adjective="冷", content="猴子")
print(result)

#############链中使用提示词模板对象#############
# chain = prompt_template | llm | StrOutputParser()
# result = chain.invoke({"adjective": "冷","content": "猴子"})

使用PromptTemplate()代码:

from langchain_core.prompts import PromptTemplate

prompt_template = PromptTemplate(
    template="给我讲一个关于{content}的{adjective}笑话。",
    input_variables=["adjective", "content"]
)
print(prompt_template) 

result = prompt_template.format(adjective="冷", content="猴子")
print(result)

结果:

input_variables=['adjective', 'content'] input_types={} partial_variables={} template='给我讲一个关于{content}的{adjective}笑话。'

给我讲一个关于猴子的冷笑话。
  • 对提示词模板的部分参数填充,生成新的提示词模板
    • 使用partial()方法,填充提示模板中的某些变量,剩下变量可继续使用
    • 使用partial()方法后,会返回一个新的PromptTemplate提示词模板对象
    • partial()参数就是需要填充的提示词模板的变量名
    • partial()参数值可以是字符串,也可以是一个方法
      代码:
from langchain_core.prompts import PromptTemplate

# 定义一个提示模板,包含adjective和content两个模板变量
prompt_template = PromptTemplate.from_template(
    template="给我讲一个关于{content}的{adjective}笑话。"
)

# 修改提示模板 生成新的题词模板
prompt_template2 = prompt_template.partial(content="鹦鹉")
print(prompt_template) 
print(prompt_template2)
result = prompt_template2.format(adjective="冷")
print(result)

结果:

input_variables=['adjective', 'content'] input_types={} partial_variables={} template='给我讲一个关于{content}的{adjective}笑话。'

input_variables=['adjective'] input_types={} partial_variables={'content': '鹦鹉'} template='给我讲一个关于{content}的{adjective}笑话。'

给我讲一个关于鹦鹉的冷笑话。

参数值为函数:

from datetime import datetime
from langchain_core.prompts import PromptTemplate

def get_date():
    now = datetime.now()
    return now.strftime("%Y-%m-%d %H:%M:%S")

prompt = PromptTemplate(
    input_variables=["date", "question"],
    template="如果今天的日期是{date},请问今天是{question}?",
)
partial_prompt = prompt.partial(date=get_date())
print(partial_prompt.format(question="星期几"))

结果:

如果今天的日期是2025-06-20 16:07:29,请问今天是星期几?

3.聊天消息提示词模板(chat prompt template)

  • 聊天模型(Chat Model)以聊天消息列表作为输入,聊天消息列表也可以通过提示词模板进行管理。
  • 聊天消息与原始字符串不同,因为每个消息都与“角色(role)”相关联。
    • 对于系统(system)消息。在一次对话中,部分模型允许多个system消息出现。但部分模型只允许一个system消息出现,如Qwen3.5模型。
  • 例如,Openai聊天模型,为聊天消息定义了三种角色类型:系统(system)、人类(human)、助手(assistant) 、工具(tool):
    • 系统(system)消息: 描述AI身份或背景内容。
    • 人类(user)消息: 是指用户发给AI的内容。
    • 助手(ai)消息: 是指AI回答用户的内容。
    • 工具(tool)消息: 是指调用工具后返回的内容。
  • 创建聊天消息模板示例1(最简单)
    • 使用ChatPromptTemplate.from_messages()方法创建提示词模板对象
      • 或者直接使用ChatPromptTemplate()对象创建提示词模板对象
    • messages参数为聊天消息模板列表。列表的每一个元素代表一条消息,消息以元祖格式定义。每个元组有两个元素,第一个元素代表消息角色,第二个元素代表消息内容。
    • 消息角色:system代表系统消息、human代表人类消息,ai代表LLM返回消息
    • 消息内容:可以使用{}定义模板参数
    • 返回提示词模板对象后,使用format_messages()将提示词模板转为消息对象组成的列表。
      • 参数必须是提示词模板的全部变量
      • 返回提示词模板对象后,可以使用invoke()代替。但一般不建议。
    • 返回提示词模板对象后,使用format()将提示词模板转为字符串。
      • 参数必须是提示词模板的全部变量
        代码:
from langchain_core.prompts import ChatPromptTemplate

# 消息定义了2个模板参数name和user_input
# 或者chat_template = ChatPromptTemplate()
chat_template = ChatPromptTemplate.from_messages(
    messages=[
        ("system", "你是一位人工智能助手,你的名字是{name}。"),
        ("human", "你好"),
        ("ai", "我很好,谢!"),
        ("human", "{user_input}"),
    ]
)
print(chat_template)             # chat_template是一个对象

# 通过模板参数格式化模板内容
messages = chat_template.format_messages(name="Bob", user_input="你名字叫什么?")
print(messages)
print(chat_template.format(name="Bob", user_input="你名字叫什么?"))

#############链中使用提示词模板对象#############
# chain = chat_template | llm | StrOutputParser()
# result = chain.invoke({"name": "Ken"," user_input": "如何称呼你?"})

结果:

input_variables=['name', 'user_input'] input_types={} partial_variables={} messages=[
SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['name'], input_types={}, partial_variables={}, template='你是一位人工智能助手 ,你的名字是{name}。'), additional_kwargs={}), 

HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='你好'), additional_kwargs={}), 

AIMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='我很好,谢!'), additional_kwargs={}), 

HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['user_input'], input_types={}, partial_variables={}, template='{user_input}'), additional_kwargs={})
]

[
    SystemMessage(
        content="你是一位人工智能助手,你的名字是Bob。",
        additional_kwargs={},
        response_metadata={},
    ),
    HumanMessage(content="你好", additional_kwargs={}, response_metadata={}),
    AIMessage(content="我很好,谢!", additional_kwargs={}, response_metadata={}),
    HumanMessage(
        content="你名字叫什么?", 
        additional_kwargs={}, 
        response_metadata={}
    ),
]

System: 你是一位人工智能助手,你的名字是Bob。
Human: 你好
AI: 我很好,谢谢!
Human: 你的名字叫什么?
  • 创建聊天消息模板示例2
    • 使用ChatPromptTemplate.from_messages()方法创建提示词模板对象
    • 使用SystemMessage(content)方法,增加系统对话内容
    • 使用HumanMessage(content)方法,增加人类对话内容
    • 使用AIMessage(content)方法,增加AI增对话内容
      • content参数:消息的文本内容。内容不能加变量。
      • additional_kwargs参数:附加元数据,可选。
      • response_metadata参数:响应时填充的元数据,可选。
      • id消息的唯一标识符(通常由系统自动生成),可选。
    • 返回提示词模板对象后,使用format_messages()方法,返回列表。
      • 方法不能加入参数
    • 返回提示词模板对象后,使用format()方法,返回字符串。
      • 方法不能加入参数
        代码:
from langchain_core.messages import SystemMessage, AIMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate

chat_template = ChatPromptTemplate.from_messages(
    messages=[
        SystemMessage(content=("你是一个乐于助人的助手,喜欢讲笑话。"),
            additional_kwargs={},
            response_metadata={}
        ),
        HumanMessage(content=("你好,我叫steven")),
        AIMessage(content=("你好,steven!很高兴认识你。")),
    ]
)

messages = chat_template.format_messages()
print(messages)
print(chat_template.format())

结果:

[
    SystemMessage(
        content="你是一个乐于助人的助手,喜欢讲笑话。",
        additional_kwargs={},
        response_metadata={},
    ),
    HumanMessage(
        content="你好,我叫steven", additional_kwargs={}, response_metadata={}
    ),
    AIMessage(
        content="你好,steven!很高 兴认识你。",
        additional_kwargs={},
        response_metadata={},
    ),
]

System: 你是一个乐于助人的助手,喜欢讲笑话。
Human: 你好,我叫steven
AI: 你好,steven!很高兴认识你。
  • 创建聊天消息模板示例3
    • 使用ChatPromptTemplate.from_messages()方法创建提示词模板对象
    • 使用SystemMessagePromptTemplate模板对象的from_template()方法,增加系统消息模板
    • 使用HumanMessagePromptTemplate模板对象的from_template()方法,增加人类消息模板
    • 使用AIMessagePromptTemplate模板对象的from_template()方法,增加AI消息模板
      • template参数用于定义模板字符串,其中模板内使用{}创建模板变量
        代码:
from langchain_core.prompts import (
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate,
    AIMessagePromptTemplate,
)
from langchain_core.prompts import ChatPromptTemplate

chat_template = ChatPromptTemplate.from_messages(
    messages=[
        SystemMessagePromptTemplate.from_template(template="你最喜欢{systext}"),
        HumanMessagePromptTemplate.from_template(template="{hmtext}"),
        AIMessagePromptTemplate.from_template(template="{aitext}"),
        HumanMessagePromptTemplate.from_template(template="{hmtext2}"),
    ]
)

# 使用模板参数格式化模板
messages = chat_template.format_messages(
    systext="讲笑话",
    hmtext="我今天心情不太好",
    aitext="我给你讲个关于游泳的笑话。",
    hmtext2="好啊",
)
print(messages)
message_str = chat_template.format(
    systext="讲笑话",
    hmtext="我今天心情不太好",
    aitext="我给你讲个关于游泳的笑话。",
    hmtext2="好啊",
)
print(message_str)

结果:

[
    SystemMessage(
        content="你最喜欢讲笑话", 
        additional_kwargs={}, 
        response_metadata={}
    ),
    HumanMessage(
        content="我今天心情不太好", additional_kwargs={}, response_metadata={}
    ),
    AIMessage(
        content="我给你讲个关于游泳的笑话。", 
        additional_kwargs={}, 
        response_metadata={}
    ),
    HumanMessage(
        content="好啊", additional_kwargs={}, response_metadata={}
    ),
]

System: 你最喜欢讲笑话
Human: 我今天心情不太好
AI: 我给你讲个关于游泳的笑话。
Human: 好啊

SystemMessage…与SystemMessagePromptTemplate…可以混合使用:

chat_template = ChatPromptTemplate.from_messages(
    messages=[
        SystemMessage(content=("你是一个乐于助人的助手,喜欢讲笑话。"),
            additional_kwargs={},
            response_metadata={}
        ),
        HumanMessagePromptTemplate.from_template(template="{hmtext}"),
        AIMessage(content=("你好,steven!很高兴认识你。")),
        HumanMessagePromptTemplate.from_template(template="{hmtext2}"),
    ]
)
# 使用模板参数格式化模板
messages = chat_template.format_messages(
    hmtext="我今天心情不太好",
    hmtext2="你讲个关于游泳的笑话。",
)
  • 创建聊天消息模板示例4
    • 使用ChatPromptTemplate.from_template()创建消息模板
      • 参数template为聊天字符串。
      • 默认字符串前缀system:为系统消息,human:为人类消息,ai:为AI消息
    • 返回提示词模板后使用format_messages(),将提示词模板转为列表。
      • 参数必须是提示词模板的全部变量
    • 返回提示词模板后使用format(),将提示词模板转为字符串。
      • 参数必须是提示词模板的全部变量
        代码:
from langchain_core.prompts import ChatPromptTemplate

chat_template2 = ChatPromptTemplate.from_template(
    template="system:你是一位人工智能助手,你的名字是{name}。\n human:你好。\n ai:我很好,谢!human:{user_input}"
)

messages = chat_template2.format_messages(name="Bob", user_input="你名字叫什么?")
print(chat_template2)
print(messages)
print(chat_template2.format(name="Bob", user_input="你名字叫什么?"))

结果:

input_variables=['name', 'user_input'] input_types={} partial_variables={} messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['name', 'user_input'], input_types={}, partial_variables={}, template='system:你是一位人工智能助手,你的名字是{name}。\n human:你好。\nai:我很好,谢!human:{user_input}'), additional_kwargs={})]

[
    HumanMessage(
        content='system:你是一位人工智能助手,你的名字是Bob。\n human:你好。\n ai:我很好,谢!human:你名字叫什么?', 
        additional_kwargs={}, 
        response_metadata={}
    )
]

Human: system:你是一位人工智能助手,你的名字是Bob。
 human:你好。
ai:我很好,谢!human:你名字叫什么?
  • ChatPromptTemplate.from_template和ChatPromptTemplate.from_messages区别
    • 关键对比
from_template from_messages
输入 一条纯字符串模板 一个消息列表(每条消息各自可以是模板)
角色 依赖字符串前缀(如 system:、user:) 通过列表指定角色(Human/System/AI/Tool/…)
适用场景 单轮对话,消息结构固定 多轮对话、需要动态插入消息(如历史记录)、复杂角色组合的场景
- from_template输入是一条简单的单轮对话提示,如果需要增加角色和历史对话内容,只是在这条对话内容中自定义如system,user,ai等对话。不是真正意义上的多轮对话历史。
- from_messages输入是多轮对话、动态插入历史消息,复杂角色(如函数调用、消息占位符)。是真正意义上的多轮对话历史。
  • 创建聊天消息模板示例5
    • 使用ChatMessagePromptTemplate.from_template()方法,创建指定角色的消息模板
      • role参数用于指定角色
      • template参数用于定义模板字符串,其中模板内使用{}创建模板变量
    • 最后,使用ChatPromptTemplate.from_messages()方法按照顺序组合所有的消息模板
      代码:
from langchain_core.prompts import ChatPromptTemplate, ChatMessagePromptTemplate

# 创建多个ChatMessagePromptTemplate
system_message = ChatMessagePromptTemplate.from_template(
    role="system", template="你是一个有帮助的AI助手,专门回答关于{topic}的问题。"
)
user_message1 = ChatMessagePromptTemplate.from_template(
    role="user", template="你好,我想了解一下{city}的情况。"
)
assistant_message = ChatMessagePromptTemplate.from_template(
    role="assistant",
    template="你好!我乐意为你提供关于{city}的信息。请问想了解什么方面?",
)
user_message2 = ChatMessagePromptTemplate.from_template(
    role="user", template="我想知道{city}的天气怎么样?"
)

# 将多个消息模板组合成一个ChatPromptTemplate
chat_prompt = ChatPromptTemplate.from_messages(
    [system_message, user_message1, assistant_message, user_message2]
)
print(chat_prompt)

# 使用组合后的模板
formatted_messages = chat_prompt.format_messages(topic="旅游", city="北京")
print(formatted_messages)

#############链中使用提示词模板对象#############
# chain = chat_template | llm | StrOutputParser()
# result = chain.invoke({"topic":"历史","city": "北京"})

结果:

input_variables = ["city", "topic"]
input_types = {}
partial_variables = {}
messages = [
    ChatMessagePromptTemplate(
        prompt=PromptTemplate(
            input_variables=["topic"],
            input_types={},
            partial_variables={},
            template="你是一个有帮助的AI助手,专门回答关于{topic}的问题。",
        ),
        additional_kwargs={},
        role="system",
    ),
    ChatMessagePromptTemplate(
        prompt=PromptTemplate(
            input_variables=["city"],
            input_types={},
            partial_variables={},
            template="你好,我想了解一下{city}的情况。",
        ),
        additional_kwargs={},
        role="user",
    ),
    ChatMessagePromptTemplate(
        prompt=PromptTemplate(
            input_variables=["city"],
            input_types={},
            partial_variables={},
            template="你好!我乐意为你提供关于{city}的信息。请问想了解什么方面?",
        ),
        additional_kwargs={},
        role="assistant",
    ),
    ChatMessagePromptTemplate(
        prompt=PromptTemplate(
            input_variables=["city"],
            input_types={},
            partial_variables={},
            template="我想知道{city}的天气怎么样?",
        ),
        additional_kwargs={},
        role="user",
    ),
]

[
    ChatMessage(
        content="你是一个有帮助的AI助手,专门回答关于旅游的问题。",
        additional_kwargs={},
        response_metadata={},
        role="system",
    ),
    ChatMessage(
        content="你好,我想了解一下北京的情况。",
        additional_kwargs={},
        response_metadata={},
        role="user",
    ),
    ChatMessage(
        content="你好!我乐意为你提供关于北京的信息。请问想了解什么方面?",
        additional_kwargs={},
        response_metadata={},
        role="assistant",
    ),
    ChatMessage(
        content="我想知道北京的天气怎么样?",
        additional_kwargs={},
        response_metadata={},
        role="user",
    ),
]

4.聊天消息消息占位符(MessagesPlaceholder)

  • 使用MessagesPlaceholder()方法,传入一个消息列表,将其插入到特定位置。
    • variable_name参数:占位符的变量名,需要与之后传入的字典键名一致。
    • optional参数:若为True,允许该占位符对应的变量为空(默认False,即必须提供)。
  • 需要使用invoke()方法来输入信息,返回对象使用messages属性来获取信息内容
    代码:
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, AIMessage

prompt_template = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful assistant"),
        MessagesPlaceholder(variable_name="msgs1"),
        MessagesPlaceholder("msgs2"),
    ]
)

res = prompt_template.invoke(
    {
        "msgs1": [HumanMessage(content="hi!")], 
        "msgs2": [AIMessage(content="hi! nice to meet you")]
    }
)

print(prompt_template)           # prompt_template是一个对象
print(prompt_template.messages)
print(res)                       # res是一个对象

#############链中使用提示词模板对象#############
# chain = prompt_template | llm | StrOutputParser()
# res = chain.invoke({
#     "msgs1": [HumanMessage(content="hi!")],
#     "msgs2": [AIMessage(content="hi! nice to meet you")]
# })

结果:

input_variables=['msgs1', 'msgs2'] input_types={'msgs1': (annotation=NoneType, required=True, 
...
MessagesPlaceholder(variable_name='msgs2')]
=================================================================
[
    SystemMessagePromptTemplate(
        prompt=PromptTemplate(
            input_variables=[],
            input_types={},
            partial_variables={},
            template="You are a helpful assistant",
        ),
        additional_kwargs={},
    ),
    MessagesPlaceholder(variable_name="msgs1"),
    MessagesPlaceholder(variable_name="msgs2"),
]
==================================================================
messages = [
    SystemMessage(
        content="You are a helpful assistant",
        additional_kwargs={},
        response_metadata={},
    ),
    HumanMessage(content="hi!", additional_kwargs={}, response_metadata={}),
    AIMessage(
        content="hi! nice to meet you", additional_kwargs={}, response_metadata={}
    ),
]
  • 另一种实现相同效果的替代方法
    • 消息角色:使用字符串"placeholder"代表占位符
      代码:
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import HumanMessage, AIMessage

prompt_template = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant"),
    ("placeholder", "{msgs1}")
    ("placeholder", "{msgs2}")
])

res = prompt_template.invoke(
    {
        "msgs1": [HumanMessage(content="hi!")], 
        "msgs2": [AIMessage(content="hi! nice to meet you")]
    }
)

print(prompt_template)           # prompt_template是一个对象
print(prompt_template.messages)

5.拼接消息

  • 使用+号拼接消息。可以是问答提示词,也可以是聊天消息
  • 拼接问答提示词
    代码:
from langchain_core.prompts import PromptTemplate
from datetime import datetime

prompt = (
    PromptTemplate.from_template("如果今天的日期是{date},")
    + "请问今天是"
    + "{question}"
    + "的日子"
)

def get_date():
    now = datetime.now()
    return now.strftime("%Y-%m-%d %H:%M:%S")

res = prompt.format(date=get_date(), question="什么节气")
print(res)

结果:

如果今天的日期是2025-06-20 16:13:50,请问今天是什么节气的日子
  • 拼接聊天消息
    代码:
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.prompts import HumanMessagePromptTemplate
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage

prompt = SystemMessage(content="你是一名架构师")
new_promot = (
    prompt
    + HumanMessage(content="你好")
    + AIMessage(content="有什么可以帮到你")
    + "{input}"
)

res = new_promot.format_messages(input="langchain的架构")
print(res)

结果:

[
    SystemMessage(content="你是一名架构师", additional_kwargs={}, response_metadata={}),
    HumanMessage(content="你好", additional_kwargs={}, response_metadata={}),
    AIMessage(content="有什么可以帮到你", additional_kwargs={}, response_metadata={}),
    HumanMessage(content="langchain的架构", additional_kwargs={}, response_metadata={}),
]

三、小样本示例提示词(Few-shot prompt templates)

1.小样本示例提示词

  • 小样本示例提示词用于问答,而非聊天消息
  • 提示词中可能包含样本,作用是帮助模型更好地理解用户意图,从而更好地回答问题或执行任务。
  • 小样本提示模板是指使用一组少量的示例来指导模型处理新的输入。这些示例可以用来提示模型,以便模型可以更好地理解和回答类似的问题。
  • 小样本示例:
    小样本示例:
Q: 什么是蝙蝠侠?
A: 蝙蝠侠是一个虚构的漫画人物。

Q: 什么是torsalplexity?
A: 未知。

Q: 什么是语言模型?
A:
告诉模型,Q是问题,A是答案,按这种格式进行问答交互。

2.使用示例集

  • 示例集
    • 示例集是一个列表,列表每个元素为一次对话演示的字典。主要由question和answer组成。
      代码:
examples = [
  {
    "question": "谁的寿命更长,穆罕默德·阿里还是艾伦·图灵?",
    "answer":
"""
这里需要跟进问题吗:是的。
跟进:穆罕默德·阿里去世时多大?
中间答案:穆罕默德·阿里去世时74岁。
跟进:艾伦·图灵去世时多大?
中间答案:艾伦·图灵去世时41岁。
所以最终答案是:穆罕默德·阿里
"""
  },
  {
    "question": "craigslist的创始人是什么时候出生的?",
    "answer":
"""
这里需要跟进问题吗:是的。
跟进:craigslist的创始人是谁?
中间答案:craigslist由Craig Newmark创立。
跟进:Craig Newmark是什么时候出生的?
中间答案:Craig Newmark于1952年12月6日出生。
所以最终答案是:1952年12月6日
"""
  },
  {
    "question": "乔治·华盛顿的祖父母中的母亲是谁?",
    "answer":
"""
这里需要跟进问题吗:是的。
跟进:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是Mary Ball Washington。
跟进:Mary Ball Washington的父亲是谁?
中间答案:Mary Ball Washington的父亲是Joseph Ball。
所以最终答案是:Joseph Ball
"""
  },
  {
    "question": "《大白鲨》和《皇家赌场》的导演都来自同一个国家吗?",
    "answer":
"""
这里需要跟进问题吗:是的。
跟进:《大白鲨》的导演是谁?
中间答案:《大白鲨》的导演是Steven Spielberg。
跟进:Steven Spielberg来自哪里?
中间答案:美国。
跟进:《皇家赌场》的导演是谁?
中间答案:《皇家赌场》的导演是Martin Campbell。
跟进:Martin Campbell来自哪里?
中间答案:新西兰。
所以最终答案是:不是
"""
  }
]
  • 格式化提示词模板
    • 使用PromptTemplate(),用于定义模板的结构和变量,格式化提示词模板,也就是修改提示词模板内容或格式。
      • template:定义提示模板的文本结构,包含占位变量。示例:“你好请问{aa}在吗?\n我是{bb}”。语法:用{}包裹变量名,如{question}。注意:所有在input_variables中声明的变量都必须在这里出现。
      • input_variables:声明模板中需要填充的变量名列表。示例:[“question”, “answer”] 表示模板需要两个变量。注意:这些变量必须出现在template字符串中。
    • 使用format()插入模板参数的值
      代码:
from langchain_core.prompts.few_shot import FewShotPromptTemplate
from langchain_core.prompts.prompt import PromptTemplate

# 示例集,省略了
examples = [
...
]

example_prompt = PromptTemplate(
    template="问题:{question}\\n{answer}",
    input_variables=["question", "answer"],
)

# 提取examples示例集合的一个示例的内容,res为字符串
res = example_prompt.format(
    question=examples[0]['question'], 
    answer=examples[0]['answer']
)
print(res)

结果:

问题:谁的寿命更长,穆罕默德·阿里还是艾伦·图灵?\n
这里需要跟进问题吗:是的。
跟进:穆罕默德·阿里去世时多大?
中间答案:穆罕默德·阿里去世时74岁。
跟进:艾伦·图灵去世时多大?
中间答案:艾伦·图灵去世时41岁。
所以最终答案是:穆罕默德·阿里
  • 追加内容到格式化提示词模板中
    • 使用FewShotPromptTemplate()方法,插入内容。
      • examples:可供参考的示例集列表
      • example_prompt:模板对象
      • suffix:在提示词模板最后追加内容
      • input_variables用于定义suffix中包含参数
    • 使用format()执行
      代码:
...
prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    suffix="问题:{input}",
    input_variables=["input"]
)
print(prompt.format(input="乔治·华盛顿的父亲是谁?"))

#############链中使用提示词模板对象#############
# chain = prompt | llm | StrOutputParser()
# res = chain.invoke({"input":"乔治·华盛顿的父亲是谁?"})

结果:

问题:谁的寿命更长,穆罕默德·阿里还是艾伦·图灵?\n
这里需要跟进问题吗:是的。
跟进:穆罕默德·阿里去世时多大?
中间答案:穆罕默德·阿里去世时74岁。
跟进:艾伦·图灵去世时多大?
中间答案:艾伦·图灵去世时41岁。
所以最终答案是:穆罕默德·阿里

问题:craigslist的创始人是什么时候出生的?\n
这里需要跟进问题吗:是的。
跟进:craigslist的创始人是谁?
中间答案:craigslist由Craig Newmark创立。
跟进:Craig Newmark是什么时候出生的?
中间答案:Craig Newmark于1952年12月6日出生。
所以最终答案是:1952年12月6日

问题:乔治·华盛顿的祖父母中的母亲是谁?\n
这里需要跟进问题吗:是的。
跟进:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是Mary Ball Washington。
跟进:Mary Ball Washington的父亲是谁?
中间答案:Mary Ball Washington的父亲是Joseph Ball。
所以最终答案是:Joseph Ball

问题:《大白鲨》和《皇家赌场》的导演都来自同一个国家吗?\n
这里需要跟进问题吗:是的。
跟进:《大白鲨》的导演是谁?
中间答案:《大白鲨》的导演是Steven Spielberg。
跟进:Steven Spielberg来自哪里?
中间答案:美国。
跟进:《皇家赌场》的导演是谁?
中间答案:《皇家赌场》的导演是Martin Campbell。
跟进:Martin Campbell来自哪里?
中间答案:新西兰。
所以最终答案是:不是

问题:乔治·华盛顿的父亲是谁?
  • 示例选择器
    • 使用SemanticSimilarityExampleSelector()方法,根据与输入的相似性选择小样本示例。
    • 该方法使用embedding模型计算输入和小样本示例之间的相似性,然后使用向量数据库执行相似搜索,获取跟输入相似的示例。
      • examples参数:可供参考的示例集列表
      • embeddings参数:指定嵌入类对象
      • vectorstore_cls参数:指定向量数据库类(不是对象!)
      • k参数:返回的示例数量
    • 返回示例选择器对象
    • 可以使用select_examples()测试,是否会找到相似的示例
      代码:
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_community.vectorstores import Chroma
from langchain_huggingface import HuggingFaceEmbeddings

llm_emb = HuggingFaceEmbeddings(
    model_name="D:/python/envs/lc/hfmodel/sentence-transformers/all-MiniLM-L6-v2",
)
examples = [
...
]

example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples=examples,
    embeddings=llm_emb,
    vectorstore_cls=Chroma,
    k=2,
)

# 选择与输入最相似的示例。
question = "乔治·华盛顿的父亲是谁?"
selected_examples = example_selector.select_examples({"question": question})
for example in selected_examples:
    for k, v in example.items():
        print(f"{k}{v}")
        print("---")
    print("================")

#############链中使用提示词模板对象#############

from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate

llm = ChatOpenAI(
    model="Pro/deepseek-ai/DeepSeek-V3",
    # model="Qwen/Qwen2.5-VL-32B-Instruct",
    openai_api_key="sk-key",
    openai_api_base="https://api.siliconflow.cn/v1",
    temperature=0.7,
    max_tokens=8000,
)

# 生成问答格式字符串
examples_text = "\n\n".join(
    [f"问题:{eg['question']}\n{eg['answer']}" for eg in selected_examples]
)
# 生成提示词模板对象
prompt = PromptTemplate(
    template="""请参考下面示例:
{examples_text}
现在回答:
问题:{input}
""",
    input_variables=["examples_text", "input"]
)
chain = prompt | llm | StrOutputParser()
result = chain.invoke({
    "examples_text": examples_text,
    "input": question
})

结果:

answer:
这里需要跟进问题吗:是的。
跟进:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是Mary Ball Washington。
跟进:Mary Ball Washington的父亲是谁?
中间答案:Mary Ball Washington的父亲是Joseph Ball。
所以最终答案是:Joseph Ball
---
question:乔治·华盛顿的祖父母中的母亲是谁?
---
================
answer:
这里需要跟进问题吗:是的。
跟进:穆罕默德·阿里去世时多大?
中间答案:穆罕默德·阿里去世时74岁。
跟进:艾伦·图灵去世时多大?
中间答案:艾伦·图灵去世时41岁。
所以最终答案是:穆罕默德·阿里
---
question:谁的寿命更长,穆罕默德·阿里还是艾伦·图灵?
---
================
  • 将示例选择器提供给FewShotPromptTemplate
    • 无需examples可供参考的示例集列表参数,换成示例选择器对象参数example_selector
      代码:
from langchain_core.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain_community.vectorstores import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_core.prompts.few_shot import FewShotPromptTemplate
from langchain_core.prompts.prompt import PromptTemplate
from langchain_openai import OpenAI
from langchain_core.output_parsers import StrOutputParser

llm = OpenAI(
    model="Pro/deepseek-ai/DeepSeek-V3",
    openai_api_key="sk-key",
    openai_api_base="https://api.siliconflow.cn/v1",
    temperature=0.7,
    max_tokens=8000,
)

llm_emb = HuggingFaceEmbeddings(
    model_name="D:/python/envs/lc/hfmodel/sentence-transformers/all-MiniLM-L6-v2",
)

examples = [
...
]

# 创建示例选择器对象
example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples=examples,
    embeddings=llm_emb,
    vectorstore_cls=Chroma,
    k=2,
)

# 创建示例提示模板
example_prompt = PromptTemplate(
    input_variables=["question", "answer"],
    template="问题: {question}\n答案: {answer}",
)

# 创建Few-Shot提示模板
few_shot_prompt = FewShotPromptTemplate(
    example_selector=example_selector,       # 使用示例选择器
    example_prompt=example_prompt,           # 使用示例提示模板
    prefix="你是一个问答助手。以下是一些示例问答:",
    suffix="问题: {question}\n答案:",
    input_variables=["question"],
)

# 构建链
chain = (
    {"question": lambda x: x}          # 输入映射
    | few_shot_prompt                  # Few-Shot提示模板
    | llm                              # 语言模型
    | StrOutputParser()                # 输出解析器
)

# 运行链
question = "谁更年轻,比尔·盖茨还是史蒂夫·乔布斯?"
response = chain.invoke(question)
print(response)

结果:

这里需要跟进问题吗:是的。
跟进:比尔·盖茨的出生日期是什么时候?
中间答案:比尔·盖茨出生于1955年10月28日。
跟进:史蒂夫·乔布斯的出生日期是什么时候?
中间答案:史蒂夫·乔布斯出生于1955年2月24日。
所以最终答案是:比尔·盖茨

总结

提示:这里对文章进行总结。

本文整理了 LangChain 提示词工程中的常见模板用法,包括普通 PromptTemplate、聊天消息模板 ChatPromptTemplate、消息占位符 MessagesPlaceholder、提示词拼接、小样本提示词 Few-shot Prompt Template 以及示例选择器等内容。实际开发中,建议优先使用模板化方式管理提示词,避免将提示词硬编码在业务代码中,从而提升提示词的可维护性、复用性和工程化能力。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐