dot Redis 8 来了 - 并且是开源的

了解更多

使用 Redis、LangChain 和 OpenAI 构建电子商务聊天机器人

鉴于最近 AI 赋能 API 和 Web 开发工具的激增,似乎每个人都在其应用程序中构建聊天机器人。想看看涉及到哪些方面吗?这里有一个概述。

一个新兴的(并且非常流行的)框架,LangChain,可以轻松开发与语言模型和外部数据或计算源交互的应用程序。它通过专注于清晰且模块化的抽象来实现构建所需的所有构建块;然后它构建常用的“链”,这些链是构建块的组合。例如,对话检索链使用户能够与外部存储中的数据进行“对话”。

它是如何做到的?OpenAI 语言模型没有经过贵公司特定数据的训练,当然也没有针对其进行调整。如果您希望聊天机器人依赖它,您需要在运行时向 OpenAI 提供您的数据。检索步骤使用向量相似性搜索 (VSS) 从 Redis 中获取与用户查询相关的数据,然后将数据与原始问题一起输入到语言模型中。它要求模型使用提供的来源 - 我们在 AI 圈子里称之为“上下文” - 来回答问题。

此链中的大部分复杂性都归结为检索步骤。这就是为什么我们很高兴在 LangChain 和 Redis Enterprise 作为向量数据库之间添加集成。这种组合使得弥合复杂 AI 和产品开发之间的差距成为可能 - 而无需大费周折。

不相信我们?在这个简短的教程中,我们构建了一个对话式零售购物助手,它可以帮助客户找到隐藏在产品目录中的感兴趣的商品。您可以按照完整的代码进行操作

构建您的聊天机器人

在我们开始之前,我们要感谢来自 LabLab AI 的 Fabian Stehle,他编写了此演示的初始原型。我们对其进行了扩展,并添加了额外的 LangChain 组件,使其具有更多功能。

首先,让我们收集项目所需的所有部分。

安装 Python 要求

此项目需要一些 Python 库。这些库存储在 github 仓库requirements.txt 文件中。

pip install langchain==0.0.123
pip install openai==0.27.2
pip install redis==4.5.3
pip install numpy
pip install pandas
pip install gdown

获取并准备产品数据集

对于零售聊天机器人,我们选择使用 Amazon Berkeley Objects 数据集。这包括大量 Amazon 产品,非常适合生成零售助手。从链接下载文件,或使用 gdown 命令行界面从 托管链接下载文件。

gdown --id 1tHWB6u3yQCuAgOYc-DxtZ8Mru3uV5_lj

我们使用 pandas Python 库来加载和预处理数据集。在加载时,我们会截断较长的文本字段。这是为了使我们的数据集更精简一些,从而节省内存和计算时间。

import pandas as pd

MAX_TEXT_LENGTH=1000  # Maximum num of text characters to use

def auto_truncate(val):

    """Truncate the given text."""

    return val[:MAX_TEXT_LENGTH]

# Load Product data and truncate long text fields

all_prods_df = pd.read_csv("product_data.csv", converters={

    'bullet_point': auto_truncate,

    'item_keywords': auto_truncate,

    'item_name': auto_truncate

})

在我们的产品数据集完全加载后,我们执行一些最终的预处理步骤来清理关键字字段并删除缺失值。

# Replace empty strings with None and drop

all_prods_df['item_keywords'].replace('', None, inplace=True)

all_prods_df.dropna(subset=['item_keywords'], inplace=True)

# Reset pandas dataframe index

all_prods_df.reset_index(drop=True, inplace=True)

如果您正在按照 github 上的代码进行操作,请使用 all_prods_df.head() 查看 dataframe。完整的数据集包含超过 100,000 种产品,但对于此聊天机器人,我们将其限制为 2,500 种产品的子集。

# Num products to use (subset)
NUMBER_PRODUCTS = 2500  

# Get the first 2500 products
product_metadata = ( 
    all_prods_df
     .head(NUMBER_PRODUCTS)
     .to_dict(orient='index')
)

# Check one of the products
product_metadata[0]

这是一个我们可以使用的产品 JSON 对象的示例。

