手记

聊天机器人的记忆技巧:如何让它记得你的对话

这张照片由 Ant Rozetsky 拍摄,来自 Unsplash

看看对话记忆如何增强聊天机器人的互动,让AI能够记住之前的对话。了解LangChain里不同类型的内存如何工作,例如ConversationBufferMemory和ConversationSummaryMemory,并通过详细图表展示不同类型的内存使用情况。让您的AI在对话中更加连贯和相关!
对话中的记忆?

会话记忆是聊天机器人的一种能力,它能够流畅地进行对话并回应多个查询。通过记住之前的互动,会话记忆确保了对话的连贯性,而无状态模型则对每个查询都是独立处理的。

比较有和没有对话记忆的大型语言模型

在对话中,蓝色框代表用户的提示,灰色框显示LLM的回复。没有对话记忆功能,LLM无法记住之前的对话,只能独立回应每个查询。

实现会话记忆

默认情况下,LLM是没有状态的记忆,这意味着每个查询都是单独处理的,不参考之前的对话。然而,对话记忆让LLM能够记住过去的对话,这对于像聊天机器人这样的应用来说非常重要。

对话中的记忆可以通过多种方式实现。在LangChain中,所有方法都基于对话链(ConversationChain)。

设置对话链

首先,初始化ConversationChain。我们将使用OpenAI的text-davinci-003作为我们的LLM,但也可以使用其他模型,比如gpt-3.5-turbo。

    从langchain导入OpenAI模块  
    从langchain.chains导入ConversationChain模块   

    # 初始化大规模语言模型  
    llm = OpenAI(  
        temperature=0,  
        openai_api_key="OPENAI_API_KEY",  
        model_name="text-davinci-003"  
    )  

    # 初始化对话流程  
    conversation = ConversationChain(llm=llm)

你可以查看ConversationChain用的提示模板:

打印 conversation.prompt.template

这个模板设置了友好对话的基调,特别强调了对话背景中的具体细节。

对话记忆的种类
会话缓存

最简单的对话记忆方式。它以原始形式保存整个对话记录,然后将这些内容传递给历史参数。

    from langchain.chains.conversation.memory 导入 ConversationBufferMemory  

    conversation_buf = ConversationChain(  
        llm=llm,  
        memory=ConversationBufferMemory()  
    )

示例交互及token计数:

    from langchain.callbacks import get_openai_callback  

    def count_tokens(chain, query):  
        with get_openai_callback() as cb:  
            result = chain.run(query)  
            print(f'共用了 {cb.total_tokens} 个 token')  
        return result  

    count_tokens(conversation_buf, "早上好,AI!")  
    count_tokens(conversation_buf, "我在这里的兴趣是探索将大型语言模型与外部知识相结合的潜力")  
    count_tokens(conversation_buf, "我只是想分析一下不同的可能性。你能想到些什么?")  
    count_tokens(conversation_buf, "哪些数据源类型可以用来给模型提供背景?")  
    count_tokens(conversation_buf, "我的目的是什么?")  
print(conversation_buf.memory.buffer)
# 打印会话缓冲区的内容
    ###输出####  

    早上好!今天天气真好,不是吗?有什么我能帮忙的吗?  
    真有趣!大型语言模型是一种能够处理自然语言并生成文本的人工智能模型。它们可以用于根据给定的上下文生成文本,或者回答有关给定上下文的问题。将它们与外部知识源结合可以更好地理解上下文并生成更准确的结果。还有其他我能帮你的吗?  
    比如说,将大型语言模型与外部知识结合可以开启很多可能性。例如,你可以用它们生成更准确和详细的文本摘要,或者对未来事件做出更准确的预测。你也可以用它们生成更准确的翻译,或者对未来事件做出更准确的预测。  
    有很多种数据源可以用来为大型语言模型提供上下文。这些包括结构化数据源,如数据库,非结构化数据源,如文本文件,甚至是音频和视频数据源。此外,你还可以使用维基百科等在线百科全书作为外部知识源,提供更多背景信息。  
    你的目标是探索将大型语言模型与外部知识结合的各种可能。  

    人类:早上好,AI!  
    AI:早上好!今天天气真好,不是吗?有什么我能帮忙的吗?  
    人类:我对探索将大型语言模型与外部知识结合的各种可能性很感兴趣。  
    AI:真有趣!大型语言模型是一种能够处理自然语言并生成文本的人工智能模型。它们可以用于根据给定的上下文生成文本,或者回答有关给定上下文的问题。将它们与外部知识源结合可以更好地理解上下文并生成更准确的结果。还有其他我能帮你的吗?  
    人类:我只想分析一下各种可能的情况。你能想到哪些?  
    AI:比如说,将大型语言模型与外部知识结合可以开启很多可能性。例如,你可以用它们生成更准确和详细的文本摘要,或者对未来事件做出更准确的预测。你也可以用它们生成更准确的翻译,或者对未来事件做出更准确的预测。  
    人类:可以用来为模型提供上下文的数据源类型有哪些?  
    AI:有很多种数据源可以用来为大型语言模型提供上下文。这些包括结构化数据源,如数据库,非结构化数据源,如文本文件,甚至是音频和视频数据源。此外,你还可以使用维基百科等在线百科全书作为外部知识源,提供更多背景信息。  
    人类:我的目标是什么?  
    AI:你的目标是探索将大型语言模型与外部知识结合的各种可能。

