五分钟带你学习LangChain 框架

LangChain是一个强大的框架,旨在帮助开发人员使用语言模型构建端到端的应用程序或者是各类Agent。它提供了一套工具、组件和接口,可简化创建应用程序的过程。LangChain 可以轻松管理与LLM的交互,将多个组件链接在一起,并集成额外的资源,以下LangChain 框架提供的几个主要模块,这些模块按照逐渐增加的复杂性排列如下:

  • 模型(models) : LangChain 支持的各种模型类型和模型集成。

  • 提示(prompts) : 包括提示管理、提示优化和提示序列化。

  • 内存(memory) : 内存是在链/代理调用之间保持状态的概念。LangChain 提供了一个标准的内存接口、一组内存实现及使用内存的链/代理示例。

  • 索引(indexes) : 为了使LLM与文档更好地进行交互而对其进行结构化的方式。在链中,索引最常用于“检索”步骤中,该步骤指的是根据用户的查询返回最相关的文档,并将文档返回给大模型进行交互。

  • 链(chains): 链不仅仅是单个 LLM 调用,还包括一系列调用(无论是调用 LLM 还是不同的实用工具)。LangChain 提供了一种标准的链接口、许多与其他工具的集成。LangChain 提供了用于常见应用程序的端到端的链调用。

  • 代理(agents) : 代理通 过调用LLM的能力做出行动决策、执行该行动、查看一个观察结果,并重复该过程直到完成。LangChain 提供了一个标准的代理接口,一系列可供选择的代理,以及端到端代理的示例。下面逐一介绍各个模块,并提供一些相应的简化版的代码示例。

在这里插入图片描述

模型Models

LangChain支持三种大类模型:

  • LLMs 大型语言模型(LLMs),将文本字符串作为输入,并返回文本字符串作为输出。

  • 聊天模型 聊天模型通常由语言模型支持,但它们的API更加结构化。具体来说,这些模型将聊天消息列表作为输入,并返回聊天消息。

  • 文本嵌入模型 文本嵌入模型将文本作为输入,并返回一个浮点数列表(向量组)。

LLM模型的调用示例

llm = OpenAI(model_name="text-ada-001", n=2, best_of=2)   **生成文本:**LLM最基本的功能就是能够调用它,传入一个字符串并返回一个字符串。   llm("Tell me a joke")   ##大模型返回文本   '  Why did the chicken cross the road?  To get to the other side.'   ##类似的还可以传入数组,得到llm_result.generations[]的各种信息   

chat模型的调用示例

chat = ChatOpenAI(temperature=0)   chat([HumanMessage(content="Translate this sentence from English to French. I love programming.")])   ##通过向聊天模型传递一个或多个消息,您可以获得聊天完成。响应将是一条消息LangChain目前支持的消息类型AIMessage、HumanMessage、SystemMessage和ChatMessage - ChatMessage接受任意角色参数。   AIMessage(content="J'aime programmer.", additional_kwargs={})   

文本嵌入模型 text-embedding-model调用示例

Embedding类是一个用于与嵌入进行交互的类。有许多嵌入提供商(OpenAI、Cohere、Hugging Face等)- 这个类旨在为所有这些提供商提供一个标准接口。嵌入会创建文本的向量表示。这使我们可以在向量空间中执行诸如语义搜索之类的操作,寻找最相似的文本片段。

LangChain中的基本Embedding类公开了两种方法:embed_documents和embed_query。最大的区别在于这两种方法具有不同的接口:一个适用于多个文档,而另一个适用于单个文档。

提示工程Prompts

Prompt是一种向语言模型提供特定的输入或指令,以此来引导模型生成用户期望的特定输出的提示词。通常这个提示词不仅仅是一个硬编码的字符串,而是一个模板、一些例子和用户输入的组合。提示词模板可能包含:

  • 对语言模型的指导,

  • 一组少量示例,以帮助语言模型生成更好的响应,

  • 对语言模型的提问。

LangChain提供了几个相关的提示模板,以便轻松构建和处理提示。包括ChatPromptTemplate,PromptTemplate,SystemMessagePromptTemplate,AIMessagePromptTemplate,HumanMessagePromptTemplate等。

