Press "Enter" to skip to content

LangChain 101 第一部分. 构建简单的问答应用

介绍

LangChain是一个强大的框架,用于创建生成文本、回答问题、翻译语言等与文本相关的应用程序。我从今年年初开始使用LangChain,并对其功能印象深刻。

本文是我关于LangChain 101课程的开始。我将开始分享概念、实践和经验,向您展示如何构建自己的LangChain应用程序。

今天,我们将讨论以下主题:

  • LangChain到底是什么?
  • LangChain的基本概念和组件
  • 如何构建一个基本的LangChain应用程序

什么是LangChain?

Lang代表语言,是LangChain的主要关注点,而chain(链)是LangChain中使用的链组件的含义。链是框架执行任务的指令序列。这简化了特定任务中使用大型语言模型的使用,并使您能够将LLMs(大型语言模型)的能力与其他编程技术相结合。

人们问我LangChain与ChatGPT或LLM有何不同。为了回答这个问题,我附上了一个突出显示差异的表格:

+==========+========================+====================+====================+|          | LangChain              | LLM                | ChatGPT            | +==========+========================+====================+====================+| 类型     | 框架                   | 模型               | 模型               | +----------+------------------------+--------------------+--------------------+| 目的     | 构建应用程序           | 生成文本           | 生成聊天           | |          | 使用LLMs              |                    | 对话               | +----------+------------------------+--------------------+--------------------+| 特点     | 链、提示、LLMs、内存、索引、代理和工具 | 大量文本和代码数据集 | 大量聊天对话数据集 | +----------+------------------------+--------------------+--------------------+| 优点     | 可以将LLMs与编程技术相结合 | 生成几乎接近人类质量的文本 | 生成逼真的聊天对话 | +----------+------------------------+--------------------+--------------------+| 缺点     | 需要一些编程知识        | 不易用于特定任务    | 不如LangChain多样化  | +----------+------------------------+--------------------+--------------------+

LangChain的基本组件

LangChain有六个基本组件:模型、提示、链、内存、索引、代理和工具

LangChain 101 第一部分. 构建简单的问答应用 四海 第1张

让我们简要介绍一下所有组件。

模型

LangChain中的模型是在大量文本和代码数据集上训练的大型语言模型(LLMs)。

在LangChain中,模型用于生成文本、回答问题、翻译语言等等。它们还用于存储框架可以随后访问的信息。例如:GPT-x、Bloom、Flan T5、Alpaca、LLama、Dolly、FastChat-T5等。

LangChain 101 第一部分. 构建简单的问答应用 四海 第2张

提示

提示是引导LLM生成所需输出的文本片段。提示可以简单或复杂,并可用于文本生成、语言翻译、回答问题等等。

在LangChain中,提示在控制LLM输出方面发挥着重要作用。通过精心制作提示,可以影响LLM生成所需的输出。

LangChain 101 第一部分. 构建简单的问答应用 四海 第3张

以下是提示的一些使用示例:

  • 指定所需的输出格式:例如,您可以使用提示指示LLM生成文本、翻译语言或回答问题。示例:将输入翻译成阿拉伯语
  • 提供上下文:提示可以为LLM提供上下文,例如输出主题的信息或所需输出的示例。示例:像学校老师一样逐步解释答案
  • 限制输出:您可以使用提示通过指定最大长度或选择要包含在输出中的关键字列表来限制LLM的输出。示例:使用少于140个字生成一条推文

索引

索引是用于存储有关数据内容的唯一数据结构。这些信息可以包括每个文档中的术语、数据集中的文档位置、文档之间的关系等。向量存储是存储数据集术语的向量表示的数据结构。一个检索器是一个接口,它根据非结构化查询返回文档。它的范围比向量存储更广泛。

LangChain 101 第一部分. 构建简单的问答应用 四海 第4张

理解索引、向量存储和检索器对于在特定数据上构建应用程序至关重要。考虑另一个包含所有三个组件的链的示例:

  • 一个链被形成以回答金融问题。
  • 该链使用索引来查找包含“金融”一词的所有文档。
  • 该链使用向量存储来查找与“金融”一词最相似的其他术语(例如“money”、“investments”等)。
  • 该链使用检索器检索在查询“有哪些投资方式?”中排名最高的文档。