{'item_id': 'B07T2JY31Y',
 'marketplace': 'Amazon',
 'country': 'IN',
 'main_image_id': '71vX7qIEAIL',
 'domain_name': 'amazon.in',
 'bullet_point': '3D Printed Hard Back Case Mobile Cover for Sony Xperia Z1 L39H Easy to put & take off with perfect cutouts for volume buttons, audio & charging ports. Stylish design and appearance, express your unique personality. Extreme precision design allows easy access to all buttons and ports while featuring raised bezel to life screen and camera off flat surface. Slim Hard Back Cover No Warranty',
 'item_keywords': 'mobile cover back cover mobile case phone case mobile panel phone panel LG mobile case LG phone cover LG back case hard case 3D printed mobile cover mobile cover back cover mobile case phone case mobile panel phone panel Sony Xperia mobile case Sony Xperia phone cover Sony Xperia back case hard case 3D printed mobile cover mobile cover back cover mobile case phone case mobile panel phone panel Sony Xperia mobile case Sony Xperia phone cover Sony Xperia back case hard case 3D printed mobile cover mobile cove',
 'material': 'Wood',
 'brand': 'Amazon Brand - Solimo',
 'color': 'others',
 'item_name': 'Amazon Brand - Solimo Designer Leaf on Wood 3D Printed Hard Back Case Mobile Cover for Sony Xperia Z1 L39H',
 'model_name': 'Sony Xperia Z1 L39H',
 'model_number': 'gz8056-SL40528',
 'product_type': 'CELLULAR_PHONE_CASE'}

将 Redis 设置为向量数据库

LangChain 有一个简单的 Redis 包装器,可以帮助您加载文本数据并创建捕获“含义”的 嵌入。在此代码中,我们准备产品文本和元数据,准备文本嵌入提供程序 (OpenAI),为搜索索引分配名称,并提供用于连接的 Redis URL。

import os

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores.redis import Redis as RedisVectorStore

# set your openAI api key as an environment variable
os.environ['OPENAI_API_KEY'] = "YOUR OPENAI API KEY"

# data that will be embedded and converted to vectors
texts = [
    v['item_name'] for k, v in product_metadata.items()
]

# product metadata that we'll store along our vectors
metadatas = list(product_metadata.values())

# we will use OpenAI as our embeddings provider
embedding = OpenAIEmbeddings()

# name of the Redis search index to create
index_name = "products"

# assumes you have a redis stack server running on local host
redis_url = "redis://localhost:6379"

此时,我们已成功处理了 Amazon 产品数据集,并将其加载到包含向量嵌入的 Redis 数据库中。

然后,我们将所有内容组合在一起以创建 Redis vectorstore

# create and load redis with documents
vectorstore = RedisVectorStore.from_texts(
    texts=texts,
    metadatas=metadatas,
    embedding=embedding,
    index_name=index_name,
    redis_url=redis_url
)

现在,我们准备创建一个使用产品数据(存储在 Redis 中)来告知对话的聊天机器人。

创建 LangChain 对话链

聊天机器人 非常受欢迎,因为它们非常有用。在我们下面构建的场景中,我们假设您需要时尚建议。您可以向机器人寻求帮助,以寻找适合休闲外出和工作相关外出的鞋子。您想要一些引人注目但不引起太多注意的东西。鉴于我们已经向其提供的数据,我们的聊天机器人应该能够推荐几双符合要求的鞋子。

现在是引入更多 LangChain 功能的时候了。为此,我们需要导入几个 LangChain 工具。

from langchain.callbacks.base import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
from langchain.chains import (
    ConversationalRetrievalChain,
    LLMChain
)
from langchain.chains.question_answering import load_qa_chain
from langchain.llms import OpenAI
from langchain.prompts.prompt import PromptTemplate

如简介中所述,此项目使用 ConversationalRetrievalChain 来简化聊天机器人开发。

Redis 保存我们的产品目录,包括元数据和 OpenAI 生成的嵌入,这些嵌入捕获产品内容的语义属性。在底层,使用 Redis 向量相似性搜索 (VSS),聊天机器人查询目录以查找与用户正在购买的产品最相似或最相关的产品。无需花哨的关键字搜索或手动过滤;VSS 会处理它。

