Chainlit集成LlamaIndex和Chromadb实现RAG增强生成对话AI应用

前言

本文主要讲解如何使用LlamaIndexChromadb向量数据库实现RAG应用,并使用Chainlit快速搭建一个前端对话网页,实现RAG聊天问答增强的应用。文章中还讲解了LlamaIndex CallbackManager回调,实现案例是使用TokenCountingHandler,实现tokens使用计算回调应用。方便知道自己的tokens使用量。

LlamaIndex 回调

LlamaIndex 提供回调来帮助调试、跟踪和追溯库的内部工作。使用回调管理器,可以根据需要添加尽可能多的回调。

除了记录与事件相关的数据之外,您还可以跟踪每个事件的持续时间和发生的次数。

此外,还会记录事件的跟踪图,回调可以随意使用这些数据。例如,LlamaDebugHandler默认情况下,大多数操作后都会打印事件的跟踪。

回调事件类型 虽然每个回调可能不会利用每种事件类型,但可以跟踪以下事件:

  • CHUNKING-> 文本分割前后的日志。
  • NODE_PARSING-> 文档及其解析成的节点的日志。
  • EMBEDDING-> 记录嵌入的文本数量。
  • LLM-> LLM 调用的模板和响应的日志。
  • QUERY-> 跟踪每个查询的开始和结束。
  • RETRIEVE-> 为查询检索到的节点的日志。
  • SYNTHESIZE-> 记录合成调用的结果。
  • TREE-> 生成摘要和摘要级别的日志。
  • SUB_QUESTION-> 记录生成的子问题和答案。

您可以实现自己的回调来跟踪这些事件,或者使用现有的回调。

Chroma简介

Chroma 是一个开源的向量数据库,专门设计用于处理大规模的向量数据,如文本嵌入、图像特征等。它提供了高效的向量搜索能力,使得应用程序能够在海量数据中快速找到与查询向量最相似的数据点。Chroma 的主要特点和优势如下:

主要特点

  1. 高性能

    • Chroma 使用先进的索引技术来加速向量搜索,即使面对非常大的数据集也能保持高效的查询速度。
    • 支持多种索引方法,可以根据具体的应用场景选择最适合的索引策略。
  2. 易用性

    • 提供简单直观的API,使得开发者可以轻松地集成Chroma到自己的应用中。
    • 支持多种编程语言的客户端库,方便不同技术栈的开发团队使用。
  3. 灵活性

    • Chroma 可以运行在本地或云端,支持分布式部署,能够根据需求扩展集群规模。
    • 支持多种数据格式和向量表示方法,适应不同的数据处理需求。
  4. 可扩展性

    • 具有良好的水平扩展能力,可以通过增加更多的节点来提高处理能力和查询吞吐量。
    • 支持数据分区和复制,确保高可用性和容错性。
  5. 社区支持

    • Chroma 拥有一个活跃的开源社区,不断贡献新的特性和改进。
    • 提供详细的文档和示例代码,帮助开发者快速上手。

应用场景

Chroma 在多个领域都有广泛的应用,包括但不限于:

  • 推荐系统:通过搜索用户行为向量,找到相似的用户或物品,从而实现个性化推荐。
  • 搜索引擎:利用文本嵌入技术,快速检索与查询语义最接近的文档或网页。
  • 内容过滤:检测和过滤潜在的有害内容,如垃圾邮件、恶意评论等。
  • 图像识别:通过比较图像特征向量,实现相似图片的搜索和分类。
  • 自然语言处理:支持文本相似度计算、情感分析等多种NLP任务。

Chroma 的设计目标是成为处理大规模向量数据的最佳选择之一,它不仅提供了强大的功能,而且易于使用,非常适合现代数据密集型应用的需求。

快速上手

创建一个文件,例如“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-vector-stores-chroma

执行以下命令安装依赖:

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
  • DashScope模型服务灵积文档地址 https://help.aliyun.com/zh/dashscope/

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

