大型语言模型 (LLM) 正在成为一种变革性技术,使开发人员能够构建他们以前无法构建的应用程序。 但是单独使用这些 LLM 往往不足以创建一个真正强大的应用程序,只有当LLM与其它各种资源介质如数据库,文档,知识库,pdf电子书等相结合时才能发挥它强大的力量。
而LangChain是LLM的接口框架,通过使用LangChain可以开发出更为强大和高效的LLM的各种应用。LangChain可以直接与 OpenAI 的 text-davinci-003、gpt-3.5-turbo 模型以及 Hugging Face 的各种开源语言模如 Google 的 flan-t5等模型集成。
今天我们主要讲解LangChain的基础知识包括如何和OpenAI、Google的LLM集成,以及如何设计高效的Prompt模板。
LangChain集成LLMs
我们通过两个简单例子来演示LangChain如何与Openai的 "text-davinci-003"模型以及谷歌的“flan-t5-xl”模型进行集成。下面我们首先安装openai和huggingface_hub这两个包
pip -q install openai langchain huggingface_hub
下面我们让langchain集成openai的 text-davinci-003模型,并对它提出一个简单的问题: 老鼠生病了能吃老鼠药吗? 看看openai的LLM怎么回答
from langchain.llms import OpenAI
import osos.environ['OPENAI_API_KEY'] = 'your_openai_api_key'
os.environ['HUGGINGFACEHUB_API_TOKEN'] = 'your_hunggingface_api_key'llm = OpenAI(model_name='text-davinci-003', temperature=0.9, max_tokens = 1024)text = "老鼠生病了能吃老鼠药吗?"print(llm(text))
接下来我们让langchain集成谷歌的 flan-t5-xl 模型,由于flan-t5-xl目前暂时不支持中文,所以我们智能用英语对它提出一个简单的小问题:Who are you ? 看看谷歌的LLM怎么回答:
from langchain.llms import HuggingFaceHubllm_hf = HuggingFaceHub(repo_id="google/flan-t5-xl",model_kwargs={"temperature":0.9}
)text = "Who are you ?"
print(llm_hf(text))
LangChain的Prompt 模板
当用户和大型语言模型(LLM)对话时,用户所说的内容就是prompt,即提示语,如果用户每次需要输入很多内容相似的prompt时,我们可以考虑生成一个prompt模板,这样可以节省用户很多时间不必去输入很多内容相似的prompt,下面我们要演示一个prompt模板的例子,我们让LLM成为一个给新开餐馆命名的顾问,用户只要把新开餐馆的主要特点告诉LLM,它就会返回10个新开餐馆的名字。
from langchain import PromptTemplaterestaurant_template = """
我想让你成为一个给新开餐馆命名的顾问。给我返回一个餐馆名字的名单. 每个餐馆名字要简单, 朗朗上口且容易记住. 它应该和你命名的餐馆类型有关.关于{restaurant_desription} 这家餐馆好听名字有哪些?
"""#创建一个prompt模板
prompt_template=PromptTemplate(input_variables=["restaurant_desription"], template=restaurant_template)
下面我们查看通过这个prompt模板生成的内容:
description = "一家以婚纱摄影为主题的汉堡店"
description_02 = "一家拉面店,营业员都穿着汉服"
description_03 = "一家能看到海景的烤肉店"# 查看模板生成的生成的内容。
print(prompt_template.format(restaurant_desription=description_03))
下面我们在langchain集成LLM时应用prompt模板,看看它的效果如何:
## 在LLM中应用prompt模板
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt_template)
print(chain.run("一家以婚纱摄影为主题的汉堡店"))
print(chain.run("一家拉面店,营业员都穿着汉服"))
print(chain.run("一家能看到海景的烤肉店"))
通过上面的示例,用户可以很方便的创建一个prompt的模板,将每次需要重复发送的内容定义在一个模板中,而将那些变化的内容定义在一个变量中,当用户在和LLM交互时只需要发送变化的内容就可以了,这样大大提高了用户和LLM交互的效率。
小样本学习
有时候我们需要给LLM少量学习样本,让LLM学习这些样本以后能够更加准确的回答问题,这称之为微调LLM(fine-tune),为此可以使用prompt的小样本模板来训练LLM,下面我们来看一个简单的示例: 我们要求用户每输入一个短语,LLM输出一个对应的反义词。下面我们首先定义两组输入输出的例子:
from langchain import PromptTemplate, FewShotPromptTemplate# 首先创建一个短语示例,该示例包含两组输入和输出,每输入一个词语,LLM就会输出一个对应的反义词
examples = [{"输入": "高兴", "输出": "悲伤"},{"输入": "高大", "输出": "低矮"},
]
接下来我们要创建一个模板对象:
#创建一个prompt模板,
example_prompt = PromptTemplate(input_variables=["输入", "输出"],template="\n输入: {输入}\n输出: {输出}\n",
)
最后创建短语模板对象,在短语模板对象中有前缀和后缀变量:
- 前缀变量:附加在prompt之前,它是对LLM发出的指令,即要求LLM做什么。
- 后缀变量:附加在prompt之后的一些文本。通常,这是用户输入内容的地方
下面我们测试一下根据短语模板生成的内容:
# 最后我们创建一个短语prompt模板对象
few_shot_prompt = FewShotPromptTemplate(#这些是我们要插入到prompt中的示例examples=examples,#将示例插入prompt时,格式化示例的方式。example_prompt=example_prompt, #输入变量是用户直接输入的变量 input_variables=["input"],#前缀变量prefix="给出每个输入词语的反义词",#后缀变量suffix="输入: {input}\n输出:", #用来连接前缀、示例和后缀的字符串。 example_separator="\n",
)#测试一下短语模板对象
print(few_shot_prompt.format(input="快乐"))
在LLM中应用小样本提示语模板
下面我们要在langchain对接LLM时使用自定义的小样本提示语模板,这样LLM就可以根据小样本提示语模板的格式和要求来返回对应的内容:
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=few_shot_prompt)
我们看到上面的LLM的回答基本上符合我们的短语模板的的要求,尽管我故意刁难了一下LLM,用成语“东窗事发”来询问反义词,LLM也立即和给我“瞎编”了一个四个字的“成语”,也算勉强通过吧,只不过我们的目的是要测试LLM对小样本的学习能力,在这方面应该算是成功的。
总结
今天我们学习了LangChain和大型语言模型(LLM)如opeanai的 "text-davinci-003"模型以及谷歌的“flan-t5-xl”模型进行集成的方法,我们还学习了如何使用LangChain中prompt模板,和小样本模板。通过使用prompt模板可以让用户大大提高和LLM交互的效率。
参考资料
LangChain官方文档
LangChain Prompt Serialization