构成聊天机器人的 ConversationalRetrievalChain 分三个阶段运行

  1. 问题创建评估输入问题,并使用 OpenAI GPT 模型将其与来自先前对话交互的知识(如果有)组合在一起。
  2. 检索在 Redis 中搜索可用的最佳产品,给定购物者表示感兴趣的商品。
  3. 问题解答从向量搜索查询中获取产品结果,并使用 OpenAI GPT 模型来帮助购物者浏览选项。

即使 LangChain 和 Redis 极大地加快了此工作流程,与像 GPT 这样的大型语言模型 (LLM) 交互也需要一个用于通信的“提示”。我们人类创建一个提示(一组指令)来引导模型的行为朝着期望的结果发展。为了从聊天机器人获得最佳结果,进一步的 提示工程可能会有所帮助。

请参阅我们为上述步骤 1 和 3 定义的两个提示。您可以始终从这些开始,并针对您自己的场景进行改进。

template = """Given the following chat history and a follow up question, rephrase the follow up input question to be a standalone question.
Or end the conversation if it seems like it's done.
Chat History:\"""
{chat_history}
\"""
Follow Up Input: \"""
{question}
\"""
Standalone question:"""

condense_question_prompt = PromptTemplate.from_template(template)

template = """You are a friendly, conversational retail shopping assistant. Use the following context including product names, descriptions, and keywords to show the shopper whats available, help find what they want, and answer any questions.

It's ok if you don't know the answer.
Context:\"""

{context}
\"""
Question:\"
\"""

Helpful Answer:"""

qa_prompt= PromptTemplate.from_template(template)

接下来,我们定义两个 OpenAI LLM,并分别使用链对其进行包装以进行问题生成和问题解答。streaming_llm 允许我们将聊天机器人响应逐个令牌地传递到 stdout,从而赋予其迷人的、类似聊天机器人的用户体验。

# define two LLM models from OpenAI
llm = OpenAI(temperature=0)

streaming_llm = OpenAI(
    streaming=True,
    callback_manager=CallbackManager([
        StreamingStdOutCallbackHandler()
    ]),
    verbose=True,
    max_tokens=150,
    temperature=0.2
)

# use the LLM Chain to create a question creation chain
question_generator = LLMChain(
    llm=llm,
    prompt=condense_question_prompt
)

# use the streaming LLM to create a question answering chain
doc_chain = load_qa_chain(
    llm=streaming_llm,
    chain_type="stuff",
    prompt=qa_prompt
)

最后,我们使用包装所有三个步骤的 ConversationalRetrievalChain 将所有内容联系在一起。

chatbot = ConversationalRetrievalChain(
    retriever=vectorstore.as_retriever(),
    combine_docs_chain=doc_chain,
    question_generator=question_generator
)

试用您友好的虚拟购物助手

请记住,这不是一个完全智能的生物。但在 Redis 的帮助下,它存储了示例的整个产品库存知识库,我们创造了非常棒的体验。

# create a chat history buffer
chat_history = []
# gather user input for the first question to kick off the bot
question = input("Hi! What are you looking for today?")

# keep the bot running in a loop to simulate a conversation
while True:
    result = chatbot(
        {"question": question, "chat_history": chat_history}
    )
    print("\n")
    chat_history.append((result["question"], result["answer"]))
    question = input()

机器人与您实时交互,并帮助您根据目录中的内容缩小到有趣的产品选择范围。这是一个简单的例子

Hi! What are you looking for today?

>> gold-plated earrings

Hi there! I'm happy to help you find the perfect earrings. Do you have a preference for yellow gold plated sterling silver or platinum or gold-plated sterling silver?

>> My preference is the yellow gold plated sterling silver

Hi there! Are you looking for yellow gold-plated sterling silver earrings with Swarovski Zirconia or Topaz gemstones? We have a few options that might fit the bill. We have yellow gold-plated sterling silver Swarovski Zirconia fancy green stud earrings, yellow gold-plated sterling silver honey topaz stud earrings made with Swarovski Topaz gemstones, and yellow gold-plated sterling silver antique drop earrings set.

在聊天机器人用“嗨!你今天想找什么?”欢迎您之后,尝试以下一些示例提示,或创建您自己的提示

  • 银色或金色的花式耳环
  • 舒适的步行鞋
  • 耐用的 iPhone 手机壳

