ERNIE-4.5-0.3B-PT Chainlit进阶:集成RAG、添加知识库、支持文件上传问答
ERNIE-4.5-0.3B-PT Chainlit进阶集成RAG、添加知识库、支持文件上传问答1. 项目概述与价值ERNIE-4.5-0.3B-PT是一个基于vLLM部署的高效文本生成模型结合Chainlit前端提供了友好的交互界面。本文将带你从基础使用升级到高级功能实现RAG检索增强生成、知识库集成和文件上传问答能力。这个进阶方案能帮你解决什么问题想象一下你不再需要每次都手动输入大量背景信息模型可以直接从你的文档中获取知识你可以上传PDF、Word等文件让AI帮你分析和回答相关问题你可以构建专属的知识库让模型变得更专业。我们将通过几个实际步骤让你的ERNIE-4.5模型从简单的对话工具升级为智能知识助手。整个过程不需要深厚的技术背景跟着做就能实现。2. 环境准备与基础检查在开始进阶功能前我们先确保基础环境正常运行。2.1 确认模型服务状态使用以下命令检查模型是否正常部署# 查看模型服务日志 cat /root/workspace/llm.log # 检查服务端口状态 netstat -tlnp | grep 8000 # 测试API接口 curl -X POST http://localhost:8000/v1/completions \ -H Content-Type: application/json \ -d {prompt: 你好, max_tokens: 50}如果看到正常的响应输出说明模型服务运行正常。如果遇到问题可以检查端口是否被占用或者重新启动服务。2.2 Chainlit前端验证启动Chainlit前端界面确保基础功能正常# 启动Chainlit应用 chainlit run app.py # 或者指定端口 chainlit run app.py --port 7860在浏览器中打开对应地址尝试进行简单对话确认模型能够正常响应。3. RAG检索增强生成集成RAGRetrieval-Augmented Generation能让模型在生成回答时参考外部知识显著提升回答的准确性和专业性。3.1 安装必要依赖首先安装RAG相关的Python库pip install langchain chromadb sentence-transformers pypdf2 python-docx3.2 实现简单的RAG系统创建一个rag_module.py文件实现基本的检索功能from langchain.vectorstores import Chroma from langchain.embeddings import HuggingFaceEmbeddings from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.document_loaders import TextLoader, PyPDFLoader, Docx2txtLoader import os class SimpleRAG: def __init__(self, persist_directory./chroma_db): self.embeddings HuggingFaceEmbeddings( model_namesentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 ) self.persist_directory persist_directory self.vectorstore None def load_documents(self, file_paths): 加载多种格式的文档 documents [] for file_path in file_paths: if file_path.endswith(.pdf): loader PyPDFLoader(file_path) elif file_path.endswith(.docx): loader Docx2txtLoader(file_path) else: loader TextLoader(file_path) documents.extend(loader.load()) # 分割文本 text_splitter RecursiveCharacterTextSplitter( chunk_size1000, chunk_overlap200 ) texts text_splitter.split_documents(documents) # 创建向量存储 self.vectorstore Chroma.from_documents( documentstexts, embeddingself.embeddings, persist_directoryself.persist_directory ) self.vectorstore.persist() def search_relevant_docs(self, query, k3): 检索相关文档 if self.vectorstore is None: return [] return self.vectorstore.similarity_search(query, kk)3.3 集成RAG到Chainlit修改你的Chainlit应用集成RAG功能import chainlit as cl from rag_module import SimpleRAG import requests import json # 初始化RAG系统 rag_system SimpleRAG() cl.on_chat_start async def start_chat(): # 初始化会话状态 cl.user_session.set(rag_context, ) await cl.Message(欢迎使用增强版ERNIE助手我可以处理文档和回答问题。).send() cl.on_message async def main(message: cl.Message): # 获取用户消息 user_message message.content # 如果有文档上下文先进行检索 rag_context cl.user_session.get(rag_context, ) if rag_context: relevant_docs rag_system.search_relevant_docs(user_message) context_text \n.join([doc.page_content for doc in relevant_docs]) enhanced_prompt f基于以下上下文\n{context_text}\n\n请回答{user_message} else: enhanced_prompt user_message # 调用ERNIE模型 response call_ernie_model(enhanced_prompt) await cl.Message(contentresponse).send() def call_ernie_model(prompt): 调用ERNIE模型API url http://localhost:8000/v1/completions headers {Content-Type: application/json} data { prompt: prompt, max_tokens: 500, temperature: 0.7 } try: response requests.post(url, headersheaders, datajson.dumps(data)) result response.json() return result[choices][0][text] except Exception as e: return f调用模型出错{str(e)}4. 知识库构建与管理现在我们来构建一个完整的知识库系统让模型能够从你的专属资料中学习。4.1 知识库初始化脚本创建knowledge_base.py文件import os import glob from rag_module import SimpleRAG class KnowledgeBaseManager: def __init__(self): self.rag SimpleRAG() self.knowledge_path ./knowledge_docs os.makedirs(self.knowledge_path, exist_okTrue) def add_document(self, file_path): 添加单个文档到知识库 if not os.path.exists(file_path): return False, 文件不存在 # 复制文件到知识库目录 import shutil filename os.path.basename(file_path) dest_path os.path.join(self.knowledge_path, filename) shutil.copy2(file_path, dest_path) # 更新向量库 self.rag.load_documents([dest_path]) return True, 文档添加成功 def batch_add_documents(self, directory_path): 批量添加文档 if not os.path.exists(directory_path): return False, 目录不存在 supported_extensions [*.txt, *.pdf, *.docx] documents [] for extension in supported_extensions: documents.extend(glob.glob(os.path.join(directory_path, extension))) if not documents: return False, 未找到支持的文档格式 for doc in documents: self.add_document(doc) return True, f成功添加 {len(documents)} 个文档 def clear_knowledge_base(self): 清空知识库 import shutil if os.path.exists(self.knowledge_path): shutil.rmtree(self.knowledge_path) os.makedirs(self.knowledge_path, exist_okTrue) # 重新初始化RAG self.rag SimpleRAG() return True, 知识库已清空4.2 Chainlit知识库管理界面在Chainlit中添加知识库管理功能cl.action_callback(manage_knowledge) async def on_action(action): 知识库管理回调 if action.value add_doc: files None while files is None: files await cl.AskFileMessage( content请上传要添加到知识库的文档支持PDF、Word、TXT, accept[application/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document, text/plain], max_size_mb10 ).send() # 保存文件并添加到知识库 import tempfile with tempfile.NamedTemporaryFile(deleteFalse) as tmp_file: tmp_file.write(files[0].content) tmp_path tmp_file.name success, message knowledge_manager.add_document(tmp_path) os.unlink(tmp_path) await cl.Message(contentmessage).send() elif action.value clear_kb: success, message knowledge_manager.clear_knowledge_base() await cl.Message(contentmessage).send() cl.on_chat_start async def start_chat_with_knowledge(): # 添加知识库管理按钮 actions [ cl.Action(namemanage_knowledge, valueadd_doc, label 添加文档), cl.Action(namemanage_knowledge, valueclear_kb, label️ 清空知识库) ] await cl.Message( content欢迎使用智能知识库助手, actionsactions ).send()5. 文件上传与问答功能实现直接的文件上传和基于文档内容的问答功能。5.1 文件上传处理增强Chainlit应用的文件处理能力cl.on_message async def handle_message_with_files(message: cl.Message): # 检查是否有文件上传 if message.elements: for element in message.elements: if element.type in [pdf, word, text]: # 保存上传的文件 file_path f./uploads/{element.name} os.makedirs(./uploads, exist_okTrue) with open(file_path, wb) as f: f.write(element.content) # 添加到临时知识库 knowledge_manager.add_document(file_path) cl.user_session.set(has_uploaded_files, True) await cl.Message(f已成功上传并分析文档{element.name}).send() return # 处理文本消息 user_message message.content # 检查是否有上传的文件上下文 if cl.user_session.get(has_uploaded_files, False): # 使用RAG增强查询 relevant_docs knowledge_manager.rag.search_relevant_docs(user_message) context \n.join([doc.page_content for doc in relevant_docs]) prompt f基于上传的文档内容 {context} 请回答以下问题{user_message} 如果文档内容中没有相关信息请如实告知。 else: prompt user_message # 调用模型 response call_ernie_model(prompt) await cl.Message(contentresponse).send()5.2 多文件批量处理支持批量文件上传和处理cl.action_callback(batch_upload) async def handle_batch_upload(action): 批量上传文件处理 files await cl.AskFileMessage( content请选择多个要上传的文档文件, accept[application/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document, text/plain], max_size_mb50, max_files10 ).send() if not files: return success_count 0 for file in files: file_path f./uploads/{file.name} with open(file_path, wb) as f: f.write(file.content) success, message knowledge_manager.add_document(file_path) if success: success_count 1 await cl.Message(contentf成功上传并处理 {success_count}/{len(files)} 个文件).send()6. 完整集成示例下面是一个完整的Chainlit应用示例集成了所有高级功能import chainlit as cl import requests import json import os from knowledge_base import KnowledgeBaseManager # 初始化知识库管理器 knowledge_manager KnowledgeBaseManager() def call_ernie_model(prompt, max_tokens500, temperature0.7): 调用ERNIE模型API url http://localhost:8000/v1/completions headers {Content-Type: application/json} data { prompt: prompt, max_tokens: max_tokens, temperature: temperature } try: response requests.post(url, headersheaders, datajson.dumps(data)) result response.json() return result[choices][0][text] except Exception as e: return f调用模型出错{str(e)} cl.on_chat_start async def start_chat(): 聊天开始时初始化 # 设置初始状态 cl.user_session.set(has_uploaded_files, False) # 欢迎消息和操作按钮 actions [ cl.Action(nameupload_doc, valuesingle, label 上传文档), cl.Action(nameupload_doc, valuebatch, label 批量上传), cl.Action(namemanage_kb, valueclear, label️ 清空知识库) ] welcome_msg ## ERNIE智能文档助手 欢迎使用增强版ERNIE助手我可以 - 回答一般问题 - 分析上传的文档内容 - 基于文档内容进行智能问答 - 管理您的专属知识库 请选择操作或直接开始对话 await cl.Message(contentwelcome_msg, actionsactions).send() cl.action_callback(upload_doc) async def handle_upload(action): 处理文档上传 if action.value single: files await cl.AskFileMessage( content请上传文档PDF/Word/TXT, accept[application/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document, text/plain], max_size_mb10 ).send() else: files await cl.AskFileMessage( content请选择多个文档文件, accept[application/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document, text/plain], max_size_mb50, max_files10 ).send() if not files: return success_count 0 for file in files: file_path f./uploads/{file.name} os.makedirs(./uploads, exist_okTrue) with open(file_path, wb) as f: f.write(file.content) success, message knowledge_manager.add_document(file_path) if success: success_count 1 cl.user_session.set(has_uploaded_files, True) await cl.Message(contentf成功处理 {success_count} 个文档现在可以基于文档内容提问了).send() cl.action_callback(manage_kb) async def manage_knowledge_base(action): 管理知识库 if action.value clear: success, message knowledge_manager.clear_knowledge_base() cl.user_session.set(has_uploaded_files, False) await cl.Message(contentmessage).send() cl.on_message async def main(message: cl.Message): 处理用户消息 user_message message.content # 检查是否有文件上传 if message.elements: for element in message.elements: if hasattr(element, type) and element.type in [pdf, word, text]: file_path f./uploads/{element.name} os.makedirs(./uploads, exist_okTrue) with open(file_path, wb) as f: f.write(element.content) knowledge_manager.add_document(file_path) cl.user_session.set(has_uploaded_files, True) await cl.Message(contentf已上传并分析文档{element.name}).send() return # 处理文本消息 if cl.user_session.get(has_uploaded_files, False): # 使用RAG增强查询 relevant_docs knowledge_manager.rag.search_relevant_docs(user_message, k3) if relevant_docs: context \n.join([doc.page_content[:500] ... for doc in relevant_docs]) prompt f基于以下文档内容 {context} 请回答这个问题{user_message} 如果文档中没有相关信息请如实告知。 else: prompt user_message else: prompt user_message # 调用模型 response call_ernie_model(prompt) await cl.Message(contentresponse).send() # 启动应用 if __name__ __main__: cl.run()7. 部署与优化建议7.1 性能优化配置为了获得更好的性能可以调整以下配置# 优化配置示例 class OptimizedConfig: # 向量检索配置 CHUNK_SIZE 800 # 减小块大小提高精度 CHUNK_OVERLAP 150 # 增加重叠提高连贯性 # 模型调用配置 MAX_TOKENS 800 # 增加最大token数 TEMPERATURE 0.3 # 降低温度提高确定性 # 缓存配置 CACHE_DIR ./cache VECTOR_CACHE_SIZE 1000 # 缓存最近1000个查询7.2 错误处理与日志添加完善的错误处理和日志记录import logging from datetime import datetime # 配置日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(fapp_{datetime.now().strftime(%Y%m%d)}.log), logging.StreamHandler() ] ) logger logging.getLogger(__name__) def safe_call_ernie_model(prompt, max_retries3): 带重试机制的模型调用 for attempt in range(max_retries): try: response call_ernie_model(prompt) return response except Exception as e: logger.error(f模型调用失败尝试 {attempt 1}: {str(e)}) if attempt max_retries - 1: return 抱歉服务暂时不可用请稍后再试。 time.sleep(1) # 等待1秒后重试8. 总结通过本文的进阶指南你已经将基础的ERNIE-4.5-0.3B-PT模型升级为了一个功能强大的智能文档助手。现在你的系统能够核心功能提升✅ 集成RAG检索增强生成提高回答准确性✅ 构建和管理专属知识库让模型更专业✅ 支持文件上传和基于文档的智能问答✅ 提供友好的图形界面操作简单直观实际应用价值企业可以用它来构建内部知识问答系统教育机构可以用它来创建智能学习助手个人用户可以用它来管理个人文档和笔记开发者可以基于这个框架继续扩展更多功能下一步建议尝试添加更多文档格式支持如PPT、Excel等探索集成网络搜索功能增强实时信息获取能力考虑添加多语言支持扩大应用范围优化性能支持更大规模的文档处理记住这是一个灵活的框架你可以根据自己的需求进行调整和扩展。遇到问题时可以参考官方文档或在技术社区寻求帮助。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。