LangChain Model IO模块
LangChain Model IO模块
cmyang1. Model I/O
LangChain的Model I/O模块提供了标准的、可扩展的接口实现与大语言模型的外部集成,包括模型输入(Prompts)、模型输出(OutPuts)和模型本身(Models),通过该模块可以快速与任意大模型进行对话。
在这个模块中,LangChain抽象出一个chain
,用于进一步简化和增强交互流程。包含三个核心部分,Format,Predict,Parse
Format:Prompts Template,通过模板化来管理大模型的输入
Predict:Models,使用通用接口调用不同的大语言模型
Parse:Output,用来从模型的推理中提取信息,并按照预先设定好的模版来规范化输出
2. Format
Prompt Template利用各种提示工程技巧,如Few-Shot、链式推理(CoT)等方法,以提高大模型的推理性能。
在实际应用开发中,提示词是动态变化的。
LangChain通过Prompt Template支持变量和动态内容的插入,使同一个应用可以根据不同的输入动态调整提示词,从而更好地响应用户的具体需求。
3. Predict
Predict处理模型从接收输入到执行推理的整个过程,LangChain在Model I/O模块中对Base类模型和Chat类模型都进行了抽象,分别归类为LLMs(Large Language Models)和Chat Models
LLMs是简化的大语言模型抽象,基于给定的Prompt提供内容生成的功能。而Chat Models专注于聊天API的抽象,需要维护上下文的记忆(聊天记录),呈现出更接近对话或聊天形式的交互。
4. Parse
大模型的输出是不稳定的,同样的输入Prompt往往会得到不同形式的输出,在应用开发中,大模型的输出可能是下一步逻辑处理的关键输入。因此,在这种情况下,规范化输出是必须要做的任务,以确保应用能够顺利进行后续的逻辑处理
输出解析器 Output Parser就是一个帮助结构化语言模型响应的抽象,可以获取格式指令或者进行更深层次的解析
5. 大模型接入
Langchain对大模型的支持:
https://python.langchain.com/docs/integrations/llms/
为了使开发者可以轻松地创建自定义链,整体采用Runnable
协议。Runnable 协议是编程中一种常见的设计模式,用于定义可以执行的任务或行为。在LangChain中通过构建标准接口,可以用户轻松定义自定义链并以标准方式调用它们,目前在LangChain已经集成的LLMs中,均实现了Runnable
接口,目前支持包括invoke
、 stream
、 batch
、 astream
等方法的调用。
invoke:处理单条输入
batch:处理批量输入
stream:流式响应
ainvoke:异步处理单条输入
abatch:异步处理批量输入
astream:异步流式响应
5.1 通义千问
在阿里云开通在线模型API:https://dashscope.console.aliyun.com/overview
pip install dashscope
在环境变量中添加通义千问的api-key,变量名:DASHSCOPE_API_KEY
1 | from langchain_community.llms import Tongyi |
[!Success] Print
我是来自阿里云的大规模语言模型,我叫通义千问。
stream流式响应
1 | from langchain_community.llms import Tongyi |
batch批量处理
1 | from langchain_community.llms import Tongyi |
[!Success] Print
[‘我是来自阿里云的大规模语言模型,我叫通义千问。’, ‘大模型是指一类参数量非常庞大的机器学习模型,通常是指预训练的深度学习模型。这些模型拥有数十亿甚至上千亿个参数,能够学习到更为复杂和泛化的语言结构和模式。大模型在自然语言处理(NLP)、计算机视觉(CV)等领域有广泛的应用,如对话系统、文本生成、翻译、问答等。\n\n例如,我就是阿里云推出的一种超大规模语言模型“通义千问”,拥有非常强大的语言理解和生成能力,可以回答各种领域的问题,提供各种帮助。其他知名的大模型还包括Google的BERT、T5,Facebook的XLM-R,以及中国的悟空、文心一言等。这些模型通过在大量无标注的文本数据上进行预训练,然后可以通过微调来适应特定的任务,从而达到优秀的性能。’]
ainvoke异步请求pip install asyncio
1 | import asyncio |
参数说明
- model:必选参数,具体调用的Completions模型名称,可以调用的模型包括text-davinci-003、text-davinci-002、text-curie-001、text-babbage-001、text-ada-001等,不同模型参数规模不同;这里需要注意,大模型领域不同于机器学习领域,后者哪怕是简单模型在某些场景下可能也会拥有比复杂模型更好的表现。在大模型领域,(就OpenAI提供的A、B、C、D四大模型来看)参数规模越大、越新版本的模型效果更好(当然费用也更高),因此课程中主要以text-davinci-003使用为例进行讲解;
- prompt:必选参数,提示词;
- suffix:可选参数,默认为空,具体指模型返回结果的后缀;
- max_tokens:可选参数,默认为16,代表返回结果的token数量;
- temperature:可选参数,取值范围为0-2,默认值为1。参数代表采样温度,数值越小,则模型会倾向于选择概率较高的词汇,生成的文本会更加保守;而当temperature值较高时,模型会更多地选择概率较低的词汇,生成的文本会更加多样;
- top_p:可选参数,取值范围为0-1,默认值为1,和temperature作用类似,用于控制输出文本的随机性,数值越趋近与1,输出文本随机性越强,越趋近于0文本随机性越弱;通常来说若要调节文本随机性,top_p和temperature两个参数选择一个进行调整即可;这里更推荐使用temperature参数进行文本随机性调整;
- n:可选参数,默认值为1,表示一个提示返回几个Completion;
- stream:可选参数,默认值为False,表示回复响应的方式,当为False时,模型会等待返回结果全部生成后一次性返回全部结果,而为True时,则会逐个字进行返回;
- logprobs:可选参数,默认为null,该参数用于指定模型返回前N个概率最高的token及其对数概率。例如,如果logprobs设为10,那么对于生成的每个token,API会返回模型预测的前10个token及其对数概率;
- echo:可选参数,默认为False,该参数用于控制模型是否应该简单地复述用户的输入。如果设为True,模型的响应会尽可能地复述用户的输入;
- stop:可选参数,默认为null,该参数接受一个或多个字符串,用于指定生成文本的停止信号。当模型生成的文本遇到这些字符串中的任何一个时,会立即停止生成。这可以用来控制模型的输出长度或格式;
- presence_penalty:可选参数,默认为0,取值范围为[-2, 2],该参数用于调整模型生成新内容(例如新的概念或主题)的倾向性。较高的值会使模型更倾向于生成新内容,而较低的值则会使模型更倾向于坚持已有的内容,当返回结果篇幅较大并且存在前后主题重复时,可以提高该参数的取值;
- frequency_penalty:可选参数,默认为0,取值范围为[-2, 2],该参数用于调整模型重复自身的倾向性。较高的值会使模型更倾向于避免重复,而较低的值则会使模型更可能重复自身;当返回结果篇幅较大并且存在前后语言重复时,可以提高该参数的取值;
- best_of:该参数用于控制模型的生成过程。它会让模型进行多次尝试(例如,生成5个不同的响应),然后选择这些响应中得分最高的一个;
- logit_bias:该参数接受一个字典,用于调整特定token的概率。字典的键是token的ID,值是应用于该token的对数概率的偏置;在GPT中我们可以使用tokenizer tool查看文本Token的标记。一般不建议修改;
- user:可选参数,使用用户的身份标记,可以通过人为设置标记,来注明当前使用者身份。需要注意的是,Completion.create函数中的user和后续介绍的对话类模型的user参数含义并不相同,需要注意区分;
6. Chat Models
LangChain抽象出来的消息类型有 AIMessage 、 HumanMessage 、 SystemMessage 、 FunctionMessage 和 ChatMessage
- SystemMessage :用于启动 AI 行为,作为输入消息序列中的第一个传入。
- HumanMessage :表示来自与聊天模型交互的用户消息。
- AIMessage :表示来自聊天模型的消息。这可以是文本,也可以是调用工具的请求
1
2
3
4
5
6
7from langchain_community.llms import Tongyi
from langchain_core.messages import SystemMessage, HumanMessage
message = [SystemMessage("是你是一个企业内的智能小助手"), HumanMessage("你是谁")]
llm = Tongyi()
result = llm.invoke(message)
print(result)[!Success] Print
我是您的智能小助手,可以在企业内部提供各种信息查询、问题解答、流程引导等服务。我可以帮助员工更高效地工作,解答他们关于公司政策、项目进度、内部系统使用等问题。请告诉我您需要什么帮助,我会尽力协助您。
7. Prompt Template
提示工程(Prompt Engineering)是指在与大语言模型进行交互时,精心设计输入文本(即提示)的过程,以获得更精准、相关或有创造性的输出,通过采用Few-Shot、Chain of Thought (CoT)等高级提示技巧,可以显著提高大模型在推理任务上的表现
LangChain 提供了创建和使用提示模板的工具,使用PromptTemplate
方法创建字符串提示模板,目前语言模型接收的提示基本都是字符串或聊天消息列表。
1 | from langchain_community.llms.tongyi import Tongyi |
[!Success] Print
薛定谔的猫是一个著名的量子力学思想实验,由奥地利物理学家埃尔温·薛定谔在1935年提出,用于揭示量子世界和宏观世界之间的矛盾。这个实验是用来说明量子力学中的超位置态和观测问题的 ……
聊天模板
1 | from langchain_community.llms.tongyi import Tongyi |
[!Success] Print
input_variables=[‘name’, ‘user_input’] messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[‘name’], template=’你是公司智能小秘书,你的名字是{name}。’)), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template=’你好,最近怎么样?’)), AIMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template=’我很好,谢谢!’)), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=[‘user_input’], template=’{user_input}’))][SystemMessage(content=’你是公司智能小秘书,你的名字是小蜜。’), HumanMessage(content=’你好,最近怎么样?’), AIMessage(content=’我很好,谢谢!’), HumanMessage(content=’你叫什么名字?’)]
我叫小蜜,是您的智能小秘书。有什么可以帮到您的吗?
input_variables:这是一个列表,包含模板中需要动态填充的变量名。这些变量名在模板字符串中以花括号(如{name})标记。通过指定这些变量,可以在后续过程中动态地替换这些占位符。
template:这是定义具体提示文本的模板字符串。它可以包含静态文本和input_variables列表中指定的变量占位符。当调用format方法时,这些占位符会被实际的变量值替换,生成最终的提示文本。
8. 构造Few-Shot模版
通过输入一些类似问题和答案,让模型参考学习,并在同一个prompt的末尾提出新的问题,以此来提升模型的推理能力
在LangChain中,需要使用 PromptTemplate
创建字符串提示模板。模板可以包括说明、少量示例以及适合给定任务的特定上下文和问题。因此,需要创建一个少量示例的列表。每个示例都是一个字典,其中键是输入变量,值是这些输入变量的值。
1 | from langchain_community.llms.tongyi import Tongyi |
[!Success] Print
艾米每次玩滑梯(包括爬上滑梯和滑下来)需要4 + 1 = 5分钟。如果水滑梯在15分钟后关闭,那么在关闭前她有15分钟的时间。所以她能滑的次数是15分钟除以5分钟每次,即15 / 5 = 3次。所以答案是3次。
9. Output Parsers
输出解析器,负责获取大模型的输出并将其转换为更合适的格式
LangChain采取的策略是通过在Prompt上增加输出解析,直接引导大模型输出的格式化方式。
LangChain构造的输出解释器必须实现两个主要方法:
- Get format instructions:该方法会返回一个字符串,其中包含有关如何格式化语言模型输出的指令。
- Parse:该方法会接收字符串,并将其解析为某种结构
支持的格式:https://python.langchain.com/docs/modules/model_io/output_parsers/
日期解析器:
1 | from langchain.output_parsers import DatetimeOutputParser |
[!Success] Print
1970-04-24 00:00:00
10. 示例选择器
Prompt Template存在的问题:不同类型的问题的提示模板不一样,应该如何在众多的提示词模板中选择适合当前输入问题的提示模板?
LangChain解决方案:抽象出一个Example selectors
模块,通过技术手段灵活的选择合适的提示模版,LangChain内置了多个预定义的示例选择器,每种选择器都有其特定的功能和适用场景
10.1 SemanticSimilarityExampleSelector
这个选择器的目的是在给定的示例集合中选出与输入在语义上最接近的示例。主要的实现步骤如下:
- 向量化表示:首先,输入文本和示例集中的每个示例都会被转换成向量化的表示。通过Embedding模型将文本转换成高维空间中的点,其中语义上相似的文本会被映射到空间中相近的位置。
- 计算语义相似度:一旦得到了输入和示例的向量化表示,下一步是计算输入与每个示例之间的语义相似度。通过计算向量之间的距离来实现,常见的度量方式包括余弦相似度、欧氏距离等。
- 选择最相似的示例:基于计算出的相似度,选择一个或多个与输入最相似的示例。这个选择过程可以是简单地选取相似度最高的示例,或者根据相似度分布采取更复杂的策略,例如选择相似度高于某个阈值的所有示例。
SemanticSimilarityExampleSelector
内部实现是使用chromadb
向量数据库进行存储和检索向量数据pip install chromadb
1 | from langchain_community.embeddings.dashscope import DashScopeEmbeddings |
[!Success] Print
[{‘answer’: ‘根据题意,只要白天温度高于30度,夜晚就会很凉爽。今天白天的温度是32度,超过了30度,因此今晚会凉爽。’, ‘question’: ‘在夏天,如果白天温度高于30度,夜晚就会很凉爽。今天白天温度是32度,请问今晚会凉爽吗?’}, {‘answer’: ‘地球绕太阳转一圈大约需要365天,也就是一年的时间。’, ‘question’: ‘地球绕太阳转一圈需要多久?’}]Human: 在夏天,如果白天温度高于30度,夜晚就会很凉爽。今天白天温度是32度,请问今晚会凉爽吗?
AI: 根据题意,只要白天温度高于30度,夜晚就会很凉爽。今天白天的温度是32度,超过了30度,因此今晚会凉爽。
Human: 地球绕太阳转一圈需要多久?
AI: 地球绕太阳转一圈大约需要365天,也就是一年的时间。月亮每天出现的时间会有所不同,因为它在天空中的位置会随着地球的自转而改变。一般来说,在没有云层遮挡的情况下,月亮会在日落后升起,并在日出前落下。具体的升落时间会受到地理位置、季节和月相的影响。在满月时,月亮整夜可见;而在新月时,月亮则不会在天空中出现。如果你需要知道特定日期和地点的月亮升起和落下时间,可以使用天文软件或在线工具进行查询。
10.2 自定义示例选择器
在LangChain中,Example Selector
的基本接口定义如下:
1 | class BaseExampleSelector(ABC): |
示例:
1 | from langchain_core.example_selectors import BaseExampleSelector |