构建由 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 的高级搜索能力和搜索优化,同时讨论针对大规模图的查询优化技术。

相关推荐
沐雪架构师1 小时前
LangChain 1.0 内置的Agent中间件详解
中间件·langchain
GPUStack2 小时前
vLLM、SGLang 融资背后,AI 推理正在走向系统化与治理
大模型·llm·vllm·模型推理·sglang·高性能推理
PaperRed ai写作降重助手2 小时前
主流 AI 论文写作工具排名(2026 最新)
人工智能·aigc·ai写作·论文写作·论文降重·论文查重·辅助写作
小程故事多_803 小时前
RAG分块天花板?LGMGC多粒度语义分块策略深度解析与实践思考
人工智能·aigc
Bruk.Liu3 小时前
(LangChain实战5):LangChain消息模版ChatPromptTemplate
人工智能·python·langchain·agent
爱敲代码的TOM3 小时前
大模型应用开发-LangChain框架基础
python·langchain·大模型应用
SmartBrain3 小时前
AI算法工程师面试:大模型和智能体知识(含答案)
人工智能·算法·语言模型·架构·aigc
renhongxia13 小时前
知识图谱如何在制造业实际落地应用
人工智能·语言模型·自然语言处理·aigc·知识图谱
Bruk.Liu3 小时前
(LangChain实战3):LangChain阻塞式invoke与流式stream的调用
人工智能·python·langchain
Bruk.Liu4 小时前
(LangChain实战4):LangChain消息模版PromptTemplate
人工智能·python·langchain