Type something to search...
提升对话质量:5个步骤让你的聊天机器人更具记忆力

提升对话质量:5个步骤让你的聊天机器人更具记忆力

学习如何构建一个能记住你对话的AI。

Source: DALLE.

聊天机器人如何记忆?

你有没有注意到聊天机器人可以多么像人类一样响应?

最受欢迎的 聊天机器人 允许你在特定主题上问它一个问题,然后跟进更多深入探讨 上下文 的额外问题。在这种典型的人类风格的 对话 中,你可能 从未重复原始主题,但聊天机器人仍然记得你在谈论什么。

聊天机器人是如何记住这些的?

在本教程中,我们将通过一个包含 对话记忆 的聊天机器人构建示例进行讲解。你将看到这有多强大,并准确了解它是如何工作的!

像搜索引擎,但完全不同

搜索引擎 也允许用户提问,从中返回与主题最匹配的结果。

然而,如果你曾经尝试向搜索引擎提出与第一次相关的第二个问题(而不重复相同的主题),搜索引擎将对该主题没有记忆,只会返回与你提供的 确切短语 匹配的任何结果。

增强了对话记忆的聊天机器人能够始终记住对话。这使它们与搜索引擎明显不同。与更基础的聊天机器人相比,增加 记忆 使一切都不同。

对话的设计

增强对话记忆的聊天机器人设计包含一个检索增强生成 (RAG) 聊天机器人的典型部分。

  • 通用客户端接口
  • 存储预处理知识的数据库
  • 用于将查询与知识库内容匹配的相似性算法
  • 用于提供响应的大型语言模型 (LLM)

该设计包括检索过程生成过程。然而,记忆的关键增强是通过对话中的先前查询和响应的缓存提供的。

来源:报告中的作者。

上面的图表展示了聊天机器人如何利用私人文档的知识库来生成响应。接收到查询后,与知识库进行匹配。生成的文档与查询一起用作上下文,以格式化为LLM提供响应的提示

记住主题

没有记忆的标准大型语言模型驱动的聊天机器人和对话型聊天机器人之间的关键区别在于,我们还将迄今为止的整个对话输入到提示中。

考虑以下图表,详细说明了如何为将对话历史发送到大型语言模型进行提示工程。

来源:报告中的作者。

在上面的图表中,请注意用户的 查询文档上下文检索到的对话 是如何附加到发送给大型语言模型以获取新响应的 提示 中的。

在收到响应后,我们将结果存储回 缓存 中。随着对话的继续,缓存进一步增长。对大型语言模型的每次后续调用都包含下一个提示中的整个对话历史。

用记忆驱动聊天机器人

一个经典的聊天机器人可以回答来自摄取文档的单次问题。然而,它无法记住原始主题

如果用户提出后续问题,聊天机器人将不会保持历史记录,并会在文档中进行完全新搜索以尝试回答问题。如果查询中缺少特定的关键词,聊天机器人可能不会给出合适的回应。

增强版的聊天机器人通过使用内存列表来维护对话。这可以简单地是一个数组分布式内存,例如Redis

在每轮对话中,提示的大小会随着我们不断将最后的对话存储在缓存中而增长。大型语言模型能够在提供响应时使用当前查询的上下文和截至目前的整个对话。

将问题与知识匹配

当用户第一次提出问题时,查询会与知识库进行匹配,以找到最佳匹配的上下文

这是创建基于私有文档的聊天机器人时RAG过程的一部分。如下面的代码所示,系统找到最佳匹配的文档作为上下文,并将其附加到LLM的提示中。

def chat(user_query, is_debug = False):
    original_best_matches, processed_best_matches = find_best_matches(user_query)
    context = "\\n\\n".join(original_best_matches)

    response = get_cohere_response(user_query, context)

    return response, context

来自LLM的响应和本轮对话的上下文都返回给客户端。

添加对话历史

到目前为止,我们已经看到一个典型的聊天机器人实现,它在将问题匹配到知识上下文后,通过提示调用大型语言模型。然而,真正的增强来自于存储对话

conversation_history = []

def add_to_conversation(user_input, search_result_context, llm_response):
    conversation_entry = {
        "user_input": user_input,
        "search_result_context": search_result_context,
        "llm_response": llm_response
    }
    conversation_history.append(conversation_entry)

