LangChain与大型语言模型(LLMs)应用基础教程:Prompt模板_langchain prompt template

大型语言模型 (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 os

os.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 HuggingFaceHub

llm_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 PromptTemplate

restaurant_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交互的效率。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费
from langchain_ollama.llms import OllamaLLM from langchain.prompts import PromptTemplate from langchain.chains import LLMChain, ConversationChain from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE from langchain.chains.router.llm_router import RouterOutputParser from langchain.chains.router import LLMRouterChain, MultiPromptChain # 专家模型(提示词),链 llm = OllamaLLM(model="qwen2:7b") # 数 math_template = """ 你是一位伟大的数学家,知道所有的数学问题,你超越了高斯和莱布尼茨,我向你提问,问题如下: {input} """ math_prompt = PromptTemplate.format_prompt(math_template) math_chain = LLMChain(llm=llm, prompt=math_prompt,output_key="text") # 理 physics_template = """ 你是一位伟大的物理学家,知道所有的物理问题,你得过诺贝尔物理学奖,我向你提问,问题如下: {input} """ physics_prompt = PromptTemplate.format_prompt(physics_template) physics_chain = LLMChain(llm=llm, prompt=physics_prompt,output_key="text") # 化 chemistry_template = """ 你是一位伟大的化学家,知道所有的化学问题,你得过诺贝尔化学奖,我向你提问,问题如下: {input} """ chemistry_prompt = PromptTemplate.format_prompt(chemistry_template) chemistry_chain = LLMChain(llm=llm, prompt=chemistry_prompt,output_key="text") # 输入问题分析清楚有哪些可能和目的,目的链 destination_chain = {"math":math_chain,"physics":physics_chain,"chemistry":chemistry_chain} # 默认链 default_chain = ConversationChain(llm=llm, output_key="text") default_template = """ math:擅长回答数学问题 physics:擅长回答物理问题 chemistry:擅长回答化学问题 """ # 路由构建 router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format( destinations=default_template ) router_promt = PromptTemplate( template=router_template, input_variables=["input"], output_parser=RouterOutputParser() ) # 路由链 router_chain = LLMRouterChain.from_llm(llm=llm,prompt=router_promt) # 最终选择(链) multi_prompt_chain = MultiPromptChain( router_chain=router_chain, default_chain=default_chain, destination_chains=destination_chain, verbose=False ) res = multi_prompt_chain.invoke({"input":"介绍一下高斯"}) print(res) 上面是源代码 KeyError Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_16272
04-03
<think>好的,用户遇到了LangChain中的KeyError问题,具体是在多提示链路由配置时出现的。我需要先分析可能的原因,然后给出解决方案。 首先,根据用户提到的错误类型KeyError,通常是因为访问了字典中不存在的键。在LangChain的多提示链配置中,路由配置可能涉及到选择不同的提示模板,这时候如果路由逻辑返回的键不在现有的提示链名称中,就会导致KeyError。例如,用户可能配置了多个提示链,但路由函数返回了一个未被定义的链名称,或者链的名称拼写不一致。 接下来,查看用户提供的引用内容。引用[2]提到如果没有配置Token,会报错ValidationError,说明环境变量或参数配置的重要性。这可能提示用户检查是否正确定义了路由所需的参数或配置项。引用[3]讨论了数据结构和API协议的一致性,这可能对应到路由配置中的Schema是否正确,确保各个提示链的名称和路由逻辑中的预期一致。 可能的原因有: 1. 提示链名称拼写错误,导致路由返回的键无法匹配。 2. 路由函数逻辑错误,返回了不在可用链列表中的键。 3. 配置文件中链的名称实际代码中的名称不一致。 解决方案方面,首先需要检查路由配置中的链名称是否正确,确保所有可能的返回值都在可用的提示链名称列表中。其次,验证路由函数的逻辑是否正确处理了所有情况,并返回有效的键。此外,检查配置文件或代码中是否存在拼写错误,比如大小写不一致或拼写错误。 最后,建议用户使用调试工具或打印中间变量来跟踪路由函数的输出,确认返回的键是否正确,并确保所有提示链都已正确注册和命名。如果问题依旧存在,可能需要审查整个多提示链的配置流程,确保每个步骤都符合LangChain的文档要求。</think>### LangChain KeyError 多提示链路由配置错误分析及解决方案 #### 错误原因分析 1. **路由键值不匹配** 当使用多提示链路由功能时,若`prompt_router`返回的`destination`值未在`destination_chains`定义的键名列表中找到匹配项,会触发`KeyError`错误[^3]。例如: ```python destination_chains = {"math": math_chain, "history": history_chain} # 若路由函数返回"science",但该键未在destination_chains中定义 ``` 2. **Schema定义不一致** 输入数据的字段名称路由判断逻辑中使用的字段名称不一致。例如路由逻辑使用`query_type`字段进行判断,但输入数据中该字段名为`question_type`。 3. **默认链缺失** 未配置`default_chain`时,当所有路由条件均不满足,系统无法选择默认处理链。 #### 分步解决方案 1. **检查路由键值映射** 验证`destination_chains`的键名是否包含路由函数所有可能的返回值: ```python print("可用链名称:", list(destination_chains.keys())) # 输出示例: ['math', 'history'] ``` 2. **标准化Schema定义** 确保输入数据字段路由判断逻辑字段完全一致: ```python class RouterInput(BaseModel): query: str = Field(description="用户问题") query_type: str = Field(description="问题类型") # 必须路由判断字段名相同 ``` 3. **添加默认处理链** 配置默认链处理未匹配情况: ```python from langchain.chains import LLMChain default_chain = LLMChain(llm=llm, prompt=default_prompt) ``` 4. **增强路由可靠性** 在路由函数中添加异常捕获和日志记录: ```python def route_query(info): try: if "方程" in info["query"]: return "math" elif "历史事件" in info["query"]: return "history" else: return "default" except KeyError as e: print(f"缺少必要字段: {e}") return "default" ``` 5. **验证配置完整性** 使用单元测试验证配置: ```python test_cases = [ {"query": "解方程x²-5x+6=0", "query_type": "数学问题"}, {"query": "明朝建立时间", "query_type": "历史问题"}, {"query": "天气预报", "query_type": "其他"} ] for case in test_cases: result = router_chain.run(case) print(f"输入: {case['query']} => 路由结果: {result}") ``` #### 典型错误示例修正 **错误配置:** ```python destination_chains = { "math_problem": math_chain, # 键名包含下划线 "history_qa": history_chain } def route_query(info): if "数学" in info["query"]: return "math-problem" # 返回带连字符的键名 ``` **修正方案:** ```python destination_chains = { "math-problem": math_chain, # 统一使用连字符命名 "history-qa": history_chain } ``` #### 调试建议 1. 启用LangChain调试模式: ```python import langchain langchain.debug = True ``` 2. 检查路由中间结果: ```python print("路由输入:", router_input) print("路由输出:", destination) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值