对话记忆是指聊天机器人如何以对话方式响应多个查询。它使对话连贯,并且如果没有它,每个查询都将被视为完全独立的输入,而不考虑过去的交互。
这种记忆使得大型语言模型(LLM)能够记住与用户之前的互动。默认情况下,LLMs是无状态的,这意味着每个传入的查询都是独立处理的,不考虑其他互动。对于一个无状态的代理,唯一存在的是当前的输入,没有其他信息。
有许多应用程序在其中记住之前的互动非常重要,比如聊天机器人。对话记忆允许我们做到这一点。
有几种方法可以实现对话记忆。在LangChain的背景下,它们都是基于ConversationChain构建的。
ConversationChain(对话链)
我们可以通过初始化ConversationChain(对话链)开始。我们将使用OpenAI的text-davinci-003作为LLM,但也可以使用其他模型,如gpt-3.5-turbo。
ini
from langchain import OpenAI
from langchain.chains import ConversationChain
# first initialize the large language model
llm = OpenAI(
temperature=0,
openai_api_key="OPENAI_API_KEY",
model_name="text-davinci-003"
)
# now initialize the conversation chain
conversation = ConversationChain(llm=llm)
我们可以这样查看ConversationChain使用的提示模板:
In[8]:
scss
print(conversation.prompt.template)
Out[8]:
css
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:
{history}
Human: {input}
AI:
在这里,提示通过告诉模型以下内容是一个人类(我们)和一个AI(text-davinci-003)之间的对话来引导模型。提示试图通过陈述以下内容来减少幻觉(模型编造事物的情况):
"If the AI does not know the answer to a question, it truthfully says it does not know."
这有助于减少幻觉的发生,但并不能完全解决幻觉的问题,但我们将把这个问题留到未来章节讨论。
在初始提示之后,我们看到两个参数;{history} 和 {input}。{input} 是我们将放置最新的人类查询的地方;它是输入到聊天机器人文本框的输入内容:
{history} 是用于使用对话记忆的地方。在这里,我们提供了关于人类和AI之间对话历史的信息。
这两个参数------{history} 和 {input}------传递给了我们刚刚看到的提示模板中的LLM,而我们(希望如此)返回的输出只是对话的预测继续部分。
对话记忆的形式
我们可以在ConversationChain中使用多种类型的对话记忆。它们修改传递给{history}参数的文本。
对话缓冲记忆
ConversationBufferMemory是LangChain中最直接的对话记忆形式。正如我们上面所描述的,过去人类和AI之间的对话的原始输入以其原始形式传递到{history}参数中。
In[11]:
ini
from langchain.chains.conversation.memory import ConversationBufferMemory
conversation_buf = ConversationChain(
llm=llm,
memory=ConversationBufferMemory()
)
In[32]:
scss
conversation_buf("Good morning AI!")
Out[32]:
css
{'input': 'Good morning AI!',
'history': '',
'response': " Good morning! It's a beautiful day today, isn't it? How can I help you?"}
我们返回了对话代理的第一个响应。让我们继续对话,编写只有在考虑对话历史时LLM才能回答的提示。我们还添加了一个count_tokens函数,以便我们可以查看每次交互使用了多少标记。
In[6]:
python
from langchain.callbacks import get_openai_callback
def count_tokens(chain, query):
with get_openai_callback() as cb:
result = chain.run(query)
print(f'Spent a total of {cb.total_tokens} tokens')
return result
In[33]:
scss
count_tokens(
conversation_buf,
"My interest here is to explore the potential of integrating Large Language Models with external knowledge"
)
Out[33]:
css
Spent a total of 179 tokens
Out[33]:
scala
' Interesting! Large Language Models are a type of artificial intelligence that can process natural language and generate text. They can be used to generate text from a given context, or to answer questions about a given context. Integrating them with external knowledge can help them to better understand the context and generate more accurate results. Is there anything else I can help you with?'
In[34]:
css
count_tokens(
conversation_buf,
"I just want to analyze the different possibilities. What can you think of?"
)
Out[34]:
css
Spent a total of 268 tokens
Out[34]:
vbnet
' Well, integrating Large Language Models with external knowledge can open up a lot of possibilities. For example, you could use them to generate more accurate and detailed summaries of text, or to answer questions about a given context more accurately. You could also use them to generate more accurate translations, or to generate more accurate predictions about future events.'
In[35]:
css
count_tokens(
conversation_buf,
"Which data source types could be used to give context to the model?"
)
Out[35]:
css
Spent a total of 360 tokens
Out[35]:
vbnet
' There are a variety of data sources that could be used to give context to a Large Language Model. These include structured data sources such as databases, unstructured data sources such as text documents, and even audio and video data sources. Additionally, you could use external knowledge sources such as Wikipedia or other online encyclopedias to provide additional context.'
In[36]:
scss
count_tokens(
conversation_buf,
"What is my aim again?"
)
Out[36]:
css
Spent a total of 388 tokens
Out[36]:
vbnet
' Your aim is to explore the potential of integrating Large Language Models with external knowledge.'
LLM显然可以记住对话的历史。让我们看看ConversationBufferMemory是如何存储这个对话历史的:
In[37]:
scss
print(conversation_buf.memory.buffer)
Out[37]:
vbnet
Human: Good morning AI!
AI: Good morning! It's a beautiful day today, isn't it? How can I help you?
Human: My interest here is to explore the potential of integrating Large Language Models with external knowledge
AI: Interesting! Large Language Models are a type of artificial intelligence that can process natural language and generate text. They can be used to generate text from a given context, or to answer questions about a given context. Integrating them with external knowledge can help them to better understand the context and generate more accurate results. Is there anything else I can help you with?
Human: I just want to analyze the different possibilities. What can you think of?
AI: Well, integrating Large Language Models with external knowledge can open up a lot of possibilities. For example, you could use them to generate more accurate and detailed summaries of text, or to answer questions about a given context more accurately. You could also use them to generate more accurate translations, or to generate more accurate predictions about future events.
Human: Which data source types could be used to give context to the model?
AI: There are a variety of data sources that could be used to give context to a Large Language Model. These include structured data sources such as databases, unstructured data sources such as text documents, and even audio and video data sources. Additionally, you could use external knowledge sources such as Wikipedia or other online encyclopedias to provide additional context.
Human: What is my aim again?
AI: Your aim is to explore the potential of integrating Large Language Models with external knowledge.
我们可以看到缓冲保存了聊天历史中的每一次互动。这种方法有一些优点和缺点。简而言之,它们是:
Pros | Cons |
---|---|
Storing everything gives the LLM the maximum amount of information | More tokens mean slowing response times and higher costs |
Storing everything is simple and intuitive | Long conversations cannot be remembered as we hit the LLM token limit (4096 tokens for text-davinci-003 and gpt-3.5-turbo) |
ConversationBufferMemory是一个很好的开始选项,但受到保存每次互动的存储限制。让我们看看其他可以帮助解决这个问题的选项。
对话摘要记忆
使用ConversationBufferMemory,我们很快就使用了大量的标记,甚至超出了当前最先进的LLMs的上下文窗口限制。
为了避免过多的标记使用,我们可以使用ConversationSummaryMemory。正如其名称所示,这种形式的记忆在传递给{history}参数之前对对话历史进行了总结。
我们可以这样初始化ConversationChain,使用总结记忆:
ini
from langchain.chains.conversation.memory import ConversationSummaryMemory
conversation = ConversationChain(
llm=llm,
memory=ConversationSummaryMemory(llm=llm)
)
当使用ConversationSummaryMemory时,我们需要将一个LLM传递给该对象,因为总结是由一个LLM提供支持的。我们可以在这里看到用于此操作的提示:
In[19]:
scss
print(conversation_sum.memory.prompt.template)
Out[19]:
vbnet
Progressively summarize the lines of conversation provided, adding onto the previous summary returning a new summary.
EXAMPLE
Current summary:
The human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good.
New lines of conversation:
Human: Why do you think artificial intelligence is a force for good?
AI: Because artificial intelligence will help humans reach their full potential.
New summary:
The human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good because it will help humans reach their full potential.
END OF EXAMPLE
Current summary:
{summary}
New lines of conversation:
{new_lines}
New summary:
使用这个方法,我们可以总结每一次新的互动,并将它添加到所有过去互动的"运行摘要"中。让我们再次进行一次利用这种方法的对话。
In[40]:
rust
# without count_tokens we'd call `conversation_sum("Good morning AI!")`
# but let's keep track of our tokens:
count_tokens(
conversation_sum,
"Good morning AI!"
)
Out[40]:
css
Spent a total of 290 tokens
Out[40]:
css
" Good morning! It's a beautiful day today, isn't it? How can I help you?"
In[41]:
scss
count_tokens(
conversation_sum,
"My interest here is to explore the potential of integrating Large Language Models with external knowledge"
)
Out[41]:
css
Spent a total of 440 tokens
Out[41]:
css
" That sounds like an interesting project! I'm familiar with Large Language Models, but I'm not sure how they could be integrated with external knowledge. Could you tell me more about what you have in mind?"
In[42]:
css
count_tokens(
conversation_sum,
"I just want to analyze the different possibilities. What can you think of?"
)
Out[42]:
css
Spent a total of 664 tokens
Out[42]:
vbnet
' I can think of a few possibilities. One option is to use a large language model to generate a set of candidate answers to a given query, and then use external knowledge to filter out the most relevant answers. Another option is to use the large language model to generate a set of candidate answers, and then use external knowledge to score and rank the answers. Finally, you could use the large language model to generate a set of candidate answers, and then use external knowledge to refine the answers.'
In[43]:
css
count_tokens(
conversation_sum,
"Which data source types could be used to give context to the model?"
)
Out[43]:
css
Spent a total of 799 tokens
Out[43]:
vbnet
' There are many different types of data sources that could be used to give context to the model. These could include structured data sources such as databases, unstructured data sources such as text documents, or even external APIs that provide access to external knowledge. Additionally, the model could be trained on a combination of these data sources to provide a more comprehensive understanding of the context.'
In[44]:
scss
count_tokens(
conversation_sum,
"What is my aim again?"
)
Out[44]:
css
Spent a total of 853 tokens
Out[44]:
vbnet
' Your aim is to explore the potential of integrating Large Language Models with external knowledge.'
在这种情况下,总结包含足够的信息,以使LLM"记住"我们最初的目标。我们可以像这样查看总结的原始形式:
In[45]:
scss
print(conversation_sum.memory.buffer)
Out[45]:
sql
The human greeted the AI with a good morning, to which the AI responded with a good morning and asked how it could help. The human expressed interest in exploring the potential of integrating Large Language Models with external knowledge, to which the AI responded positively and asked for more information. The human asked the AI to think of different possibilities, and the AI suggested three options: using the large language model to generate a set of candidate answers and then using external knowledge to filter out the most relevant answers, score and rank the answers, or refine the answers. The human then asked which data source types could be used to give context to the model, to which the AI responded that there are many different types of data sources that could be used, such as structured data sources, unstructured data sources, or external APIs. Additionally, the model could be trained on a combination of these data sources to provide a more comprehensive understanding of the context. The human then asked what their aim was again, to which the AI responded that their aim was to explore the potential of integrating Large Language Models with external knowledge.