Chainlit集成LlamaIndex实现知识库高级检索(BM25全文检索器)

检索原理

BM25Retriever类是一个基于BM25算法设计的检索器,它主要用于从一组文档或节点中检索出与查询最相关的文档或节点。这个类的设计目的是为了提高文本检索的效率和准确性,尤其是在处理大量文本数据时。

BM25(Best Matching 25)算法是一种在信息检索领域广泛应用的经典算法,它是对传统的TF-IDF(Term Frequency-Inverse Document Frequency)算法的一种改进。BM25算法的核心思想是利用词频(TF)和逆文档频率(IDF)来衡量文档与查询之间的相关性,同时考虑到文档长度信息对相关性的影响。以下是对BM25算法的一些关键特性和原理的介绍:

原理

BM25算法基于这样一个假设:对于一个特定的查询项,它在相关文档中出现的频率应该高于在非相关文档中的频率。该算法通过结合词项频率(TF)和文档频率(DF)来计算文档的得分。具体来说,BM25算法包括以下几个组成部分:

  1. 词项频率(TF):词项频率是指一个词项在文档中出现的次数。BM25对传统的TF计算方法进行了调整,引入了饱和度和长度归一化,以防止长文档由于包含更多词项而获得不公平的高评分。

  2. 逆文档频率(IDF):逆文档频率是衡量词项稀有程度的一个指标。它基于整个文档集合来计算,用来降低常见词项的权重,并提升罕见词项的权重。

  3. 文档长度信息:BM25算法引入了文档长度信息,以进一步调整相关性的计算。这样可以避免因为文档长度不同而导致的相关性偏差。

计算公式

BM25算法的计算公式可以表述为:

在这里插入图片描述

其中:

  • ( tf_{t,d} ) 是词项 ( t ) 在文档 ( d ) 中的词频;
  • ( IDF(t) ) 是词项 ( t ) 的逆文档频率;
  • ( k_1 ) 和 ( b ) 是自由参数,用于调节计算过程中的影响;
  • ( |d| ) 是文档 ( d ) 的长度;
  • ( avgdl ) 是文档集合中所有文档长度的平均值。

改进与变种

除了标准的BM25算法之外,还有几种重要的变种,如BM25FBM25L

  • BM25F:这是BM25的一个重要扩展,可以在多个文档域上进行计算。
  • BM25L:该变种考虑了文档长度对得分的影响,通过引入文档长度规范化项来平衡不同长度的文档。

应用场景

BM25算法因其在处理词频和相关性之间非线性关系上的优势,被广泛应用于搜索引擎和相关领域。在实际应用中,如Elasticsearch和Lucene这样的全文搜索引擎,默认使用的就是Okapi BM25算法。

总结来说,BM25算法是一种强大而灵活的信息检索算法,它通过对TF-IDF模型的改进,提高了搜索结果的相关性,同时通过引入文档长度因子等改进措施,增强了算法的实用性。

该检索技术的优缺点

LlamaIndex是一个基于语言模型(LLM)的开源信息检索系统,它提供了高效的数据索引和查询功能,适用于大规模文本数据集的快速检索。其中,BM25Retriever是LlamaIndex提供的一个检索器,它基于BM25算法,这是一种广泛使用的信息检索排序函数,专门用于文档检索,尤其擅长处理长文档和短查询。下面将详细探讨BM25Retriever在LlamaIndex中的优缺点。

优点

  1. 优化的TF-IDF: BM25Retriever是基于TF-IDF(词频-逆文档频率)的改进版本,它解决了标准TF-IDF方法的一些局限性,如长文档可能得到过高评分的问题。BM25通过调整参数k1和b来考虑文档长度的影响,从而使得检索结果更加准确。

  2. 文档长度的考虑: BM25Retriever的一个关键特性是它考虑了文档长度对评分的影响。对于长文档,BM25Retriever会调整评分,确保不会因为文档较长而产生不公平的优势,这有助于提高检索结果的相关性。

  3. 灵活性: BM25Retriever可以很容易地与其他检索技术相结合,例如与向量检索混合使用,形成一种称为混合检索的技术。这种组合可以利用各自的优势,提供更加全面的检索服务。

