掘金 人工智能 前天 15:03
LangChain Prompts模块
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入介绍了LangChain框架中的Prompts模块,该模块旨在提升AI交互中任务的成功率。文章详细讲解了PromptTemplate、ChatPromptTemplate和FewShotPromptTemplate这三大核心组件。PromptTemplate作为基础模板引擎,通过动态参数替换实现指令与数据的解耦;ChatPromptTemplate则专注于多轮对话场景,支持角色化消息模板;FewShotPromptTemplate通过预置示例来引导模型生成特定风格的输出。此外,文章还探讨了f-string、jinja2和mustache等模板渲染格式,以及MessagesPlaceholder在动态管理对话上下文中的应用,为开发者提供了全面的Prompt设计指导。

🔧`PromptTemplate`:基础模板引擎,支持动态参数替换,实现指令与数据的解耦。它允许使用f-string、jinja2或mustache语法格式化模板,通过占位符机制避免硬编码,提高代码复用性。关键属性包括`template`(定义模板字符串)、`template_format`(指定模板渲染格式)和`input_variables`(定义用户需要提供的变量名称列表)。

💬`ChatPromptTemplate`:专为多轮对话场景设计,支持组合system、human、ai等多种消息模板,从而生成适合聊天模型的结构化输入。它由SystemMessagePromptTemplate和HumanMessagePromptTemplate等组件构成,分别用于定义系统消息和用户输入消息的模板。

🔄`MessagesPlaceholder`:用于动态管理对话上下文,解决多轮对话中历史消息注入、格式对齐与动态内容替换等问题。它可以作为ChatPromptTemplate的一部分,灵活地插入和管理对话历史记录,确保对话的连贯性和上下文关联性。

LangChain Prompts模块学习

背景

在AI交互中,清晰的提示词设计与输出控制是提升任务成功率的关键,例如:

由此可以看出,一个“好”的提示词对模型输出结果影响较大,那么如何写好提示词?

本文将介绍LangChain框架提供了哪些Prompts方法

概念介绍

模型输入(Prompts)有助于将用户输入和参数转换为语言模型的指令。这可以用来指导模型的响应,帮助其理解上下文并生成相关且连贯的语言输出。提示模板输出一个 PromptValue。此 PromptValue 可以传递给 LLM 或 ChatModel,也可以转换为字符串或消息列表。此 PromptValue 存在的目的是为了方便在字符串和消息之间切换。LangChain框架主要提供了一下3个PromptTemplate

验证模型:Deepseek-chat

from langchain.chat_models import ChatOpenAIimport osllm = ChatOpenAI(    model="deepseek-chat",    api_key=os.getenv("DEEPSEEK_API_KEY"),    base_url="https://api.deepseek.com/v1",    temperature=0.7,    max_tokens=100)

基础模板类:PromptTemplates

提示模板由一个字符串模板组成。它接受来自用户的一组参数,这些参数可用于生成语言模型的提示。可以使用 f 字符串(默认)、jinja2 或 mustache 语法来格式化模板。

class PromptTemplate(StringPromptTemplate):    template: str                                          # 必填定义提示模板的字符串内容,包含占位符(如 {variable})用于动态替换    template_format: PromptTemplateFormat = "f-string"     # 指定模板渲染格式,可选值:"f-string"、"mustache"、"jinja2"    validate_template: bool = False                        # 是否验证模板合法性(如变量是否匹配、语法是否正确),默认关闭以避免性能损耗
class BasePromptTemplate(    RunnableSerializable[dict, PromptValue], Generic[FormatOutputType], ABC):    """Base class for all prompt templates, returning a prompt."""    功能:定义模板中必须由用户提供的变量名称列表(如 {topic})。这些变量在调用 format() 时需显式传入        示例:input_variables=["adjective", "content"] 对应模板中的 {adjective} 和 content 占位符    input_variables: list[str]    功能:声明模板中的可选变量,通常用于占位符或动态推断场景。这些变量无需用户显式传入,由系统自动处理    optional_variables: list[str] = Field(default=[])    功能:指定输入变量的类型约束(如 intstr)。若未声明,默认所有变量为字符串类型,增强类型安全性    input_types: typing.Dict[str, Any] = Field(default_factory=dict, exclude=True)  # noqa: UP006    功能:定义如何解析模型的输出(如转为 JSON 或结构化数据)    output_parser: Optional[BaseOutputParser] = None    功能:预填充模板中的部分变量(如固定指令、上下文信息),减少重复参数传递。例如,预填 date="2025-05-22" 后,调用时只需传入其他变量    partial_variables: Mapping[str, Any] = Field(default_factory=dict)        功能:用于追踪模板的元数据(如版本、作者)和标签(如分类标记),支持调试与监控    metadata: Optional[typing.Dict[str, Any]] = None  # noqa: UP006    tags: Optional[list[str]] = None