利弊:

  • 优点:信息保留效果最佳,实现简单。
  • 缺点:更多的tokens会导致响应变慢和成本增加,长时间对话受限于token的数量。
对话记忆摘要

因此,需要总结对话记录以减少使用过多的 token,这需要一个大模型来生成摘要。

    from langchain.chains.conversation.memory import ConversationSummaryMemory  

    conversation_sum = ConversationChain(  
        llm=llm,  
        memory=ConversationSummaryMemory(llm=llm)  
    )  

    print(conversation_sum.memory.prompt.template)  

    count_tokens(conversation_sum, "早安,AI!")  
    count_tokens(conversation_sum, "我在这里的兴趣是探索将大型语言模型与外部知识结合的潜力")  
    count_tokens(conversation_sum, "我只是想分析不同的可能性。你有什么想法?")  
    count_tokens(conversation_sum, "我们可以使用哪些数据源类型来为模型提供上下文?")  
    count_tokens(conversation_sum, "我刚才的目标是什么?")  

    # 查看对话总结  
    print(conversation_sum.memory.buffer)
    ##输出##
    早上好!今天天气不错吧?我怎么帮您呢?
    听起来这是一个有趣的项目!我对大型语言模型很熟悉,但不确定它们如何与外部知识结合使用。您能详细说说您具体的想法吗?
    我能想到几种可能。一种选择是使用大型语言模型生成一系列候选答案来回答给定的问题,然后使用外部知识筛选出最相关答案。另一种选择是使用大型语言模型生成一系列候选答案,然后使用外部知识对答案进行评分和排序。最后,您还可以使用大型语言模型生成一系列候选答案,然后使用外部知识完善答案。
    可以用于为模型提供背景的数据来源有很多种。这些可能包括结构化数据来源,如数据库,非结构化数据来源,如文本文件,甚至提供外部知识访问的外部API。此外,模型可以在这些数据来源的组合上进行训练,以提供更全面的理解背景。
    您的目标是探索将大型语言模型与外部知识结合的可能性。

    人类用早安问候了AI,AI回应了早安,并询问如何帮助。人类表达了对探索将大型语言模型与外部知识结合潜力的兴趣,AI积极回应并要求更多信息。人类让AI思考各种可能性,AI提出了三种选择:使用大型语言模型生成一系列候选答案,然后使用外部知识筛选出最相关答案,对答案进行评分和排序,或者完善答案。然后人类询问哪些类型的数据源可以用于为模型提供背景,AI回答说有很多不同类型的数据来源可以使用,如结构化数据来源,非结构化数据来源或外部API。此外,模型可以在这些数据来源的组合上进行训练,以提供更全面的理解背景。人类最后再次询问他们的目标,AI回答说他们的目标是探索将大型语言模型与外部知识结合的可能性。

优点和缺点:

  • 优点:在长对话中减少令牌使用,这使得更长时间的互动成为可能。
  • 缺点:短对话中令牌使用增多,依赖于准确的总结
  • 图表:缓冲内存与摘要内存中的令牌计数
会话窗口缓存记忆