官方文档提供的示例可以使用from_template方法直接将自定义template文本作为参数建立提示词模板, 也可以将PromptTemplate实例化后作为参数传递给MessagePromptTemplates。

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)       prompt=PromptTemplate(       template="You are a helpful assistant that translates {input_language} to {output_language}.",       input_variables=["input_language", "output_language"],   )   system_message_prompt_2 = SystemMessagePromptTemplate(prompt=prompt)       assert system_message_prompt == system_message_prompt_2    chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])       ##get a chat completion from the formatted messages   chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages()   

few shot examples 是一组示例,可用于帮助语言模型生成更好的响应。要使用 few shot examples 生成提示,可以使用 FewShotPromptTemplate。这个类接受一个 PromptTemplate 和一个 few shot examples 列表。然后,它将用 few shot examples 格式化提示模板。

如果在构建prompt过程中,如果有很多example示例,可以使用ExampleSelector类进行select_examples,该方法接受输入变量,然后返回一个示例列表。该方法根据示例example与输入的相似度等选择示例。它通过查找嵌入与输入的余弦相似度最大的示例来实现此目的。使用方法示例如下:

example_selector = SemanticSimilarityExampleSelector.from_examples(       # 该变量是一个示例的数组       examples,        # This is the embedding class used to produce embeddings which are used to measure semantic similarity.       OpenAIEmbeddings(),        # This is the VectorStore class that is used to store the embeddings and do a similarity search over.       Chroma,        # This is the number of examples to produce.       k=1   )   similar_prompt = FewShotPromptTemplate(       # We provide an ExampleSelector instead of examples.       example_selector=example_selector,       example_prompt=example_prompt,       prefix="Give the antonym of every input",       suffix="Input: {adjective}\nOutput:",        input_variables=["adjective"],   )   

输出解析器也是提示工程中的重要一环,一般来说LLM语言模型输出文本。但是很多时候,需要获得比文本更结构化的信息。这就是输出解析器的作用。

输出解析器是帮助结构化语言模型响应的类。如逗号分隔列表:

['Vanilla',    'Chocolate',    'Strawberry',    'Mint Chocolate Chip',    'Cookies and Cream']   

或者定义好我们想要接受的响应格式,并将模式作为参数传递给prompt模板,最终得到的大模型响应结果就可以按照预先定义的格式来,例如:

response_schemas = [       ResponseSchema(name="answer", description="answer to the user's question"),       ResponseSchema(name="source", description="source used to answer the user's question, should be a website.")   ]   output_parser = StructuredOutputParser.from_response_schemas(response_schemas)   **进行调用后**    output_parser.parse(output.content)    **结果**    {'answer': 'Paris', 'source': 'https://en.wikipedia.org/wiki/Paris'}   

序列化提示模板,可以将PromptTemplate保存到本地文件系统中。langchain会自动通过文件扩展名推断文件格式。当前,langchain支持将模板保存为YAML和JSON文件。

内存 Memory

底层的LLMs和聊天模型是无状态的,因此每个请求都是独立地处理。但在某些应用程序中(如聊天机器人),记住以前的交互非常重要,无论是在短期还是长期层面上。因此需要一定的memory来存储过程中的交互数据。Memory中可以保存最近n个对话和以前对话的消息摘要。

缓存窗口内存:ConversationBufferWindowMemory函数,保留了对话随时间推移的交互列表。它仅使用最后K个交互。这可以用于保持最近交互的滑动窗口,以便缓冲区不会过大。K值作为参数可以自定义。

实体摘要内存/对话摘要内存:ConversationEntityMemory,通过该函数来总结并记住特定实体的信息。它使用LLMs提取实体的信息,并移逐渐建立对实体的了解(通过LLMs的能力)。ConversationSummaryMemory 这种记忆类型可以创建关于对话的摘要,有助于从对话中概括信息。概括能力仍然需要llm。

对话摘要缓存内存:ConversationSummaryBufferMemory结合了前两个想法。它将最近的交互记录缓存在内存中,但不仅仅是完全清除旧的交互,而是将它们编译成一份摘要并同时使用。不过,与之前的实现不同,它使用token长度而不是交互数量K来确定何时清除交互。

对话缓冲内存:ConversationTokenBufferMemory 会在内存中保留最近的对话内容,并使用token长度而不是对话数量来决定何时刷新对话。可以将历史记录作为消息列表。

基于向量存储的记忆:VectorStoreRetrieverMemory将记忆存储在VectorDB中,并在每次调用时查询最重要的K个文档。与大多数其他记忆类不同的是,它不明确跟踪交互的顺序。在这种情况下,“文档”是先前的对话片段。这可以用来提到AI在对话中早期被告知的相关信息。

索引 Indexes:

主要关注于构建索引,目标是使用它们作为检索器。我们主要关注的检索器类型是 Vectorstore 检索器。它提供一系列能力将文件等非结构化数据存储起来并提供索引以供检索,更好的与大模型交互。

通过文件回答问题包括四个步骤:

  1. 创建索引

  2. 从该索引创建检索器

  3. 创建一个问题回答链

  4. 问问题!

首先可以使用VectorstoreIndexCreator创建索引,然后用它来询问数据问题,示例代码如下:

from langchain.indexes import VectorstoreIndexCreator   index = VectorstoreIndexCreator().from_loaders([loader])   query = "What did the president say about Ketanji Brown Jackson"   index.query(query)   #下述方法可以返回查询的数据来源sources地址   index.query_with_sources(query)   

其中这个 VectorstoreIndexCreator 背后的主要功能如下:

加载文件后有三个主要步骤:

  1. 将文档分割成块

  2. 为每个文档创建嵌入

  3. 在向量库中存储文档和嵌入

VectorstoreIndexCreator 只是所有这些逻辑的包装器。它可以在它使用的文本分割器、它使用的嵌入以及它使用的向量存储中进行配置。配置方法如下:

index_creator = VectorstoreIndexCreator(       vectorstore_cls=Chroma,        embedding=OpenAIEmbeddings(),       text_splitter=CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)   )   与向量存储相关的高级功能如下:   docsearch = Chroma.from_texts(texts, embeddings)       query = "What did the president say about Ketanji Brown Jackson"   #搜索   docs = docsearch.similarity_search(query)      #添加文本   docsearch.add_texts(["Ankush went to Princeton"])    #从文档初始化向量存储。使用文本拆分器方法直接获取文档   documents = text_splitter.create_documents([state_of_the_union], metadatas=[{"source": "State of the Union"}])   