import os
import timeimport chainlit as cl
import chromadb
import pandas as pd
import tiktoken
from llama_index.core import (Settings,VectorStoreIndex,StorageContext, )
from llama_index.core.callbacks import TokenCountingHandler, CallbackManager
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.schema import TextNode
from llama_index.embeddings.dashscope import DashScopeEmbedding, DashScopeTextEmbeddingModels, \DashScopeTextEmbeddingType
from llama_index.llms.dashscope import DashScope, DashScopeGenerationModels
from llama_index.vector_stores.chroma import ChromaVectorStoreSettings.llm = DashScope(model_name=DashScopeGenerationModels.QWEN_TURBO, api_key=os.environ["DASHSCOPE_API_KEY"], max_tokens=512,system_prompt="总是用中文回答"
)
Settings.embed_model = DashScopeEmbedding(model_name=DashScopeTextEmbeddingModels.TEXT_EMBEDDING_V2,text_type=DashScopeTextEmbeddingType.TEXT_TYPE_DOCUMENT,
)
Settings.node_parser = SentenceSplitter(chunk_size=128, chunk_overlap=20)
Settings.num_output = 512
Settings.context_window = 6000encoding = tiktoken.get_encoding('cl100k_base')token_counter = TokenCountingHandler(tokenizer=encoding.encode,verbose=False,  # set to true to see usage printed to the console
)Settings.callback_manager = CallbackManager([token_counter])@cl.cache
def get_vector_store_index():db = chromadb.PersistentClient(path="./chroma_db")chroma_collection = db.get_or_create_collection("quickstart")vector_store = ChromaVectorStore(chroma_collection=chroma_collection, persist_dir="./chroma_db")vector_index = VectorStoreIndex.from_vector_store(vector_store=vector_store, embed_model=Settings.embed_model)print('total_embedding_token_count', token_counter.total_embedding_token_count)# reset the counts at your discretion!token_counter.reset_counts()for doc in vector_index.docstore.docs.values():print(doc)return vector_index@cl.cache
def get_vector_store_index2():def csv_to_nodes(csv_path):# 读取CSV文件df = pd.read_csv(csv_path)# 将每一行转换为Node对象text_nodes = []for (key, value) in df.values:value = str(value) if pd.notna(value) else ''text_nodes.append(TextNode(text=f"{key} {value}"))return text_nodes# 示例使用file_path = './data_file/石家庄医专客服知识库.csv'  # 替换为你的CSV文件路径nodes = csv_to_nodes(file_path)db = chromadb.PersistentClient(path="./chroma_db")chroma_collection = db.get_or_create_collection("quickstart")vector_store = ChromaVectorStore(chroma_collection=chroma_collection, persist_dir="./chroma_db")storage_context = StorageContext.from_defaults(vector_store=vector_store)vector_index = VectorStoreIndex(nodes, storage_context=storage_context, show_progress=True)return vector_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()query_engine = vector_store_index.as_query_engine(similarity_top_k=5, 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} 秒")print("Embedding Tokens: ",token_counter.total_embedding_token_count,"\n","LLM Prompt Tokens: ",token_counter.prompt_llm_token_count,"\n","LLM Completion Tokens: ",token_counter.completion_llm_token_count,"\n","Total LLM Token Count: ",token_counter.total_llm_token_count,)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()
  • 这里我使用的国内阿里云的DashScope sdk 服务。
  • 首次启动使用vector_store_index = get_vector_store_index2()之后改为vector_store_index = get_vector_store_index(),get_vector_store_index 是从chroma_db获取数据索引的,get_vector_store_index2 是将文本数据插入到chroma_db中。
  • 代码还有一些不完善的地方,比如异常的处理还不完善,部署生产的时候记得完善
  • 还可以使用tiktoken.encoding_for_model("gpt-3.5-turbo").encode 获取token编码器,但是llamaindex中只有open ai的模型和编码器的映射关系,所以这个方法只适用OPENAI。

