个人理解(大佬多指教)为什么需要LangChain
我们可以看看大模型使用有哪些困难:
一.大模型种类繁多并且接口迥异,使用大模型开发的自由度过高导致难以统一开发方法。
针对这个问题:langchain提供了统一的LLM的接口和使用方法,我们甚至可以参照它的接口定义自己实现对任意LLM的接口。
后面我们对LLM的操作只要使用这个对象即可,是不是学习成本就降下来了。
为了规范LLM操作的输入和输出格式,langchain还提供了prompt模板(如果没有这个模块我们就需要手工拼接字符串来实现,虽然现在的模块用起来也不是那么便捷)和输出解析器(由于大语言模型的输出可能是任意字符串,为了可以将其用于软件工程中,必须从中获取到格式化的信息,这个输出解析器就是这个作用).
二.大模型的本身知识相对通用和“落后”,针对垂直领域的知识不够了解(由于我们大多数实际场景是对于某个专业领域进行开发)。例如:
针对这个问题我们首先会想到在”提问”的时候将对应的领域知识也附带给到LLM,那样LLM的输入也会有相应信息了,但是并没有这么直接....
假设我们有10个G的文本的专业知识库,由于LLM的输入长度限制,我们倾向于将和问题描述最相近的一些文本段附带上去吧!这个时候我们怎么从这10个G的知识库中快速找出这些文本段呢?
人们发现使用向量数据库是个好方法,我们就把专业知识库的文本段都使用向量数据库进行保存(这里的向量的作用是进行索引,原本的文本依然会保存),这个时候我们就能很快的将和问题描述最相近的一些文本段找出来了.
而langchain就给我们提供了从文本段切割,向量索引生成和存储,问题向量和存储向量匹配,返回文本段与问题组合等功能。(具体API命名参照API文档)
三.大模型对单次复杂任务的准确率较低。
由于大语言模型的基本原理是针对现有文本的概率性补全,所以在复杂任务的根据其输出的长度递增其补全正确的概率就会逐步下降(误差累积的思想).
为了使复杂任务的输出误差尽量降低,我们可以将其拆分成细小的子任务,这样即可以在任务流程上面进行约束,也方便我们对每个子任务进行单独的调整(软件模块解耦的思想)
为了实现这个目的langchain提供了一个名为chain(链,就是上面的子任务)的概念,就是将上面拆分出来的子任务的输入输出进行正确的对接,最后用LLM逐级独立驱动子任务,从而达到完成复杂任务的目的.
四.大模型本身并没有记忆性,并且现在的大模型输入输出的限制长度很难完成实际任务。
针对实际场景我们可能希望连续执行多次任务的时候可以像人一样有相应的记忆,我们会考虑将之前任务的输入输出都存起来,这样在下次任务的时候同下次任务的提示词一起给到LLM这样就能实现所谓的记忆。
langchain提供了memory模块,这个模块就是实现了上述方法,但是在怎么存和如何组合之前问题上langchain给了我们不同的方法.
五.大模型本身无法直接获取外部世界信息和对外部世界进行操作,但是我们经常需要使用大模型进行自动化任务.
我们为了实现大语言模型来调用工具(这个工具当然也需要有对应的接口,比如你想要关灯,就可能需要有个关灯的函数)。
①我们可以先将函数定义和描述给到langchain,
②在后续做任务的时候langchain将输入提示词和前面的函数描述通过一定的提示词模板给到LLM。
③LLM会给出调用函数及其调用方法,再通过对应的输出解析器得到函数调用的代码.
④最后langchain再调用得到的代码实现对应操作//现在重要的操作还是需要人工确认下的。
Langchain的agents模块就是实现上述功能的,而其中的tools模块就是各种操作的实例化。