Chainlit集成LlamaIndex实现知识库高级检索(组合对象检索)

news2024/9/30 9:18:22

检索原理

对象组合索引的原理 是利用IndexNode索引节点,将两个不同类型的检索器作为节点对象,使用 SummaryIndex (它可以用来构建一个包含多个索引节点的索引结构。这种索引通常用于从多个不同的数据源或索引方法中汇总信息,并能够基于这些信息进行更复杂的查询操作,如摘要生成。)当查询SummaryIndex时,它会考虑所有包含在内的索引节点,并根据需要综合它们的信息来生成最终的响应或摘要。

组合对象索引检索器的优缺点

结合向量检索(Vector Retrieval)和BM25检索的方式,具有其独特的优点和缺点。下面是对这两种检索方式及其组合使用的优缺点的概述:

向量检索(Vector Retrieval)

优点:
  1. 语义理解:向量检索基于嵌入模型,能够更好地理解文本之间的语义关系,而不仅仅是关键字匹配。
  2. 上下文感知:向量检索可以捕捉句子或段落之间的上下文关系,对于长文本的理解更为有效。
  3. 泛化能力:即使查询词不在文档中出现,只要语义上相关,也可以找到相关的文档。
缺点:
  1. 计算成本:向量检索需要对文档进行嵌入编码,这可能会增加计算资源的需求。
  2. 索引维护:维护一个大型的向量索引可能较为复杂,并且随着文档数量的增加,索引的更新和存储可能变得昂贵。
  3. 精确度依赖于模型质量:向量检索的效果高度依赖于所使用的嵌入模型的质量,如果模型训练不当,效果可能会大打折扣。

BM25 检索

优点:
  1. 简单高效:BM25是一种基于统计的检索模型,不需要复杂的机器学习模型即可实现高效的文档检索。
  2. 可解释性强:因为它是基于关键词频率和文档频率等统计特征,所以结果更容易理解和解释。
  3. 广泛支持:许多搜索引擎和数据库系统已经内置了BM25支持,易于集成。
缺点:
  1. 缺乏语义理解:BM25主要依赖关键词匹配,对于文本的深层语义理解不如向量检索。
  2. 短查询局限性:对于短的或非常特定的查询,BM25可能无法提供最佳的相关性排序。
  3. 忽略上下文:BM25没有考虑到句子或段落之间的上下文关系,这可能导致某些情况下相关性较低。

组合使用的优势

  1. 互补优势:结合两种方法可以在保持简单高效的检索速度的同时,提高检索结果的相关性和准确性。
  2. 灵活性:可以根据具体应用场景灵活调整检索策略,比如对于某些需要强语义理解的任务,可以更依赖向量检索;而对于简单的关键词搜索,可以更多地使用BM25。
  3. 鲁棒性增强:通过融合两种检索方式,可以降低单一方法带来的风险,提高系统的整体性能。

组合使用的挑战

  1. 复杂性增加:维护两种检索机制会增加系统的复杂性,包括数据预处理、索引构建、查询处理等多个环节。
  2. 权衡问题:如何平衡两种检索方法的贡献度是一个需要仔细设计的问题,可能需要通过实验和调参来优化。
  3. 性能开销:虽然理论上可以提高检索质量,但在实际部署中可能需要考虑额外的计算资源消耗。

总的来说,结合向量检索和BM25检索可以利用各自的优势,以期达到更好的检索效果。但在实际应用中,需要根据具体需求和资源条件来进行权衡和选择。

LlamaIndex官方地址 https://docs.llamaindex.ai/en/stable/

LlamaIndex官方地址 https://docs.llamaindex.ai/en/stable/

快速上手

创建一个文件,例如“chainlit_chat”

mkdir chainlit_chat

进入 chainlit_chat文件夹下,执行命令创建python 虚拟环境空间(需要提前安装好python sdkChainlit 需要python>=3.8。,具体操作,由于文章长度问题就不在叙述,自行百度),命令如下:

python -m venv .venv
  • 这一步是避免python第三方库冲突,省事版可以跳过
  • .venv是创建的虚拟空间文件夹可以自定义

