提示工程 | 豆包MarsCode AI刷题

160 阅读6分钟

提示的结构

image.png

  • 指令告诉模型这个任务大概要做什么、怎么做。
  • 上下文则充当模型的额外知识来源。
  • 提示输入通常就是具体的问题或者需要大模型做的具体事情。
  • 输出指示器标记要生成的文本的开始。

LangChain 提示模板的类型

LangChain中提供String(StringPromptTemplate)和Chat(BaseChatPromptTemplate)两种基本类型的模板

image.png

使用 PromptTemplate

from langchain import PromptTemplate

template = """\
你是业务咨询顾问。
你给一个销售{product}的电商公司,起一个好的名字?
"""
prompt = PromptTemplate.from_template(template)

print(prompt.format(product="鲜花"))

输出:

你是业务咨询顾问。
你给一个销售鲜花的电商公司,起一个好的名字?

其中,"你是业务咨询顾问。你给一个销售{product}的电商公司,起一个好的名字?" 就是原始提示模板,{product} 是占位符,然后通过PromptTemplate的from_template方法,我们创建了一个提示模板对象,并用prompt.format方法将模板中的 {product} 替换为 "鲜花",达到我们的目的。

这样就得到了一句具体的提示:你是业务咨询顾问。你给一个销售鲜花的电商公司,起一个好的名字?

使用 ChatPromptTemplate

示例。

# 导入聊天消息类模板
from 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)

输出:

content='1. 花语创意\n2. 花韵设计\n3. 花艺创新\n4. 花漾装饰\n5. 花语装点\n6. 花翩翩\n7. 花语之美\n8. 花馥馥\n9. 花语时尚\n10. 花之魅力' 
additional_kwargs={} 
example=False

FewShot的思想起源

Few-Shot(少样本)

One-Shot(单样本)

Zero-Shot(零样本)

在提示工程(Prompt Engineering)中,Few-Shot 和 Zero-Shot 学习的概念也被广泛应用。

  • 在Few-Shot学习设置中,模型会被给予几个示例,以帮助模型理解任务,并生成正确的响应。
  • 在Zero-Shot学习设置中,模型只根据任务的描述生成响应,不需要任何示例。

构建FewShotPrompt

1. 创建示例样本

创建示例作为提示的样本。

samples = [
  {
    "flower_type": "玫瑰",
    "occasion": "爱情",
    "ad_copy": "玫瑰,浪漫的象征,是你向心爱的人表达爱意的最佳选择。"
  },
  {
    "flower_type": "康乃馨",
    "occasion": "母亲节",
    "ad_copy": "康乃馨代表着母爱的纯洁与伟大,是母亲节赠送给母亲的完美礼物。"
  },
  {
    "flower_type": "百合",
    "occasion": "庆祝",
    "ad_copy": "百合象征着纯洁与高雅,是你庆祝特殊时刻的理想选择。"
  },
  {
    "flower_type": "向日葵",
    "occasion": "鼓励",
    "ad_copy": "向日葵象征着坚韧和乐观,是你鼓励亲朋好友的最好方式。"
  }
]

2. 创建提示模板

配置一个提示模板,将一个示例格式化为字符串。

from langchain.prompts.prompt import PromptTemplate
template="鲜花类型: {flower_type}\n场合: {occasion}\n文案: {ad_copy}"
prompt_sample = PromptTemplate(input_variables=["flower_type", "occasion", "ad_copy"], 
                               template=template)
print(prompt_sample.format(**samples[0]))

提示模板的输出如下:

鲜花类型: 玫瑰
场合: 爱情
文案: 玫瑰,浪漫的象征,是你向心爱的人表达爱意的最佳选择。

3. 创建 FewShotPromptTemplate 对象

然后,使用prompt_sample以及samples列表中的所有示例创建一个FewShotPromptTemplate对象。

from langchain.prompts.few_shot import FewShotPromptTemplate
prompt = FewShotPromptTemplate(
    examples=samples,
    example_prompt=prompt_sample,
    suffix="鲜花类型: {flower_type}\n场合: {occasion}",
    input_variables=["flower_type", "occasion"]
)
print(prompt.format(flower_type="野玫瑰", occasion="爱情"))

输出:

鲜花类型: 玫瑰
场合: 爱情
文案: 玫瑰,浪漫的象征,是你向心爱的人表达爱意的最佳选择。

鲜花类型: 康乃馨
场合: 母亲节
文案: 康乃馨代表着母爱的纯洁与伟大,是母亲节赠送给母亲的完美礼物。

鲜花类型: 百合
场合: 庆祝
文案: 百合象征着纯洁与高雅,是你庆祝特殊时刻的理想选择。

鲜花类型: 向日葵
场合: 鼓励
文案: 向日葵象征着坚韧和乐观,是你鼓励亲朋好友的最好方式。

鲜花类型: 野玫瑰
场合: 爱情

4. 调用大模型创建新文案

最后把这个对象输出给大模型。

import os
os.environ["OPENAI_API_KEY"] = '你的Open AI Key'
from langchain.llms import OpenAI
model = OpenAI(model_name='gpt-3.5-turbo-instruct')
result = model(prompt.format(flower_type="野玫瑰", occasion="爱情"))
print(result)

输出:

文案: 野玫瑰代表着爱情的坚贞,是你向心爱的人表达爱意的最佳礼物。

使用示例选择器

如果我们的示例很多,那么一次性把所有示例发送给模型是不现实而且低效的。LangChain给我们提供了示例选择器来选择最合适的样本。

下面,就是使用示例选择器的示例代码。

from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings

# 初始化示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
    samples,
    OpenAIEmbeddings(),
    Chroma,
    k=1
)

# 创建一个使用示例选择器的FewShotPromptTemplate对象
prompt = FewShotPromptTemplate(
    example_selector=example_selector, 
    example_prompt=prompt_sample, 
    suffix="鲜花类型: {flower_type}\n场合: {occasion}", 
    input_variables=["flower_type", "occasion"]
)
print(prompt.format(flower_type="红玫瑰", occasion="爱情"))

输出:

鲜花类型: 玫瑰
场合: 爱情
文案: 玫瑰,浪漫的象征,是你向心爱的人表达爱意的最佳选择。

鲜花类型: 红玫瑰
场合: 爱情

在这个步骤中,它首先创建了一个SemanticSimilarityExampleSelector对象,这个对象可以根据语义相似性选择最相关的示例。然后,它创建了一个新的FewShotPromptTemplate对象,这个对象使用了上一步创建的选择器来选择最相关的示例生成提示。

然后又用这个模板生成了一个新的提示,因为我们的提示中需要创建的是红玫瑰的文案,所以,示例选择器example_selector会根据语义的相似度(余弦相似度)找到最相似的示例,也就是“玫瑰”,并用这个示例构建了FewShot模板。

这样,我们就避免了把过多的无关模板传递给大模型,以节省Token的用量。

Few-Shot CoT

Few-Shot CoT 简单的在提示中提供了一些链式思考示例,足够大的语言模型的推理能力就能够被增强。简单说,就是给出一两个示例,然后在示例中写清楚推导的过程。

整体指导:

  1. 首先AI需要理解用户的需求。
  2. 然后AI需要搜索相关信息。 
  3. 基于收集到的信息AI需要制定一个决策。
  4. 最后AI使用OutputParser生成一个销售列表。

Zero-Shot CoT

直接告诉模型要一步一步地思考,慢慢地推理。