单独使用 LLM 对于一些简单的应用程序来说很好,但许多更复杂的应用程序需要链接 LLM - 彼此或与其他专家链接。LangChain 提供了 Chains 的标准接口,以及一些常见的 Chain 实现,方便使用。
提供了以下文档部分:
- 入门:链条入门指南,可帮助您快速启动和运行。
- 操作指南:操作指南的集合。这些重点介绍了如何使用各种类型的链。
- 参考:所有 Chain 类的 API 参考文档。
开始
在本教程中,我们将学习如何在 LangChain 中创建简单的链。我们将学习如何创建链、向其添加组件并运行它。
在本教程中,我们将介绍:
- 使用简单的 LLM 链
- 创建顺序链
- 创建自定义链
为什么我们需要链条?
链允许我们将多个组件组合在一起以创建一个单一的、连贯的应用程序。例如,我们可以创建一个接受用户输入的链,使用 PromptTemplate 对其进行格式化,然后将格式化后的响应传递给 LLM。我们可以通过将多个链组合在一起,或者通过将链与其他组件组合来构建更复杂的链。
快速开始:使用LLMChain
这LLMChain是一个简单的链,它接受一个提示模板,用用户输入格式化它并返回来自 LLM 的响应。
要使用LLMChain,首先创建一个提示模板。
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
llm = OpenAI(temperature=0.9)
prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
我们现在可以创建一个非常简单的链,它将接受用户输入,用它格式化提示,然后将它发送给 LLM。
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
# Run the chain only specifying the input variable.
print(chain.run("colorful socks"))
Colorful Toes Co.
如果有多个变量,您可以使用字典一次输入它们。
prompt = PromptTemplate(
input_variables=["company", "product"],
template="What is a good name for {company} that makes {product}?",
)
chain = LLMChain(llm=llm, prompt=prompt)
print(chain.run({
'company': "ABC Startup",
'product': "colorful socks"
}))
Socktopia Colourful Creations.
LLMChain您也可以使用聊天模型:
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
)
human_message_prompt = HumanMessagePromptTemplate(
prompt=PromptTemplate(
template="What is a good name for a company that makes {product}?",
input_variables=["product"],
)
)
chat_prompt_template = ChatPromptTemplate.from_messages([human_message_prompt])
chat = ChatOpenAI(temperature=0.9)
chain = LLMChain(llm=chat, prompt=chat_prompt_template)
print(chain.run("colorful socks"))
Rainbow Socks Co.
调用链的不同方式
所有继承自的类都Chain提供了几种运行链逻辑的方法。最直接的一种是使用__call__:
chat = ChatOpenAI(temperature=0)
prompt_template = "Tell me a {adjective} joke"
llm_chain = LLMChain(
llm=chat,
prompt=PromptTemplate.from_template(prompt_template)
)
llm_chain(inputs={"adjective":"corny"})
{'adjective': 'corny',
'text': 'Why did the tomato turn red? Because it saw the salad dressing!'}
默认情况下,__call__返回输入和输出键值。return_only_outputs您可以通过设置为将其配置为仅返回输出键值True。
llm_chain("corny", return_only_outputs=True)
{'text': 'Why did the tomato turn red? Because it saw the salad dressing!'}
如果Chain只输出一个输出键(即只有一个元素在它的output_keys),你可以使用run方法。请注意,run输出的是字符串而不是字典。
# llm_chain only has one output key, so we can use run
llm_chain.output_keys
['text']
llm_chain.run({"adjective":"corny"})
'Why did the tomato turn red? Because it saw the salad dressing!'
在一个输入键的情况下,可以不指定输入映射直接输入字符串。
# These two are equivalent
llm_chain.run({"adjective":"corny"})
llm_chain.run("corny")
# These two are also equivalent
llm_chain("corny")
llm_chain({"adjective":"corny"})
{'adjective': 'corny',
'text': 'Why did the tomato turn red? Because it saw the salad dressing!'}
提示:您可以通过其方法轻松地将Chain对象集成为Tool您的对象。请在此处查看示例。Agentrun
向链中添加内存
Chain支持将BaseMemory对象作为memory参数,允许Chain对象在多次调用中持久保存数据。换句话说,它创建了Chain一个有状态的对象。
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
conversation = ConversationChain(
llm=chat,
memory=ConversationBufferMemory()
)
conversation.run("Answer briefly. What are the first 3 colors of a rainbow?")
# -> The first three colors of a rainbow are red, orange, and yellow.
conversation.run("And the next 4?")
# -> The next four colors of a rainbow are green, blue, indigo, and violet.
'The next four colors of a rainbow are green, blue, indigo, and violet.'
本质上,BaseMemory定义了一个如何langchain存储内存的接口。它允许通过方法读取存储的数据load_memory_variables并通过save_context方法存储新数据。您可以在内存部分了解更多信息。
调试链
由于大多数对象涉及大量输入提示预处理和 LLM 输出后处理,因此很难Chain仅从其输出调试对象。Chain设置verbose为将在运行时True打印出对象的一些内部状态。Chain
conversation = ConversationChain(
llm=chat,
memory=ConversationBufferMemory(),
verbose=True
)
conversation.run("What is ChatGPT?")
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Current conversation:
Human: What is ChatGPT?
AI:
> Finished chain.
'ChatGPT is an AI language model developed by OpenAI. It is based on the GPT-3 architecture and is capable of generating human-like responses to text prompts. ChatGPT has been trained on a massive amount of text data and can understand and respond to a wide range of topics. It is often used for chatbots, virtual assistants, and other conversational AI applications.'
组合链SequentialChain
调用语言模型后的下一步是对语言模型进行一系列调用。我们可以使用顺序链来做到这一点,顺序链是按预定义顺序执行其链接的链。具体来说,我们将使用SimpleSequentialChain. 这是最简单的顺序链类型,其中每个步骤都有一个输入/输出,一个步骤的输出是下一个步骤的输入。
在本教程中,我们的顺序链将:
- 首先,为产品创建公司名称。我们将重用LLMChain我们之前初始化的来创建这个公司名称。
- 然后,为产品创建一个标语。我们将初始化一个新的LLMChain来创建这个标语,如下所示。
second_prompt = PromptTemplate(
input_variables=["company_name"],
template="Write a catchphrase for the following company: {company_name}",
)
chain_two = LLMChain(llm=llm, prompt=second_prompt)
现在我们可以将这两个 LLMChain 结合起来,这样我们就可以一步创建一个公司名称和一个标语。
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)
> Entering new SimpleSequentialChain chain...
Rainbow Socks Co.
"Put a little rainbow in your step!"
> Finished chain.
"Put a little rainbow in your step!"
Chain使用类创建自定义链
LangChain 提供了许多开箱即用的链,但有时您可能希望为您的特定用例创建自定义链。对于这个例子,我们将创建一个自定义链来连接 2 的输出LLMChain。
为了创建自定义链:
- 从类的子Chain类开始,
- 填写input_keys和output_keys属性,
- 添加_call显示如何执行链的方法。
这些步骤在下面的示例中进行了演示:
from langchain.chains import LLMChain
from langchain.chains.base import Chain
from typing import Dict, List
class ConcatenateChain(Chain):
chain_1: LLMChain
chain_2: LLMChain
@property
def input_keys(self) -> List[str]:
# Union of the input keys of the two chains.
all_input_vars = set(self.chain_1.input_keys).union(set(self.chain_2.input_keys))
return list(all_input_vars)
@property
def output_keys(self) -> List[str]:
return ['concat_output']
def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:
output_1 = self.chain_1.run(inputs)
output_2 = self.chain_2.run(inputs)
return {'concat_output': output_1 + output_2}
现在,我们可以尝试运行我们调用的链。
prompt_1 = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
chain_1 = LLMChain(llm=llm, prompt=prompt_1)
prompt_2 = PromptTemplate(
input_variables=["product"],
template="What is a good slogan for a company that makes {product}?",
)
chain_2 = LLMChain(llm=llm, prompt=prompt_2)
concat_chain = ConcatenateChain(chain_1=chain_1, chain_2=chain_2)
concat_output = concat_chain.run("colorful socks")
print(f"Concatenated output:\n{concat_output}")
Concatenated output:
Funky Footwear Company
"Brighten Up Your Day with Our Colorful Socks!"
操作指南
链由链接组成,链接可以是原始链或其他链。基元可以是prompts、models、任意函数或其他链。此处的示例分为三个部分:
通用功能
涵盖通用链(在广泛的应用程序中很有用)以及与这些链相关的通用功能。
- Async API for Chain
- Creating a custom Chain
- Loading from LangChainHub
- LLM Chain
- Additional ways of running LLM Chain
- Parsing the outputs
- Initialize from string
- Router Chains
- Sequential Chains
- Serialization
- Transformation Chain
索引相关链
与使用索引相关的链。
- Analyze Document
- Chat Over Documents with Chat History
- Graph QA
- Hypothetical Document Embeddings
- Question Answering with Sources
- Question Answering
- Summarization
- Retrieval Question/Answering
- Retrieval Question Answering with Sources
- Vector DB Text Generation
所有其他相关链
所有其他类型的链条!
- API Chains
- Self-Critique Chain with Constitutional AI
- FLARE
- GraphCypherQAChain
- BashChain
- LLMCheckerChain
- LLM Math
- LLMRequestsChain
- LLMSummarizationCheckerChain
- Moderation
- Router Chains: Selecting from multiple prompts with MultiPromptChain
- Router Chains: Selecting from multiple prompts with MultiRetrievalQAChain
- OpenAPI Chain
- PAL
- SQL Chain example