模板渲染格式

f-string
from langchain_core.prompts import PromptTemplateprompt_template = PromptTemplate.from_template("Does {x} like {y} and why? ")prompt = prompt_template.format(x="foo", y="bar")print(prompt)  # Output: Does foo like bar and why? 
from langchain_core.prompts import PromptTemplatetemplate = "Does {x} like {y} and why? "prompt_template = PromptTemplate(    template=template,    template_format="f-string",    validate_template=True,    input_variables=["x", "y"],    optional_variables=[],    input_types={        "x": str,        "y": str,    },    partial_variables={        "brand": "Generic"    },    metadata={        "version": "1.0",        "author": "AI Engineer"    },    tags=["marketing", "product"])# 填充变量并生成提示prompt = prompt_template.format(x="foo", y="bar")print("生成的提示:", prompt) # Output: Does foo like bar and why?# 疑问 prompt_template.format(x="foo", y=99) pormpt输出?
生成的提示: Does foo like 99 and why? 
jinja2
from langchain_core.prompts import PromptTemplatefrom typing import Dict, Anyfrom pydantic import Fieldfrom langchain_core.output_parsers import BaseOutputParserfrom langchain.chat_models import ChatOpenAIimport osfrom langchain_core.messages import AIMessage# 定义一个模板字符串,使用 Jinja2 格式template = """{% if product_category == 'electronics' %}请为{{ product_name }}(电子产品)设计宣传语,强调其技术创新。{% else %}请为{{ product_name }}(普通商品)设计宣传语,突出性价比。{% endif %}"""# 创建 PromptTemplate 实例,配置所有参数prompt_template = PromptTemplate(    template=template,    template_format="jinja2",    validate_template=True,    input_variables=["product_category", "product_name"],    optional_variables=["brand"],    input_types={        "product_category": str,        "product_name": str,        "brand": str    },    partial_variables={        "brand": "Generic"    },    metadata={        "version": "1.0",        "author": "AI Engineer"    },    tags=["marketing", "product"])# 填充变量并生成提示prompt = prompt_template.format(    product_category="electronics",    product_name="智能耳机",    brand="TechBrand")print("生成的提示:", prompt) # Output: 请为智能耳机(电子产品)设计宣传语,强调其技术创新。# 填充变量并生成提示prompt = prompt_template.format(    product_category="merchandise",    product_name="智能耳机",    brand="TechBrand")print("生成的提示:", prompt) # Output: 请为智能耳机(普通商品)设计宣传语,突出性价比。
生成的提示: 请为智能耳机(电子产品)设计宣传语,强调其技术创新。生成的提示: 请为智能耳机(普通商品)设计宣传语,突出性价比。
mustache
from langchain_core.prompts import PromptTemplate# 定义 mustache 风格模板template = """{{#is_electronics}}请为{{product_name}}(电子产品)设计宣传语,强调其技术创新。{{/is_electronics}}{{^is_electronics}}请为{{product_name}}(普通商品)设计宣传语,突出性价比。{{/is_electronics}}"""prompt_template = PromptTemplate(    template=template,    template_format="mustache",    validate_template=False,   # mustache 模板不能自动校验,validate_template 必须设为 False。    input_variables=["product_name", "is_electronics"],    optional_variables=[],    input_types={        "product_name": str,        "is_electronics": bool    },    metadata={        "version": "1.0",        "author": "AI Engineer"    },    tags=["marketing", "product"])# 填充变量并生成提示(电子产品)prompt1 = prompt_template.format(product_name="智能手表", is_electronics=True)print("电子产品提示:", prompt1) # Output: 请为智能手表(电子产品)设计宣传语,强调其技术创新。# 填充变量并生成提示(普通商品)prompt2 = prompt_template.format(product_name="保温杯", is_electronics=False)print("普通商品提示:", prompt2) # Output: 请为保温杯(普通商品)设计宣传语,突出性价比。
电子产品提示: 请为智能手表(电子产品)设计宣传语,强调其技术创新。普通商品提示: 请为保温杯(普通商品)设计宣传语,突出性价比。

