构建由 LLM 驱动的 Neo4j 应用程序——使用 Neo4j 和 Haystack 实现强大搜索功能

在本章中,我们将开始探索如何将 Haystack 与 Neo4j 集成,结合大语言模型(LLMs)和图数据库的能力,构建一个 AI 驱动的搜索系统。Haystack 是一个开源框架,支持开发者利用现代自然语言处理技术、机器学习模型和基于图的数据,创建智能应用。对于我们的智能搜索系统,Haystack 将作为一个统一的平台,协调 LLM、搜索引擎和数据库,实现高度上下文化且相关性强的搜索结果。

基于上一章对 Neo4j 数据进行清洗和结构化的工作,我们将从使用 OpenAI 的 GPT 模型生成向量(embeddings)开始。这些向量将丰富图数据库,使其更强大,能够处理细腻且具上下文意识的搜索查询。Haystack 将作为 OpenAI 模型与 Neo4j 图数据库之间的桥梁,结合双方的优势。

本章内容包括如何设置和配置 Haystack,以实现与 Neo4j 的无缝集成。我们将引导你构建强大的搜索功能,最终使用 Gradio 部署完整的搜索系统,并托管在 Hugging Face Spaces 上。

本章主要涵盖以下内容:

  • 使用 Haystack 生成向量,增强 Neo4j 图数据
  • 将 Haystack 连接至 Neo4j,实现高级向量搜索
  • 构建强大的搜索体验
  • 对 Haystack 集成进行微调

技术要求

为了顺利实现 Haystack 和 Neo4j 的集成,并构建 AI 驱动的搜索系统,你需要确保开发环境已正确配置。以下是本章所需的技术条件:

  • Python:需要安装 Python 3.11,Python 用于脚本编写和与 Neo4j 交互。可从 Python 官方网站下载安装:www.python.org/downloads/

  • Neo4j AuraDB 或本地 Neo4j 实例:你需要有一个 Neo4j 数据库用于存储和查询图数据,可以是本地安装的 Neo4j,也可以是云端的 Neo4j AuraDB。如果你从上一章继续,可以使用之前搭建并导入数据的 Neo4j 实例,保持工作连贯。

  • Cypher 查询语言:熟悉 Cypher 查询语言非常重要,本章会大量使用 Cypher 创建和查询图数据。详细语法请参考:neo4j.com/docs/cypher...

  • Neo4j Python 驱动:安装 Neo4j Python 驱动,通过 Python 连接 Neo4j,安装命令如下:

    复制代码
    pip install neo4j
  • Haystack:本章使用 Haystack 版本 v2.5.0,安装命令如下:

    复制代码
    pip install haystack-ai
  • OpenAI API 密钥:为了使用基于 GPT 的模型生成向量,你需要一个有效的 OpenAI API 密钥。

    1. 如果还没有账号,请在 OpenAI 注册:platform.openai.com/signup

    2. 免费套餐的 API 密钥多数场景无法满足本项目需求,需要订阅付费版本以访问必要的接口和额度。

    3. 登录后进入 API 密钥管理页面:platform.openai.com/api-keys,生成新的 API 密钥。

    4. 同时安装 OpenAI Python 包:

      pip install openai

  • Gradio:用于创建用户友好的聊天界面,安装命令:

    复制代码
    pip install gradio
  • Hugging Face 账户:要将聊天机器人部署到 Hugging Face Spaces,需要注册 Hugging Face 账户,网址:huggingface.co/。

  • Google Cloud Storage(可选):如果你将 CSV 文件存储在 Google Cloud Storage,需要在脚本中正确配置文件路径。

  • python-dotenv 包:用于管理项目中的环境变量,安装命令:

    复制代码
    pip install python-dotenv

本章所有代码示例和资源均托管在 GitHub 仓库:github.com/PacktPublis...

在该仓库中,进入名为 ch6 的文件夹,可以找到本章相关的脚本、文件和配置,包含 Neo4j 与 Haystack 集成及基于电影数据集构建 AI 搜索系统的全部内容。请克隆或下载仓库以便跟随示例操作。

使用 Haystack 生成向量,增强你的 Neo4j 图数据

本节重点介绍如何为上一章中添加到 Neo4j 图中的电影剧情生成向量。向量是现代搜索系统的关键,它将文本转换成高维向量,支持相似度搜索,从而让搜索引擎能够理解词语和短语之间的上下文关系,提高搜索结果的准确性和相关性。