自定义您的链以获得更好的性能

LangChain 最好的部分之一是每个类抽象都经过制作,以便您可以扩展或创建自己的抽象。下面,我们自定义 BaseRetriever 类以在返回结果之前执行一些文档预处理。

import json
from langchain.schema import BaseRetriever
from langchain.vectorstores import VectorStore
from langchain.schema import Document
from pydantic import BaseModel

class RedisProductRetriever(BaseRetriever, BaseModel):
    vectorstore: VectorStore

    class Config:
        arbitrary_types_allowed = True

    def combine_metadata(self, doc) -> str:
        metadata = doc.metadata
        return (
           "Item Name: " + metadata["item_name"] + ". " +
           "Item Description: " + metadata["bullet_point"] + ". " +
           "Item Keywords: " + metadata["item_keywords"] + "."
        )

    def get_relevant_documents(self, query):
        docs = []
        for doc in self.vectorstore.similarity_search(query):
            content = self.combine_metadata(doc)
            docs.append(Document(
                page_content=content,
                metadata=doc.metadata
            ))

        return docs

我们需要更新检索类和聊天机器人以使用上面的自定义实现。

redis_product_retriever = RedisProductRetriever(vectorstore=vectorstore)

chatbot = ConversationalRetrievalChain(
    retriever=redis_product_retriever,
    combine_docs_chain=doc_chain,
    question_generator=question_generator
)

完成!现在您的聊天机器人可以在您的对话中注入更多产品信息,因为它会引导您走向电子商务的辉煌!这是另一个简短的对话示例

Hi! What are you looking for today?

>>> fancy footwear for going out

Hi there! We have a few great options for women's shoes and sandals. We have the Amazon Brand - The Fix Women's Giana Open Toe Bootie with Pearl Buckle, bright white leather, 9.5 B US, Flavia Women's Beige Fashion Sandals-7 UK (39 EU) (8 US) (FL/236/BEG), Flavia Women's Blue Fashion Sandals-8 UK (40 EU) (9 US) (FL/211/BLU), and The Fix Women's Faris Flat Slide Sandal with Pearls. All of these shoes feature a variety of styles and colors to choose from. Let me know if you have any questions about any of these items!

>>> These are nice. However, I am looking for men's shoes. Can you help me?

Hi there! We have a great selection of men's formal shoes available. We have Amazon Brand - Symbol Men's Formal Shoes, Amazon Brand - Symbol Men's Leather Formal Shoes, and more. All of our formal shoes are made from high quality materials and feature a variety of closure types, toe styles, and heel types. They also come with a manufacturer's warranty and care instructions to ensure they last. Let me know if you have any questions or need help finding the perfect pair of shoes for you!

>>>Can you show me some more men's options?

Hi there! I'm here to help you find the perfect item for you. We have a few options available for men's formal shoes. We have the Men's Stainless Steel Link Bracelet, the Amazon Brand - Arthur Harvey Men's Leather Formal Shoes, and the Amazon Brand - Symbol Men's Formal Derby shoes. All of these items feature a variety of features such as leather material, lace-up closure, pointed toe, block heel, and more. If you have any questions about any of these items, please let me know. I'm happy to help!

>>> Ok this looks great, thanks!

后续步骤

使用 LangChain 和 Redis 构建很容易。尝试自己构建 此聊天机器人,或针对您的用例进行自定义。免费试用 Redis Enterprise 或提取我们的 Redis Stack docker 容器以开始使用。

有兴趣动手进行 AI 开发吗?我们的合作伙伴 LabLab AI 将在下个月举办 一系列黑客马拉松,其中包含 Redis。争夺奖品、炒作和名声。事实上,4 月 14 日开始将举办一个带有 Stable Diffusion 的黑客马拉松

Stable diffusion AI hackathon promo image

喜欢 Tyler 和 Harrison 关于生成式 AI 的介绍吗?在 5 月 24 日举行的免费虚拟活动 RedisDays Virtual 上观看他们在联合会议期间分享更多实际示例。

了解更多关于 Redis 中的 向量相似性搜索。您可能会对您能完成的事情感到惊讶。