对话模板:ChatPromptTemplate

SystemMessagePromptTemplate 和 HumanMessagePromptTemplate 是 ChatPromptTemplate 的组成部分,用于定义不同角色的消息内容

    ChatPromptTemplate用于多轮对话场景,支持组合 system、human、ai 等多种消息模板,生成适合聊天模型的输入。

    HumanMessagePromptTemplate用于定义“用户输入”消息模板,支持变量占位符,灵活插入用户输入内容。

    SystemMessagePromptTemplate用于定义“系统消息”模板,通常用于设定 AI 的角色、行为准则等。

ChatPromptTemplate 类的实例,使用format_messages方法生成适用于聊天模型的提示。

class ChatPromptTemplate(BaseChatPromptTemplate):    """Prompt template for chat models."""    messages: Annotated[list[MessageLike], SkipValidation()]    """List of messages consisting of either message prompt templates or messages."""    validate_template: bool = False    """Whether or not to try validating the template."""
from langchain_core.prompts import ChatPromptTemplatetemplate = ChatPromptTemplate([    ("system", "You are a helpful AI bot. Your name is {name}."),    ("human", "Hello, how are you doing?"),    ("ai", "I'm doing well, thanks!"),    ("human", "{user_input}"),],validate_template = True)prompt_value = template.invoke(    {        "name": "Bob",        "user_input": "What is your name?"    })for message in prompt_value.messages:    print(message.content)# Output:#    SystemMessage: You are a helpful AI bot. Your name is Bob.#    HumanMessage : Hello, how are you doing?#    AIMessage    : I'm doing well, thanks!#    HumanMessage : What is your name?
You are a helpful AI bot. Your name is Bob.Hello, how are you doing?I'm doing well, thanks!What is your name?
from langchain_core.prompts import (    ChatPromptTemplate,    HumanMessagePromptTemplate,    SystemMessagePromptTemplate,)# 定义一个多轮对话模板prompt = ChatPromptTemplate([    SystemMessagePromptTemplate.from_template("你是一个乐于助人的AI助手。"),    HumanMessagePromptTemplate.from_template("请用{language}写一个冒泡排序。"),])# 填充变量并生成消息列表prompt_value = prompt.invoke({"language": "Python"})for message in prompt_value.messages:    print(message.type, ":", message.content)
system : 你是一个乐于助人的AI助手。human : 请用Python写一个冒泡排序。

Messages Placeholder

MessagesPlaceholder 是 LangChain 框架中用于动态管理对话上下文的结构化占位符,主要解决多轮对话中历史消息注入、格式对齐与动态内容替换等问题。

class MessagesPlaceholder(BaseMessagePromptTemplate):    variable_name: str    """Name of variable to use as messages."""    optional: bool = False    """If True format_messages can be called with no arguments and will return an empty        list. If False then a named argument with name `variable_name` must be passed        in, even if the value is an empty list."""    n_messages: Optional[PositiveInt] = None    """Maximum number of messages to include. If None, then will include all.    Defaults to None."""

以下是两种不同的写法:

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholderfrom langchain_core.prompts import MessagesPlaceholdertemplate = ChatPromptTemplate([    ("system", "You are a helpful AI bot."),    MessagesPlaceholder(variable_name="conversation", optional=True)])prompt_value = template.invoke(    {        "conversation": [            ("human", "Hi!"),            ("ai", "How can I assist you today?"),            ("human", "Can you make me an ice cream sundae?"),            ("ai", "No.")        ]    })for message in prompt_value.messages:    print(message.content)
You are a helpful AI bot.Hi!How can I assist you today?Can you make me an ice cream sundae?No.
template = ChatPromptTemplate([    ("system", "You are a helpful AI bot."),    ("placeholder", "{conversation}")])prompt_value = template.invoke(    {        "conversation": [            ("human", "Hi!"),            ("ai", "How can I assist you today?"),            ("human", "Can you make me an ice cream sundae?"),            ("ai", "No.")        ]    })for message in prompt_value.messages:    print(message.content)
You are a helpful AI bot.Hi!How can I assist you today?Can you make me an ice cream sundae?No.

Single-variable template

from langchain_core.prompts import ChatPromptTemplatetemplate = ChatPromptTemplate([    ("system", "You are a helpful AI bot. Your name is Carl."),    ("human", "{user_input}"),])prompt_value = template.invoke("Hello, there!")for message in prompt_value.messages:    print(message.content)
You are a helpful AI bot. Your name is Carl.Hello, there!