我们将集成 Haystack 与 OpenAI 的 GPT 模型生成向量,并将这些向量存储到 Neo4j 图中,从而实现更准确且具上下文感知的搜索功能。

初始化 Haystack 和 OpenAI 以生成向量

在生成向量之前,你需要确保 Haystack 已正确安装并与 OpenAI API 集成,从他们基于 GPT 的模型获取向量。请按以下步骤设置 Haystack:

  1. 安装所需的库(如果尚未安装),执行以下命令:

    pip install haystack haystack-ai openai neo4j-haystack

  2. 配置你的 OpenAI API 密钥,并确保在项目根目录下的 .env 文件中正确设置:

ini 复制代码
OPENAI_API_KEY=your_openai_api_key_here
  1. 通过创建 Python 脚本初始化 Haystack 并连接 OpenAI 来生成向量,示例如下:
ini 复制代码
# 使用 OpenAI 初始化 Haystack 以生成文本向量
def initialize_haystack():
    # 初始化文档存储(这里使用内存存储,后续可配置其他存储)
    document_store = InMemoryDocumentStore()
    # 初始化 OpenAITextEmbedder 以生成文本向量
    embedder = OpenAITextEmbedder(
        api_key=Secret.from_env_var("OPENAI_API_KEY"),
        model="text-embedding-ada-002"
    )
    return embedder

该配置使用内存中的文档存储初始化了 Haystack,并通过 OpenAI 向量模型配置了向量检索器。

为电影剧情生成向量

接下来,我们将为存储在 Neo4j 图中的电影剧情生成向量。目标是检索剧情描述,生成对应的向量,并将这些向量关联回对应的电影节点:

从 Neo4j 查询电影剧情:

首先,需要从 Neo4j 查询电影剧情。使用以下 Cypher 查询语句获取电影标题和剧情摘要:

ini 复制代码
# 从 Neo4j 获取电影剧情和标题
def retrieve_movie_plots():
    # 查询每个 Movie 节点的 "title"、"overview" 和 "tmdbId" 属性
    query = """
    MATCH (m:Movie)
    WHERE m.embedding IS NULL
    RETURN m.tmdbId AS tmdbId, m.title AS title, m.overview AS overview
    """
    with driver.session() as session:
        results = session.run(query)
        # 将每部电影的标题、剧情摘要和 ID 存入列表
        movies = [
            {
                "tmdbId": row["tmdbId"],
                "title": row["title"],
                "overview": row["overview"]
            }
            for row in results
        ]
    return movies

该查询会返回图中每部电影的 tmdbId 和剧情摘要(overview)。

使用 OpenAI 和 Haystack 生成向量:

在获取剧情摘要后,使用 Haystack 中的 OpenAITextEmbedder 生成向量:

python 复制代码
# 使用 ThreadPoolExecutor 并行生成向量
def generate_and_store_embeddings(embedder, movies, max_workers=10):
    results_to_store = []

    def process_movie(movie):
        title = movie.get("title", "Unknown Title")
        overview = str(movie.get("overview", "")).strip()
        tmdbId = movie.get("tmdbId")

        if not overview:
            print(f"Skipping {title} --- No overview available.")
            return None

        try:
            print(f"Generating embedding for: {title}")
            embedding_result = embedder.run(overview)
            embedding = embedding_result.get("embedding")
            if embedding:
                return (tmdbId, embedding)
            else:
                print(f"No embedding generated for: {title}")
        except Exception as e:
            print(f"Error processing {title}: {e}")
        return None

将向量存入 Neo4j:

生成向量后,下一步是将其存回 Neo4j 图中。每个电影节点将更新一个存储向量的属性:

python 复制代码
# 将向量存储回 Neo4j
def store_embedding_in_neo4j(tmdbId, embedding):
    query = """
    MATCH (m:Movie {tmdbId: $tmdbId})
    SET m.embedding = $embedding
    """
    with driver.session() as session:
        session.run(query, tmdbId=tmdbId, embedding=embedding)
    print(f"Stored embedding for TMDB ID: {tmdbId}")

这会将向量以名为 embedding 的属性保存到每个 Movie 节点中。

验证 Neo4j 中的向量存储情况:

向量存储后,你可以查询部分节点,确认向量属性是否存在:

ini 复制代码
# 验证 Neo4j 中存储的向量
def verify_embeddings():
    query = """
    MATCH (m:Movie)
    WHERE exists(m.embedding)
    RETURN m.title, m.embedding
    LIMIT 10
    """
    with driver.session() as session:
        results = session.run(query)
        for record in results:
            title = record["title"]
            embedding = np.array(record["embedding"])[:5]
            print(f" {title}: {embedding}...")

该查询会返回部分电影的标题和对应的向量(仅展示前5个维度),便于确认向量已成功存储。

注意

以上代码仅为核心片段,完整版本可参考 GitHub 仓库:github.com/PacktPublis...

至此,我们已用向量丰富了图数据库,新增了相似度搜索能力,能够执行更具上下文意识和智能化的查询。这一步对于提升搜索体验、实现基于文本语义的高级检索操作(而非简单关键词匹配)至关重要。

接下来,Neo4j 图已经被向量增强,下一步是将 Haystack 与 Neo4j 连接,实现高级向量搜索。在后续章节中,我们将重点介绍如何利用这些向量,在 Neo4j 中执行高效且精准的向量搜索,帮助我们基于向量相似度检索电影或其他节点。

将 Haystack 连接至 Neo4j 实现高级向量搜索

电影向量现已存储于 Neo4j 中,我们需要在 embedding 属性上配置一个向量索引,以便根据向量相似度高效地搜索电影。通过在 Neo4j 创建向量索引,我们可以快速检索在高维向量空间中相近的节点,从而支持复杂查询,比如查找剧情相似的电影。

向量索引创建完成后,将其与 Haystack 集成,实现基于向量相似度(如余弦相似度)的检索。

在 Neo4j 中创建向量搜索索引

首先,你需要删除(如果存在) embedding 属性上已有的向量索引,然后创建一个新的索引以支持向量搜索。以下是在 Python 脚本中使用 Cypher 查询完成该操作的示例:

python 复制代码
def create_or_reset_vector_index():
    with driver.session() as session:
        try:
            # 如果已有索引,则删除
            session.run("DROP INDEX overview_embeddings IF EXISTS ")
            print("旧索引已删除")
        except:
            print("无可删除的索引")
        # 创建 embedding 属性上的新向量索引
        print("创建新向量索引中")
        query_index = """
        CREATE VECTOR INDEX overview_embeddings IF NOT EXISTS
        FOR (m:Movie) ON (m.embedding)
        OPTIONS {indexConfig: {
            `vector.dimensions`: 1536,
            `vector.similarity_function`: 'cosine'}}
        """
        session.run(query_index)
        print("向量索引创建成功")

使用 Haystack 和 Neo4j 向量索引执行相似度搜索

创建向量索引后,可以利用 Haystack 基于电影剧情向量执行相似度搜索。该方法能够将给定的电影剧情或任意文本查询转换为向量,并与 Neo4j 中已存向量进行比较,返回最相关的结果。

以下示例演示如何使用 Haystack 的 OpenAITextEmbedder 生成查询向量,并执行相似度搜索:

ini 复制代码
text_embedder = OpenAITextEmbedder(
    api_key=Secret.from_env_var("OPENAI_API_KEY"),
    model="text-embedding-ada-002"
)

# 第一步:为查询文本生成向量
query_embedding = text_embedder.run(query).get("embedding")

if query_embedding is None:
    print("查询向量生成失败。")
    return

print("查询向量生成成功。")

使用 Haystack 和 Neo4j 执行向量搜索查询

在创建向量索引并将向量存入 Neo4j 后,你可以传入查询文本或电影剧情样本,系统将生成查询向量,和 Neo4j 中的向量比对,返回最相关的结果。

下面是一个不使用 Cypher,直接用 Haystack 进行向量搜索并展示最相似电影剧情的示例:

python 复制代码
# 第二步:利用查询向量搜索最相似文档
similar_documents = document_store.query_by_embedding(
    query_embedding, top_k=3
)

if not similar_documents:
    print("未找到相似文档。")
    return

print(f"找到 {len(similar_documents)} 个相似文档。\n\n")

# 第三步:展示结果
for doc in similar_documents:
    title = doc.meta.get("title", "N/A")
    overview = doc.meta.get("overview", "N/A")
    score = doc.score
    print(
        f"标题: {title}\n剧情摘要: {overview}\n"
        f"相似度得分: {score:.2f}\n{'-'*40}"
    )
