快速入门指南 – LangChain中文网
langchain源码剖析系列课程
九天玩转Langchain!
- 1. LangChain是什么
- 2. LangChain Expression Language (LCEL)
- Runnable 接口
- 3. Model I/O
- 3.1 Prompt Templates
- 3.2 Language Model
- 3.3 Output Parsers
- Use case(Q&A with RAG)
1. LangChain是什么
LangChain是一个基于LLM
开发应用程序的框架,把调用LLM的过程组成一条链的形式,具体要执行哪些函数是由LLM的推理结果决定的。(区别于传统程序是写死的)同时LangChain也是一个丰富的工具生态系统的一部分,我们可以在此框架集成并在其之上构建自己的Agent。
LangChain的模块组成:Model I/O
(与语言模型进行接口)、Retriever
(与特定于应用程序的数据进行接口)、Memory
(在Pipeline运行期间保持记忆状态)、Chain
(构建调用序列链条)、Agent
(让管道根据高级指令选择使用哪些工具)、Callback
(记录和流式传输任何管道的中间步骤)
快速安装:
pip install langchain
2. LangChain Expression Language (LCEL)
LangChain应用程序的核心构建模块是LLMChain。它结合了三个方面:
- LLM: 语言模型是核心推理引擎。要使用LangChain,您需要了解不同类型的语言模型以及如何使用它们。
- Prompt Templates: 提供语言模型的指令。这控制了语言模型的输出,因此了解如何构建提示和不同的提示策略至关重要。
- Output Parsers: 将LLM的原始响应转换为更易处理的格式,使得在下游使用输出变得容易。
每个Langchain组件都是LCEL对象,我们可以使用LangChain 表达式语句(LCEL)
轻松的将各个组件链接在一起,如下实现prompt + model + output parser的chain = prompt | llm | output_parser
,其中|
符号可以实现将数据从一个组件提供的输出,输入到下一个组件中:
from langchain_community.llms import vllm # this LLM class can be everyone
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParserprompt = ChatPromptTemplate.from_messages([("system", "You are world class technical documentation writer."),("user", "{input}")
])llm = vllm.VLLM(model="/data1/huggingface/LLM/Mistral-7B-Instruct-v0.2")output_parser = StrOutputParser()chain = prompt | llm | output_parserprint(chain.invoke({"input": "how can langsmith help with testing?"}))
接下来仔细看一些下着三个组件:
prompt
是一个 BasePromptTemplate
,这意味着它接受模板变量的字典并生成 PromptValue
。PromptValue
是完整提示的包装器,可以传递给 LLM
(将字符串作为输入)或ChatModel
(将一系列消息作为输入)。它可以与任何一种语言模型类型一起使用,因为它定义了生成BaseMessages
和生成字符串的逻辑。
prompt_value = prompt.invoke({"input": "how can langsmith help with testing?"})
打印出来可以看到,prompt_value 是一个ChatPromptValue
对象,里面的message是一个list,包含不同角色message的对话信息。
ChatPromptValue(messages=[SystemMessage(content='You are world class technical documentation writer.'), HumanMessage(content='how can langsmith help with testing?')])
如果model为 ChatModel
,这意味着它将输出 a BaseMessage
。而如果我们的model是 LLM
,它将输出一个字符串
。
最后,我们将model输出传递给output_parser
,这意味着 BaseOutputParser
它需要字符串或 BaseMessage
作为输入。StrOutputParser
是将任何输入转换为字符串。
LCEL 可以轻松地从基本组件构建复杂的链条。它通过提供以下功能来实现此目的: 每个 LCEL 对象都实现该Runnable接口,该接口定义了一组通用的调用方法(invoke
、batch
、stream
、ainvoke
、 …)。这使得 LCEL 对象链也可以自动支持这些调用,大大简化了调用方式。也就是说,每个 LCEL 对象的chain 本身就是一个 LCEL 对象。
而且每个组件都内置了与 LangSmith 的集成。如果我们设置以下两个环境变量,所有链跟踪都会记录到 LangSmith。
import os
os.environ["LANGCHAIN_API_KEY"] = "..."
os.environ["LANGCHAIN_TRACING_V2"] = "true"
Runnable 接口
标准接口包括:
stream
:流回响应块(流式调用)
invoke
:在输入上调用链(单次调用)
batch
:在输入列表上调用链(批调用)
这些也有相应的异步方法:
astream
:异步流回响应块
ainvoke
:在输入异步上调用链
abatch
:在输入列表上调用异步链
astream_log
:除了最终响应之外,还实时流回发生的中间步骤
astream_events
:链中发生的betalangchain-core流事件( 0.1.14 中引入)
各种组件的输入输出格式:
3. Model I/O
首先我们从最基本面的部分讲起,Model I/O 指的是和LLM直接进行交互的过程。
在langchain的Model I/O这一流程中,LangChain抽象的组件主要有三个:
- Language models: 语言模型是核心推理引擎。要使用LangChain,您需要了解不同类型的语言模型以及如何使用它们。
- Prompt Templates: 提供语言模型的指令。这控制了语言模型的输出,因此了解如何构建提示和不同的提示策略至关重要。
- Output Parsers: 将LLM的原始响应转换为更易处理的格式,使得在下游使用输出变得容易。
下面我们展开介绍一下.
3.1 Prompt Templates
Prompt指用户的一系列指令和输入,是决定Language Model输出内容的唯一输入,主要用于帮助模型理解上下文,并生成相关和连贯的输出,如回答问题、拓写句子和总结问题。在LangChain中的相关组件主要有Prompt Template
和Example selectors
,以及后面会提到的辅助/补充Prompt的一些其它组件
Prompt Template
: 预定义的一系列指令和输入参数的prompt模版(默认使用str.fromat
格式化),支持更加灵活的输入,如支持output instruction(输出格式指令)
,partial input(提前指定部分输入参数)
,examples(输入输出示例)
等;LangChain提供了大量方法来创建Prompt Template,有了这一层组件就可以在不同Language Model和不同Chain下大量复用Prompt Template了,Prompt Template
中也会有下面将提到的Example selectors
,Output Parser
的参与Example selectors
: 在很多场景下,单纯的instruction + input
的prompt不足以让LLM完成高质量的推理回答,这时候我们就还需要为prompt补充一些针对具体问题的示例(in-context learning),LangChain将这一功能抽象为了Example selectors
这一组件,我们可以基于关键字,相似度(通常使用MMR
/cosine
similarity
/ngram
来计算相似度, 在后面的向量数据库章节中会提到)。为了让最终的prompt不超过Language Model的token上限(各个模型的token上限见下表),LangChain还提供了LengthBasedExampleSelector
,根据长度来限制example数量,对于较长的输入,它会选择包含较