向量存储完成后,需要使用检索器来进行下一步查询。LangChain最支持的索引,因此也是最支持的检索器是VectorStoreRetriever。正如其名称所示,此检索器主要由VectorStore支持。

#从向量数据库db中初始化一个检索器   retriever = db.as_retriever()   #默认情况下,vectorstore检索器使用相似性搜索。如果底层的vectorstore支持最大边际相关性搜索,则可以指定该搜索类型。   retriever = db.as_retriever(search_type="mmr")   docs = retriever.get_relevant_documents("what did he say about ketanji brown jackson")   

链 Chains

使用单独的LLM对于一些简单的应用程序来说是可以的,但许多更复杂的应用程序需要链接LLM——无论是相互链接还是与其他专家链接。LangChain为链提供了标准接口,以及一些常见的链实现,以便于使用。链允许我们将多个组件组合在一起,创建一个单一的、一致的应用程序。例如,我们可以创建一个链,该链接接受用户输入,使用 PromptTemplate 对其进行格式化,然后将格式化后的响应传递给 LLM。我们可以通过将多个链组合在一起,或者通过将链与其他组件组合在一起,来构建更复杂的链。

LLMChain 是一个简单的链,它接受一个大模型+一个提示模板(可以是自定义的PromptTemplate),也可以使用chatllm+ChatPromptTemplate;然后将信息发个大模型并得到返回。

调用Chain的方式

可以将chain作为一个function集成在Tool中,从而构建代理。代码示例如下:

tools.append(       Tool(                   name="Calculator",                   func=llm_math_chain.run,           description="在需要回答数学问题时非常有用",           args_schema=CalculatorInput            )    )   

向链中添加内存

Chain 支持将 BaseMemory 对象作为其内存参数,允许 Chain 对象跨多个调用持久存储数据。换句话说,它使 Chain 成为一个有状态对象。

调试链

因为大多数 Chain 对象都涉及大量的输入提示预处理和 LLM 输出后处理,所以很难单独从它的输出调试 Chain 对象。如果详细设置为 True,将在 Chain 对象运行时打印出它的一些内部状态。

组合Chain:

我们可以组合这两个 LLMChains,这样我们就可以在一个步骤中创建完成两个不同的任务,示例代码如下:

from langchain.chains import SimpleSequentialChain   overall_chain = SimpleSequentialChain(chains=[chain, chain_two], verbose=True)      #Run the chain specifying only the input variable for the first chain.   catchphrase = overall_chain.run("colorful socks")   print(catchphrase)   