print("\n\n")

接下来,我们将结合 Neo4j 的 Cypher 查询与 Haystack,执行向量搜索,实现相似电影剧情的检索功能。

使用 Cypher 和 Haystack 运行向量搜索查询

为了执行向量搜索,我们将结合 Cypher 的图查询能力,并利用 OpenAITextEmbedder 生成的向量嵌入进行相似度搜索。

与直接用 Haystack 查询向量索引不同,这种方法结合了 Cypher 的灵活性,能够返回更复杂的数据(例如电影元信息,如演员和类型),同时保持向量相似度搜索的高效性。

具体步骤如下:

  1. 使用 OpenAITextEmbedder 嵌入查询:
    将用户的文本查询(例如电影剧情)转换为高维向量嵌入。
  2. 使用 Neo4j 和 Cypher 搜索:
    通过 Cypher 查询 Neo4j 的向量索引,比较查询向量与存储的电影剧情向量,检索相似电影。
  3. 返回丰富数据:
    对于每个结果,获取额外的电影信息,如标题、剧情摘要、演员、类型以及相似度得分。

向量搜索实现示例:

定义 Cypher 查询:

首先定义一个 Cypher 查询,调用 Neo4j 向量索引(overview_embeddings),基于查询向量与电影向量的余弦相似度,返回 top_k 个最相似的电影:

ini 复制代码
cypher_query = """
    CALL db.index.vector.queryNodes("overview_embeddings", $top_k, $query_embedding)
    YIELD node AS movie, score
    MATCH (movie:Movie)
    RETURN movie.title AS title, movie.overview AS overview, score
"""

生成查询向量:

使用 OpenAITextEmbedder 将用户输入的查询文本(如电影剧情)转换为向量。该向量随后会传递给 Neo4j 向量索引用于比较:

ini 复制代码
text_embedder = OpenAITextEmbedder(
    api_key=Secret.from_env_var("OPENAI_API_KEY"),
    model="text-embedding-ada-002"
)

使用 Haystack 流水线运行向量搜索:

配置 Haystack 流水线来管理各组件:

  • query_embedder 负责从用户查询生成向量
  • retriever 使用 Cypher 查询 Neo4j,基于查询向量返回最相似电影
ini 复制代码
retriever = Neo4jDynamicDocumentRetriever(
    client_config=client_config,
    runtime_parameters=["query_embedding"],
    compose_doc_from_result=True,
    verify_connectivity=True,
)

pipeline = Pipeline()
pipeline.add_component("query_embedder", text_embedder)
pipeline.add_component("retriever", retriever)
pipeline.connect(
    "query_embedder.embedding", "retriever.query_embedding"
)

result = pipeline.run(
    {
        "query_embedder": {"text": query},
        "retriever": {
            "query": cypher_query,
            "parameters": {
                "index": "overview_embeddings", "top_k": 3
            },
        },
    }
)

展示结果:

搜索完成后,从结果中提取文档,并打印电影标题、剧情摘要和相似度得分:

python 复制代码
# 从检索结果中提取文档
documents = result["retriever"]["documents"]
for doc in documents:
    title = doc.meta.get("title", "N/A")
    overview = doc.meta.get("overview", "N/A")
    score = getattr(doc, "score", None)
    score_display = f"{score:.2f}" if score is not None else "N/A"
    print(
        f"Title: {title}\nOverview: {overview}\n"
        f"Score: {score_display}\n{'-'*40}\n"
    )

使用 Cypher 和 Haystack 的优势:

  • Cypher 灵活性:结合 Cypher 与 Haystack,不仅能查询向量嵌入,还能检索图数据库中额外的关系信息,如演员、类型及实体间关系。
  • 结果丰富:除了找到最相似电影外,还能轻松扩展查询,获取相关元数据(如演员、评分),或者加入更多过滤条件(如上映年份、类型)细化搜索。
  • 大图优化:Neo4j 的向量索引支持对大规模复杂关系数据集的高效查询,Haystack 的嵌入模型则提供精准的剧情语义理解。

接下来,我们将看一个具体的应用示例。

示例用例

假设你想查找剧情类似于"一个英雄必须拯救世界免于毁灭"的电影。通过我们刚才创建的流水线,你可以检索到相关结果:

标题:黑客帝国(The Matrix) 剧情简介:一名电脑黑客从神秘反抗者那里了解到自己现实的真相,以及他在对抗控制者战争中的角色。 相似度得分:0.98

标题:盗梦空间(Inception) 剧情简介:一名通过梦境共享技术窃取企业秘密的小偷,被赋予了将一个想法植入CEO大脑的逆向任务。 相似度得分:0.96

标题:黑暗骑士(The Dark Knight) 剧情简介:蝙蝠侠在警官吉姆·戈登和地区检察官哈维·登特的帮助下,加大了对犯罪的打击力度。 相似度得分:0.94

该流水线结合了两方面的优势------通过向量嵌入实现的相似度搜索,以及 Cypher 进行图数据查询的丰富功能,支持对电影等大规模数据集进行强大且灵活的搜索。

注意

以上代码仅为片段,完整版本请见 GitHub 仓库:github.com/PacktPublis...

至此,我们已将 Haystack 与 Neo4j 连接,实现了高级向量搜索功能。有了向量索引,Neo4j 能高效地基于向量相似度搜索相似电影节点。Haystack 的集成使你能够通过 Neo4jDynamicDocumentRetriever 无缝执行此类搜索,该检索器借助向量嵌入和 Neo4j 的图能力在图中寻找相似项。

下一节,我们将探讨如何构建一个以搜索为驱动的聊天机器人,结合 Haystack 和 Neo4j 的强大功能,提供丰富且具上下文感知的回答。通过 Gradio,我们将创建一个直观的聊天界面,实现用户交互和自然语言查询的高级搜索。这将融合大语言模型、向量搜索和 Neo4j 的优势,打造用户友好、AI 驱动的搜索体验。

使用 Gradio 和 Haystack 构建以搜索驱动的聊天机器人

本节将介绍如何集成 Gradio,构建一个由 Haystack 和 Neo4j 驱动的交互式聊天机器人界面。Gradio 使得创建基于网页的聊天界面变得简单。该聊天机器人允许用户输入查询,随后触发对存储在 Neo4j 中电影向量的基于向量的搜索。聊天机器人会返回详细的回复,包括电影标题、剧情摘要和相似度得分,提供信息丰富且用户友好的体验。

搭建 Gradio 界面

如果你尚未安装 Gradio,可通过以下命令安装:

复制代码
pip install gradio

注意:本章脚本适用于 Gradio v5.23.1。

接下来,我们搭建一个基本的 Gradio 界面,用于触发搜索流水线并显示结果:

ini 复制代码
import gradio as gr

# 定义 Gradio 聊天机器人接口
def chatbot(user_input):
    return perform_vector_search_cypher(user_input)

# 创建 Gradio 界面
chat_interface = gr.Interface(
    fn=chatbot,
    inputs=gr.Textbox(
        placeholder="你想看什么类型的电影?",
        lines=3,
        label="你的电影偏好"
    ),
    outputs=gr.Textbox(
        label="推荐结果",
        lines=12
    ),
    title="AI 电影推荐系统",
    description="问我关于电影的问题!我可以根据你的喜好推荐电影。",
    examples=[
        ["我想看带有时间旅行的科幻电影"],
        ["推荐一部有美好结局的浪漫喜剧"],
        ["我想看带超级英雄但不要太严肃的电影"],
        ["我想看紧张刺激的惊悚片"],
        ["给我推荐一些关于人工智能统治世界的电影"]
    ],
    flagging_mode="never"
)

该界面允许用户输入文本查询,聊天机器人将调用 perform_vector_search_cypher() 函数搜索最相关的电影。

与 Haystack 和 Neo4j 集成

为了让聊天机器人具备强大功能,我们将它连接到 Haystack 的向量生成模块和 Neo4j 的向量搜索功能。我们使用 OpenAITextEmbedder 来生成用户查询及 Neo4j 中电影剧情的向量。电影向量存储在 Neo4j 的向量索引中,我们通过该索引查询最相似的电影。

以下是如何将聊天机器人与之前的 Haystack 设置集成的示例:

