Chainlit集成LlamaIndex实现知识库高级检索(组合对象检索)
检索原理
对象组合索引的原理 是利用IndexNode索引节点,将两个不同类型的检索器作为节点对象,使用 SummaryIndex (它可以用来构建一个包含多个索引节点的索引结构。这种索引通常用于从多个不同的数据源或索引方法中汇总信息,并能够基于这些信息进行更复杂的查询操作,如摘要生成。)当查询SummaryIndex时,它会考虑所有包含在内的索引节点,并根据需要综合它们的信息来生成最终的响应或摘要。
组合对象索引检索器的优缺点
结合向量检索(Vector Retrieval)和BM25检索的方式,具有其独特的优点和缺点。下面是对这两种检索方式及其组合使用的优缺点的概述:
向量检索(Vector Retrieval)
优点:
- 语义理解:向量检索基于嵌入模型,能够更好地理解文本之间的语义关系,而不仅仅是关键字匹配。
- 上下文感知:向量检索可以捕捉句子或段落之间的上下文关系,对于长文本的理解更为有效。
- 泛化能力:即使查询词不在文档中出现,只要语义上相关,也可以找到相关的文档。
缺点:
- 计算成本:向量检索需要对文档进行嵌入编码,这可能会增加计算资源的需求。
- 索引维护:维护一个大型的向量索引可能较为复杂,并且随着文档数量的增加,索引的更新和存储可能变得昂贵。
- 精确度依赖于模型质量:向量检索的效果高度依赖于所使用的嵌入模型的质量,如果模型训练不当,效果可能会大打折扣。
BM25 检索
优点:
- 简单高效:BM25是一种基于统计的检索模型,不需要复杂的机器学习模型即可实现高效的文档检索。
- 可解释性强:因为它是基于关键词频率和文档频率等统计特征,所以结果更容易理解和解释。
- 广泛支持:许多搜索引擎和数据库系统已经内置了BM25支持,易于集成。
缺点:
- 缺乏语义理解:BM25主要依赖关键词匹配,对于文本的深层语义理解不如向量检索。
- 短查询局限性:对于短的或非常特定的查询,BM25可能无法提供最佳的相关性排序。
- 忽略上下文:BM25没有考虑到句子或段落之间的上下文关系,这可能导致某些情况下相关性较低。
组合使用的优势
- 互补优势:结合两种方法可以在保持简单高效的检索速度的同时,提高检索结果的相关性和准确性。
- 灵活性:可以根据具体应用场景灵活调整检索策略,比如对于某些需要强语义理解的任务,可以更依赖向量检索;而对于简单的关键词搜索,可以更多地使用BM25。
- 鲁棒性增强:通过融合两种检索方式,可以降低单一方法带来的风险,提高系统的整体性能。
组合使用的挑战
- 复杂性增加:维护两种检索机制会增加系统的复杂性,包括数据预处理、索引构建、查询处理等多个环节。
- 权衡问题:如何平衡两种检索方法的贡献度是一个需要仔细设计的问题,可能需要通过实验和调参来优化。
- 性能开销:虽然理论上可以提高检索质量,但在实际部署中可能需要考虑额外的计算资源消耗。
总的来说,结合向量检索和BM25检索可以利用各自的优势,以期达到更好的检索效果。但在实际应用中,需要根据具体需求和资源条件来进行权衡和选择。
LlamaIndex官方地址 https://docs.llamaindex.ai/en/stable/
LlamaIndex官方地址 https://docs.llamaindex.ai/en/stable/
快速上手
创建一个文件,例如“chainlit_chat”
mkdir chainlit_chat
进入 chainlit_chat文件夹下,执行命令创建python 虚拟环境空间(需要提前安装好python sdk。 Chainlit 需要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 timeimport 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 BM25RetrieverSettings.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 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()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.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是和上下文本块的重合文本的大小。 - 代码中
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)和服务。下面是代码的详细解释:
-
导入模块:
- 导入了
os和time模块用于操作系统路径和计时。 chainlit是一个用于快速构建交互式AI应用的Python库。llama_index提供了一系列工具用于创建和查询知识库索引。
- 导入了
-
设置LLM和Embedding模型:
- 设置了DashScope作为默认的LLM和Embedding模型,并指定了API密钥和模型名称。
- 这些设置影响了如何处理文本输入以及如何生成响应。
-
定义获取向量存储索引的函数
get_vector_store_index:- 如果指定的存储目录存在,则从存储加载索引。
- 否则,从指定的数据目录读取文档来创建一个新的向量存储索引并保存到存储目录中。
-
定义聊天开始时触发的函数
start:- 发送一条欢迎消息给用户。
-
定义处理用户消息的函数
main:- 创建一个向量检索器和一个BM25检索器,两者都设置为返回前5个最相似的结果。
- 创建两个
IndexNode对象,分别代表向量检索器和BM25检索器。 - 创建一个
SummaryIndex来包含这两个检索器节点。 - 使用这个总结索引来创建一个查询引擎,该引擎以树状总结模式运行,并且支持流式传输结果。
- 对于用户的每条消息,使用查询引擎异步查询,并通过流式传输的方式发送每个token给用户。
- 记录并打印查询所需的时间。
- 收集并显示源文档的名字作为数据来源。
代码展示了一个完整的流程,从加载或创建索引,到处理用户输入,再到生成并发送响应。这是一个典型的问答系统的实现方式,特别是当需要从大量的文档中提取信息时。
在项目根目录下创建data_file文件夹