示例增强模板:FewShotPromptTemplate

FewShotPromptTemplate是向模型提供你希望它执行的操作的示例, 比如:在提示词中可以添加,按照以下格式生成

class FewShotPromptTemplate(_FewShotPromptTemplateMixin, StringPromptTemplate):    """Prompt template that contains few shot examples."""    validate_template: bool = False    """Whether or not to try validating the template."""    example_prompt: PromptTemplate    """PromptTemplate used to format an individual example."""    suffix: str    """A prompt template string to put after the examples."""    example_separator: str = "\n\n"    """String separator used to join the prefix, the examples, and suffix."""    prefix: str = ""    """A prompt template string to put before the examples."""    template_format: Literal["f-string", "jinja2"] = "f-string"    """The format of the prompt template. Options are: 'f-string', 'jinja2'."""
import osfrom langchain_core.prompts import FewShotPromptTemplate, PromptTemplatefrom langchain.chat_models import ChatOpenAIexamples = [    {        "question": "家庭成员的年龄和职业推理",        "answer": """         1. 母亲是教师,年龄为 40 岁。        2. 父亲比母亲大 5 岁,所以父亲 45 岁。        3. 儿子是程序员,年龄是母亲的一半,即 20 岁。        4. 女儿是医生,年龄比父亲小 10 岁,即 35 岁。        最终结论:        - 父亲:45 岁,职业:未知        - 母亲:40 岁,职业:教师        - 儿子:20 岁,职业:程序员        - 女儿:35 岁,职业:医生        """    },    {        "question": "公司员工的职位与年龄推理",        "answer": """         1. 员工 A 是项目经理,年龄 35 岁。        2. 员工 B 是设计师,年龄比项目经理小 5 岁,即 30 岁。        3. 员工 C 是工程师,年龄是设计师的两倍,即 60 岁。        4. 员工 D 是实习生,年龄比设计师小 10 岁,即 20 岁。        最终结论:        - A:35 岁,职业:项目经理        - B:30 岁,职业:设计师        - C:60 岁,职业:工程师        - D:20 岁,职业:实习生        """    },    {        "question": "学生兴趣小组的年龄与兴趣推理",        "answer": """         1. 学生甲是 15 岁,兴趣是编程。        2. 学生乙比甲大 2 岁,兴趣是绘画。        3. 学生丙比乙小 1 岁,兴趣是音乐。        4. 学生丁比丙大 3 岁,兴趣是运动。        最终结论:        - 甲:15 岁,兴趣:编程        - 乙:17 岁,兴趣:绘画        - 丙:16 岁,兴趣:音乐        - 丁:19 岁,兴趣:运动        """    }]# 创建示例提示模板example_prompt = PromptTemplate(    input_variables=["question", "answer"],    template="问题: {question}\n推理过程:{answer}")few_shot_prompt = FewShotPromptTemplate(    examples=examples,    example_prompt=example_prompt,    prefix="任务说明:回答以下问题\n",    suffix="问题:{user_input}\n答案:",    input_variables=["user_input"])usr_input = """1. 员工 A 是项目经理,年龄 20 岁。        2. 员工 B 是设计师,年龄比项目经理小 4 岁。        3. 员工 C 是工程师,年龄是设计师的两倍。        4. 员工 D 是实习生,年龄比设计师小 10 岁。"""# 生成格式化后的字符串formatted_prompt = few_shot_prompt.format(user_input=usr_input)# 初始化模型llm = ChatOpenAI(    model="deepseek-chat",    api_key=os.getenv("DEEPSEEK_API_KEY"),    base_url="https://api.deepseek.com/v1",    temperature=0.7,    max_tokens=400)# 调用提示模板生成答案response = llm.invoke(formatted_prompt)print(response.content)
/tmp/ipykernel_13815/1004832111.py:71: LangChainDeprecationWarning: The class `ChatOpenAI` was deprecated in LangChain 0.0.10 and will be removed in 1.0. An updated version of the class exists in the :class:`~langchain-openai package and should be used instead. To use it run `pip install -U :class:`~langchain-openai` and import as `from :class:`~langchain_openai import ChatOpenAI``.  llm = ChatOpenAI(### 初始信息整理:1. **员工A**     - 职位:项目经理     - 年龄:20岁  2. **员工B**     - 职位:设计师     - 年龄比项目经理小4岁  3. **员工C**     - 职位:工程师     - 年龄是设计师的两倍  4. **员工D**     - 职位:实习生     - 年龄比设计师小10岁  ### 分步推理:#### 第一步:计算员工B的年龄- 员工B的年龄 = 项目经理的年龄 - 4  - 项目经理(A)的年龄 = 20岁  - 因此,员工B的年龄 = 20 - 4 = **16岁**  #### 第二步:计算员工C的年龄- 员工C的年龄 = 设计师的年龄 × 2  - 设计师(B)的年龄 = 16岁  - 因此,员工C的年龄 = 16 × 2 = **32岁**  #### 第三步:计算员工D的年龄- 员工D的年龄 = 设计师的年龄 - 10  - 设计师(B)的年龄 = 16岁  - 因此,员工D的年龄 = 16 - 10 = **6岁**  #### 验证年龄合理性:- 员工D的年龄为6岁,现实中不太可能成为实习生(通常实习生需成年)。可能是题目设定特殊,暂按逻辑计算。  ### 最终结论:- **A**:20岁,职业:项目经理  - **B**:16岁,职业:设计师  - **C**:32岁,职业:工程师  - **D**:6岁,职业:实习生  ### 完整答案:```- A:20 岁,职业:项目经理- B:16 岁,职业:设计师

流水线模板:PipelinePromptTemplate

PipelinePromptTemplate 用于将多个提示模板(PromptTemplate)或链式组件(如 LLM、工具等)组合成一个“流水线”,实现多阶段、分步处理复杂任务。它常用于需要多步推理、信息汇总、上下文动态注入等场景。

新版 LangChain 已不推荐单独的 PipelinePromptTemplate 类,推荐直接用“RunnablePassthrough链式写法”来实现流水线功能。

from langchain_core.prompts import PromptTemplatefrom langchain_core.runnables import RunnablePassthrough, RunnableSequencefrom langchain.chat_models import ChatOpenAI# 定义子模板city_template = PromptTemplate.from_template("推荐一个适合{season}旅游的城市:")attraction_template = PromptTemplate.from_template("列举{city}的3个热门景点:")food_template = PromptTemplate.from_template("推荐{city}的{attraction}周边美食:")llm = ChatOpenAI(    model="deepseek-chat",    api_key=os.getenv("DEEPSEEK_API_KEY"),    base_url="https://api.deepseek.com/v1",    temperature=0.7,    max_tokens=100)# 构建多阶段链travel_chain = (    RunnablePassthrough.assign(        city=lambda x: llm.invoke(city_template.format(season=x["season"])).content    )    | RunnablePassthrough.assign(        attraction=lambda x: llm.invoke(attraction_template.format(city=x["city"])).content    )    | RunnablePassthrough.assign(        food=lambda x: llm.invoke(food_template.format(            city=x["city"], attraction=x["attraction"]        )).content    )    | (lambda x: f"**{x['season']}旅行攻略**\n城市:{x['city']}\n景点:{x['attraction']}\n美食:{x['food']}"))# 调用链生成攻略result = travel_chain.invoke({"season": "春季"})print(result)
    **春季旅行攻略**    城市:春季是万物复苏、气候宜人的季节,适合去一些风景优美、气候温和的城市旅行。以下推荐几个适合春季旅游的国内外城市,各有特色,供你参考:    ---    ### **国内推荐:**    1. **杭州(浙江)**          - **推荐理由**:西湖的春天桃红柳绿,苏堤、白堤樱花和桃花盛开,龙井茶园新绿盎然。          - **亮点**:漫步西湖、品龙井茶    景点:以下是杭州春季旅游的3个热门景点推荐,结合自然风光与茶文化体验:    ---    ### **1. 西湖(苏堤 & 白堤)**      - **春日特色**:          - 苏堤"六桥烟柳"春色如画,两岸樱花、桃花交错盛开,形成粉色长廊。          - 白堤"一株柳树一株桃"的经典景观,3月底至4月初最佳,桃红柳绿    美食:以下是杭州春季旅游的3个热门景点推荐,结合自然风光、茶文化体验及周边美食,助你规划一场春日味觉与视觉的双重盛宴:    ---    ### **1. 西湖(苏堤 & 白堤)**      - **春日特色**:          - 苏堤"六桥烟柳":两岸樱花、桃花交错盛开,形成粉色长廊,最佳观赏期为3月下旬至4月中旬。          - 白堤经典景观:

本文由博客一文多发平台 OpenWrite 发布!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

LangChain Prompts PromptTemplate ChatPromptTemplate MessagesPlaceholder
相关文章