LangChain 实战: Model I/O

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

前言

吴恩达老师在他的ChatGPT Prompt Engineering for Developers公开课中,分享了关于Prompt 工程的两条原则:一是清晰且具体的prompt, 二是给大模型思考的时间(推理或计算过程)。

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

  • 写清晰的提示
  • 给模型提供参考 Few Shot
  • 将复杂任务拆分成子任务
  • 给GPT时间思考
  • 使用外部工具(agent)
  • 反复迭代问题

我在之前刷的时候,focus在语法层。当写这篇文章时,边二刷,边感觉这些策略如太极一般简单。这些策略不只反映大模型的工作流程,也跟我们解决问题时的思考过程是一样的。

我们来看下这个demo:

c 复制代码
你是一位专业的老喻干货店小编,负责文案的撰写。
对于远近闻名的赣南板鸭,是江西年夜饭的一道佳肴,您能写一篇吸引人的推广文章吗?
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返回如下:

json 复制代码
{ "description": "赣南板鸭,江西年夜饭的瑰宝,以酥脆的皮、嫩滑的肉质和独特的香味而闻名。经过精心烹制的板鸭,口感丰富,美味无比。",
"reason": "这篇推广文章突出了赣南板鸭的独特口感和美味,同时提到它是江西年夜饭的一道传统佳肴,吸引读者的兴趣并激发他们品尝的欲望。" }

Model I/O

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

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

提示模板

老喻干货店有很多干货、地方特色,如果我们要为每一种干货写一段简介文案,就可以使用PromptTemplate。

ini 复制代码
# 引入LangChain提示模板
from langchain import PromptTemplate
# 新建模板
template = """您是一位专业的老喻干货店小编,负责文案编写。\n
对于售价为 {price} 元的 {food_name} ,您能写一段吸引人的简短描述吗?
"""
# 根据原始模板创建LangChain提示模板
prompt = PromptTemplate.from_template(template) 
# 打印LangChain提示模板的内容
print(prompt)

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

ini 复制代码
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应用。

模型调用

python 复制代码
# 设置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 元的 赣南板鸭 ,您能写一段吸引人的简短描述吗?", 大模型返回如下:

复制代码
品味正宗赣南板鸭,尽享美食的极致享受!香脆外皮、嫩滑肉质,每一口都散发着浓郁的鸭香,让您的味蕾沉醉其中。无论是家庭聚会还是节日盛宴,赣南板鸭都是不可错过的美味选择。

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

ini 复制代码
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 社区有很多开源的大模型,我们来试下:

python 复制代码
# 引入提示模板
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 文档。

ini 复制代码
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课
相关推荐
加油吧zkf14 分钟前
水下目标检测:突破与创新
人工智能·计算机视觉·目标跟踪
加油吧zkf14 分钟前
AI大模型如何重塑软件开发流程?——结合目标检测的深度实践与代码示例
开发语言·图像处理·人工智能·python·yolo
峙峙峙27 分钟前
线性代数--AI数学基础复习
人工智能·线性代数
weiwuxian32 分钟前
揭开智能体的神秘面纱:原来你不是"超级AI"!
人工智能
Codebee33 分钟前
“自举开发“范式:OneCode如何用低代码重构自身工具链
java·人工智能·架构
商汤万象开发者36 分钟前
懒懒笔记 | 课代表带你梳理【RAG课程 19:基于知识图谱的RAG】
llm
说私域1 小时前
基于开源AI智能名片链动2+1模式的S2B2C商城小程序:门店私域流量与视频号直播融合的生态创新研究
人工智能·小程序·开源
Ronin-Lotus1 小时前
深度学习篇---Yolov系列
人工智能·深度学习
静心问道1 小时前
GoT:超越思维链:语言模型中的有效思维图推理
人工智能·计算机视觉·语言模型
aneasystone本尊1 小时前
学习 Claude Code 的工具使用(三)
人工智能