记忆

LangChain中的记忆是一种存储数据的方法,LLM以后可以访问这些数据。这些信息可以包括先前链的结果、当前链的上下文以及LLM所需的任何其他信息。它还使应用程序能够跟踪当前对话的上下文。

LangChain 101 第一部分. 构建简单的问答应用 四海 第5张

记忆在LangChain中起着至关重要的作用,它允许LLM从先前的交互中学习并建立知识库。然后可以利用这个知识库来提高未来链的性能。

考虑创建一个旨在回答与房地产相关的问题的链。该链可以使用记忆来存储先前链的结果,这些链已经回答了与房地产相关的问题。当链询问一个类似主题的新问题时,这些信息可以用来提高其性能。

链是LangChain框架执行任务所需的指令序列。链可以根据应用程序的要求连接其他LangChain组件。它们使框架能够执行各种任务。

LangChain 101 第一部分. 构建简单的问答应用 四海 第6张

假设我们正在创建一个用于辅助面试准备的应用程序:

  • 提示:“我正在为软件工程师职位的面试做准备。你能问我一些可能会遇到的常见面试问题吗?”
  • 函数A:该函数将访问LLM在软件工程领域的知识,例如它对软件工程师常见面试问题的了解。它还可以在向量存储中查找适当的数据。
  • 函数B:该函数将操作数据,例如生成软件工程师常见面试问题列表或帮助学生准备面试的资源列表。它将选择一个问题并提问。
  • 记忆:可能会问一些后续问题,以更好地了解所选主题的知识。记忆实现将允许链保持对话的上下文。

代理和工具

代理和工具是LangChain中的两个重要概念。代理是可重用的组件,可以执行特定任务,例如文本生成、语言翻译和问题回答。工具是可以用于辅助开发各种代理的函数库。

LangChain 101 第一部分. 构建简单的问答应用 四海 第7张

示例:

  • NewsGenerator代理 – 用于生成新闻文章或标题。
  • DataManipulator工具 – 用于操作数据(清理、转换或提取特征)。

应用程序。构建问答系统。

Colab和Github链接。

让我们构建一个问答系统,以回答我们关于阿拉伯联合酋长国官方假期的问题。根据我们所学到的组件,我们可以绘制一个类似下面的模式:

LangChain 101 第一部分. 构建简单的问答应用 四海 第8张

首先,我们安装所有依赖项。一些版本可能已经更新,但安装特定版本将解决大多数,如果不是全部的内部依赖关系。

pip install chromadb==0.3.25   pydantic==1.10.9 openai==0.27.8 bs4 tiktoken==0.4.0 langchain==0.0.235   huggingface_hub==0.16.4 sentence_transformers==2.2.2 panda

我们将使用的数据可以在以下网站找到,如下表所示:

+--------+-----+-----------------------------+|  Date  | Day |           Holiday           |+--------+-----+-----------------------------+| 1 Jan  | Sun | New Year's Day              || 20 Apr | Thu | Eid al-Fitr Holiday         || 21 Apr | Fri | Eid al-Fitr                 || 22 Apr | Sat | Eid al-Fitr Holiday         || 23 Apr | Sun | Eid al-Fitr Holiday         || 27 Jun | Tue | Arafat Day                  || 28 Jun | Wed | Eid al-Adha                 || 29 Jun | Thu | Eid al-Adha Holiday         || 30 Jun | Fri | Eid al-Adha Holiday         || 21 Jul | Fri | Islamic New Year            || 29 Sep | Fri | Prophet Muhammad's Birthday || 1 Dec  | Fri | Commemoration Day           || 2 Dec  | Sat | National Day                || 3 Dec  | Sun | National Day Holiday        |+--------+-----+-----------------------------+

在将数据存储在内存或数据帧中之后,我们可以导入必要的包:

# Load language model, embeddings, and index for conversational AIfrom langchain.chat_models import ChatOpenAI                #modelfrom langchain.indexes import VectorstoreIndexCreator       #indexfrom langchain.document_loaders.csv_loader import CSVLoader #toolfrom langchain.prompts import PromptTemplate                #promptfrom langchain.memory import ConversationBufferMemory       #memoryfrom langchain.chains import RetrievalQA                    #chain

