今天介绍的系统是一个可交互的AI助手应用,核心功能是:允许用户上传本地文档构建专属知识库,并通过自然语言提问获取基于知识库的精准回答
核心技术栈
后端框架:Python+Chainlit (快速构建AI应用界面)
大模型集成:月之暗面、Deepseek
RAG核心:Llamaindex (处理文档索引与检索)
嵌入模型:HuggingFace 开源模型 (BAAI/bge-small-zh-v1.5)
前端技术:JavaScript (DOM操作)、CSS(样式定制)
模块详解:从前端到后端
1、前端交互层:用户体验的入口
前端部分主要负责界面展示与用户交互,包含两个核心文件 test.js 和 back.css
①test.js:通过 MutationObserver监听 DOM 变化,当页面加载时自动将特定元素的文本修改为 "RAG 知识库检索系统"。这个小技巧能动态调整页面显示内容,让系统名称更贴合功能定位
// 监听DOM变化,动态修改页面文本
const observer = new MutationObserver(() => {
const spanElement = document.querySelector('div.text-xs.text-muted-foreground span');
if (spanElement) {
spanElement.textContent = "RAG知识库检索系统";
observer.disconnect(); // 完成修改后停止监听
}
});
②back.css:自定义应用的视觉风格,通过设置背景色、背景图片等样式,让界面更符合使用场景(比如专业的知识库系统风格)
body, .cl-root {
background-color: #f0f2f5;
background-image: url('../public/background.png');
background-size: cover;
}
2、大模型配置层:AI的力量源泉
llms.py 负责集成第三方大模型,为系统提供生成能力。这里以月之暗面和 DeepSeek 为例,通过 LlamaIndex 的OpenAI兼容接口实现调用:
①定义模型参数:包括 API 密钥、模型名称、API 地址和温度参数(控制回答随机性)
②扩展模型列表:将自定义模型添加到 LlamaIndex 的支持列表中,确保框架能识别
# 月之暗面模型配置
def moonshot_llm(**kwargs):
llm = OpenAI(
api_key="sk-xxx", # 你自己的APIkey
model="kimi-k2-0711-preview",
api_base="https://api.moonshot.cn/v1",
temperature=0.6, # 中等随机性,平衡创造性与准确性
**kwargs
)
return llm
通过这种方式,系统可以灵活切换不同大模型,适应不同场景的需求(比如有的模型擅长对话,有的擅长专业领域问答)
3、应用交互层:连接用户与后端的桥梁
app_ui.py 是基于Chainlit 构建的核心交互逻辑,负责:
①用户认证:通过简单的用户名密码验证(默认 admin/admin)控制访问权限
②会话初始化:聊天开始时加载大模型和 RAG 引擎,确保系统就绪
③消息处理:接收用户提问和文件上传,将请求转发给后端处理
④文件处理:当用户上传文档时,自动创建向量索引并更新知识库
# 处理用户消息与文件上传
@cl.on_message
async def main(message: cl.Message):
# 提取上传的文件
files = [msg.file for msg in message.elements if isinstance(msg, (cl.File, cl.Image))]
if files:
# 读取文件并创建索引
data = SimpleDirectoryReader(input_files=files).load_data()
index = await create_index(data)
# 更新聊天引擎,使用新索引
chat_engine = index.as_chat_engine(chat_mode=ChatMode.CONTEXT)
cl.user_session.set("chat_engine", chat_engine)
# 生成回答并流式返回
res = await cl.make_async(query_engine.stream_chat)(message.content)
for token in res.response_gen:
await msg.stream_token(token)
这里的关键是实时更新知识库——用户上传文件后,系统会立即将其纳入检索范围,无需重启应用
4、RAG核心层:让AI有理有据
base_rag.py 实现了检索增强生成的核心逻辑,是系统区别于普通大模型对话的关键:
①索引创建:将文档转换为向量并保存到本地(index目录),实现高效检索
②索引加载:启动时加载已保存的索引,避免重复处理文档
③聊天引擎:结合索引(知识库)、对话记忆(上下文)和系统提示,生成基于上下文的回答
# 创建文档向量索引
def create_index(data) -> BaseIndex:
index = VectorStoreIndex.from_documents(data) # 文档向量化
index.storage_context.persist(persist_dir="index") # 保存索引到本地
return index
# 初始化聊天引擎
async def create_chat_model():
storage_context = StorageContext.from_defaults(persist_dir="./index")
index = load_index_from_storage(storage_context) # 加载已有索引
memory = ChatMemoryBuffer.from_defaults(token_limit=1024) # 对话记忆
return index.as_chat_engine(
chat_mode=ChatMode.CONTEXT,
memory=memory,
system_prompt="我是一个AI助手,可以回答任何问题,请输入你的问题"
)
通过向量索引,系统能快速从海量文档中找到与问题相关的内容,让大模型基于这些 "证据" 生成回答,既保证准确性,又避免幻觉
5、嵌入模型层:文本向量化的关键
embeddings.py 提供文本向量化能力,使用开源的BAAI/bge-small-zh-v1.5模型:
def embed_model_local_bge_small(**kwargs):
return HuggingFaceEmbedding(
model_name="BAAI/bge-small-zh-v1.5", # 中文优化的嵌入模型
cache_folder=r"../embed_cache" # 模型缓存目录
)
嵌入模型将文本转换为计算机可理解的向量,是实现 "语义检索" 的基础 —— 即使问题与文档中的表述不同,只要语义相近,也能被准确检索到
系统工作流程:从提问到回答的完整路径
1、初始化阶段:应用启动时,加载本地索引(若存在),初始化大模型和聊天引擎,等待用户连接
2、用户交互阶段:
- 用户输入问题:系统通过 Chainlit 接收提问
- 用户上传文件:系统自动读取文件内容,创建新的向量索引并更新聊天引擎
3、检索增强阶段:
- 当用户提问时,聊天引擎先从向量索引中检索相关文档片段
- 将检索到的内容作为上下文,传递给大模型
4、生成回答阶段:大模型结合上下文和对话历史,生成回答并流式返回给用户
7137

被折叠的 条评论
为什么被折叠?