接下来激活你创建虚拟空间,命令如下:

#linux or mac
source .venv/bin/activate
#windows
.venv\Scripts\activate

在项目根目录下创建requirements.txt,内容如下:

chainlit
llama-index-core
llama-index-llms-dashscope
llama-index-embeddings-dashscope
llama-index-retrievers-bm25~=0.3.0

执行以下命令安装依赖:

pip install -r .\requirements.txt
  • 安装后,项目根目录下会多出.chainlit.files文件夹和chainlit.md文件

代码创建

只使用通义千问的DashScope模型服务灵积的接口

在项目根目录下创建.env环境变量,配置如下:

DASHSCOPE_API_KEY="sk-api_key"
  • DASHSCOPE_API_KEY 是阿里dashscope的服务的APIkey,代码中使用DashScope的sdk实现,所以不需要配置base_url。默认就是阿里的base_url。
  • 阿里模型接口地址 https://dashscope.console.aliyun.com/model

在项目根目录下创建app.py文件,代码如下:

  • 此代码使用摘要索引和向量索引,利用RetrieverQueryEngine 路由检索器,根据问题分类提示,选择摘要索引和向量索引进行索引。
import os
import time

import chainlit as cl
from llama_index.core import (
    Settings,
    VectorStoreIndex,
    load_index_from_storage, StorageContext, SimpleDirectoryReader, SummaryIndex, )
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.schema import IndexNode
from llama_index.embeddings.dashscope import DashScopeEmbedding, DashScopeTextEmbeddingModels, \
    DashScopeTextEmbeddingType
from llama_index.llms.dashscope import DashScope, DashScopeGenerationModels
from llama_index.retrievers.bm25 import BM25Retriever

Settings.llm = DashScope(
    model_name=DashScopeGenerationModels.QWEN_TURBO, api_key=os.environ["DASHSCOPE_API_KEY"], max_tokens=512
)
Settings.embed_model = DashScopeEmbedding(
    model_name=DashScopeTextEmbeddingModels.TEXT_EMBEDDING_V2,
    text_type=DashScopeTextEmbeddingType.TEXT_TYPE_DOCUMENT,
)
Settings.node_parser = SentenceSplitter(chunk_size=512, chunk_overlap=20)
Settings.num_output = 512
Settings.context_window = 6000


@cl.cache
def get_vector_store_index():
    storage_dir = "./storage_obj"
    if os.path.exists(storage_dir):
        storage_context = StorageContext.from_defaults(persist_dir=storage_dir)
        index = load_index_from_storage(storage_context)
    else:
        documents = SimpleDirectoryReader("./data_file").load_data(show_progress=True)
        index = VectorStoreIndex.from_documents(documents)
        index.storage_context.persist(persist_dir=storage_dir)
    return index


vector_store_index = get_vector_store_index()


@cl.on_chat_start
async def start():
    await cl.Message(
        author="Assistant", content="你好! 我是泰山AI智能助手. 有什么可以帮助你的吗?"
    ).send()


@cl.on_message
async def main(message: cl.Message):
    start_time = time.time()
    vector_retriever = vector_store_index.as_retriever(similarity_top_k=5)
    bm25_retriever = BM25Retriever.from_defaults(docstore=vector_store_index.docstore, similarity_top_k=5)
    vector_obj = IndexNode(
        index_id="vector", obj=vector_retriever, text="Vector Retriever"
    )
    bm25_obj = IndexNode(
        index_id="bm25", obj=bm25_retriever, text="BM25 Retriever"
    )
    summary_index = SummaryIndex(objects=[vector_obj, bm25_obj])
    query_engine = summary_index.as_query_engine(
        response_mode="tree_summarize", streaming=True, verbose=True
    )
    msg = cl.Message(content="", author="Assistant")
    res = await query_engine.aquery(message.content)
    async for token in res.response_gen:
        await msg.stream_token(token)
    print(f"代码执行时间: {time.time() - start_time} 秒")
    source_names = []
    for idx, node_with_score in enumerate(res.source_nodes):
        node = node_with_score.node
        source_name = f"source_{idx}"
        source_names.append(source_name)
        msg.elements.append(
            cl.Text(content=node.get_text(), name=source_name, display="side")
        )
    await msg.stream_token(f"\n\n **数据来源**: {', '.join(source_names)}")
    await msg.send()

  • 代码中的persist_dir=storage_dir 不设置的默认是 ./storage.
  • 代码中chunk_size是将长文档分割的文本块的大小,chunk_overlap 是和上下文本块的重合文本的大小。
  • 代码中IndexNode是索引节点
    • IndexNode对象
      在代码片段中,vector_obj和bm25_obj都是IndexNode实例。每个IndexNode对象包含了三个主要属性:

      • index_id:索引的唯一标识符。
      • obj:实际的检索对象,这里是指向实际检索逻辑的对象,例如vector_retriever或bm25_retriever。
      • text:描述性文本,用于标识节点的作用