将你的文件放到data_file文件夹下。
llama_index 库支持多种文件格式的加载,以便从中提取文本内容用于索引构建和后续的信息检索或问答任务。以下是一些常见的文件格式支持:
- 文本文件 (
.txt):简单的纯文本文件。 - PDF 文件 (
.pdf):便携文档格式,广泛用于书籍、报告等文档。 - Microsoft Word 文档 (
.doc,.docx):Word 文档格式。 - CSV 文件 (
.csv):逗号分隔值文件,常用于表格数据。 - HTML 文件 (
.html,.htm):超文本标记语言文件。 - Markdown 文件 (
.md,.markdown):轻量级标记语言。 - JSON 文件 (
.json):JavaScript 对象表示法,常用于数据交换。 - EPUB 文件 (
.epub):电子书格式。 - 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 在本地快速部署大型语言模型,可进行定制并创建属于您自己的模型》
相关文章:
Chainlit集成LlamaIndex实现知识库高级检索(组合对象检索)
检索原理 对象组合索引的原理 是利用IndexNode索引节点,将两个不同类型的检索器作为节点对象,使用 SummaryIndex (它可以用来构建一个包含多个索引节点的索引结构。这种索引通常用于从多个不同的数据源或索引方法中汇总信息,并能…...
万界星空科技铜拉丝行业MES系统,实现智能化转型
一、铜拉丝行业生产管理的难点主要体现在以下几个方面: 1、标准严格:铜线产品对质量的要求极高,特别是在电气性能、导电性、耐腐蚀性等方面,任何微小的瑕疵都可能影响产品的使用效果和安全性。 2、过程监控:生产过程…...
ECCV 2024 现场:参会者付高价、跨万里,却无法入场?
ECCV(European Conference on Computer Vision,欧洲计算机视觉国际会议)是计算机视觉领域的重要国际会议之一,与CVPR和ICCV并称为计算机视觉的三大顶级会议。 ECCV2024是该系列会议的第18届会议,2024年9月29日至10月4…...
使用rsync+jenkins实现服务自动部署全流程
项目背景:城市政务云服务器没有上k8s,所有后端服务都是原始方式部署启动 (java -jar xxx.jar),那么有没有方式简化部署难度,实现自动部署?当然是有的,下面详细介绍(以Cen…...
python 实现decision tree决策树算法
decision tree决策树算法介绍 决策树算法(Decision Tree Algorithm)是一种基于输入特征对实例进行分类的树结构模型,主要用于分类和回归任务。其基本原理是根据训练数据的特征属性和类别标签之间的关系,生成一个能够对新样本进行…...
前端大模型入门:实战篇之Vue3+Antdv+transformers+本地模型实现增强搜索
本文将之前的文章,实现一个场景的实战应用,包含代码等内容。利用纯前端实现增强的列表搜索,抛弃字符串匹配,目标是使用番茄关键字可以搜索到西红柿 1 准备工作 1.1 了解llm和web开发 web端的ai开发参考 前端大模型入门ÿ…...
《向量数据库指南》——Fivetran 的 Partner SDK:构建自定义连接器和目标
哈哈,说到 Fivetran 的 Partner SDK,这可真是个好东西啊!作为向量数据库领域的“老司机”,我今天就来给大家详细讲讲这个 SDK 的厉害之处,以及如何用它来构建自定义连接器和目标,实现与 Fivetran 自动化数据移动平台的无缝集成。 一、Fivetran Partner SDK:开启自定义连…...
微信小程序的 button 标签的边框如何去除?
目录 问题描述: 问题原因: 解决办法: 方案一 方案二 问题描述: 实际开发中会发现这个 button 自带有样式,当背景颜色设置为白色的时候还有一个黑色的边框,刚开始那个边框怎么都去不掉 无法去除的边框…...
20240926 关于Goland处理wsl-GOROOT原理猜测
GOROOT的原理 go sdk与java jdk类似,是go的编译工具链的集合。 在windows上,我们通过在系统环境变量中添加GOROOT并设置为go sdk地址,使得命令行可以访问到go sdk并执行go test、build等命令,这样设置的变量是全局生效的&#x…...
Anki 学习日记 - 卡片模版 - 单选ABCD(纯操作)
摘要:在不懂前端语言的情况下自定义卡片模版,卡片模版的字段 安装(官网):Anki - powerful, intelligent flashcards (ankiweb.net) 一、在哪能修改卡片模版 管理笔记模板 - > 添加 -> 问答题 -> 设置名称 二…...
钉钉x昇腾:用AI一体机撬动企业数字资产智能化
“走红”近两年后,大模型正在加速走进千行万业。 由于大模型的主要模态是文字和图片,恰好是数字化办公最基础的内容要素,办公于是成了离AI最近的场景。 公文写作、表格生成、提炼大纲、文本翻译、代码润色、数据统计、智能问答……越来越多…...
【C/C++】 秋招常考面试题最全总结(让你有一种相见恨晚的感觉)
目录 1.C程序编译链接过程 2.浅拷贝和move有区别吗 3.深拷贝和浅拷贝的区别 4.空类的大小 5.类的继承有几种方式,区别是什么? 六、extern 关键字的作用 七、static关键字的作用 八、指针和引用的区别 九、C内存分配方式 十、结构体对齐…...
CSS面试真题 part1
CSS面试真题 part1 1、说说你对盒子模型的理解2、谈谈你对BFC的理解3、什么是响应式设计?响应式设计的基本原理是什么?如何做?4、元素水平垂直居中的方法有哪些?如果元素不定宽高呢?5、如何实现两栏布局,右…...
针对考研的C语言学习(定制化快速掌握重点5)
顺序表 特点: 写代码主要就是增删改查!!! 写代码的边界性非常重要以及考研插入和删除的位置都是从1开始,而数组下标是从0开始 【注】下标和位置的关系 线性表最重要的是插入和删除会涉及边界问题以及判断是否合法 …...
构建高效房屋租赁系统:Spring Boot应用
1 绪论 1.1 研究背景 中国的科技的不断进步,计算机发展也慢慢的越来越成熟,人们对计算机也是越来越更加的依赖,科研、教育慢慢用于计算机进行管理。从第一台计算机的产生,到现在计算机已经发展到我们无法想象。给我们的生活改变很…...
学习单片机编程和硬件设计步骤
学习单片机编程和硬件设计可以分为几个步骤: 理解基本概念:首先需要了解单片机的基本概念、硬件结构和工作原理 。 选择开发平台:选择一个合适的单片机系列作为起点,如Arduino、ESP8266/ESP32或STM32系列 。 准备工具和环境&…...
.net Framework 4.6 WebAPI 使用Hangfire
C# 使用 Hangfire 第一章 .net Framework 4.6 WebAPI 使用Hangfire 文章目录 C# 使用 Hangfire前言一、hangfire是什么?二、hangfire的特点三、.net Framework 中hangfire的使用方法第一步:创建WebAPI控制器第二步:添加nuget包第三步 创建startup类新建项目startup类Startu…...
两个向量所在平面的法线,外积,叉积,行列式
偶尔在一个数学题里面看到求两向量所在平面的法线,常规方法可以通过法线与两向量垂直这一特点,列两个方程求解;另外一种方法可以通过求解两个向量的叉积,用矩阵行列式 (determinant) 的方式,之前还没见过,在…...
C++之 友元重载 以及最常用的几种友元函数
在之前的友元中就曾经讲过,我们为了去访问修改私有成员中的数据时,只能通过公有的办法去进行访问操作,非常的局限。所以C引用了友元函数,只要加上friend关键字,C的这个类,会自动把这个函数的权限拉到类内&a…...
动态规划(3)——dp多状态问题Ⅰ
题一.按摩师(LeetCode) 题目描述 一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...
