提示工程-上
所以,为什么输出解析器指定的format_instructions之后,为什么能够让模型生成结构化的输出?
你只需打印最终传递给大模型的提示就好了
原来,,在LangChain框架中,输出解析器在生成提示(prompt)时,隐式地在原始提示中加入了一段特殊文本,这段文本位于 {format_instructions} 部分。LangChain自动将这段格式化指令添加到提示中,明确告知模型输出所需的结构和格式。这段指令详细地描述了我们希望得到的响应格式,通常以特定的schema(数据结构定义)来表达。
原理解析:
- {format_instructions} 的作用:在LangChain中,
{format_instructions}实际上是一个指示模型如何格式化其输出的模板。它告诉模型必须遵循某种结构或规则来生成输出。这种结构可以是一个JSON对象,也可以是其他标准化格式的输出。此格式化指令从一个json开头,到结束,形成一个明确的格式要求。 - Schema的含义:在这里,
schema是对输出数据结构的描述。它是一个规定了数据组织形式的模板,确保模型输出的结果符合预定的数据格式(例如,JSON格式)。这种结构化的输出能够使模型生成的结果更加规范化、可解析且符合后续处理的需求。 - 模型响应的引导:通过这种明确的提示工程(Prompt Engineering),模型(特别是像GPT-3.5及以上版本这种具有较高智能的模型)能够根据给定的格式化指令生成符合期望的数据结构。例如,若提示中要求生成JSON格式的输出,模型将按照JSON的语法和结构来组织输出内容。
基本上,对所有主要语言模型进行的研究表明,在提示中包含例子都将产生更高质量的答案。 在针对大模型的提示工程(Prompt Engineering)方面,吴恩达老师在他的公开课程《ChatGPT Prompt Engineering for Developers》中,提出了两个核心原则:清晰而具体的指示和给模型足够的思考时间。这两个原则旨在确保大语言模型能够理解并有效地处理任务,输出高质量的响应。
类似的原则也出现在OpenAI官方文档中的《GPT最佳实践》部分,其中列出了六大策略,这些策略与吴恩达的原则高度契合:
- 写清晰的指示:提供明确、具体的指令,避免模糊或不明确的表达,确保模型能够理解并正确执行任务。
- 给模型提供参考(示例) :通过提供示例或参考答案,帮助模型理解期望的输出格式或行为。
- 将复杂任务拆分成子任务:对于难度较大的任务,将其拆解成较小、易于处理的子任务,帮助模型逐步解决问题。
- 给GPT时间思考:为模型提供足够的时间进行深思熟虑,避免过于简短的反馈或急于生成结果,从而提升回答的质量。
- 使用外部工具:在需要时,可以结合外部工具或API,拓展模型的功能或提供额外的信息支持。
- 反复迭代问题:通过多次提问和调整提示,逐步优化输出,确保结果满足预期。
下面,我们进一步探讨如何做好提示工程
提示的结构
这是一个实用的提示框架ICIO 框架
🤖 Instruction (任务) :你希望 AI 去做的任务,比如翻译或者写一段文字
📋 Context (背景) :给 AI 更多的背景信息,引导模型做出更贴合需求的回复,比如你要他写的这段文字用在什么场景的、达到什么目的的
📖 Input Data (输入数据) :告诉 AI 你这次你要他处理的数据。 比如你要他翻译那么你每次要他翻译的句子就是「输入数据」
📤 Output Indicator (输出格式) :告诉 AI 他输出的时候要用什么格式、风格、类型,如果你无所谓它输出时候的格式,也可以不写
案例 - 翻译法文到英文用于商务报告
# Intruction
描述:请将以下的法文段落翻译成英文。
重要性:翻译的准确性对于我们的商务报告至关重要。
# Context
场景:这段法文将用于我们公司的年度商务报告。
目的:报告将呈现给公司的股东和潜在投资者,所以翻译需要准确且专业。
# Input Data
"La croissance économique de la France a été stable au cours des dernières années, malgré les défis mondiaux."
# Output Indicator
风格:正式和专业的商务英文风格。
注意事项:请确保翻译内容无语法错误,并保持原文的意思。
LangChain中提供String(StringPromptTemplate)和Chat(BaseChatPromptTemplate)两种基本类型的模板,并基于它们构建了不同类型的提示模板:
这些模板的导入方式如下:
# 从 LangChain 的提示模块(prompts)中导入各种提示模板类
# PromptTemplate 是基础的提示模板类,用于创建简单的模板
from langchain.prompts.prompt import PromptTemplate
# FewShotPromptTemplate 是一个增强版的提示模板,适用于少量示例(few-shot learning)场景
# 适合用在需要模型学习一些示例并根据这些示例进行推理的任务中
from langchain.prompts import FewShotPromptTemplate
# PipelinePromptTemplate 主要用于定义一个提示管道(Pipeline),
# 这种管道允许多个模板按顺序组合使用,适合复杂任务的处理
from langchain.prompts.pipeline import PipelinePromptTemplate
# ChatPromptTemplate 用于定义聊天模型(如 GPT)的提示模板,适合用于对话型模型的场景
# 可以为模型构建一个聊天对话的上下文模板
from langchain.prompts import ChatPromptTemplate
# 从 langchain.prompts 中导入几种不同类型的消息模板,分别用于不同的消息角色
# 这些模板帮助为多轮对话构建具体的消息格式,使得对话变得更加结构化和清晰
# ChatMessagePromptTemplate 用于构建聊天消息的模板,适用于处理具有多轮对话的聊天模型
from langchain.prompts import ChatMessagePromptTemplate
# SystemMessagePromptTemplate 用于构建系统消息的模板,通常由系统发送,用于设置对话的环境或规则
from langchain.prompts import SystemMessagePromptTemplate
# AIMessagePromptTemplate 用于构建 AI 消息的模板,定义 AI 的回答格式
from langchain.prompts import AIMessagePromptTemplate
# HumanMessagePromptTemplate 用于构建人类用户消息的模板,定义用户输入的格式
from langchain.prompts import HumanMessagePromptTemplate
下面将分别介绍各个模板的使用
1. 使用 PromptTemplate
代码示例
pythonfrom langchain import PromptTemplate
template = """\
你是业务咨询顾问。
你给一个销售{product}的电商公司,起一个好的名字?
"""
prompt = PromptTemplate.from_template(template)
print(prompt.format(product="鲜花"))
解释
PromptTemplate 是 LangChain 提供的一个强大工具,它允许用户创建灵活且可复用的提示(prompts)。通过占位符 {},你可以将动态值传入模板中,生成特定场景下的提示信息。
-
模板创建:
- 在上面的示例中,
template字符串是一个简单的提示模板,其中"{product}"是一个占位符,它将被实际的产品名替换。这个模板要求用户作为“业务咨询顾问”,根据给定的产品(如“鲜花”),提供电商公司命名建议。
- 在上面的示例中,
-
创建
PromptTemplate对象:- 使用
PromptTemplate.from_template(template),我们可以将一个包含占位符的模板字符串转换为一个PromptTemplate对象。这个对象能够接受不同的变量进行格式化。
- 使用
-
格式化模板:
- 调用
prompt.format(product="鲜花")时,product变量的值(例如 "鲜花")会替换掉模板中的{product}占位符。最终,得到的提示会是:
你是业务咨询顾问。 你给一个销售鲜花的电商公司,起一个好的名字? - 调用
-
灵活性:
- LangChain 的
PromptTemplate通过from_template方法自动从模板字符串中提取变量名(如product)。这意味着你无需显式地指定哪些变量需要格式化。
- LangChain 的
手动指定 input_variables
你也可以通过构造函数手动指定变量名。例如:
pythonprompt = PromptTemplate(
input_variables=["product", "market"],
template="你是业务咨询顾问。对于一个面向{market}市场的,专注于销售{product}的公司,你会推荐哪个名字?"
)
print(prompt.format(product="鲜花", market="高端"))
这将生成:
你是业务咨询顾问。对于一个面向高端市场的,专注于销售鲜花的公司,你会推荐哪个名字?
这种方式直接在 PromptTemplate 对象创建时指定了输入变量,而不依赖 from_template 方法自动提取变量。
2. 使用 ChatPromptTemplate
对于基于 OpenAI GPT 等聊天模型的对话应用,LangChain 提供了专门为这种场景设计的模板:ChatPromptTemplate。这种模板适用于多轮对话并区分不同角色(如系统消息、用户消息、助理消息)。
OpenAI 消息格式
pythonimport openai
openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
)
消息角色:
- 系统消息 (
system) 用于设置对话上下文和模型行为(例如修改助手个性)。 - 用户消息 (
user) 用于表达用户的查询或需求。 - 助手消息 (
assistant) 用于表示模型的回应。
LangChain 的 ChatPromptTemplate
pythonfrom langchain.prompts import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
# 构建模板
template = "你是一位专业顾问,负责为专注于{product}的公司起名。"
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template = "公司主打产品是{product_detail}。"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
prompt_template = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
# 格式化提示
prompt = prompt_template.format_prompt(product="鲜花装饰", product_detail="创新的鲜花设计。").to_messages()
# 调用模型
import os
os.environ["OPENAI_API_KEY"] = '你的OpenAI Key'
from langchain.chat_models import ChatOpenAI
chat = ChatOpenAI()
result = chat(prompt)
print(result)
解释
-
角色消息模板:
-
SystemMessagePromptTemplate和
HumanMessagePromptTemplate用于定义系统消息和用户消息模板。在这个示例中:
- 系统消息设置了模型的角色和任务:“你是一位专业顾问,负责为专注于{product}的公司起名。”
- 用户消息指定了公司主打产品的详细信息:“公司主打产品是{product_detail}。”
-
-
创建
ChatPromptTemplate:- 使用
ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt]),将系统消息和用户消息结合起来,构建一个完整的对话提示模板。
- 使用
-
格式化和调用模型:
- 通过
prompt_template.format_prompt,将实际的产品信息(如“鲜花装饰”和“创新的鲜花设计”)替换到模板中。然后使用.to_messages()方法将格式化后的提示转换为消息格式。 - 调用 OpenAI 的聊天模型 (
ChatOpenAI) 将生成的消息传递给模型,生成响应。
- 通过
最终,模型会根据提示生成类似这样的公司命名建议:
1. 花语创意
2. 花韵设计
3. 花艺创新
4. 花漾装饰
...
微总结
- PromptTemplate 允许用户创建具有动态占位符的提示模板,灵活地生成不同的提示内容,适用于非对话场景。
- ChatPromptTemplate 专为多轮对话和不同角色的消息设计,能够清晰地定义系统、用户和助手的角色信息,适用于与聊天模型(如 GPT-3.5 和 GPT-4)进行交互。
下一节,我们将使用 FewShotPromptTemplate