MODEL_TO_ENCODING: dict[str, str] = {# chat"gpt-4o": "o200k_base","gpt-4": "cl100k_base","gpt-3.5-turbo": "cl100k_base","gpt-3.5": "cl100k_base",  # Common shorthand"gpt-35-turbo": "cl100k_base",  # Azure deployment name# base"davinci-002": "cl100k_base","babbage-002": "cl100k_base",# embeddings"text-embedding-ada-002": "cl100k_base","text-embedding-3-small": "cl100k_base","text-embedding-3-large": "cl100k_base",# DEPRECATED MODELS# text (DEPRECATED)"text-davinci-003": "p50k_base","text-davinci-002": "p50k_base","text-davinci-001": "r50k_base","text-curie-001": "r50k_base","text-babbage-001": "r50k_base","text-ada-001": "r50k_base","davinci": "r50k_base","curie": "r50k_base","babbage": "r50k_base","ada": "r50k_base",# code (DEPRECATED)"code-davinci-002": "p50k_base","code-davinci-001": "p50k_base","code-cushman-002": "p50k_base","code-cushman-001": "p50k_base","davinci-codex": "p50k_base","cushman-codex": "p50k_base",# edit (DEPRECATED)"text-davinci-edit-001": "p50k_edit","code-davinci-edit-001": "p50k_edit",# old embeddings (DEPRECATED)"text-similarity-davinci-001": "r50k_base","text-similarity-curie-001": "r50k_base","text-similarity-babbage-001": "r50k_base","text-similarity-ada-001": "r50k_base","text-search-davinci-doc-001": "r50k_base","text-search-curie-doc-001": "r50k_base","text-search-babbage-doc-001": "r50k_base","text-search-ada-doc-001": "r50k_base","code-search-babbage-code-001": "r50k_base","code-search-ada-code-001": "r50k_base",# open source"gpt2": "gpt2","gpt-2": "gpt2",  # Maintains consistency with gpt-4
}

代码解读

这段代码是一个使用Python编写的基于向量检索的对话系统。它结合了多个库和技术,包括chainlit用于构建对话界面,chromadb作为向量数据库存储,以及llama_index(一个用于构建语言模型应用的框架)来处理文档解析、索引创建和查询等任务。下面是对代码的主要部分进行的详细解释:

1. 导入必要的库

首先导入了代码中将要用到的各种库和模块。

2. 设置环境

  • 使用Settings类配置了语言模型(LLM)和嵌入模型(embedding model),这里选择了阿里云的Qwen Turbo模型作为LLM,并设置了API密钥和最大输出令牌数。
  • 嵌入模型使用的是DashScope提供的文本嵌入模型。
  • 配置了节点解析器SentenceSplitter,用于将文档分割成适合向量化的小片段。
  • 初始化了一个令牌计数处理器TokenCountingHandler,用于统计模型处理过程中的令牌使用情况。

3. 向量存储索引

定义了两个函数get_vector_store_indexget_vector_store_index2,这两个函数负责从不同的数据源创建向量存储索引。

  • get_vector_store_index函数直接从已有的Chroma数据库加载数据,创建向量存储索引。
  • get_vector_store_index2函数则从CSV文件读取数据,将其转换为TextNode对象列表,再通过这些节点创建向量存储索引。这适用于需要从头开始处理和索引新数据的情况。

4. 对话管理

  • start函数在对话开始时调用,发送一条欢迎消息给用户。
  • main函数处理用户的输入消息,使用之前创建的向量存储索引来查找最相关的答案,并流式地返回给用户。此外,还会打印出代码执行时间和令牌使用统计数据。

5. 数据源展示

对于查询结果中的每个源节点,都会附加一个侧边显示的文本元素,这样用户可以查看到答案的具体来源。

