Redis 作为上下文存储与 OpenAI Chat

本笔记本演示了如何将 Redis 用作 ChatGPT 的高速上下文内存。

先决条件

  • 具有 Redis Search 和 Redis JSON 模块的 Redis 实例
  • Redis-py 客户端库
  • OpenAI Python 客户端库
  • OpenAI API 密钥

安装

安装示例所需的 Python 模块。

! pip install -q redis openai python-dotenv 'openai[datalib]'

OpenAI API 密钥

创建一个 .env 文件并将您的 OpenAI 密钥添加到其中。

OPENAI_API_KEY=your_key

OpenAI 设置

密钥加载 + 用于聊天补全的辅助函数。

from openai import OpenAI
import os
from dotenv import load_dotenv

load_dotenv()
oai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

def get_completion(prompt, model="gpt-3.5-turbo"):
    messages = [{"role": "user", "content": prompt}]
    response = oai_client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0,
    )
    return response.choices[0].message.content

实验 - 对模型知识截止日期之外的主题进行聊天补全

Gpt-3.5-turbo 的训练数据截止到 2021 年 9 月。让我们问它一个关于该日期之后的事情。在这种情况下,是 FTX/Sam Bankman-Fried 的丑闻。我们在这里使用一个旧模型进行演示。较新的模型,如 gpt-4o,具有较晚的知识截止日期(2023 年末),在这里也能正常工作。

prompt = "FTX,Sam Bankman-Fried 的公司,是否被认为是一家管理良好的公司?"
response = get_completion(prompt)
print(response)
是的,FTX 通常被认为是一家管理良好的公司。FTX 的创始人兼首席执行官 Sam Bankman-Fried 在加密货币行业拥有良好的业绩记录,并已成功将该公司发展成为全球领先的加密货币交易所之一。FTX 还因其用户友好的平台、创新的产品和强大的客户服务而获得好评。此外,FTX 在监管合规方面一直很积极,并已采取措施确保用户资金的安全。总的来说,FTX 被视为加密货币领域的管理良好的公司。

信息不完整

这些 AI 系统的一个不幸行为是,即使系统对其结果没有信心,它也会提供听起来很自信的响应。一种缓解此问题的方法是进行提示工程,如下所示。

prompt ="FTX,Sam Bankman-Fried 的公司,是否被认为是一家管理良好的公司? 如果您不确定,请说未知。"
response = get_completion(prompt)
print(response)
FTX 通常被认为是一家管理良好的公司。其创始人兼首席执行官 Sam Bankman-Fried 在加密货币行业以其领导力和战略眼光而闻名。自 2017 年成立以来,FTX 也经历了显著的增长和成功。然而,如果没有具体的内部知识或数据,最终无法确定 FTX 是否被明确认为是一家管理良好的公司。

附加上下文

对抗信息不完整的另一种方法是为系统提供更多信息,以便它可以做出明智的决定,而不是猜测。我们将使用 Redis 作为该附加上下文的来源。我们将从 GPT 知识截止日期之后提取商业新闻文章,以便系统能够更好地理解 FTX 的实际管理情况。

启动 Redis Stack Docker 容器

! docker compose up -d

连接 Redis 客户端

from redis import from_url

REDIS_URL = 'redis://localhost:6379'
client = from_url(REDIS_URL)
client.ping()
True

创建索引

FT.CREATE

from redis.commands.search.field import TextField, VectorField
from redis.commands.search.indexDefinition import IndexDefinition, IndexType

schema = [ VectorField('$.vector', 
            "FLAT", 
            {   "TYPE": 'FLOAT32', 
                "DIM": 1536, 
                "DISTANCE_METRIC": "COSINE"
            },  as_name='vector' ),
            TextField('$.content', as_name='content')
        ]
idx_def = IndexDefinition(index_type=IndexType.JSON, prefix=['doc:'])
try: 
    client.ft('idx').dropindex()
except:
    pass
client.ft('idx').create_index(schema, definition=idx_def)
b'OK'

将数据文件加载到 Redis 中,作为具有文本和向量字段的 JSON 对象

Redis JSON

directory = './assets/'
model = 'text-embedding-3-small'
i = 1

for file in os.listdir(directory):
    with open(os.path.join(directory, file), 'r') as f:
        content = f.read()
        # 使用新的基于客户端的方法创建嵌入
        response = oai_client.embeddings.create(
            model=model,
            input=[content]
        )
        # 从响应对象访问嵌入
        vector = response.data[0].embedding

        # 使用您的 JSON 客户端存储内容和向量
        client.json().set(f'doc:{i}', '$', {'content': content, 'vector': vector})
    i += 1

嵌入问题并执行 VSS 以查找最相关的文档

KNN 搜索

from redis.commands.search.query import Query
import numpy as np

response = oai_client.embeddings.create(
    input=[prompt],
    model=model
)
# 从响应中提取嵌入向量
embedding_vector = response.data[0].embedding

# 将嵌入转换为 float32 类型的 numpy 数组,然后转换为字节
vec = np.array(embedding_vector, dtype=np.float32).tobytes()

# 构建并执行 Redis 查询
q = Query('*=>[KNN 1 @vector $query_vec AS vector_score]') \
    .sort_by('vector_score') \
    .return_fields('content') \
    .dialect(2)
params = {"query_vec": vec}

context = client.ft('idx').search(q, query_params=params).docs[0].content
print(context)

将问题重复给 OpenAI 并附带上下文

现在我们有了相关的上下文,将其添加到 OpenAI 的提示中,并获得一个截然不同的响应。

prompt = f"""
使用三引号分隔的信息,回答这个问题:FTX,Sam Bankman-Fried 的公司,是否被认为是一家管理良好的公司?

上下文:```{context}```
"""

response = get_completion(prompt)
print(response)
根据提供的信息,FTX,Sam Bankman-Fried 的公司,并不被认为是一家管理良好的公司。该公司已面临破产程序、客户资金处理不当、未经授权的交易、被监管机构冻结资产,以及缺乏可信赖的财务信息。新任首席执行官 John J. Ray III 将此情况描述为“公司控制的完全失败”,并表示存在严重的管理不善。此外,该公司在处理数十亿美元业务时,其财务状况、记录保存的缺乏以及不充分的会计工具的使用,都引发了对其管理实践的严重担忧。