代码解读

这段代码是一个使用Chainlit框架构建的简单聊天机器人应用,它集成了向量检索(Vector Retrieval)和BM25检索机制,并使用了来自DashScope的LLM(Large Language Model)和服务。下面是代码的详细解释:

  1. 导入模块

    • 导入了ostime模块用于操作系统路径和计时。
    • chainlit是一个用于快速构建交互式AI应用的Python库。
    • llama_index提供了一系列工具用于创建和查询知识库索引。
  2. 设置LLM和Embedding模型

    • 设置了DashScope作为默认的LLM和Embedding模型,并指定了API密钥和模型名称。
    • 这些设置影响了如何处理文本输入以及如何生成响应。
  3. 定义获取向量存储索引的函数get_vector_store_index

    • 如果指定的存储目录存在,则从存储加载索引。
    • 否则,从指定的数据目录读取文档来创建一个新的向量存储索引并保存到存储目录中。
  4. 定义聊天开始时触发的函数start

    • 发送一条欢迎消息给用户。
  5. 定义处理用户消息的函数main

    • 创建一个向量检索器和一个BM25检索器,两者都设置为返回前5个最相似的结果。
    • 创建两个IndexNode对象,分别代表向量检索器和BM25检索器。
    • 创建一个SummaryIndex来包含这两个检索器节点。
    • 使用这个总结索引来创建一个查询引擎,该引擎以树状总结模式运行,并且支持流式传输结果。
    • 对于用户的每条消息,使用查询引擎异步查询,并通过流式传输的方式发送每个token给用户。
    • 记录并打印查询所需的时间。
    • 收集并显示源文档的名字作为数据来源。

    代码展示了一个完整的流程,从加载或创建索引,到处理用户输入,再到生成并发送响应。这是一个典型的问答系统的实现方式,特别是当需要从大量的文档中提取信息时。

在项目根目录下创建data_file文件夹

在这里插入图片描述
将你的文件放到data_file文件夹下。
llama_index 库支持多种文件格式的加载,以便从中提取文本内容用于索引构建和后续的信息检索或问答任务。以下是一些常见的文件格式支持:

  1. 文本文件 (.txt):简单的纯文本文件。
  2. PDF 文件 (.pdf):便携文档格式,广泛用于书籍、报告等文档。
  3. Microsoft Word 文档 (.doc, .docx):Word 文档格式。
  4. CSV 文件 (.csv):逗号分隔值文件,常用于表格数据。
  5. HTML 文件 (.html, .htm):超文本标记语言文件。
  6. Markdown 文件 (.md, .markdown):轻量级标记语言。
  7. JSON 文件 (.json):JavaScript 对象表示法,常用于数据交换。
  8. EPUB 文件 (.epub):电子书格式。
  9. PPTX 文件 (.pptx):PowerPoint 演示文稿。

除了上述文件格式外,llama_index 可能还支持其他一些格式,具体取决于其内部依赖库的支持情况。例如,它可能通过第三方库支持解析像 .xls, .xlsx 这样的 Excel 文件。

为了加载这些不同类型的文件,llama_index 提供了多个不同的读取器(readers),如 SimpleDirectoryReader 可以用来加载一个目录中的多个文件,而针对特定文件格式(如 PDF 或 Word 文档),则有专门的读取器类。