在上面的代码中,我们将用户的查询、搜索结果和大型语言模型的响应保存到内存数组中。我们可以稍后检索这些数据,以便在后续的提示中包含到大型语言模型中。

更新LLM提示与记忆

现在对话被保存到记忆中,我们可以检索所有先前的查询和响应,以便在下一个响应中包含它们。

def conversation(user_query, is_debug = False):
    history = "\\n\\n=========================\\n\\n".join(
        [f"User: {entry['user_input']}\\nSearch Result Context: {entry['search_result_context']}\\nLLM Response: {entry['llm_response']}" for entry in conversation_history]
    )

    query = f"This is the entire conversation up to this point. Use this as additional context when answering the question from the user.\\n CONTEXT: {history}\\n\\n"
    query += f"\\n\\n=========================\\n\\n USER QUERY: {user_query}"

    response, context = process_chat(query, is_debug)

    add_to_conversation(user_query, context, response)
    return response

注意我们如何构建一个包含对话历史新提示

一点提示工程的作用

一个独特的 分隔字符串 被添加到 提示 中,以提供对话部分与当前用户查询之间的边界。

一系列条形字符 “=====” 被用来向 LLM 表明这是对话历史。我们接着给 LLM 一个指令,要求在提供响应时使用这些数据。

“这是到目前为止的整个对话。在回答用户的问题时,将此作为额外的 上下文。上下文: { }, 用户查询: { }”

在将历史附加到提示后,我们包含当前用户查询,并请求 LLM 给出新的响应。

结果就像 魔法 一样!

print(conversation('Who are the first 5 authors from the report?'))
print(conversation('Which one is the first?'))
print(conversation('Which one is fifth?'))

报告中的前五位作者是:

  1. Govindasamy Bala
  2. Deliang Chen
  3. Tamsin Edwards
  4. Sandro Fuzzi
  5. Thian Yew Gan

Govindasamy Bala 是报告的第一作者。

第五位作者是 Thian Yew Gan。

注意 LLM 如何利用 先前对话 作为 上下文 回答关于 “报告中的作者” 的后续问题。

我们可以通过直接询问 LLM 对话的主题来验证对话记忆是否正常工作。

print(conversation('What is the topic of this conversation?'))

这个对话的主题是报告的前五位作者。

将对话限制为30分钟

由于我们将对话存储在缓存中,它可能很容易超出LLM输入令牌的大小限制(例如,128KB等)。

因此,我们可以将对话存储限制为特定的时间段。在30分钟后启用滚动缓存刷新,可以在较长时间后清除缓存。用户可以开始一个新的对话主题。

from cachetools import TTLCache
from datetime import datetime

conversation_ttl_cache = TTLCache(maxsize=1000, ttl=1800)

def add_to_conversation_cache(user_input, search_result_context, llm_response):
    current_time = datetime.now().isoformat()
    conversation_entry = {
        "user_input": user_input,
        "search_result_context": search_result_context,
        "llm_response": llm_response,
        "timestamp": current_time
    }

    conversation_ttl_cache[current_time] = conversation_entry

上述示例提供了一种修改后的对话保存方法。我们使用生存时间缓存,而不是使用基本数组,可以设置为30分钟的过期。保存到列表中的条目将在一段时间后过期

然后,我们可以检索缓存中所有未被删除的条目,并将它们包含在LLM的上下文中。请记住,这可以通过将更改为用户ID会话ID来扩展到多个用户。

扩展到分布式缓存

到目前为止,我们已经使用数组和时间敏感缓存实现了缓存。然而,我们可以通过使用 Redis 将聊天机器人扩展到 分布式缓存

下面是将对话存储在 Redis 中的示例,而不是内存数组。

import json
import redis

r = redis.Redis(host='localhost', port=6379, db=0)

def add_to_conversation_redis(user_id, user_input, search_result_context, llm_response):
    conversation_entry = {
        "user_input": user_input,
        "search_result_context": search_result_context,
        "llm_response": llm_response,
        "timestamp": current_time
    }

    conversation_entry_str = json.dumps(conversation_entry)

    key = user_id

    r.setex(key, 1800, conversation_entry_str)