缺点

  1. 中文支持问题: 默认情况下,BM25Retriever的tokenizer可能不支持中文处理,这意味着在处理中文文本时需要额外的步骤或定制的解决方案,如使用jieba分词器来处理中文文本。

  2. 计算资源需求: 尽管BM25Retriever在文档检索方面表现优秀,但它需要进行大量的计算来确定文档与查询的相关性得分,尤其是在大型数据集中,这可能会导致较高的计算资源需求。

  3. 参数调优: BM25算法依赖于一些参数(如k1, b等),这些参数可能需要根据具体的应用场景进行调优才能达到最佳性能。如果不正确地设置这些参数,可能会影响检索结果的质量。

综上所述,BM25Retriever在LlamaIndex中提供了一种强大的检索机制,尤其适用于需要精确排序结果的应用场景。然而,在使用时需要注意其对于特定语言的支持情况以及可能产生的计算开销等问题。在实际应用中,根据具体的业务需求选择合适的检索器,并且合理地调整参数以优化性能是非常重要的。

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文件,代码如下:

import os
import timeimport chainlit as cl
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.retrievers.bm25 import BM25Retriever
from llama_index.core import (Settings,VectorStoreIndex,SimpleDirectoryReader, load_index_from_storage, StorageContext,
)
from llama_index.core.node_parser import SentenceSplitter
from llama_index.embeddings.dashscope import DashScopeEmbedding, DashScopeTextEmbeddingModels, \DashScopeTextEmbeddingType
from llama_index.llms.dashscope import DashScope, DashScopeGenerationModelsSettings.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_bm25_512"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)node_parser = SentenceSplitter.from_defaults(chunk_size=512, chunk_overlap=20)nodes = node_parser.get_nodes_from_documents(documents)print(f"nodes: {len(nodes)}")index = VectorStoreIndex(nodes=nodes)index.storage_context.persist(persist_dir=storage_dir)return indexvector_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()retriever = BM25Retriever.from_defaults(docstore=vector_store_index.docstore, similarity_top_k=5)query_engine = RetrieverQueryEngine.from_args(retriever, streaming=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.nodesource_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 是和上下文本块的重合文本的大小。
  • 代码中 node_parser = HierarchicalNodeParser.from_defaults( node_parser_ids=node_parser_ids, node_parser_map=node_parser_map ) 可以简写为 node_parser = HierarchicalNodeParser.from_defaults() 会按照 [2048,512,128]三种层次分割,经过我测试不使用默认的效果会更好
  • similarity_top_k=5 返回5条最相关的数据

代码解读

这段代码是一个使用ChainLit框架构建的聊天机器人应用,它集成了向量数据库索引和检索功能,以从文档中检索信息并回答用户的问题。下面是代码的逐部分解释:

  1. 导入模块

    • ostime 是标准库模块,分别用于操作系统相关功能和计时功能。
    • chainlit as cl 用于创建交互式的Web应用程序。
    • llama_index 是一个用于构建索引、检索器和查询引擎的库,帮助处理文本数据并进行问答系统开发。
  2. 设置环境变量

    • 设置了DashScope的LLM(Language Model)和Embedding模型,并指定了使用的模型类型以及API密钥位置。这些设置是根据环境变量DASHSCOPE_API_KEY来获取的。
  3. 向量存储索引函数 (get_vector_store_index)

    • 这个函数首先检查是否存在一个持久化的存储目录。如果存在,则加载已有的索引;如果不存在,则读取指定目录下的文档,将其分割成节点,创建向量存储索引,并将其持久化到指定目录。
  4. 聊天开始时的事件处理器 (start)

    • 当聊天会话开始时,发送一条消息给用户作为问候。
  5. 接收消息时的事件处理器 (main)

    • 当收到用户的输入消息时,使用BM25检索器来检索最相关的文档,并通过RetrieverQueryEngine生成答案。
    • 使用异步生成器流式传输响应给用户,并记录每个源文档的信息,以便显示数据来源。

这段代码展示了一个基于文档检索的问答系统的实现方式,利用了现代语言模型的能力来生成高质量的回答。注意,在实际部署时需要确保环境变量DASHSCOPE_API_KEY已经正确设置,并且指定的数据文件夹路径是正确的。此外,还需确保所有依赖项已安装,并且与ChainLit框架兼容。

