大型语言模型(LLM)已经彻底改变了自然语言处理(NLP)任务。它们改变了我们与文本数据交互和处理的方式。这些强大的AI模型,如OpenAI的GPT-4,改变了理解、生成人类类似文本的方式,导致各种行业出现了众多突破性应用。
LangChain是一个用于构建基于大型语言模型(如GPT)的应用程序的开源框架。它使应用程序能够将语言模型连接到其他数据源,并允许语言模型与其环境进行交互。
在这篇博客中,我们将讨论LangChain在基于LLM的应用开发中的应用。通过提示LLM,现在比以前任何时候都可以更快地开发AI应用程序。基于LLM的应用需要多次提示和输出解析,因此我们需要为此编写大量代码。LangChain通过利用NLP应用开发中发现的基本抽象,使得这一开发过程变得更加容易。本博客的内容主要基于短课程LangChain用于LLM应用开发。
LangChain框架概述LangChain是一个用于开发应用程序的开源框架。它将大型语言模型(如GPT-4)与外部数据相结合。LangChain有Python或JavaScript(TypeScript)包可用。LangChain注重组合和模块化。它具有模块化组件,其中单个组件可以相互结合使用,也可以单独使用。LangChain可以应用于多个用例,并可以组合其模块化组件以实现更完整的端到端应用程序。
LangChain的关键组件LangChain强调灵活性和模块化。它将自然语言处理流程划分为独立的模块化组件,使开发人员能够根据需要定制工作流程。LangChain框架可以分为六个模块,每个模块允许与LLM进行不同方面的交互。
模型:
-
LLMs --- 20+集成
-
Chat Models
-
Text Embedding Models --- 10+集成 提示:
-
提示模板
-
输出解析器 --- 5+集成
-
示例选择器 --- 10+集成 索引:
-
文档加载器: 50+集成
-
文本拆分器: 10+集成
-
向量空间: 10+集成
-
检索器: 5+集成/实现 链:
-
Prompt + LLM + Output parsing
-
可用作更长链的构建块
-
更多特定于应用的链:20+类型
-
检索器: 5+集成/实现 代理:
-
代理是一种端到端用例类型,将模型用作推理引擎
-
代理类型: 5+类型
-
代理工具包: 10+实现
模型模型是任何语言模型应用的核心元素。模型指的是支持LLM的语言模型。LangChain提供了与任何语言模型接口和集成的构建块。LangChain为两种类型的模型提供接口和集成:
LLMs --- 以文本字符串作为输入并返回文本字符串的模型Chat Models --- 由语言模型支持但以聊天消息列表作为输入并返回聊天消息的模型。
# This is langchain's abstraction for chatGPT API Endpointfrom langchain.chat_models import ChatOpenAI
# To control the randomness and creativity of the generated text by an LLM, # use temperature = 0.0chat = ChatOpenAI(temperature=0.0)
Prompts是编程模型的新方式。提示是指创建输入以传递到模型的风格。提示通常由多个组件构成。提示模板和示例选择器提供了主要类和函数,以便轻松构建和使用提示。
我们将定义一个模板字符串,并使用该模板字符串和ChatPromptTemplate从LangChain创建提示模板。
提示模板
# Define a template string
template_string = """Translate the text that is delimited by triple backticks \
into a style that is {style}. text: ```{text}```
"""
# Create a prompt template using above template stringfrom langchain.prompts import ChatPromptTemplateprompt_template = ChatPromptTemplate.from_template(template_string
上述的prompt_template有两个字段,即style和text。我们也可以从此提示模板中提取原始模板字符串。现在,如果我们想要将文本翻译为某种其他样式,我们需要定义我们的翻译样式和文本。
customer_style = """American English in a calm and respectful tone
"""
customer_email = """
Arrr, I be fuming that me blender lid flew off and splattered me kitchen walls \
with smoothie! And to make matters worse, the warranty don't cover the cost of \
cleaning up me kitchen. I need yer help right now, matey!
"""
在这里,我们将风格设置为美国英语,语气平静且尊重。我们使用带有将被三个反引号括起来的文本翻译为特定风格的f-string指令来指定提示,然后将上述样式(客户风格)和文本(客户电子邮件)传递给LLM进行文本翻译。
# customer_message will generate the prompt and it will be passed into
# the llm to get a response.
customer_messages = prompt_template.format_messages(
style=customer_style,
text=customer_email)
# Call the LLM to translate to the style of the customer message.
customer_response = chat(customer_messages)
当我们构建复杂的应用程序时,提示可以变得相当长和详细。我们不使用f字符串,而是使用提示模板,因为提示模板是有用的抽象,可以帮助我们重用好的提示。我们可以创建提示模板并重用这些提示模板,并为模型指定输出样式和文本以供工作。
LangChain提供了一些常见操作的提示,例如摘要或回答问题,或者连接到SQL数据库或连接到不同的API。因此,通过使用LangChain的一些内置提示,我们可以快速获得一个正在运行的应用程序,而无需自行设计提示。
输出解析器LangChain的提示库的另一个方面是它还支持输出解析。输出解析器有助于从语言模型的输出中获取结构化信息。输出解析器涉及将模型的输出解析为更结构化的格式,以便我们可以使用输出执行下游任务。
当我们使用LLMs构建复杂应用程序时,我们经常指示LLM以特定格式生成其输出,例如使用特定的关键字。LangChain的库函数假设LLM将使用某些关键字来解析其输出。
我们可以有一个LLM输出JSON,我们将使用LangChain解析该输出,如下所示:
我们需要首先定义我们希望如何格式化LLM输出。在这种情况下,我们定义了一个具有提及产品是否为礼物、交付所需的天数以及价格是否可负担的字段的Python字典。
# Following is one example of the desired output.
{
"gift": False,
"delivery_days": 5,
"price_value": "pretty affordable!"
}
我们可以在下面提到的三个反引号中包含客户评论。我们可以定义以下评论模板:
# This is an example of customer review and a template that try to get the desired output
customer_review = """\
Need to be actual review
"""
review_template = """\
For the following text, extract the following information:
gift: Was the item purchased as a gift for someone else? \
Answer True if yes, False if not or unknown.
delivery_days: How many days did it take for the product \
to arrive? If this information is not found, output -1.
price_value: Extract any sentences about the value or price,\
and output them as a comma separated Python list.
Format the output as JSON with the following keys:
gift
delivery_days
price_value
text: {text}
"""
# This is an example of customer review and a template that try to get the desired output
customer_review = """\
Need to be actual review
"""
review_template = """\
For the following text, extract the following information:
gift: Was the item purchased as a gift for someone else? \
Answer True if yes, False if not or unknown.
delivery_days: How many days did it take for the product \
to arrive? If this information is not found, output -1.
price_value: Extract any sentences about the value or price,\
and output them as a comma separated Python list.
Format the output as JSON with the following keys:
gift
delivery_days
price_value
text: {text}
"""
# We will wrap all review template, customer review in langchain to get output
# in desired format. We will have prompt template created from review template.
from langchain.prompts import ChatPromptTemplate
prompt_template = ChatPromptTemplate.from_template(review_template)
print(prompt_template)
# Create messages using prompt templates created earlier and customer review.
# Finally, we pass messgaes to OpenAI endpoint to get response.
messages = prompt_template.format_messages(text=customer_review)
chat = ChatOpenAI(temperature=0.0)
response = chat(messages)
print(response.content)
上述响应仍然不是字典,而是字符串。我们需要使用Python字典将LLM输出字符串解析为字典。我们需要为Python字典中的每个字段项定义ResponseSchema。为了简洁起见,我没有提供这些代码片段。它们可以在我的GitHub笔记本中找到。这是一种非常有效的方法,可以将LLM输出解析为Python字典,使其更易于在下游处理中使用。
ReAct框架
![](https://file.jishuzhan.net/article/1724792718321782785/dad6f464c2693efc323509bc50f760f6.webp)
在上述示例中,LLM使用诸如"思想"、"行动"和"观察"等关键词,使用名为ReAct的框架执行思维推理链。"思想"是LLM所想的,通过给LLM思考的空间,LLM可以得到更准确的结论。"行动"是一个关键词来执行特定的行动,而"观察"是一个关键词来展示LLM从特定行动中所学到的内容。如果我们有一个指示LLM使用这些特定关键词(如思想、行动和观察)的提示,那么这些关键词可以与解析器结合使用,以提取标记有这些关键词的文本。
记忆大型语言模型无法记住之前的对话。
当你与这些模型互动时,它们自然不会记得你之前说的话或之前的所有对话,这在你构建一些应用程序(如聊天机器人)并希望与它们进行对话时是一个问题。
通过模型、提示和解析器,我们可以重用我们自己的提示模板,与他人共享提示模板,或使用LangChain内置的提示模板,这些模板可以与输出解析器结合使用,以便我们获得特定格式的输出,并让解析器解析该输出并将其存储在特定字典或其他数据结构中,从而使下游处理更容易。
我将在下一篇博客中讨论链和代理。我还将在我的另一篇博客中讨论如何在我们的数据中进行问题回答。最后,我们可以看到,通过提示LLM或大型语言模型,现在比以前任何时候都更有可能开发出更快的AI应用程序。但是一个应用程序可能需要多次提示LLM并解析其输出,因此需要编写大量的粘合代码。Langchain有助于简化这个过程。