import osos.environ['OPENAI_API_KEY'] = 'sk-...'

在本教程中,我们将使用OpenAI API密钥。现在我们可以将所有模块放到位。

def load_llm():    # 设置LLM模型    llm = ChatOpenAI(temperature=0,model_name="gpt-3.5-turbo")    return llm

def load_index():    # 如果您想避免保存/加载文件的步骤,     # 您可以使用VectorstoreIndexCreator()的`from_documents()`方法    loader = CSVLoader(file_path='uae_holidays.csv')    index = VectorstoreIndexCreator().from_loaders([loader])    return indextemplate = """You are a assistant to help answer when are the official UAE holidays,     based only on the data provided.Context: {context}-----------------------History: {chat_history}=======================Human: {question}Chatbot:"""# 使用模板创建提示prompt = PromptTemplate(    input_variables=["chat_history", "context", "question"],    template=template)# 设置对话内存memory = ConversationBufferMemory(memory_key="chat_history",           return_messages=True, input_key="question")# 设置基于检索的对话人工智能qa = RetrievalQA.from_chain_type(    llm=load_llm(),    chain_type='stuff',    retriever=load_index().vectorstore.as_retriever(),    verbose=True,    chain_type_kwargs={        "prompt": prompt,        "memory": memory,    })

我们将详细讨论所有组件。目前,我们选择了OpenAI的gpt-3.5-turbo,一个自定义提示,开箱即用的VectorstoreIndexCreator(),设置了ConversationBufferMemory来跟踪聊天历史记录,并将所有内容链接到一个RetrievalQA链中。

三月/十二月节假日

query = "三月有没有节假日?"print_response_for_query(query)

> 链式结束。根据提供的数据,三月没有节假日。

回答正确。十二月呢?

query = "不好意思,我是说十二月"print_response_for_query(query)

> 链式结束。根据提供的数据,阿联酋十二月有两个官方节假日。第一个是12月1日的纪念日,是星期五。第二个是12月2日的国庆节,是星期六。此外,还有12月3日的国庆假期,是星期天。

你是否注意到我们在这里使用了记忆?如果没有它,回答可能会是:

> 链式结束。对不起,我不能理解你的意思。你在十二月具体在找什么?

值得注意的是,尽管一开始计算中官方节假日数量出现错误,但回答中包含了所有三个节假日。升级提示可能可以解决这个问题。

多链示例:开斋节

现在让我们问一个更棘手的问题。

query = "今年标志着开斋节结束的假期是什么时候开始的?"print_response_for_query(query)

所以现在,链式需要找到标志着开斋节结束的假期名称的信息,然后从表中检索所需信息。

> 链式结束。今年标志着开斋节结束的假期,也称为开斋节,从4月21日开始。

这非常有趣。链式正确地识别出开斋节是开斋节结束的假期。问题在于数据有错误,模型无法识别这是一个为期四天的周末。当然,解决这个问题的简单方法是清理数据,可能通过工具或修改提示。

最近的假期是什么?

最后一个问题是找出接下来的官方假期是什么。

query = "今天是7月16日。最近的假期是什么时候?"print_response_for_query(query)

> 链式结束。最近的假期是伊斯兰新年,日期是7月21日。

可以看到,最近的假期被正确地检测出来了。我留给你思考是如何构建回答这个问题的可能链式。

总结

在本讲座中,我们学习了关于LangChain的基础知识,包括模型、链式、提示、代理、记忆和索引。我们还看到了LangChain如何执行不同的任务并构建回答问题的应用程序的示例。

即将来临的讲座

LangChain 101课程目前正在开发中。

在课程的后续部分,我们将学习:

  • 如何在我们的计算机上使用模型
  • 如何使用自己的数据
  • 如何使用链式执行更复杂的任务
  • 如何使用记忆存储信息
  • 以及更多内容。

我们将继续使用LangChain构建实际应用程序。

考虑关注我在VoAGI或LinkedIn上,以了解更多关于LangChain的信息并获取更新,包括新的讲座、功能、教程和示例。

感谢您的时间!

LangChain 101 第一部分. 构建简单的问答应用 四海 第9张

Leave a Reply

Your email address will not be published. Required fields are marked *