在项目根目录下创建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

启动后界面如下:

在这里插入图片描述
在这里插入图片描述
BM25Retriever索引器还可以与向量检索器等其他索引器,利用QueryFusionRetriever类将其融合查询。

后续会出更多关于LlamaIndex高级检查的技术文章教程,感兴趣的朋友可以持续关注我的动态!!!

相关文章推荐

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

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

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

相关文章

如何使用ssm实现新媒体视域下的中国古诗词展演+vue

TOC ssm678新媒体视域下的中国古诗词展演vue 绪论 课题背景 身处网络时代,随着网络系统体系发展的不断成熟和完善,人们的生活也随之发生了很大的变化。目前,人们在追求较高物质生活的同时,也在想着如何使自身的精神内涵得到提…

物联网助力智慧交通:优势与前景

智慧交通是当今城市发展的必然趋势,而物联网技术在交通运输领域的应用正是为实现智慧交通建设提供了前所未有的机遇和优势。物联网作为连接和控制物理世界的重要技术手段,在交通领域的应用极大地改善了交通系统的效率、安全性和环保性。 首先&#xff0c…

智能算法躲避拥堵,高德企业用车上线“动态选路服务”为出行提效

近日,高德企业用车正式上线了一项全新服务——“动态选路服务”,旨在基于智能算法,动态规避突发拥堵路线,为企业用车用户提供更便捷、智能的出行方案。 以技术着眼细节,高德企业用车在帮助企业用车用户节约出行时间和…

大部分基础排序复习C++(归并、快排、堆)

归并排序(稳定) 时间复杂度: O(N * logN ) 。空间复杂度 O(N) 归并排序主要是分治的思想: 将一段数组以中间点mid划分成两半,让它们各自去下一层递归,继续对半划分,直到这个数组只有一个元素…

MySQL(学习笔记)(02)(进阶篇)

P1 存储引擎 MySQL的体系结构 存储引擎简介 存储引擎的选择 P2 索引(重要) 索引概述 索引结构 二叉树 B树(多路平衡查找) B树 hash 总结 索引分类 思考题 索引语法 SOL性能分析 索引使用 索引设计原则 P3 SQL优化 P4 视图/存储过…

redis常用五种数据类型的常用指令

本文为初识redis记录的基本知识,如有不正确之处还请指出 一、redis五种类型简介 string:存储结构为简单动态字符串(SDS) hash:存储结构可以是哈希表(O(1))、压缩列表&am…

动手学深度学习(李沐)PyTorch 第 3 章 线性神经网络