例如,如果你有一个包含多种文件格式的目录,你可以使用 SimpleDirectoryReader 来加载它们。如果你只处理一种类型的文件,比如 PDF 文件,你可以选择使用更具体的读取器,比如 PDFReader

运行应用程序

要启动 Chainlit 应用程序,请打开终端并导航到包含的目录app.py。然后运行以下命令:

 chainlit run app.py -w   
  • -w标志告知 Chainlit 启用自动重新加载,因此您无需在每次更改应用程序时重新启动服务器。您的聊天机器人 UI 现在应该可以通过http://localhost:8000访问。
  • 自定义端口可以追加--port 80

启动后界面如下:

在这里插入图片描述
在这里插入图片描述

总结

在chunk_size大小为512,chunk_overlap为20时,整体回复表现良好。但是也有很大的局限性,模型在选择问题时,能否正确选择,这个变得很关键,但实际上往往很难做到正确选择,就比如,我提问2023年的财务报表,模型会倾向于这是一个总结摘要类的问题,会去摘要索引里查找,但是实际上023年的财务报表数据实在向量索引存储的。

相关文章推荐

《Chainlit快速实现AI对话应用的界面定制化教程》
《Chainlit接入FastGpt接口快速实现自定义用户聊天界面》
《使用 Xinference 部署本地模型》
《Fastgpt接入Whisper本地模型实现语音输入》
《Fastgpt部署和接入使用重排模型bge-reranker》
《Fastgpt部署接入 M3E和chatglm2-m3e文本向量模型》
《Fastgpt 无法启动或启动后无法正常使用的讨论(启动失败、用户未注册等问题这里)》
《vllm推理服务兼容openai服务API》
《vLLM模型推理引擎参数大全》
《解决vllm推理框架内在开启多显卡时报错问题》
《Ollama 在本地快速部署大型语言模型,可进行定制并创建属于您自己的模型》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2179255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零工市场小程序如何提高找兼职的效率?

越来越多的人们会选择成为自由职业者,或者在空暇时兼职来获取酬劳,那么传统的找兼职方式,如:中介公司、招聘广告等。 如今大家的生活都已经进入了“快节奏”,零工市场小程序针对这样的问题而提出了解决方案&#xff0…

python Scrapy 框架 demo

文章目录 前言python Scrapy 框架 demo1. 安装2. 百度热搜爬取demo2.1. 初始化项目2.2. 修改 items.pyitems.py2.3. 创建 spiders/baidu_spider.py2.4. 修改 pipelines.py2.5. 修改 settings.py 3. settings.py 相关配置说明4. 启动爬虫测试 前言 如果您觉得有用的话&#xff0…

python+requests接口测试

pythonrequest 一、调用的方法 requests是一个第三方库 (1) a、下载地方库pip install requests b、pycaharm中下载 (2)导入requests库 (3)requests中的三种调用方法 第一种: requests.…

算法训练营打卡Day18

目录 二叉搜索树的最小绝对差二叉搜索树中的众数二叉树的最近公共祖先额外练手题目 题目1、二叉搜索树的最小绝对差 力扣题目链接(opens new window) 给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。 示例: 思…

时间复杂度及空间复杂度(简略)

目录 时间复杂度空间复杂度 时间复杂度 计算时间复杂度时,我们只需计算大致执行次数,再用大O的渐进表示法就可以了 常见的复杂度为O(N),O(1),O(N^2)的几个情况这里就不提了,下面是几个相对来说需要分析的算法 算法1: // 计算str…

【Python报错已解决】TypeError: ‘int‘ object is not subscriptable

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

如何在实际开发中深入使用 yalantinglibs 编译期反射库

yaLanTingLibs 是阿里云开源的现代 C 基础工具库的集合,包括序列化、http、rpc、协程、编译期反射、metric 和日志等库,可以帮助 C 开发者快速构建高性能的 C 应用。2024 云栖大会操作系统技术 Workshop 上,阿里云智能集团高级技术专家、pure…

