这次我们来看一个基于 SpringAI + SpringBoot + Vue + RAG + PGVector + Embedding 技术栈构建的企业级智能问答系统。这个项目不是简单的概念演示,而是一个可以直接部署、用于企业内部知识管理和智能问答的实战方案。它的核心价值在于,将前沿的 RAG(检索增强生成)技术与成熟的 Java 后端、Vue 前端以及 PostgreSQL 向量数据库结合,提供了一个开箱即用的企业知识库解决方案。
对于开发者而言,最关心的是它能不能跑起来、硬件门槛高不高、以及如何接入自己的数据。这个项目给出了明确的答案:它支持本地部署,后端基于 SpringBoot,前端是 Vue,知识库的核心是 PGVector 和 Embedding 模型。这意味着你不需要昂贵的 GPU 集群,利用 CPU 或普通 GPU 即可完成知识库的构建和问答。本文将带你从零开始,完成环境搭建、知识库构建、服务启动到最终问答测试的全流程,重点关注部署细节、接口调用和实际效果验证。
1. 核心能力速览
在深入细节之前,我们先通过一个表格快速了解这个项目的核心规格和特点,帮助你判断是否值得投入时间。
| 能力项 | 说明 |
|---|---|
| 项目类型 | 企业级智能问答系统 / 知识库 |
| 技术栈 | SpringAI (后端AI框架)、SpringBoot (后端)、Vue 3 (前端)、RAG (检索增强生成)、PGVector (PostgreSQL向量扩展)、Embedding 模型 |
| 核心功能 | 文档上传与管理、智能知识检索、基于上下文的精准问答、多轮对话 |
| 硬件门槛 | 低。Embedding 模型可运行于 CPU,大语言模型(LLM)可调用云端 API(如 OpenAI、通义千问)或本地轻量模型。PGVector 对服务器内存有一定要求。 |
| 启动方式 | 前后端分离部署。后端通过 SpringBoot 启动,前端通过 Node.js 构建后访问。支持 Docker 容器化部署。 |
| 接口能力 | 提供完整的 RESTful API,支持文档上传、知识库查询、智能问答等操作。 |
| 批量任务 | 支持批量文档上传与向量化处理,适合初始化知识库。 |
| 适合场景 | 企业内部知识管理、智能客服助手、产品文档问答、新员工培训系统等。 |
从表格可以看出,这是一个工程化程度高、技术选型主流、硬件要求友好的项目。它避开了需要重型 GPU 的本地大模型训练,转而采用“Embedding本地化 + LLM API调用”的混合架构,降低了部署成本。
2. 适用场景与使用边界
适合谁用?
- 企业开发者/团队:需要快速搭建一个私有化、可定制、能对接内部文档的知识问答系统。
- Java 技术栈团队:项目后端基于 SpringBoot 和 SpringAI,对于熟悉 Java 生态的团队来说,二次开发和维护成本低。
- 学习 RAG 的实践者:想通过一个完整的项目,理解从文档处理、向量化、检索到生成的完整 RAG 流水线。
能解决什么问题?
- 信息孤岛:将散落在 Confluence、Wiki、PDF、Word 等处的企业文档统一管理,并实现智能检索。
- 问答效率低下:员工无需手动翻阅大量文档,通过自然语言提问即可获得精准、有依据的答案。
- 7x24小时自助服务:可作为智能客服基础,回答常见问题,减轻人工客服压力。
不适合什么场景?
- 需要极高实时性(毫秒级)的问答:RAG 流程涉及检索和生成,有一定延迟。
- 完全离线的封闭环境且无法连接任何外部 API:如果必须完全离线,需要本地部署完整的 LLM,对硬件要求会显著提高。
- 处理高度动态、实时变化的数据:RAG 知识库需要定期更新,不适合股票价格、实时新闻等场景。
合规与安全边界
- 数据隐私:所有文档处理和问答均在自有服务器进行,保证了企业数据的私密性。
- 版权与授权:上传至系统的文档应确保拥有相应的版权或使用授权,避免侵权风险。
- 内容安全:接入的 LLM API(如 OpenAI)需配置合规的内容过滤策略,防止生成不当内容。自建本地模型也需进行安全对齐。
3. 环境准备与前置条件
开始部署前,请确保你的开发或服务器环境满足以下要求。这是项目能成功运行的基础。
操作系统
- Linux (Ubuntu 20.04+/CentOS 7+), macOS, 或 Windows 10/11 (建议使用 WSL2 以获得最佳体验)。
后端环境 (SpringBoot)
- JDK: 版本 17 或 21(与 SpringBoot 3.x 兼容)。
- Maven: 3.6+ 或Gradle,用于项目构建。
- PostgreSQL: 版本 12+。这是存储向量数据和元数据的核心。
- PGVector 扩展: 需要在 PostgreSQL 中安装此扩展以支持向量运算。
前端环境 (Vue)
- Node.js: 版本 16+,推荐 18 LTS。
- npm或yarn或pnpm: 包管理工具。
AI 模型与 API
- Embedding 模型: 例如
BGE、text2vec等。项目通常会集成sentence-transformers库,并指定一个默认模型(如BAAI/bge-small-zh)。该模型在 CPU 上即可运行,首次运行时会自动下载。 - 大语言模型 (LLM) API: 需要一个可访问的 LLM 服务端点。常见选择:
- 云端 API: OpenAI GPT, 阿里云通义千问, 智谱 AI 等。你需要准备相应的 API Key。
- 本地 API: 通过
Ollama、LM Studio或vLLM等工具在本地部署一个开源模型(如 Qwen、ChatGLM),并提供兼容 OpenAI 格式的 API。
硬件建议
- CPU: 4核以上,用于运行 SpringBoot 应用和 Embedding 模型推理。
- 内存: 8GB 以上。PostgreSQL 处理向量检索时比较吃内存,知识库越大,所需内存越多。
- 磁盘: 预留 10GB 以上空间,用于存储 PostgreSQL 数据、模型缓存和上传的文档。
- 网络: 如果需要调用云端 LLM API,需保证服务器能稳定访问外网。
4. 安装部署与启动方式
我们将按照“数据库 -> 后端 -> 前端”的顺序进行部署。
4.1 数据库准备 (PostgreSQL + PGVector)
安装 PostgreSQL: 以 Ubuntu 为例。
sudo apt update sudo apt install postgresql postgresql-contrib sudo systemctl start postgresql sudo systemctl enable postgresql安装 PGVector 扩展:
# 进入 PostgreSQL 命令行 sudo -u postgres psql # 在 psql 中创建数据库并启用扩展 CREATE DATABASE enterprise_knowledge_db; \c enterprise_knowledge_db; CREATE EXTENSION IF NOT EXISTS vector; \q对于 Windows 或 macOS,请参考 PGVector 官方 GitHub 仓库的安装指南。
配置连接:记下你的数据库连接信息(主机、端口、数据库名、用户名、密码),后端配置需要用到。
4.2 后端服务 (SpringBoot) 部署
假设你已经克隆或下载了项目代码。
修改配置文件: 找到后端项目的
application.yml或application.properties文件。# application.yml 示例 spring: datasource: url: jdbc:postgresql://localhost:5432/enterprise_knowledge_db username: your_db_username password: your_db_password driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: update show-sql: true # AI 配置 (以 SpringAI 的 OpenAI 配置为例) spring: ai: openai: api-key: ${OPENAI_API_KEY:sk-your-openai-key-here} # 建议使用环境变量 chat: options: model: gpt-3.5-turbo # 或 gpt-4, qwen-max 等 embedding: openai: api-key: ${OPENAI_API_KEY} # 如果使用OpenAI的Embedding # 或者使用本地 Embedding 模型 # 如果项目配置了本地 Embedding,可能类似这样: # embedding: # onnx: # model: BAAI/bge-small-zh-v1.5关键点:
- 将数据库连接信息替换为你自己的。
spring.ai.openai.api-key需要替换成你的真实 API Key,强烈建议通过环境变量 (OPENAI_API_KEY) 设置,而不是硬编码在配置文件中。- 如果项目使用本地 Embedding 模型,配置项可能不同,请根据项目具体文档调整。
构建与启动:
# 进入后端项目根目录 cd /path/to/springboot-backend # 使用 Maven 打包 mvn clean package -DskipTests # 运行 Jar 包 java -jar target/your-backend-application.jar # 或者直接使用 SpringBoot Maven 插件运行 mvn spring-boot:run启动成功后,控制台应显示 SpringBoot 启动日志,并提示类似
Tomcat started on port(s): 8080的信息。
4.3 前端项目 (Vue) 部署
安装依赖:
cd /path/to/vue-frontend npm install # 或 yarn install 或 pnpm install配置后端 API 地址: 找到前端项目的环境配置文件,通常是
.env.development或.env.production,或者src/config/api.js等。# .env.development 示例 VUE_APP_API_BASE_URL=http://localhost:8080/api/v1将
localhost:8080修改为你的后端服务实际地址和端口。构建与运行:
- 开发模式运行:
访问npm run servehttp://localhost:8081(端口可能不同) 即可。 - 生产环境构建:
构建产物通常在npm run builddist目录下,你可以将其部署到 Nginx、Apache 等静态文件服务器,并配置代理指向后端 API。
- 开发模式运行:
5. 功能测试与效果验证
服务启动后,我们通过以下几个核心功能来验证系统是否工作正常。
5.1 知识库管理:文档上传与向量化
这是 RAG 系统的第一步。我们需要将文档(如 PDF、TXT、Word)上传,系统会将其切分、转换为向量并存入 PGVector。
测试目的:验证文档上传、解析、向量化入库的完整流程。
操作步骤:
- 打开前端页面,登录后进入“知识库管理”或类似模块。
- 点击“上传文档”,选择一个测试用的 PDF 文件(例如一份产品说明书或技术文档)。
- 上传后,在任务列表或文档列表中应能看到该文档,状态从“处理中”变为“已完成”。
后台验证: 你可以通过后端日志观察处理过程,或直接查询数据库:
-- 连接到你的知识库数据库 SELECT COUNT(*) FROM document_chunks; -- 查看文档块数量 SELECT * FROM document_chunks LIMIT 1; -- 查看一条向量记录如果embedding字段有数据(一长串数字数组),说明向量化成功。
5.2 智能问答:基于知识的精准回答
这是核心功能。系统根据用户问题,从向量库中检索相关文档片段,组合成上下文发送给 LLM 生成答案。
测试目的:验证 RAG 检索和生成链路是否通畅,答案是否基于上传的知识。
操作步骤:
- 在前端问答界面,输入一个与你上传文档内容相关的问题。
- 示例问题(假设上传了 SpringBoot 文档):“如何在 SpringBoot 中配置多数据源?”
- 点击发送。系统会显示“思考中…”,然后返回答案。
效果验证:
- 成功标准:返回的答案应准确、具体,并且能在你上传的文档中找到依据。答案末尾通常会附带“参考来源”或引用片段。
- 对比测试:问一个文档中绝对没有的问题(例如“今天天气怎么样?”)。一个设计良好的企业知识库系统应该回答“根据现有知识,我无法回答这个问题”或引导用户询问知识库相关的问题,而不是胡编乱造。
5.3 多轮对话测试
测试目的:验证系统是否能维护对话上下文,在后续问题中正确引用之前的对话内容。
操作步骤:
- 第一问:“我们公司产品的核心优势是什么?”(基于上传的产品文档)。
- 第二问:“针对刚才提到的优势,我们的售后服务政策是如何支持的?”预期结果:第二个回答应该能结合第一个问题的上下文(核心优势),并从文档中检索出相关的售后服务信息进行回答。
6. 接口 API 与批量任务
对于开发者,直接调用 API 进行集成或批量操作更为常见。
6.1 核心 API 调用示例
后端启动后,Swagger 或类似的 API 文档通常位于http://localhost:8080/swagger-ui.html或http://localhost:8080/doc.html。以下是一些关键接口的调用示例。
1. 文档上传接口 (Upload Document)
curl -X POST "http://localhost:8080/api/documents/upload" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: multipart/form-data" \ -F "file=@/path/to/your/document.pdf" \ -F "tags=技术文档,产品"2. 智能问答接口 (Chat with Knowledge Base)
import requests import json url = "http://localhost:8080/api/chat/completions" headers = { "Content-Type": "application/json", "Authorization": "Bearer YOUR_TOKEN" } payload = { "message": "如何在 SpringBoot 中配置多数据源?", "conversationId": "optional_session_id", # 用于多轮对话 "stream": False # 是否流式输出 } response = requests.post(url, headers=headers, data=json.dumps(payload), timeout=60) if response.status_code == 200: answer_data = response.json() print(f"答案: {answer_data.get('answer')}") print(f"参考来源: {answer_data.get('sources')}") else: print(f"请求失败: {response.status_code}, {response.text}")6.2 批量任务处理
初始化知识库时,往往需要处理成百上千份文档。系统应支持批量上传或指定目录扫描。
最佳实践:
- 编写脚本批量调用上传 API:遍历文档目录,依次调用上传接口。
- 关注异步处理:大批量文档向量化耗时较长,确保后端有异步任务队列(如 Spring
@Async)处理,避免 HTTP 请求超时。 - 监控与重试:脚本中应加入日志记录和失败重试机制。
- 数据库索引优化:在批量导入前,可以为向量字段创建索引(如
ivfflat或hnsw),但建议在数据导入后再创建,以提高索引构建效率和质量。CREATE INDEX ON document_chunks USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
7. 资源占用与性能观察
系统运行后,需要关注以下几个关键性能指标。
内存占用:
- Java 后端:使用
jconsole、jvisualvm或top命令观察。SpringBoot 应用本身内存占用在 500MB-2GB 不等,取决于 JVM 参数和加载的模型。 - PostgreSQL:向量检索是内存密集型操作。使用
pg_top或查询pg_stat_activity监控。确保服务器有足够空闲内存(>总向量数据大小的1/3)。 - Embedding 模型:首次加载模型到内存会占用较多空间(例如
bge-small-zh约几百MB)。后续每次调用会占用 CPU/GPU 计算资源。
- Java 后端:使用
响应时间:
- 问答延迟:拆分为检索时间(PGVector查询)和生成时间(LLM API调用)。可在后端日志中打点记录,或通过前端网络面板查看接口耗时。
- 优化检索:PGVector 的索引类型 (
ivfflat,hnsw) 和参数 (lists,m,ef_construction) 对检索速度和精度有巨大影响。需要根据数据量和精度要求进行调优。
并发能力:
- 使用压力测试工具(如 JMeter)模拟多用户并发提问,观察系统响应时间和错误率。瓶颈通常出现在数据库检索或 LLM API 调用上。
8. 常见问题与排查方法
部署和运行过程中,你可能会遇到以下问题。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 后端启动失败,数据库连接错误 | 1. PostgreSQL 服务未启动。 2. 数据库连接配置错误(IP、端口、用户名、密码)。 3. PGVector 扩展未在目标数据库创建。 | 1. 检查 PostgreSQL 服务状态。 2. 使用 psql命令行手动连接测试。3. 在目标数据库中执行 \dx查看扩展列表。 | 1. 启动服务。 2. 修正 application.yml配置。3. 执行 CREATE EXTENSION vector;。 |
| 上传文档后,一直显示“处理中” | 1. 文档解析失败(不支持的格式或损坏)。 2. Embedding 模型下载失败或加载出错。 3. 异步任务队列未正常工作。 | 1. 查看后端日志中的错误堆栈。 2. 检查网络,确认模型能否正常下载。 3. 检查是否有 @Async线程池配置。 | 1. 尝试上传 TXT 格式简单文档测试。 2. 手动下载模型文件到本地指定路径。 3. 检查并配置线程池。 |
| 问答接口返回错误或超时 | 1. LLM API Key 无效或额度不足。 2. LLM API 网络不通。 3. 检索出的上下文过长,超出 LLM 令牌限制。 | 1. 检查 API Key 配置和环境变量。 2. 使用 curl直接测试 LLM API 端点。3. 查看日志中发送给 LLM 的最终 prompt 长度。 | 1. 更换或充值 API Key。 2. 配置网络代理或更换可用区域。 3. 调整检索返回的文本块数量或大小。 |
| 问答答案与文档无关(胡编乱造) | 1. 向量检索相似度阈值设置过低,检索到了不相关文本。 2. Embedding 模型不适合当前领域文本。 3. LLM 的 system prompt指令不够强。 | 1. 查看检索到的源文本和相似度分数。 2. 尝试不同的 Embedding 模型(如 bge-large-zh)。3. 检查并优化系统提示词,强调“仅根据上下文回答”。 | 1. 提高相似度阈值过滤。 2. 更换或微调 Embedding 模型。 3. 强化系统指令,使用 RAG 专用 prompt 模板。 |
| 前端访问后端 API 跨域错误 | 后端未配置 CORS 或配置不正确。 | 浏览器开发者工具 Console 和 Network 面板查看错误。 | 在后端 SpringBoot 配置类中添加全局 CORS 配置。 |
| 向量检索速度很慢 | 1. 数据量增大,未使用索引或索引低效。 2. PostgreSQL 配置参数(如 shared_buffers,work_mem)过低。 | 1. 使用EXPLAIN ANALYZE分析查询计划。2. 检查 PostgreSQL 配置。 | 1. 为向量列创建合适的hnsw索引。2. 根据服务器内存调整 PostgreSQL 配置。 |
9. 最佳实践与使用建议
为了让系统更稳定、高效地运行,遵循以下建议:
文档预处理是关键:
- 格式统一:尽量将文档转换为纯文本或 Markdown 格式,去除无关的排版信息。
- 智能分块:不要简单按固定长度分块。尝试按段落、标题进行语义分块,保证块的完整性。
- 添加元数据:为每个文本块附加来源、标题、章节等元数据,便于检索和溯源。
Embedding 模型选型:
- 中文场景优先选择
BAAI/bge系列模型。 - 如果领域专业性强(如医学、法律),考虑使用领域数据对通用 Embedding 模型进行微调。
- 中文场景优先选择
检索策略优化:
- 混合检索:结合向量检索(语义)和关键词检索(BM25),提升召回率。
- 重排序:使用更精细的模型(如
bge-reranker)对初步检索结果进行重排序,提升精度。 - 元数据过滤:允许用户按文档类型、部门等元数据过滤检索范围。
LLM 提示工程:
- 设计强大的
system prompt,明确指令模型“严格依据提供的上下文回答”,并定义无法回答时的回应方式。 - 在
user prompt中清晰地将“问题”和“上下文”分隔开。
- 设计强大的
系统监控与维护:
- 日志记录:详细记录问答日志,包括用户问题、检索到的源、生成的答案,用于效果分析和迭代优化。
- 知识库更新:建立定期或触发式的知识库更新机制,确保信息时效性。
- 效果评估:定期抽样测试,评估问答准确率、相关性等指标。
这个基于 SpringAI + SpringBoot + Vue + RAG + PGVector 的企业知识库项目,提供了一个从技术选型到落地实现的完整范本。它最大的优势在于技术栈成熟、架构清晰、可扩展性强。你可以基于此,轻松替换其中的任何一个组件——比如将 Embedding 模型从 OpenAI 换成本地模型,将 LLM 从 GPT 换成通义千问或本地部署的 Qwen,甚至扩展支持更多的文档类型和检索算法。
部署过程中,最可能遇到的坑集中在环境配置(数据库、PGVector)和网络连接(LLM API)上。按照本文的步骤,先确保数据库和 PGVector 就绪,然后让后端服务跑起来,最后再调试前端和复杂的问答逻辑,能帮你快速定位问题。
建议你先用一两篇简单的 TXT 文档完成从上传到问答的端到端流程验证,打通整个链路。之后,再逐步深入优化分块策略、调整检索参数、完善前端交互。当你看到系统能准确地从自己上传的公司制度里找到年假规定时,这个项目的价值就真正体现出来了。