技术亮点

  • 向量化存储:使用Chroma作为向量数据库,能够高效地存储和检索文档的向量表示。
  • 动态响应:通过streaming=True参数设置,使得查询结果可以以流的形式逐步返回给用户,提供更好的交互体验。
  • 多源信息融合:能够根据用户的查询从多个源节点中提取相关信息,整合成完整的回复。
  • 性能监控:通过令牌计数处理器记录模型处理过程中的令牌消耗,有助于评估和优化系统的运行成本。

这段代码展示了如何利用现代AI工具和技术构建一个功能强大的问答系统,不仅能够处理复杂的查询,还能够提供来源透明度,增强用户体验。

运行应用程序

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

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

启动后界面如下:

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

相关文章推荐

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pollard‘s p-1算法

概述 光滑数 (Smooth number):指可以分解为多个小素数乘积的正整数 当p是N 的因数,并且p−1是光滑数,可以考虑使用Pollards p-1算法来分解N 当p是N的因数,并且p1是光滑数,可以考虑使用Williamss p1算法来分解N 这里…

程序员节-回顾篇

回顾: 时间如白驹过隙,转眼间,我们又走过了一个充满挑战与机遇的年份。回顾过去的一年,心中充满了感慨与收获。 一、个人成长 这一年里,我在各个方面都有了显著的成长。在工作上,我通过不断学习和实践&a…

【小洛的VLOG】Web 服务器高并发压力测试(Reactor模型测试)

目录 引言 工具介绍 环境介绍 测试结果 个人主页:东洛的克莱斯韦克-CSDN博客 引言 大部分的网络通信都是支持TCP/IP协议栈,为了保证通信的可靠性,客户端和服务端之间需要建立链接。服务端能并发处理多少个链接,平均每秒钟能处理…

国产蓝牙耳机哪个品牌值得买?百元国产蓝牙耳机品牌排行榜

一款优质的蓝牙耳机总能为我们带来更加便捷、舒适的听觉体验,而在众多蓝牙耳机品牌中,国产蓝牙耳机凭借其高性价比、丰富的功能和独特的设计,逐渐赢得了消费者的青睐,那么国产蓝牙耳机哪个品牌值得买?作为一个资深的蓝…

一、Linux 目录文件

一、目录结构 |-/ # 根节(cd /) |-/bin # 系统命令 |-/boot # 启动目录 |-/dev # 设备文件保存目录 |-/etc # 系统的所有配置文件|-profile # 环境变量配置文件(修改后需source /etc/profile使配置文件立即生效) |-/home # 普通用…

光储充微电网:策略调度带领能源新未来---安科瑞 吴雅芳

一、光储充微电网概述 光储充微电网是一种高度智能化的电力系统,在新能源领域占据着重要地位。它主要由光伏电站、储能系统、充电桩、微电网控制器等组成。 光伏电站是光储充微电网的核心部分之一,应选择稳定的组件和好的支架。在设计光伏发电系统时&a…

解锁文本数据可视化的无限可能:Wordcloud库全解析

文章目录 **🌟解锁文本数据可视化的无限可能:Wordcloud库全解析🔐**1. **背景介绍**2. **Wordcloud库是什么?**3. **如何安装Wordcloud库?**4. **Wordcloud库的基本函数使用方法**5. **实际应用场景**6. **常见问题及解…

实操 maxkey对接三方文档

实操 maxkey 对接三方文档 概述前置准备:MaxKey 安装与配置:第三方系统准备网络环境 对接三方配置oauth2协议对接导入jar包(调接口)权限加回调重定向获取token处理业务 api对接三方获取api凭证配置 MaxKey更新代码 概述 最近在搞m…

hhdb数据库介绍

背景 随着互联网的崛起,海量数据的存储、计算、分析需求越来越普遍。在各种计算机应用场景中,传统集中式数据库面临着理论升级和技术升级两大难题。21世纪以来,随着以 Hadoop及其衍生技术为代表的大规模数据处理技术的崛起,数据库…