ini 复制代码
# 使用 Cypher 支持的搜索和 Haystack 的对话聊天机器人处理器
def perform_vector_search(query):
    print("接收到消息:", query)
    cypher_query = """
        CALL db.index.vector.queryNodes("overview_embeddings", $top_k, $query_embedding)
        YIELD node AS movie, score
        MATCH (movie:Movie)
        RETURN movie.title AS title, movie.overview AS overview, score
    """
    # 向量生成器
    embedder = OpenAITextEmbedder(
        api_key=Secret.from_env_var("OPENAI_API_KEY"),
        model="text-embedding-ada-002"
    )
    # 检索器
    retriever = Neo4jDynamicDocumentRetriever(
        client_config=client_config,
        runtime_parameters=["query_embedding"],
        compose_doc_from_result=True,
        verify_connectivity=True,
    )
    # 流水线配置
    pipeline = Pipeline()
    pipeline.add_component("query_embedder", embedder)
    pipeline.add_component("retriever", retriever)
    pipeline.connect(
        "query_embedder.embedding", "retriever.query_embedding"
    )

将 Gradio 连接到完整流水线

现在,将这个 Gradio 聊天机器人与之前搭建的 Haystack 和 Neo4j 流水线连接起来。Gradio 界面将调用 perform_vector_search_cypher() 函数,该函数利用 Neo4jDynamicDocumentRetriever 根据用户查询搜索相似电影。

更新 main() 函数以初始化聊天机器人:

csharp 复制代码
# 主函数,协调整个流程
def main():
    # 第一步:在 Neo4j AuraDB 中创建或重置向量索引
    create_or_reset_vector_index()
    # 第二步:启动 Gradio 聊天机器人界面
    chat_interface.launch()

if __name__ == "__main__":
    main()

运行聊天机器人

运行聊天机器人只需执行你的 Python 脚本,Gradio 界面将在浏览器中启动,允许你实时与聊天机器人交互:

复制代码
python search_chatbot.py

Gradio 界面会在浏览器中打开,你可以输入如下查询:

"告诉我一个拯救世界的英雄的故事。"

聊天机器人会基于向量搜索返回与该查询相似的电影剧情。

注意

以上代码仅为核心片段,完整版本请见 GitHub 仓库:github.com/PacktPublis...

至此,本节我们已经构建了一个功能完善的以搜索为驱动的聊天机器人,结合了 Gradio、Haystack 和 Neo4j。该机器人利用存储在 Neo4j 中的向量,实现高级向量搜索,基于上下文为用户返回相关结果,如从 Neo4j 中检索有意义的电影标题和演员信息,响应用户查询。

不过,这仅仅是开始。下一节,我们将深入探讨如何微调 Haystack 集成,并探索优化搜索性能、调整检索模型以及优化聊天机器人回复等高级技术,以打造更流畅、高效的搜索驱动体验。

微调你的 Haystack 集成

现在是时候探索如何微调该集成,以提升性能和用户体验。虽然当前的配置已经能提供丰富且具上下文感知的回答,但你可以通过多种高级技术来优化搜索流程,提高检索准确性,使聊天机器人的交互更加流畅。

本节将重点调整 Haystack 的关键组件,包括尝试不同的向量模型、优化 Neo4j 查询以加快响应速度,以及改进聊天机器人回复的展示方式。这些增强措施将帮助你扩展聊天机器人的能力,以应对更复杂的查询,提升响应速度,并提供更加相关的搜索结果。

尝试不同的向量模型

目前我们使用的是 OpenAI 的 text-embedding-ada-002 模型来生成向量。自发布以来,该模型在广泛任务中表现稳定且高效,但值得注意的是,OpenAI 最近推出了新模型,如 text-embedding-3-smalltext-embedding-3-large,在性能和成本效益上都有显著提升。例如,text-embedding-3-small 在多语言和英语任务中表现更佳,同时成本仅为 text-embedding-ada-002 的五分之一。尽管本项目为了保持一致性未更换模型,但在实现类似流水线时,读者可以考虑使用 text-embedding-3-small,以在不牺牲性能的前提下提升效率------特别是当向量生成频繁或规模较大时。

此外,Haystack 支持多种其他模型,你可以尝试不同模型,寻找对你的具体用例最准确或最相关的结果。例如,可以切换为维度更高、功能更强的 OpenAI 模型,或尝试 Haystack 支持的其他向量服务。

以下示例演示如何轻松切换到另一种模型:

ini 复制代码
embedder = OpenAITextEmbedder(
    api_key=Secret.from_env_var("OPENAI_API_KEY"),
    model="text-embedding-babbage-001"  # 试验不同的模型
)