这种方法仅保留指定数量的最近交互,从而有效地限制了使用的令牌(token)数量。

    从langchain.chains.conversation.memory模块导入ConversationBufferWindowMemory  

    # 使用带缓冲区窗口的会话内存初始化会话链  
    conversation_bufw = ConversationChain(  
        llm=llm,  
        memory=ConversationBufferWindowMemory(k=1)  
    )  

    # 示例交互  
    print(conversation_bufw("早安,AI!"))  
    print(conversation_bufw("我想探索大型语言模型与外部知识结合的潜力"))  
    print(conversation_bufw("我只是想看看有哪些可能。你有什么想法吗?"))  
    print(conversation_bufw("可以用哪些数据源为模型提供上下文信息?"))  
    print(conversation_bufw("我刚才说的目标是什么来着?"))  

    # 查看窗口中的对话历史记录  
    bufw_history = conversation_bufw.memory.load_memory_variables(inputs=[])['history']  
    print(bufw_history)

模型的记忆容量:

    ##输出##

    早上好!今天天气真好,不是吗?有什么我可以帮您的吗?
    真有趣!大型语言模型是一种能够处理自然语言并生成文本内容的人工智能。结合外部知识可以帮助模型更好地理解上下文并生成更准确的结果。您有关于这种集成的具体问题要问吗?
    将大型语言模型与外部知识结合有很多可能性。例如,您可以使用外部知识为模型提供额外的上下文,或者使用额外的训练数据进行训练。您还可以使用外部知识帮助模型更好地理解给定文本的上下文,或者帮助生成更准确的结果。
    可以用来为模型提供上下文的数据源包括文本语料库、结构化数据库和本体。文本语料库提供了大量的文本数据,可以用来训练模型并提供额外的上下文。结构化数据库提供了结构化数据,可以帮助模型更好地理解上下文。本体提供了可以用来为模型提供额外上下文的知识结构化表示。
    您的目标是利用数据源来丰富模型的背景知识。

    人类:我的目标是什么呢?
    AI:您的目标是利用数据源来丰富模型的背景知识。

优点和缺点:

  • 优点:限制了Token使用量,可以调整窗口大小。
  • 缺点:无法记住较远的互动。
  • 图表:缓冲窗口内存中的Token计数
会话摘要缓存

结合了摘要功能和缓冲内存,保持近期与远期互动之间的平衡。

    from langchain.chains.conversation.memory import ConversationSummaryBufferMemory  

    conversation_sum_bufw = ConversationChain(  
        llm=llm,  
        memory=ConversationSummaryBufferMemory(llm=llm, max_token_limit=650)  
    )  

    ### 示例对话,带有 token 限制:  

    count_tokens(conversation_sum_bufw, "早安,AI!")  
    count_tokens(conversation_sum_bufw, "我对整合大型语言模型和外部知识的潜力很感兴趣。")  
    count_tokens(conversation_sum_bufw, "我只是想分析一下不同的可能性,你觉得怎么样?")  
    count_tokens(conversation_sum_bufw, "有没有哪些数据源类型可以用来为模型提供上下文?")  
    count_tokens(conversation_sum_bufw, "我刚才说的目标是什么来着?")
    ###输出结果###  
    消息:早上好AI!  
    回应:[AI回应]  
    当前token计数:3  

    消息:我想探索将大型语言模型与外部知识结合的可能性  
    回应:[AI回应]  
    当前token计数:23  

    消息:我只是想分析不同的可能性。你觉得有哪些可能?  
    回应:[AI回应]  
    当前token计数:40  

    消息:哪些数据源可以为模型提供上下文?  
    回应:[AI回应]  
    当前token计数:56  

    消息:我刚才的目标是什么?  
    回应:[AI回应]  
    当前token计数:69  

优缺点:

  • 具体来说,优点:通过总结较旧的互动来保留较早的互动,以原始形式保持最近的互动。
  • 具体来说,缺点:需要仔细调整哪些内容进行总结,哪些内容进行存储。

对比图:

总结

对话记忆增强了大规模语言模型维持连贯且情境感知的对话的能力。不论是通过缓冲记忆、摘要、窗口式记忆,还是它们的组合,每种方法都有其独特的优势和权衡,让开发人员为他们的具体应用场景选择最佳方案。想要了解更多详情,请访问LangChain的对话记忆页面。

0人推荐
随时随地看视频
慕课网APP