RAG : 检索增强生成(Retrieval Augmented Generation )
* 为LLM提供来自外部知识源的额外信息。这允许它们生成更准确和有上下文的答案,同时减少幻觉
*(1)检索:外部相似搜索
*(2)增强:提示词更新
*(3)生成:更详细的提示词输入LLM
Langchain中文档转换:
>文档切割器和按字符分割
>代码文档分割器
>按token分割文档
>文档总结、精炼、翻译
提示词模板(PromptTemplate)
提示词模板是一种特殊的文本,它可以为特定任务提供额外的上下文信息。在LLM 应用中,用户输人通常不直接被传递给模型本身,而是被添加到一个更大的文本,即提示词模板中。提示词模板为当前的具体任务提供了额外的上下文信息,这能够更好地引导模型生成预期的输出。
在 LangChain 中,可以使用 MessagePromptTemplate 来创建提示词模板。可以用一个或多个MessagePromptTemplate创建一个 ChatPromptTemplate,示例代码如下:from langchain.prompts.chat import ( ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, ) template=( "You are a helpful assistant that translates {input_language} to {output_language}." ) # 首先定义了两个模板: # 一个是系统消息模板,描述了任务的上下文(翻译助手的角色和翻译任务); system_message_prompt = SystemMessagePromptTemplate.from_template(template) # 另一个是人类消息模板,其中的内容是用户的输入。 human_template="{text}" human_message_prompt = HumanMessagePromptTemplate.from_template(human_template) # 使用ChatPromptTemplate的from_messages 方法将这两个模板结合起来生成一个聊天提示词模板 chat_prompt = ChatPromptTemplate.from_messages( [system_message_prompt, human_message_prompt] ) # 当想要检查发送给模型的提示词是否确实与预期的提示词相符时, # 可以调用ChatPromptTemplate的format_messages方法,查看该提示词模板的最终呈现: chat_prompt.format_messages( input_language="English", output_language="French", text="I love programming." ) ''' 输出: [ SystemMessage(content='You are a helpful assistant that translates English to French.'), HumanMessage(content='I love programming.') ] '''
通过这种方式,不仅可以让聊天模型包装器生成预期的输出,还能让开发者不必担心提示词是否符合消息列表的数据格式,只需要提供具体的任务描述即可。
提示词模板的职责就是根据大语言模型平台的API类型,包装并生成适合的提示词。为了满足不同类型模型平台底层 API的需求,提示词模板提供了format 方法和format_prompt方法,输出可以是字符串、消息列表,以及ChatPromptValue 形式。比如对于需要输入字符串的 LLM 模型包装器,提示词模板会使用to_string 方法将提示词转化为一个安符串。而对于需要输人消息列表的聊天模型包装器,提示词模板则会使用 to_messages 方法将提示词转化为一个消息列表。
提示词模板包装器分为PromptTemplate包装器和ChatPromptTemplate包装器两类。
PromptTemplate包装器:
from langchain import PromptTemplate template=""" You are an expert data scientist with an expertise in building deep Learning models, Explain the concept of {concept} in a couple of lines """ #实例化模板的第一种方式: prompt= PromptTemplate(template=template, input_variables=["concept" ]) #实例化模板的第二种方式: prompt=PromptTemplate.from_template(template) #将用户的输入通过format方法嵌入提示词模板,并且做格式化处理 final_prompt=prompt.format(concept="NLP") print(prompt) ''' input_variables=['concept'] template='\n You are an expert data scientist with an expertise in building deep\n Learning models, Explain the concept of {concept} in a couple of lines\n' ''' print(final_prompt) ''' You are an expert data scientist with an expertise in building deep Learning models, Explain the concept of NLP in a couple of lines '''
ChatPromptTemplate包装器:
ChatPromptTemplate包装器构造的提示词是消息列表,支持输出 Message 对象。LangChain 提供了内置的聊天提示词模板(ChatPromptTemplate)和角色消息提示词模板。角色消息提示词板包括AIMessagePromptTemplate、SystemMessagePromptTemplate 和 HumanMessagePromptTemplate这3种。
# 先导人内置的聊天提示词模板和角色消息提示词模板: from langchain.prompts import ( ChatPromptTemplate, PromptTemplate, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate ) # 将SystemMessagePromptTemplate类和HumanMessagePromptTemplate 类实例化为包装器 # 使用 from_template 方法实例化 SystemMessagePromptTemplate 类和 HumanMessagePomptTemplate类、 # 传入定义的template模板字符串,得到人类消息模板对象和系统消息模板对象 template=""" You are an expert data scientist with an expertise in building deep Learning models. """ system_message_prompt=SystemMessagePromptTemplate.from_template(template) human_template="Explain the concept of {concept} in a couple of lines" human_message_prompt=HumanMessagePromptTemplate.from_template(human_template) # 实例化ChatPromptTemplate 类,将前面两个对象作为参数传递给ChatPromptTemplate 类实例化后的包装器 # 调用其from_messages方法生成消息列表提示词包装器实例 chat_prompt=ChatPromptTemplate.from_messages( [ system_message_prompt, human_message_prompt ] ) # 调用format_prompt方法,传入concept参数值,获得的是ChatPromptValue对象 chat_prompt.format_prompt(concept="NLP") # ChatPromptValue 对象中有to_string和to_messages方法,分别返回字符串和消息列表 # 调用to_messsages方法,返回消息列表 chat_prompt.format_prompt(concept="NLP").to_messages() # 调用to_string方法,返回字符串 chat_prompt.format_prompt(concept="NLP").to_string()
以format为前缀的类方法:
主要用于在实例化模板对象后将外部用户输入格式化并传入对象内。
实例化LLM 模型包装器的内置模板对象,需要使用format方法,
实例化聊天模型包装器的内置模板对象,需要使用 format_prompt 方法。
以from_为前缀的类方法:
主要用于实例化内置模板对象。
PromptTemplate类只能使用 from_template方法,
ChatPromptTemplate类使用 from_messages 方法
为了实现这两种类型的相互转换,聊天模型包装器使用format_prompt方法实例化模板对象,生成的对象符合PromptValue数据模式。
所有返回该数据模式的对象都包含以to_为前级的方法名,包括to_string方法和to_messages方法,分别用于导出字符串和包含角色的消息列表。
创建第一个链
使用LangChain的LLMChain(大语言模型包装链)对模型进行包装,实现与提示词模板类似的功能。这种方式更为直观易懂,你会发现,导人 LLMChain 并将提示词模板和聊天模型传递进去后,链就造好了。链的运行可以通过函数式调用实现,也可以直接“run”一下。以下是相关代码:from langchain import LLMChain from langchain.chat_models import ChatOpenAI from langchain.prompts.chat import ( ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, ) # 初始化ChatOpenAI聊天模型,温度设置为0 chat=ChatOpenAI(temperature=0) # 定义系统消息模板 template=( "You are a helpful assistant that translates {input_language} to {output_language}." ) system_message_prompt = SystemMessagePromptTemplate.from_template(template) # 定义人类消息模板 human_template="{text}" human_message_prompt = HumanMessagePromptTemplate.from_template(human_template) # 使用ChatPromptTemplate的from_messages 方法将这两个模板结合起来生成一个聊天提示词模板 chat_prompt = ChatPromptTemplate.from_messages( [system_message_prompt, human_message_prompt] ) # 使用LLMChain组合聊天模型组件和提示词模板 chain = LLMChain(llm=chat, prompt=chat_prompt) # 运行链,传入参数 chain.run( input_language="English", output_language="French", text="I love programming." )
这样,我们就可以方便地与LLM交互,并且不需要每次都为提示词模板提供所有的参数。
模型包装器
LangChain 的模型包装器组件是基于各个模型平台的 API协议进行开发的,主要提供了两种类型的包装器。一种是通用的LLM 模型包装器,另一种是专门针对Chat类型 API的 Chat Model(聊天模型包装器)。
以 OpenAI平台的两种类型 API为例,如果使用 text-davinci-003模型,则导人的是 OpenAI 的 LLM 模型包装器,而使用 GPT-4 模型则需要导人 ChatOpenAI的聊天模型包装器。选择的模型包装器不同,获得的模型响应也不同:1,LLM 模型包装器的响应是字符串
2,聊天模型包装器接收一系列的消息作为输入,并返回一个消息类型作为输出,获得的响应是 AIMessage 消息数据。
LangChain 的模型包装器组件提供了一种方便的方式来使用各种类型的大语言模型,无论是通用的 LLM 模型包装器,还是专门针对聊天场景的聊天模型包装器,都能让开发者更高效地利用大语言模型的能力。模型包装器的区别:
1.输入的区别
对于 LLM 模型包装器,其输入通常是单一的字符串提示词(prompt)。例如你可以输入"Translate the following English text to French:'{text}"",然后模型会生成对应的法文翻译。另外,LLM模型包装器主要用于文本任务,例如给定一个提示“今天的天气如何?”模型会生成一个相应的答案“今天的天气很好。”
聊天模型包装器,其输人则是一系列的聊天消息。通常这些消息都带有发言人的标签(比如系统、AI和人类)。每条消息都有一个role(角色)和content(内容)。例如,你可以输入[{"role":"user","content":"Translate the following English text toFrench:"{text}"}],模型会返回对应的法文翻译,但是返回内容包含在 AIMessage(...)内。
2.输出的区别
LLM 模型包装器:输出一个字符串,这个字符串是模型对提示词的补全。聊天模型包装器:输出一则聊天消息,是模型对输入消息的响应。
两个包装器都实现了基础模型接口。这个接口公开了两个常见的方法:predict(接收一个字符串并返回一个字符串)和predict messages(接收则消息并返回一则消息)。这样,无论你是使用特定的模型,还是创建一个应该匹配其他类型模型的应用,都可以通过这个共享接口来进行操作。
模型I/O功能:输出解析器
输出解析器两大功能:添加提示词模板的输出指令、解析输出格式
-
**输出解析器跟提示词模板有什么关系呢?
答:输出解析器是通过改变提示词模板,即增加输出指令,来指导模型按照特定格式输出内容的。
-
LangChain 提供了一系列预设的输出解析器,这些输出解析器能够针对不同的数据类型给出合适的输出指令,并将输出解析为不同的数据格式。这些输出解析器包括:
1.BooleanOutputParser:用于解析布尔值类型的输出。
2.CommaSeparatedListOutputParser:用于解析以逗号分隔的列表类型的输出。
3.DatetimeOutputParser:用于解析日期时间类型的输出。
4.EnumOutputParser:用于解析枚举类型的输出。
5.ListOutputParser:用于解析列表类型的输出。
6.PydanticOutputParser:用于解析符合 Pydantic 大语言模型需求的输出。
7.StructuredOutputParser:用于解析具有特定结构的输出。-
CommaSeparatedListOutputParser 类的源码如下:
class CommaSeparatedListOutputParser(ListOutputParser): """Parse out comma separated lists.""" def get_format_instructions(self) -> str: return ( "Your response should be a list of comma separated values," "eg: `foo,bar,baz`" # 预设的输出指令 ) def parse(self, text: str) -> List[str]: """Parse the output of an LLM call.""" return text.strip().split(",") # 实例化 CommaSeparatedListOutputParser类之后,调用get format instructions()方法返回上述字符串 # parse方法内处理了不同类型的数据,这些都是LangChain 造好的“轮子”