快手:数据库升级实践,实现PB级数据的高效管理|OceanBase案例

本文作者:胡玉龙,快手技术专家 快手在较初期采用了OceanBase 3.1版本成功替换了多个核心业务、数百套的MySQL集群。至2023年,快手的数据量已突破800TB大关,其中最大集群的数据量更是达到了数百TB级别。为此,快手将数据…

Docker安装consul + go使用consul + consul知识

1. 什么是服务注册和发现 假如这个产品已经在线上运行,有一天运营想搞一场促销活动,那么我们相对应的【用户服务】可能就要新开启三个微服务实例来支撑这场促销活动。而与此同时,作为苦逼程序员的你就只有手动去 API gateway 中添加新增的这…

基于AI的智能化渗透测试技术研究

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

问题:vscode 打印中文时终端输出乱码

文章目录 问题分析解决 问题 在 vscode 编辑器中的终端运行出来的中文是乱码 分析 乱码原因:因windows中文版系统cmd编码默认为GBK,而vscode默认新建文件的编码为UTF-8所以会出现中文乱码情况 解决 终端下输入 chcp 查看当前的cmd编码设置。如图&…

在windows下编译 chromium 的问题汇总(103.0.5060.68 之四)

其实,按照chromium 官方文档来看,大概率是不会出错的,但由于各自的系统差异化,当中遇到的坑也是各不相同。 尤其是在国内的网络情况下,出错是再所难免的,关于这一点,chromium官方文档是没有提及…

哈希-01-数据分类处理

文章目录 1. 题目描述2. 思路3. 代码 1. 题目描述 信息社会,有海量的数据需要分析处理,比如公安局分析身份证号码、 QQ 用户、手机号码、银行帐号等信息及活动记录。 采集输入大数据和分类规则,通过大数据分类处理程序,将大数据…

基于SSM+Vue+MySQL的在线视频学习系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网的飞速发展,在线视频学习已成为人们获取知识、提升技能的重要途径。然而,传统的视频学习平台往往存在内容管理不便、用户体验不佳等问题。因此,开发一款基于SSM(SpringS…

12、echarts 没有显示折线图

一、问题描述 echarts 没有显示折线图,但是,有数据显示: 看图表展示,y轴数据全部没有显示,直接可以判定是数据结构出问题了。 检查 series.data[] 数据结构: dataList [{"dateStr":"202…

06.C/C++内存管理

在这里C的内存管理相较于C作出了许多升级,下面我们就来了解一下。 1.C/C内存分布 我们先来看一下下面的问题,温习一下C的内存分布 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1…

Web安全 - 跨站点请求伪造CSRF(Cross Site Request Forgery)

文章目录 OWASP 2023 TOP 10CSRF 导图CSRF的基本概念CSRF的工作原理常见CSRF攻击模式CSRF防御策略补充建议应用场景实战防御策略选择1. CSRF Token(首选)2. SameSite Cookie属性3. 验证Referer和Origin4. 多因素认证 实现方案CSRF Token实现SameSite Coo…

JavaWeb——Vue组件库Element(3/6):常见组件:Dialog对话框、Form表单(介绍、使用、实际效果)

目录 Dialog对话框 介绍 使用 实际效果 Form表单 介绍 使用 实际效果 Dialog对话框 介绍 Dialog对话框:在保留当前页面状态的情况下,告知用户并承载相关操作。 Dialog 对话框组件可以在保留当前页面信息的状态下弹出一个对话框,并…

初始MYSQL数据库(8)—— JDBC编程

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: MYSQL 目录 JDBC的概念 JDBC的使用 加载驱动包 建立连接 创建 statement 对象 定义并执行SQL语句 处理结果集 关闭资源 SQL注入 …

taobao.item_get_appAPI接口原app数据测试指南

在电商竞争日益激烈的当下,数据成为了商家们争夺市场的重要武器。淘宝,作为中国最大的在线零售平台,其庞大的商品库和用户群体为商家提供了巨大的商机。为了帮助商家更好地了解市场动态,优化库存和营销策略,淘宝推出了…