迁移学习|ResNet18

一、导入库 二、设置随机种子 三、数据增强和数据加载 四、加载预训练模型 五、定义损失函数和优化器 六、学习率调度器 七、训练模型 八、可视化训练过程 九、总结 1. 常见优化器概述 1.1 随机梯度下降(SGD: Stochastic Gradient Descent) 简介&…

SIP 业务举例之 三方通话:邀请第三方加入的信令流程

目录 1. 3-Way Conference - Third Party Is Added 简介 2. RFC5359 的 3-Way Conference - Third Party Is Added 信令流程 3. 3-Way Conference - Third Party Is Added 总结 博主wx:yuanlai45_csdn 博主qq:2777137742 想要 深入学习 5GC IMS 等通信知识(加入 51学通信)…

青少年编程能力等级测评CPA C++(三级)-试卷2

青少年编程能力等级测评CPA C(三级)-试卷2 一、单项选择题(共15题,每题3分,共45分) CP3_2_1.在宽度为500米的河道上,修建一个拦河大坝。施工队每天筑坝50米,由于当时条件…

Qt 实战(11)样式表 | 11.2、使用样式表

文章目录 一、使用样式表1、盒子模型2、应用样式表2.1、全局应用2.2、局部应用2.3、通过文件应用 3、使用样式表实现换肤 前言: 在Qt框架中,样式表(Style Sheets)是一种功能强大的工具,它允许开发者以一种简洁而高效的…

怎么把本地代码上传到阿里云里面

项目需求 将本地项目上传到阿里云,一般有两种情况 1.在本地创建的项目,没有关联过其他的git远程仓库。 2.从其他项目复制的项目代码,但是想要以此项目为基础重新创建一个新的项目。 解决方式 第一种 第一种项目很好解决,就按…

LeetCode题练习与总结:路径交叉--335

一、题目描述 给你一个整数数组 distance 。 从 X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说&#xf…

从安灯系统看汽车零部件工厂的智能制造转型

在当今快速发展的制造业领域,汽车零部件工厂正面临着日益激烈的市场竞争和不断提高的客户需求。为了在竞争中脱颖而出,实现可持续发展,许多汽车零部件工厂纷纷踏上智能制造转型之路。而安灯系统作为一种重要的生产管理工具,在这场…

Nginx可视化管理平台nginxWebUI(1)【保姆级部署方式】

目录 nginxWebUI简介 1.概述: 2.功能 NginxWebUI的部署方式 实验环境: 1.安装JDK环境、nginx和nginx程序 2.启动nginxWebUI 3.使用浏览器登录webUI 访问格式: 登陆成功后我们就来到了它的可视化管理页面 nginxWebUI简介 1.概述&am…

面试总结一

面试总结 1、自我介绍一下自己2.面试11、css常用布局有哪些2、css常用的属性3.js原型链4、开发中遇到的技术难点5、闭包6、ts了解什么呢7.git都用什么命令8、vue怎么打包9.vue启动一个项目需要什么10、vue怎么创建一个项目 2.面试21.vue2和vue3有什么区别2.复杂组件的封装&…

vue-element-admin顶部导航栏的修改

基于vue-element-admin的顶部一级导航栏的调整&#xff0c;因为一级路由过多导致其他元素被挤到第二行&#xff0c;故现在将原来一级路由数组拆分成两个数组&#xff0c;第二个数组以子菜单显示 关键处调整代码 html <el-menu:active-text-color"variables.menuActiv…

如何为自己的跨境网站添加多国语言翻译功能及推荐起尔网定制与插件开发

如何为自己的跨境网站添加多国语言翻译功能及推荐起尔网定制与插件开发 在全球化的浪潮下&#xff0c;跨境电商成为越来越多企业拓展国际市场的重要途径。然而&#xff0c;语言障碍成为了一个不可忽视的问题。为了更好地服务全球用户&#xff0c;为自己的跨境网站添加多国语言…