Redis 存储 字符串,而不是 对象。这是因为需要网络调用将数据发送到服务。因此,我们在按照指定键存储到 Redis 之前,将对话 JSON对象 转换为字符串。

来源:DALLE.

一个更强大的聊天机器人

正如我们所看到的,将对话记忆构建到大型语言模型驱动的聊天机器人中是一种增强其能力的强大方式。

我们已经演示了如何通过利用一个简单的内存数组来构建具有记忆的聊天机器人是多么简单。然而,您可以进一步提升这些增强功能。以下是一些入门的想法。

时间敏感缓存

与其使用简单的数组来存储对话,不如使用时间敏感缓存数据结构,该结构在特定时间段后过期条目。

分布式缓存

利用 分布式记忆 使用 Redis 或其他基于服务的缓存产品。这些缓存可以在网络服务器上或通过互联网运行,使您的聊天机器人能够运行多个主机实例并连接到一个公共缓存以实现 持久 记忆。

将缓存持久化到磁盘

对话不必在短时间内被删除。实际上,它可以通过持久化到 磁盘数据库 来无限期存储。对话可以在几天、几周甚至几年后被检索和重新使用。

用户或会话ID

对话可以使用 用户会话ID 作为 缓存键 存储,其中整个对话作为该键下提供的列表。通过这种方式,整个用户的对话可以使用 滚动过期,而不是逐个回合地过期,数据仅在一段时间不活动后才会过期。

本教程的代码可以在 这里 下载。

关于作者

Image 5

此故事发布在 Generative AI 上。

Image 6

Related Posts

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

AI 研究报告和论文写作 合并两个系统指令以获得两个模型的最佳效果 Perplexity AI 的 Deep Research 工具提供专家级的研究报告,而 OpenAI 的 ChatGPT-o3-mini-high 擅长推理。我发现你可以将它们结合起来生成令人难以置信的论文,这些论文比任何一个模型单独撰写的都要好。你只需要将这个一次性提示复制到 **

阅读更多
让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

Non members click here作为一名软件开发人员,多年来的一个发现总是让我感到惊讶,那就是人们还在 Excel

阅读更多
使用 ChatGPT 搜索网络功能的 10 种创意方法

使用 ChatGPT 搜索网络功能的 10 种创意方法

例如,提示和输出 你知道可以使用 ChatGPT 的“搜索网络”功能来完成许多任务,而不仅仅是基本的网络搜索吗? 对于那些不知道的人,ChatGPT 新的“搜索网络”功能提供实时信息。 截至撰写此帖时,该功能仅对使用 ChatGPT 4o 和 4o-mini 的付费会员开放。 ![](https://images.weserv.nl/?url=https://cdn-im

阅读更多
掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

10 个常见问题解答 本文是我推出的一个名为“10 个常见问题解答”的新系列的一部分。在本系列中,我旨在通过回答关于该主题的十个最常见问题来分解复杂的概念。我的目标是使用简单的语言和相关的类比,使这些想法易于理解。 图片来自 [Solen Feyissa](https://unsplash.com/@solenfeyissa?utm_source=medium&utm_medi

阅读更多
在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和科技这样一个动态的行业中,保持领先意味着不断提升你的技能。无论你是希望深入了解人工智能模型性能、掌握数据分析,还是希望通过人工智能转变传统领域如法律,这些课程都是你成功的捷径。以下是一个精心策划的高价值课程列表,可以助力你的职业发展,并让你始终处于创新的前沿。 1. 生成性人工智能简介课程: [生成性人工智能简介](https://genai.works

阅读更多
揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

在AI军备竞赛中分辨事实与虚构 DeepSeek AI真的是它所宣传的游戏规则改变者,还是仅仅聪明的营销和战略炒作?👀 虽然一些人将其视为AI效率的革命性飞跃,但另一些人则认为它的成功建立在借用(甚至窃取的)创新和可疑的做法之上。传言称,DeepSeek的首席执行官在疫情期间像囤积卫生纸一样囤积Nvidia芯片——这只是冰山一角。 从其声称的550万美元培训预算到使用Open

阅读更多
Type something to search...