AutoGen、LangChain、LlamaIndex玩了一圈,越来越感觉Prompt Engineering 才是核心。欢迎大家一同学习AIGC、AGI,欢迎点赞,谈论区讨论。

前语

  吴恩达教师在他的ChatGPT Prompt Engineering for Developers公开课中,共享了关于Prompt 工程的两条原则:一是明晰且具体的prompt, 二是给大模型考虑的时刻(推理或核算进程)。

  建议大家刷一下这个公开课,里边展示了以下6大战略:

  • 写明晰的提示
  • 给模型供给参阅 Few Shot
  • 将杂乱任务拆分红子任务
  • 给GPT时刻考虑
  • 运用外部东西(agent)
  • 反复迭代问题

  我在之前刷的时候,focus在语法层。当写这篇文章时,边二刷,边感觉这些战略如太极一般简略。这些战略不只反映大模型的作业流程,也跟咱们处理问题时的考虑进程是相同的。

咱们来看下这个demo:

你是一位专业的老喻干货店小编,担任案牍的撰写。
关于家喻户晓的赣南板鸭,是江西年夜饭的一道好菜,您能写一篇招引人的推行文章吗?
The output should be a markdown code snippet formatted in the following schema, including the leading and tailing "```json" and "```"
```json
{
    "description": string // 板鸭的描绘案牍,
    "reason": string // 引荐理由
}

   LLM返回如下:

{ "description": "赣南板鸭,江西年夜饭的瑰宝,以酥脆的皮、嫩滑的肉质和共同的香味而出名。经过精心烹制的板鸭,口感丰富,甘旨无比。",
"reason": "这篇推行文章突出了赣南板鸭的共同口感和甘旨,一起提到它是江西年夜饭的一道传统好菜,招引读者的爱好并激发他们品尝的欲望。" }

Model I/O

  假如说LangChain这个AI结构是车的话,LLM便是这台车的发动机。LLM的运用分红三步:输入提示(Prompt)、调用模型(Predict)和输出解析(Parse),LangChain把这个进程称为Model I/O。

  要开发AI运用的咱们,必须得研讨这台发动机啊。否则比及华为鸿蒙智仓一发力,冰箱彩电大沙发就没得玩了。在输入提示环节,LangChain为咱们供给了PromptTemplate;调用模型环节,LangChain为不同的大模型供给了一致的接口,便利咱们切换高度各种大模型;输出解析环节供给了各种Parser,可以精确地从模型输出中获取需要的信息。将大模型返回的非结构化文本,转换成程序便利处理的结构化数据。

提示模板

  老喻干货店有许多干货、地方特色,假如咱们要为每一种干货写一段简介案牍,就可以运用PromptTemplate。

# 引进LangChain提示模板
from langchain import PromptTemplate
# 新建模板
template = """您是一位专业的老喻干货店小编,担任案牍编写。n
关于价格为 {price} 元的 {food_name} ,您能写一段招引人的简略描绘吗?
"""
# 依据原始模板创立LangChain提示模板
prompt = PromptTemplate.from_template(template) 
# 打印LangChain提示模板的内容
print(prompt)

  上述的代码其实生成的prompt具体内容是:

input_variables=['food_name', 'price']
output_parser=None 
partial_variables={} 
template='/n您是一位专业的老喻干货店小编,担任案牍编写。
n关于价格为 {price} 元的 {food_name} ,您能写一段招引人的简略描绘吗?n'
template_format='f-string' 
validate_template=True

  f-string的意思是它是一个模板字符串,有两个变量{food_name}和{price}表明干货的名称和价格,在模板中占位,在最后生成prompt时会被相应的值替换。

   from_template表明可以从一个模板创立一个PromptTemplate实例。所以PromptTemplatefrom_template方法便是将一个模板字符串转化为包括input_variables、output_parser、partial_variables、template、template_format、validate_template的更好操作的PromptTemplate目标,产品经理睬依据各种运用场景预设许多内置模板,它们也是运用的核心。

模型分类

  常用的LLM分红三在类:

  • LLM
    比方 text-davinci-003、LlaMa、Claude都是典型的文本大模型。OpenAI最近还推出了GPT-4V多模态大模型、Google 的Gemini也是。LLM担任依据Prompt,生成输出并返回。

  • 谈天模型 Chat Model
      比较上面的模型,类似于ChatGPT的谈天模型有比较固定的role和结构,背面仍是由上面的言语模型支撑。

  • 文本嵌入模型 Embedding Model
      OpenAI 的 text-embedding-ada-002会将文本转变成LLM更好理解和核算的浮点数(检索的相似cosine核算)。存入向量数据库,做RAG运用。

模型调用

# 设置OpenAI API Key
import os
os.environ["OPENAI_API_KEY"] = '你的Open AI API Key'
# 引进LangChain中的OpenAI模型接口
from langchain import OpenAI
# 新建模型实例
model = OpenAI(model_name='gpt-3.5-turbo')
# 输入提示
input = prompt.format(food_name=["赣南板鸭"], price='40')
# 得到模型的输出
output = model(input)
# 打印输出内容
print(output)  

  prompt.format会将food_name替换为“赣南板鸭”,price替换为’40’,得到的prompt便是:”您是一位专业的老喻干货店小编,担任案牍编写。n关于价格为 40 元的 赣南板鸭 ,您能写一段招引人的简略描绘吗?”, 大模型返回如下:

品尝正宗赣南板鸭,尽享美食的极致享用!香脆外皮、嫩滑肉质,每一口都散发着浓郁的鸭香,让您的味蕾陶醉其间。无论是家庭聚会仍是节日盛宴,赣南板鸭都是不行错过的甘旨选择。

   提示词模板可以复用,如下:

foods = ["三江萝卜腌菜", "高安腐竹", "黑木耳"]
prices = ["15", "20", "65"]
for food, price in zip(foods, prices): # 运用提示模板生成输入 
    input_prompt = prompt.format(flower_name=food, price=price) # 得到模型的输出 
    output = model(input_prompt) # 打印输出内容 
    print(output)
三江萝卜腌菜,清爽可口的甘旨选择!新鲜的萝卜经过精心腌制,口感酥脆,带有微妙的酸甜味道,让您一口接一口停不下来。无论是作为开胃菜仍是伴碟佐餐,三江萝卜腌菜都能为您的餐桌增加一抹甘旨风情。

替换LLM

  LangChain供给了一致的LLM调用接口,便利灵活替换各种模型。Hugging Face 社区有许多开源的大模型,咱们来试下:

# 引进提示模板
from langchain import PromptTemplate
# 创立模板
template = """/n您是一位专业的老喻干货店小编,担任案牍编写。
n关于价格为 {price} 元的 {food_name} ,您能写一段招引人的简略描绘吗?n
"""
# 依据模板创立LangChain提示模板
prompt = PromptTemplate.from_template(template) 
# 打印LangChain提示模板的内容
print(prompt)
import os
os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的HuggingFace API Token'
# 引进LangChain中的OpenAI模型接口
from langchain import HuggingFaceHub
# 创立模型实例
model= HuggingFaceHub(repo_id="google/flan-t5-large")
# 输入提示
input = prompt.format(food_name=["赣南板鸭"], price='40')
# 得到模型的输出
output = model(input)
# 打印输出内容
print(output)

  所以,咱们可以总结LangChain中的PromptTemplate的优点:

  • 可读性更好
  • 可复用
  • 好保护

  一类模板处理一类问题,

  • 变量处理
  • 参数化

输出解析

  LangChain 供给的解析模型输出的功能,使你可以更容易地从模型输出中获取结构化的信息,这将大大加速基于言语模型进行运用开发的功率。

  接下来,咱们就经过 LangChain 的输出解析器来重写,让模型生成结构化的输出,一起对其进行解析,将解析好的数据存入 CSV 文档。

from langchain import PromptTemplate, OpenAI
#OpenAI Key
import os
os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key'
# 创立提示模板 多加了fomat_instructions
prompt_template = """您是一位专业的干货店小编,担任写案牍。
关于价格为 {price} 元的 {food_name} ,您能写一段招引人的简略描绘吗?
{format_instructions}"""
# 新建模型实例
model = OpenAI(model_name='gpt-3.5-turbo')
# 导入结构化输出解析器和ResponseSchema
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
# 界说咱们想要接收的响应模式
response_schemas = [
    ResponseSchema(name="description", description="干货的描绘案牍"),
    ResponseSchema(name="reason", description="问什么要这样写这个案牍")
]
# 依据响应schema 创立输出解析器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
# 获取格式指示
format_instructions = output_parser.get_format_instructions()
# 依据模板创立提示,一起在提示中加入输出解析器的说明 对运用partial_variables
prompt = PromptTemplate.from_template(prompt_template, 
                partial_variables={"format_instructions": format_instructions}) 
# 数据预备
foods = ["三江萝卜腌菜", "高安腐竹", "黑木耳"]
prices = ["15", "20", "65"]
# 创立一个空的DataFrame用于存储成果
import pandas as pd
df = pd.DataFrame(columns=["food", "price", "description", "reason"]) # 先声明列名
for food, price in zip(foods, prices):
    # 依据提示预备模型的输入
    input = prompt.format(food_name=food, price=price)
    # 获取模型的输出
    output = model(input)
    # 解析模型的输出(这是一个字典结构)
    parsed_output = output_parser.parse(output)
    # 在解析后的输出中增加“flower”和“price”
    parsed_output['food'] = food
    parsed_output['price'] = price
    # 将解析后的输出增加到DataFrame中
    df.loc[len(df)] = parsed_output  
# 打印字典
print(df.to_dict(orient='records'))
# 保存DataFrame到CSV文件
df.to_csv("foods_with_descriptions.csv", index=False)

总结

  • model I/O
  • 三个流程里的东西
  • 贴合的实战

参阅资料

  • 黄佳教师的LangChain课