通义千问1.5-1.8B-Chat-GPTQ-Int4 WebUI实战MySQL数据库集成与智能问答系统搭建你是不是也遇到过这样的场景公司内部有海量的产品手册、技术文档和常见问题解答每当新员工入职或者客户咨询时大家都要花大量时间去文档里翻找答案效率低下还容易出错。或者你想给自己的项目加一个智能客服但总觉得从零开始训练模型太复杂成本也太高。今天我们就来解决这个问题。我将带你一步步搭建一个基于通义千问轻量级模型和MySQL数据库的智能问答系统。这个系统的核心思路很简单把已有的知识比如文档、问答对存到数据库里当用户提问时系统能自动从数据库里找到最相关的信息然后让通义千问模型组织成通顺、准确的回答。这样一来你既拥有了一个专属的知识大脑又无需从头训练大模型。整个过程就像搭积木我们会从最基础的MySQL环境准备开始到设计数据库表最后完成一个能通过Web界面进行智能问答的完整应用。即使你之前没怎么接触过数据库或大模型部署跟着做下来也能搞定。1. 为什么选择这个技术组合在开始动手之前我们先花几分钟聊聊为什么选通义千问1.5-1.8B-Chat-GPTQ-Int4这个模型以及为什么一定要用MySQL。首先这个版本的模型是经过量化处理的简单说就是“瘦身”了。原来的模型可能很大需要很强的显卡才能跑起来但经过GPTQ-Int4量化后它对硬件的要求大大降低。你甚至可以在消费级的显卡上流畅运行它同时还能保持不错的对话能力。这对于我们构建一个成本可控、易于部署的智能系统来说是个非常务实的选择。其次我们选择MySQL作为知识库的载体而不是简单的文本文件主要基于几个考虑。一是结构化存储你可以很方便地对知识进行分类、打标签、设置有效期管理起来井井有条。二是查询效率当知识条目成千上万时数据库的索引机制能让你快速定位到需要的信息这是文件搜索无法比拟的。三是持久化与可靠性数据库能确保数据不会意外丢失并且可以轻松地备份和迁移。最后它还能记录对话历史方便你后续分析用户的常见问题持续优化你的知识库。所以这个组合可以理解为MySQL充当了系统的“记忆库”和“资料库”而通义千问模型则是那个“聪明的大脑”负责理解问题并从记忆库中提取、组织信息形成最终的回答。两者结合就能构建出一个既智能又实用的问答系统。2. 基础环境搭建与准备工欲善其事必先利其器。我们先来把运行这个系统所需的基础软件环境准备好。这里主要分为两大块数据库环境和Python项目环境。2.1 MySQL数据库安装与配置我们的知识库和对话记录都将存放在MySQL里所以第一步就是安装它。这里以在Ubuntu系统上安装为例其他系统步骤类似。打开终端依次执行以下命令# 更新软件包列表 sudo apt update # 安装MySQL服务器 sudo apt install mysql-server -y安装完成后MySQL服务会自动启动。但我们还需要进行一些安全设置并为我们的项目创建一个专用的数据库和用户。运行MySQL的安全安装脚本sudo mysql_secure_installation这个脚本会引导你完成几个步骤设置验证密码插件一般选“是”。为root用户设置一个强密码请务必记住。移除匿名用户选“是”。禁止root用户远程登录选“是”更安全。移除测试数据库选“是”。重新加载权限表选“是”。接下来我们登录MySQL为智能问答系统创建一个新的数据库和用户。# 以root身份登录MySQL sudo mysql -u root -p # 输入你刚才设置的root密码登录成功后你会看到mysql提示符。在这里执行以下SQL命令-- 创建一个名为 qwen_knowledge_base 的数据库 CREATE DATABASE qwen_knowledge_base CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建一个新用户例如叫 qwen_app并设置密码请替换 your_strong_password CREATE USER qwen_applocalhost IDENTIFIED BY your_strong_password; -- 授予这个用户对 qwen_knowledge_base 数据库的所有权限 GRANT ALL PRIVILEGES ON qwen_knowledge_base.* TO qwen_applocalhost; -- 让权限生效 FLUSH PRIVILEGES; -- 退出MySQL EXIT;好了数据库部分就准备好了。我们创建了一个叫qwen_knowledge_base的数据库以及一个专门用来连接它的用户qwen_app。2.2 Python环境与项目初始化我们的Web应用和模型调用都将使用Python。建议使用Python 3.8或更高版本。首先创建一个项目目录并进入mkdir qwen_mysql_qa_system cd qwen_mysql_qa_system然后创建一个Python虚拟环境来隔离项目依赖python3 -m venv venv source venv/bin/activate # Linux/Mac # 如果是Windows使用 venv\Scripts\activate虚拟环境激活后命令行提示符前通常会显示(venv)。接下来安装我们需要的核心Python包pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 根据你的CUDA版本选择 pip install transformers accelerate # 用于加载和运行模型 pip install flask # 轻量级Web框架 pip install mysql-connector-python # MySQL数据库连接器 pip install sentence-transformers # 用于将文本转换为向量做语义检索这里安装的sentence-transformers库很重要。因为我们要做的是“语义检索”即根据问题的意思去找答案而不是简单匹配关键词。这个库可以帮助我们把一段文本无论是用户问题还是知识库条目转换成一组数字向量意思相近的文本其向量在空间中的距离也更近这样我们就能快速找到最相关的知识。至此基础环境就全部准备好了。接下来我们要设计数据库的“图纸”。3. 数据库设计为知识打造一个家现在我们要在qwen_knowledge_base数据库里创建几张表用来存放不同的数据。你可以把它们想象成几个不同的文件夹或Excel表格。我们主要需要两张核心表知识库表存放所有我们提前准备好的问答对、文档片段等知识。对话历史表记录每一次用户对话的上下文方便后续查询和分析。再次登录MySQL这次使用我们刚创建的应用用户mysql -u qwen_app -p qwen_knowledge_base # 输入密码 your_strong_password然后执行下面的SQL语句来创建表-- 1. 知识库表 CREATE TABLE knowledge_base ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(500) COMMENT 知识条目标题或问题摘要, content TEXT COMMENT 知识的具体内容或答案, category VARCHAR(100) COMMENT 分类如“产品功能”、“技术支持”等, tags VARCHAR(255) COMMENT 标签用逗号分隔如“安装,故障,入门”, embedding_vector LONGTEXT COMMENT 存储content字段的文本向量JSON格式, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_category (category), INDEX idx_created_at (created_at) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci COMMENT核心知识库; -- 2. 对话历史表 CREATE TABLE conversation_history ( id INT AUTO_INCREMENT PRIMARY KEY, session_id VARCHAR(100) COMMENT 会话唯一标识可用于区分不同用户或对话, user_query TEXT COMMENT 用户提出的原始问题, retrieved_knowledge_id INT COMMENT 本次回答所引用的知识库条目ID, ai_response TEXT COMMENT 模型生成的回答, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_session_id (session_id), INDEX idx_created_at (created_at), FOREIGN KEY (retrieved_knowledge_id) REFERENCES knowledge_base(id) ON DELETE SET NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci COMMENT用户对话历史记录;我来解释一下关键字段knowledge_base表content这里存放你的知识可以是一段产品描述、一个问题的标准答案或者一份操作指南的片段。embedding_vector这是实现智能检索的关键。我们会用sentence-transformers库把content文本转换成向量一组数字然后存到这里。当用户提问时我们把问题也转换成向量然后在数据库里找和它“距离”最近的向量对应的知识就是最相关的。conversation_history表它记录了每一次交互方便你回溯。session_id可以用来关联同一用户的多次对话。retrieved_knowledge_id是一个外键指向knowledge_base表。这样你就知道模型每次的回答是基于哪条知识生成的非常有助于后期分析和优化。表创建好后我们可以先插入几条示例数据方便后续测试INSERT INTO knowledge_base (title, content, category, tags) VALUES (产品退货政策, 自收到商品之日起7天内如商品未经使用且包装完好可申请无理由退货。退货时请提供原始订单号和商品照片。, 售后服务, 退货,政策,期限), (软件安装系统要求, 安装本软件需要操作系统为Windows 10及以上版本或macOS 10.15及以上版本。至少需要4GB内存和2GB可用磁盘空间。, 技术支持, 安装,系统要求,配置), (如何重置账户密码, 请访问登录页面点击“忘记密码”链接按照提示输入注册邮箱系统将发送重置链接至您的邮箱。, 账户管理, 密码,重置,安全);现在我们的知识库就有了最初的“记忆”。接下来我们要让模型和这个数据库连接起来。4. 核心功能实现连接、检索与回答这是最核心的部分我们将编写Python代码实现三个关键功能连接数据库、从知识库中智能检索、调用通义千问模型生成回答。在你的项目目录下创建一个名为app.py的文件我们将把主要逻辑写在这里。4.1 数据库连接与向量检索模块首先我们编写一个类来处理所有和数据库相关的操作。# app.py import json import mysql.connector from mysql.connector import Error from sentence_transformers import SentenceTransformer import numpy as np class KnowledgeBaseManager: def __init__(self, hostlocalhost, databaseqwen_knowledge_base, userqwen_app, passwordyour_strong_password): 初始化数据库连接和文本向量化模型 self.host host self.database database self.user user self.password password self.connection None # 加载一个轻量级的中文文本向量模型 self.embedding_model SentenceTransformer(paraphrase-multilingual-MiniLM-L12-v2) def connect(self): 建立数据库连接 try: self.connection mysql.connector.connect( hostself.host, databaseself.database, userself.user, passwordself.password ) if self.connection.is_connected(): print(成功连接到MySQL数据库) except Error as e: print(f连接数据库时出错: {e}) raise def close(self): 关闭数据库连接 if self.connection and self.connection.is_connected(): self.connection.close() print(数据库连接已关闭) def get_text_embedding(self, text): 将文本转换为向量 # 模型返回的是numpy数组我们将其转换为列表以便存储为JSON embedding self.embedding_model.encode(text) return embedding.tolist() def search_similar_knowledge(self, query, top_k3): 语义搜索找到与用户问题最相关的知识条目 策略计算问题向量与所有知识向量的余弦相似度取最相似的top_k条 if not self.connection: self.connect() cursor self.connection.cursor(dictionaryTrue) # 1. 将用户问题转换为向量 query_embedding self.get_text_embedding(query) query_embedding_str json.dumps(query_embedding) # 2. 从数据库获取所有已存储向量的知识实际应用中应考虑分页或增量更新缓存 cursor.execute(SELECT id, title, content, embedding_vector FROM knowledge_base WHERE embedding_vector IS NOT NULL) all_knowledge cursor.fetchall() similarities [] for item in all_knowledge: # 3. 解析数据库中存储的向量 stored_embedding json.loads(item[embedding_vector]) # 4. 计算余弦相似度 cos_sim np.dot(query_embedding, stored_embedding) / (np.linalg.norm(query_embedding) * np.linalg.norm(stored_embedding)) similarities.append((cos_sim, item)) # 5. 按相似度排序取最相关的几条 similarities.sort(keylambda x: x[0], reverseTrue) top_results [item for _, item in similarities[:top_k]] cursor.close() return top_results def insert_conversation(self, session_id, user_query, knowledge_id, ai_response): 将一次完整的对话记录存入数据库 if not self.connection: self.connect() cursor self.connection.cursor() sql INSERT INTO conversation_history (session_id, user_query, retrieved_knowledge_id, ai_response) VALUES (%s, %s, %s, %s) val (session_id, user_query, knowledge_id, ai_response) cursor.execute(sql, val) self.connection.commit() record_id cursor.lastrowid cursor.close() return record_id # 简单测试一下 if __name__ __main__: kb_manager KnowledgeBaseManager() kb_manager.connect() # 测试搜索 test_query 我电脑内存只有2G能安装你们的软件吗 results kb_manager.search_similar_knowledge(test_query) print(f针对问题 {test_query} 找到的相关知识) for r in results: print(f- ID:{r[id]}, 标题{r[title]}, 内容{r[content][:100]}...) kb_manager.close()运行这个脚本如果看到它成功连接到数据库并输出了与测试问题相关的知识条目应该是关于“软件安装系统要求”的那条那么恭喜你智能检索的核心部分已经工作了4.2 集成通义千问模型接下来我们要加载通义千问模型并编写一个函数让它基于我们检索到的知识来生成回答。# 在 app.py 中继续添加 from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline import torch class QwenChatModel: def __init__(self, model_name_or_pathQwen/Qwen1.5-1.8B-Chat-GPTQ-Int4): 加载量化后的通义千问对话模型 print(f正在加载模型: {model_name_or_path} 这可能需要几分钟...) self.tokenizer AutoTokenizer.from_pretrained(model_name_or_path) self.model AutoModelForCausalLM.from_pretrained( model_name_or_path, torch_dtypetorch.float16, # 使用半精度浮点数节省显存 device_mapauto # 自动选择GPU或CPU ) # 创建文本生成管道 self.pipe pipeline( text-generation, modelself.model, tokenizerself.tokenizer, max_new_tokens512, # 生成文本的最大长度 temperature0.7, # 控制随机性越低越确定越高越有创意 do_sampleTrue, ) print(模型加载完成) def generate_response(self, user_query, context_knowledge): 基于检索到的知识上下文生成回答 # 构建给模型的提示词Prompt这是影响回答质量的关键 # 我们告诉模型你是一个助手请根据以下已知信息来回答问题。 prompt f你是一个有帮助的AI助手。请根据以下已知信息来回答用户的问题。 如果已知信息不足以回答问题请根据你的知识如实说明不要编造信息。 已知信息 {context_knowledge} 用户问题{user_query} 请用中文给出清晰、准确的回答 # 调用模型生成 outputs self.pipe(prompt) generated_text outputs[0][generated_text] # 从生成的完整文本中提取出“助手”的回答部分即提示词之后的部分 # 这里是一个简单的分割更复杂的场景可能需要更精细的处理 response generated_text.split(请用中文给出清晰、准确的回答)[-1].strip() return response # 测试模型集成 if __name__ __main__: # ... 之前的测试代码 ... print(\n--- 测试模型集成 ---) # 注意首次运行会下载模型请确保网络通畅 chat_model QwenChatModel() # 模拟检索到的知识实际应从search_similar_knowledge获取 mock_knowledge 安装本软件需要操作系统为Windows 10及以上版本或macOS 10.15及以上版本。至少需要4GB内存和2GB可用磁盘空间。 test_question 我电脑内存只有2G能安装你们的软件吗 answer chat_model.generate_response(test_question, mock_knowledge) print(f用户问题{test_question}) print(f模型回答{answer})现在我们已经有了能检索知识的数据库模块和能生成回答的模型模块。是时候把它们和一个简单的Web界面结合起来了。5. 构建Web交互界面我们将使用Flask这个轻量级的Web框架来快速搭建一个界面。创建一个新的文件web_ui.py或者将以下代码整合到app.py中。# web_ui.py from flask import Flask, render_template, request, jsonify, session import uuid from app import KnowledgeBaseManager, QwenChatModel # 假设上面的类都在app.py中 import datetime app Flask(__name__) app.secret_key your_secret_key_here # 用于session请在生产环境中更换 # 初始化我们的核心组件 kb_manager KnowledgeBaseManager() chat_model QwenChatModel() app.route(/) def index(): 渲染主页面 # 为每个新会话生成一个唯一ID if session_id not in session: session[session_id] str(uuid.uuid4()) return render_template(index.html) # 我们需要创建一个HTML模板 app.route(/ask, methods[POST]) def ask_question(): 处理用户提问的API接口 data request.json user_query data.get(question, ).strip() if not user_query: return jsonify({error: 问题不能为空}), 400 try: # 1. 从知识库中检索最相关的信息 relevant_knowledge_list kb_manager.search_similar_knowledge(user_query, top_k2) # 将检索到的知识拼接成上下文 context \n.join([f{i1}. {item[content]} for i, item in enumerate(relevant_knowledge_list)]) if not context: context 当前知识库中没有找到直接相关的信息。 knowledge_id None else: # 假设我们使用最相关的那条知识的ID进行记录 knowledge_id relevant_knowledge_list[0][id] if relevant_knowledge_list else None # 2. 调用模型生成回答 ai_response chat_model.generate_response(user_query, context) # 3. 将本次对话存入历史记录 session_id session.get(session_id, anonymous) kb_manager.insert_conversation(session_id, user_query, knowledge_id, ai_response) # 4. 返回结果给前端 return jsonify({ answer: ai_response, relevant_knowledge: [{title: k[title], content_preview: k[content][:150]} for k in relevant_knowledge_list], timestamp: datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S) }) except Exception as e: print(f处理问题时出错: {e}) return jsonify({error: 系统处理问题出错请稍后重试。}), 500 if __name__ __main__: # 确保数据库连接 kb_manager.connect() print(智能问答系统Web服务启动中...) # 运行在本地5000端口debug模式仅用于开发 app.run(host0.0.0.0, port5000, debugTrue)我们还需要一个简单的HTML页面作为前端。在项目目录下创建一个templates文件夹然后在里面创建index.html!-- templates/index.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title通义千问智能问答系统/title style body { font-family: Segoe UI, Tahoma, Geneva, Verdana, sans-serif; max-width: 800px; margin: 40px auto; padding: 20px; background-color: #f5f7fa; } .container { background: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.08); padding: 30px; } h1 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; } .chat-box { border: 1px solid #ddd; border-radius: 8px; padding: 20px; margin: 20px 0; height: 400px; overflow-y: auto; background-color: #fafafa; } .message { margin-bottom: 15px; padding: 12px 16px; border-radius: 18px; max-width: 80%; line-height: 1.5; } .user-message { background-color: #3498db; color: white; margin-left: auto; } .bot-message { background-color: #ecf0f1; color: #2c3e50; } .input-area { display: flex; gap: 10px; } #questionInput { flex-grow: 1; padding: 15px; border: 1px solid #ccc; border-radius: 8px; font-size: 16px; } #askButton { padding: 15px 30px; background-color: #2ecc71; color: white; border: none; border-radius: 8px; cursor: pointer; font-size: 16px; } #askButton:hover { background-color: #27ae60; } .knowledge-info { font-size: 0.9em; color: #7f8c8d; margin-top: 5px; padding-left: 10px; border-left: 3px solid #f1c40f; } .loading { display: none; text-align: center; color: #7f8c8d; margin: 10px; } /style /head body div classcontainer h1 智能知识库问答/h1 p基于通义千问模型与MySQL知识库。你可以询问关于产品、服务或文档的任何问题。/p div classchat-box idchatBox div classmessage bot-message 你好我是基于公司知识库训练的智能助手。请问有什么可以帮您 /div /div div classinput-area input typetext idquestionInput placeholder请输入您的问题例如退货政策是什么 autocompleteoff button idaskButton onclickaskQuestion()发送/button /div div classloading idloadingIndicator正在思考中.../div div stylemargin-top: 30px; font-size: 0.9em; color: #95a5a6; pstrong提示/strong 系统会先从MySQL知识库中查找相关信息再结合通义千问模型生成回答。/p /div /div script function askQuestion() { const input document.getElementById(questionInput); const question input.value.trim(); const chatBox document.getElementById(chatBox); const loading document.getElementById(loadingIndicator); if (!question) return; // 添加用户消息到界面 const userMsg document.createElement(div); userMsg.className message user-message; userMsg.textContent question; chatBox.appendChild(userMsg); // 清空输入框并显示加载中 input.value ; loading.style.display block; chatBox.scrollTop chatBox.scrollHeight; // 发送请求到后端 fetch(/ask, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ question: question }) }) .then(response response.json()) .then(data { loading.style.display none; if (data.error) { // 显示错误 const errorMsg document.createElement(div); errorMsg.className message bot-message; errorMsg.textContent 抱歉出错了${data.error}; chatBox.appendChild(errorMsg); } else { // 显示AI回答 const botMsg document.createElement(div); botMsg.className message bot-message; botMsg.innerHTML strong回答/strongbr${data.answer.replace(/\n/g, br)}; chatBox.appendChild(botMsg); // 如果有关联的知识显示来源提示 if (data.relevant_knowledge data.relevant_knowledge.length 0) { const infoDiv document.createElement(div); infoDiv.className knowledge-info; infoDiv.innerHTML 本次回答参考了 ${data.relevant_knowledge.length} 条相关知识。; chatBox.appendChild(infoDiv); } // 显示时间戳 const timeDiv document.createElement(div); timeDiv.style.textAlign right; timeDiv.style.fontSize 0.8em; timeDiv.style.color #bdc3c7; timeDiv.textContent data.timestamp; chatBox.appendChild(timeDiv); } chatBox.scrollTop chatBox.scrollHeight; }) .catch(error { loading.style.display none; console.error(Error:, error); const errorMsg document.createElement(div); errorMsg.className message bot-message; errorMsg.textContent 网络请求失败请检查控制台或稍后重试。; chatBox.appendChild(errorMsg); chatBox.scrollTop chatBox.scrollHeight; }); } // 支持按回车键发送 document.getElementById(questionInput).addEventListener(keypress, function(e) { if (e.key Enter) { askQuestion(); } }); /script /body /html现在所有组件都齐了在终端中确保你的虚拟环境是激活状态然后运行python web_ui.py打开浏览器访问http://localhost:5000你应该能看到一个简洁的聊天界面。试着输入“退货政策是什么”系统会先从MySQL知识库中找到我们预先插入的“产品退货政策”那条知识然后调用通义千问模型生成一个完整的、通顺的回答。6. 总结与后续优化建议走到这一步你已经成功搭建了一个将大模型与数据库结合的原型系统。它不再是“空口无凭”的聊天机器人而是有了一个可靠的“记忆库”作为支撑。回顾一下我们完成的工作从零开始配置了MySQL数据库设计了存储知识和历史的两张核心表编写了能够进行语义检索的数据库模块集成了轻量级的通义千问模型并通过一个简单的Web界面将所有功能串联起来提供了一个完整的交互体验。实际用下来这个基础框架已经能解决很多场景下的问题。比如你可以把公司的产品手册分段存入知识库它就能回答关于产品功能的问题把客服常见问答对导入它就能充当第一线的智能客服。模型负责理解和组织语言数据库负责提供准确的事实依据两者结合的效果比单纯使用模型要好得多也更容易控制回答的质量和范围。当然这只是一个起点。如果你想让这个系统更强大、更实用可以考虑从这几个方向继续优化首先是知识库的丰富与优化定期更新和维护知识条目是关键你可以写个脚本批量导入文档甚至为每条知识设置权重或有效期。其次是检索效果的提升我们目前是每次查询都计算所有向量的相似度当知识库很大时这会变慢可以考虑使用专门的向量数据库如Milvus、Chroma来替代或者对MySQL中的向量字段建立特定索引。最后是系统功能的完善比如增加一个管理后台方便非技术人员上传和管理知识或者加入多轮对话的能力让系统能记住上下文对话更连贯。整个搭建过程就像拼装一个智能积木希望这个实战指南能为你提供一个清晰的蓝图。技术本身不是目的用它来解决实际的问题、提升效率才是关键。你可以基于这个原型根据自己的具体需求去调整和扩展打造出更贴合业务场景的智能应用。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。