LangChain实战课-05-提示工程(上) | 豆包MarsCode AI刷题

99 阅读5分钟

这里要想清楚我们始终其实是在构建promptTemplate而不是别的什么,不管是chatPromptTemplate还是fewShotPromptTemplate都是在原来的promptTemplate延展出来的,所以搞清楚最基本的promptTemplate以及后续其他的是如何在前者基础上加上自己的特点的内容的

1. 引出

前面提到,我们通过在prompt中加入一个schema就能实现最终的输出按照我们想要的格式输出出来,为什么呢?

这是因为我们在提示词中加入了一段话:

The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```": 
```json 
{         
    "description": string  // 鲜花的描述文案         
    "reason": string  // 为什么要这样写这个文案 
}

这就是一个非常酷的提示词工程的应用,通过加这样一个提示词,模型给我们的输出就完美的按照给定格式进行输出了。

2. 提示模板

吴恩达指出写好提示词两大原则:第一条原则是写出清晰而具体的指示,第二条原则是给模型思考的时间

OpenAI遵循上述两大原则给出六大策略:

  1. 写清晰的指示
  2. 给模型提供参考(也就是示例)
  3. 将复杂任务拆分成子任务
  4. 给GPT时间思考
  5. 使用外部工具
  6. 反复迭代问题

我们接下来就着重在“给模型提供参考”这块下功夫,看看如何通过给一些参考示例,来提高模型的表达效果。

1. 整体的提示结构

这块介绍了一个一般化的提示结构都包含什么:

image.png

  • 指令:就是整体上告诉模型你应该怎么做,整体的流程大概是个什么样的。
  • 上下文:模型的额外知识来源。
  • 提示输入:具体的你要模型实现什么或者做什么。
  • 输出指示器:“解”,“answer:”

2. LangChain提示模板的类型

image.png

1. PromptTemplate

from langchain.prompts.prompt import PromptTemplate

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

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

prompt = PromptTemplate(
    input_variables=["product", "market"],
    template="你是业务咨询顾问。对于一个面向{market}市场的,专注于销售{product}的公司,你会推荐哪个名字?",
)
print(prompt.format(product="鲜花", market="高端"))

image.png

2. ChatPromptTemplate

相比于上面,这里只是做了些角色的区分,不同的角色使用不同的提示词.

"""
本文件是【提示工程(上):用少样本FewShotTemplate和ExampleSelector创建应景文案】章节的配套代码,课程链接:https://juejin.cn/book/7387702347436130304/section/7388069971579895818
您可以点击最上方的“运行“按钮,直接运行该文件;更多操作指引请参考Readme.md文件。
""" 
# 导入聊天消息类模板
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 API Key'

from langchain_openai import ChatOpenAI

chat = ChatOpenAI(
    model=os.environ.get("LLM_MODELEND"),
)
result = chat(prompt)
print(result.content)

image.png

3. FewShotPromptTemplate

介绍几个概念:Zero-shot、One-shot、Few-shot 其实就是举例子说明某个概念,举一个例子就是one-shot,少许例子就是Few-shot,不举例子就能直接回答未曾见过的内容就是天赋型选手zero-shot.

详细讲解一下代码步骤:

  1. 创建示例样本
# 1. 创建一些示例
samples = [
  {
    "flower_type": "玫瑰",
    "occasion": "爱情",
    "ad_copy": "玫瑰,浪漫的象征,是你向心爱的人表达爱意的最佳选择。"
  },
  {
    "flower_type": "康乃馨",
    "occasion": "母亲节",
    "ad_copy": "康乃馨代表着母爱的纯洁与伟大,是母亲节赠送给母亲的完美礼物。"
  },
  {
    "flower_type": "百合",
    "occasion": "庆祝",
    "ad_copy": "百合象征着纯洁与高雅,是你庆祝特殊时刻的理想选择。"
  },
  {
    "flower_type": "向日葵",
    "occasion": "鼓励",
    "ad_copy": "向日葵象征着坚韧和乐观,是你鼓励亲朋好友的最好方式。"
  }
]
  1. 创建提示模板
# 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]))
  1. 创建 FewShotPromptTemplate 对象
# 3. 创建一个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="爱情"))
  1. 调用大模型创建新文案
# 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)
文案: 野玫瑰代表着爱情的坚贞,是你向心爱的人表达爱意的最佳礼物。

5. 使用示例选择器 (注意,因为示例选择器使用向量相似度比较的功能,此处需要安装向量数据库,这里我使用的是开源的Chroma,你也可以选择之前用过的Qdrant。)

# 5. 使用示例选择器
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 # 选择最相似的前k个示例
)

# 创建一个使用示例选择器的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="爱情"))

示例选择器的作用其实就是samples的一个筛选,相比原来传入那么多few-shot,这里只传相似的以节省tokens。