问答与来源

如果我们想通过chain对一系列文档进行带来源的问答,首先,我们需要准备数据。在此示例中,我们在向量数据库上进行相似性搜索,但这些文档可以以任何方式获取(本教程的重点是强调在获取文档后要做什么)。可以使用如下代码思路:

#准备问题   query = "What did the president say about Justice Breyer"   #准备文档数据源&向量化存储   docsearch = Chroma.from_texts(texts, embeddings, metadatas=[{"source": str(i)} for i in range(len(texts))])       docs = docsearch.similarity_search(query)      #使用链   chain = load_qa_with_sources_chain(OpenAI(temperature=0), chain_type="stuff")      chain({"input_documents": docs, "question": query}, return_only_outputs=True)   

进一步的,可以使用向量数据进行索引对问题进行基于来源的问答。它通过使用RetrievalQAWithSourcesChain来完成从索引中查找文档的工作。代码如下:

docsearch = Chroma.from_texts(texts, embeddings, metadatas=[{"source": f"{i}-pl"} for i in range(len(texts))])      from langchain import OpenAI       chain = RetrievalQAWithSourcesChain.from_chain_type(OpenAI(temperature=0), chain_type="stuff", retriever=docsearch.as_retriever())      chain({"question": "What did the president say about Justice Breyer"}, return_only_outputs=True)   

代理 Agent:

Agent也可以称为“智能体”或“智能业务助理”,在大模型技术驱动下,它通过"大模型 + 插件 + 执行流程 / 思维链"的方式,对应控制端 (Brain / 大脑)、感知端 (Preception)、执行端 (Action) 环节,实现了复杂的功能。一个代理 (Agent)至少 由三个部分组成:

  1. LLM:作为Agent的大脑,用于核心控制器,例如规划,反馈,学习等。

  2. 工具 tool:代理可以使用的工具。工具是代理可以用来与世界互动的功能。这些工具可以是通用工具(例如搜索),其他链,甚至是其他代理。

  3. 代理执行器 :这决定了采取哪些行动。
    在这里插入图片描述

### 关于LangChain框架的介绍 LangChain是一个专为利用语言模型开发应用程序而设计的强大框架,目标在于协助开发者简化同大型预训练模型之间的交互过程、数据查询操作以及连接多种功能性模块来执行较为复杂的任务流程[^1]。 #### 架构与主要组成部分 该框架提供了众多实用工具、组件和API接口,允许编程者便捷地创建具有情境意识并能进行逻辑推断的应用软件。具体来说,LangChain由几个核心部分构成: - **基础服务层**:负责管理底层资源和服务调用; - **中间件层**:实现了诸如对话管理器之类的功能单元; - **应用层**:包含了针对特定业务需求定制的各种插件和扩展包; 这些层次共同作用使得整个平台既灵活又高效。 #### 应用场景举例 借助这一先进的技术解决方案,在实际项目里可以见到如下几种典型用途案例: - 开发智能客户服务机器人,它们可以根据客户提问自动给出恰当回应,并且随着经验积累变得越来越聪明; - 协助撰写文章或者制作新闻摘要等工作,大大提高了工作效率的同时也保证了产出物的质量; - 支持科研工作者处理庞杂的数据集,自动生成统计图表及解释说明文档; - 实现多语种即时互译功能,方便人们跨越文化障碍开展交流合作活动; - 建立企业内部的知识管理系统,让员工更容易获取所需资料信息[^3]。 #### 发展方向展望 面对日新月异的技术变革趋势,LangChain也在持续演进当中。预计未来会朝着以下几个方面前进: - 加强与其他前沿科技(比如深度神经网络算法)的合作关系,增强自然语言理解水平; - 更加注重用户体验改进,依据个体偏好量身打造专属的服务模式; - 探索新的行业应用场景,助力各行各业加速信息化进程; - 对现有体系结构做进一步精简调整,确保即使是在高并发环境下也能保持良好性能表现。 #### 使用入门指南 对于初次接触此项目的朋友们而言,可以从官方提供的教程材料入手学习如何安装部署环境以及编写第一个简单的例子程序。由于该项目正处于快速发展阶段,因此建议定期查看最新发布的版本更新日志以便及时掌握任何可能影响到已有代码兼容性的改动之处[^2]。 ```bash pip install langchain ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值