3.1 线性回归 线性回归是对n维输入的加权,外加偏差 线性回归可以看作是单层神经网络 回归问题中最常用的损失函数是平方误差函数。 平方误差可以定义为以下公式: 常数1/2不会带来本质的差别,但这样在形式上稍微简单一些 (因为当…

一篇讲完CSS的核心内容

目录 一 、引言 1.1CSS概念 二、 CSS简介 2.1 什么是CSS 2.2 CSS能干什么 2.3 CSS书写规范 2.4 基础语法 三、 CSS导入方式 3.1 内嵌方式(内联方式) 3.2 内部方式 3.3 外部方式 四、 CSS选择器 4.1 基本选择器 [重点] 4.2 属性选择器 五、 CSS属性 5.1 文字属性…

Excel的基本应用__1

1. 模拟运算 1.1 单变量求解 1.1.1 步骤 1.1.1 效果 1.2 模拟运算表 1.2.1 步骤 1.2.2 效果 2.选择性粘贴--转至 3. Excel中如何使用和定义名称 使用 相当于全局变量,可以在不同表中调用 3.1名称中使用常量 3.2名称中使用函数 调用 可以在不同的表中调用 3.…

C语言 | Leetcode C语言题解之第433题最小基因变化

题目&#xff1a; 题解&#xff1a; int minMutation(char * start, char * end, char ** bank, int bankSize) {int m strlen(start);int **adj (int **)malloc(sizeof(int *) * bankSize);int endIndex -1;for (int i 0; i < bankSize; i) {adj[i] (int *)malloc(si…

Dynamic Connected Networks for Chinese Spelling Check(ACL2021)

Dynamic Connected Networks for Chinese Spelling Check(ACL2021) 一&#xff0e;概述 文中认为基于bert的非自回归语言模型依赖于输出独立性假设。不适当的独立性假设阻碍了基于bert的模型学习目标token之间的依赖关系&#xff0c;从而导致了不连贯的问题。为些&#xff0c…

CORS解决浏览器跨域请求(同源策略)限制原理、后端springboot CROS跨域解决方案

文章目录 1 浏览器的同源策略1.1 什么是源&#xff08;origin&#xff09;&#xff1f;1.2 跨域请求&#xff1f;1.3 同源策略&#xff08;跨域限制&#xff09;是什么&#xff1f;1.3.1 同源策略的具体限制&#xff1f;1.3.2 浏览器CORS校验 2 CORS解决Ajax跨域问题2.1 CORS概…

【JavaEE】——内存可见性问题

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯&#xff0c;你们的点赞收藏是我前进最大的动力&#xff01;&#xff01;希望本文内容能够帮助到你&#xff01; 目录 一&#xff1a;内存可见性问题 1&#xff1a;代码解释 2&#xff1a;结果分析 &#xff08;1&#xf…

分享开源且强大的HTML5网页视频播放器

随着互联网技术的飞速发展&#xff0c;视频内容已成为现代网络体验中不可或缺的一部分。无论是在线教育、娱乐还是企业宣传&#xff0c;高质量的视频播放器都是确保用户获得良好观看体验的关键。HTML5的出现极大地推动了网页视频播放技术的进步&#xff0c;逐渐取代了传统的Fla…

MySQL篇(日志)

目录 一、错误日志 二、二进制日志 1. 简介 2. 作用 3. 参数说明 3.1. 两个参数 3.2. 格式 3.3. 查看 3.4. 删除 4. 查询日志 三、慢查询日志 一、错误日志 错误日志是 MySQL 中最重要的日志之一&#xff0c;它记录了当 mysqld 启动和停止时&#xff0c; 以及服务器…

三菱FX5U PLC故障处理(各种出错的内容、原因及处理方法进行说明。)

对使用系统时发生的各种出错的内容、原因及处理方法进行说明。 故障排除的步骤 发生故障时&#xff0c;按以下顺序实施故障排除。 1.确认各模块是否正确安装或正确配线。 2、确认CPU模块的LED。 3.确认各智能功能模块的LED。(各模块的用户手册) 4、连接工程工具&#xff0c;启…

kubernetes网络(三)之bird的路由反射器的使用

一、摘要 上一篇文章中我们用 bird 程序实现了三台服务器之间的BGP full mesh。本文我们将实验把full mesh方式改为RR 路由反射器方式 &#xff0c;让宿主的BIRD相互学习到对方的容器网段&#xff0c;从而达到容器网段能相互通信的目的。 二、bird 实验 bird简介 BIRD 实际…

操作系统 | 学习笔记 | | 王道 | 5.3 磁盘和固态硬盘

5.3 磁盘和固态硬盘 5.3.1 磁盘 磁盘结构 磁盘&#xff1a;磁盘的表面由一些磁性物质组成&#xff0c;可以用这些磁性物质来记录二进制数据 磁道&#xff1a;磁盘的盘面被划分成一个个磁道。这样的一个“圈”就是一个磁道 扇区&#xff1a;一个磁道又被划分成一个个扇区&am…

828华为云征文 | 在华为云X实例上安装部署企业Wiki知识分享平台的实践

目录 前言 1. 华为云X实例介绍 1.1 华为云Flexus云服务概述 1.2 Flexus云服务器X实例的特点 2. MM-Wiki知识分享平台介绍 2.1 什么是MM-Wiki 2.2 MM-Wiki的功能特点 3. 安装部署环境 4. MM-Wiki安装部署步骤 4.1 下载与准备工作 4.2 安装MM-Wiki 4.3 启动与运行 5…

[spring]MyBatis介绍 及 用MyBatis操作简单数据库

文章目录 一. 什么是MyBatis二. MyBatis操作数据库步骤创建工程创建数据库创建对应实体类配置数据库连接字符串写持久层代码单元测试 三. MyBatis基础操作打印日志参数传递增删改查 四. MyBatis XML配置文件配置链接字符串和MyBatis写持久层代码方法定义Interface方法实现xml测…