你还可以探索 OpenAI 其他模型,甚至集成不同的向量生成服务,比较它们在你的电影聊天机器人中的表现,以选择最佳方案。

优化 Neo4j 以加快查询速度

虽然 Neo4j 已经能高效处理基于图的查询,但针对大规模数据集,你仍然可以应用多种优化手段。通过为更多常用属性建立索引,可以提升查询性能。

为额外属性建立索引

除了 embedding 属性上的向量索引外,你还可以为其他常被查询的属性建立索引,比如 titletmdbId,以加快检索速度。这样在基于这些属性过滤或查询电影时,搜索会更加迅速高效:

scss 复制代码
def create_additional_indexes():
    with driver.session() as session:
        session.run("CREATE INDEX IF NOT EXISTS movie_title_index FOR (m:Movie) ON (m.title)")
        session.run("CREATE INDEX IF NOT EXISTS movie_tmdbId_index FOR (m:Movie) ON (m.tmdbId)")
        print("额外索引创建成功")

为这些属性建立索引,可以优化在非向量搜索场景下的查找,比如按标题过滤或精确获取某部电影。

持续改进聊天机器人的搜索体验,你还可以记录用户查询并进行分析,下面详细说明。

查询日志记录与分析

日志记录帮助你追踪最常见的搜索模式。通过对用户查询日志及其分析,你可以调整索引策略、优化检索器,或微调向量模型以提高准确率。

以下是实现简单日志记录机制的示例:

python 复制代码
import logging

logging.basicConfig(filename='chatbot_queries.log', level=logging.INFO)

def log_query(query):
    logging.info(f"用户查询: {query}")

每当用户输入查询时,都会被记录下来,便于后续分析。你可以基于这些日志做出有针对性的系统调整,确保系统随着时间推移变得更灵敏、更准确。

这些技术能显著提升你的搜索驱动型聊天机器人的性能、准确性和用户体验。无论是尝试不同的向量模型、优化 Neo4j 查询,还是改善结果格式化,每一次调整都让你的交互更顺畅、更强大。

通过这些高级技术,你的聊天机器人能够更好地扩展,应对更复杂的查询,并返回更加相关且吸引人的结果。

总结

在本章中,我们成功构建了一个功能完善的以搜索驱动的聊天机器人,集成了 Gradio、Haystack 和 Neo4j。首先,我们利用 OpenAI 模型生成的电影向量丰富了 Neo4j 图,实现了高级的基于向量的搜索功能。随后,我们将 Haystack 连接到 Neo4j,实现对图中存储的向量进行相似度搜索。最后,我们使用 Gradio 创建了一个用户友好的聊天界面,能够根据用户查询动态检索电影详情,如标题和演员信息。

下一章,我们将聚焦于 Haystack 的高级搜索能力和搜索优化,同时讨论针对大规模图的查询优化技术。

相关推荐
SEO_juper4 分钟前
企业级 AI 工具选型报告:9 个技术平台的 ROI 对比与部署策略
人工智能·搜索引擎·百度·llm·工具·geo·数字营销
奇舞精选2 小时前
prompt的参数调优入门指南 - 小白也能轻松掌握
人工智能·aigc
DisonTangor2 小时前
商汤InternLM发布最先进的开源多模态推理模型——Intern-S1
人工智能·深度学习·开源·aigc
同志们2 小时前
LiteLLM Go: 多平台LLM客户端统一接口实现
llm·go
软件测试君2 小时前
【Rag实用分享】小白也能看懂的文档解析和分割教程
aigc·openai·ai编程
Q同学2 小时前
SciMaster:无需微调,在人类最后考试上刷新 SOTA
人工智能·llm·agent
都叫我大帅哥3 小时前
LangChain分层记忆解决方案:完整案例
python·langchain
alex1003 小时前
AI Agent开发学习系列 - langchain之LCEL(5):如何创建一个Agent?
人工智能·python·语言模型·langchain·prompt·向量数据库·ai agent
聚客AI4 小时前
🚀深度解析Agentic RAG:如何突破模型的知识边界
人工智能·llm·掘金·日新计划
redreamSo6 小时前
AI Daily | AI日报:Meta百亿抢人,AI数据标注产业升级; 百度全栈自研,AI应用大放异彩; Hinton访华:多模态大模型已有「意识」
程序员·aigc·资讯