ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于Langchain4j与Spring Boot的RAG智能客服与工单系统实践

基于Langchain4j与Spring Boot的RAG智能客服与工单系统实践 这次我们来看一个把 RAG 落地到真实业务场景的 Java 技术栈项目基于 Langchain4j Spring Boot Vue RAG PGVector Embedding 的企业智能客服和工单处理系统。它解决的核心问题很明确企业内部的制度文档、产品手册、FAQ 散落在各处客服每次都要人工翻资料回答效率低、口径不一致。这个系统把文档统一进知识库用向量检索把最相关的片段捞出来再交给大模型生成回答回答解决不了时还可以自动生成工单流转给人工处理。对 Java 开发者来说这个项目最大的价值在于 RAG 不是 Python 生态的专利。Langchain4j 可以在 Spring Boot 里完成知识库构建、向量检索、大模型对话和工单处理的完整闭环。前端用 Vue 做对话界面和管理后台向量存储用 PostgreSQL 自带的 PGVector 插件不用额外维护 Milvus 等重组件。整条链路相对轻量适合企业内部工具、客服系统二次开发也适合作为 RAG 项目的工程化参考。本文会完整梳理这个系统的技术架构、知识库建设流程、环境准备、部署启动、功能验证、API 调用、资源占用和排错思路。内容以这套技术栈的通用落地方式展开具体端口、接口路径、模型名以你自己的项目配置为准。1. 核心能力速览能力项说明系统类型企业智能客服 工单处理 企业知识库后端技术栈Spring Boot Langchain4j前端技术栈Vue向量数据库PostgreSQL PGVector 插件嵌入模型文本 Embedding 模型可选用 Qwen Embedding 等大模型接入通过 Langchain4j 对接可配置不同模型供应商核心功能文档知识库管理、RAG 检索问答、多轮对话、工单生成与流转启动方式后端服务 前端项目分别启动需先初始化数据库部署形态本地开发环境或服务器 Docker 部署是否支持 API后端提供 REST 接口支持对话、知识库、工单等接口调用是否支持批量任务知识库支持批量导入文档工单支持批量状态处理推荐硬件调用云端大模型时普通开发机即可本地推理需按模型评估显存从技术栈看这个项目最值得关注的地方是它把 Java 后端、前端界面、RAG 检索和向量数据库组合成了一套可运营的企业客服系统。相比纯对话 Demo它有知识库管理、工单流转和用户界面更接近生产可用状态。2. 适用场景与使用边界2.1 适用场景这个系统适合以下场景企业内部客服员工咨询行政制度、IT 故障、人事政策时AI 先从知识库检索制度文档再给出带依据的回答。产品售前售后把产品 FAQ、规格参数、使用手册导入知识库减少人工重复回答。工单自动流转AI 无法解决的复杂问题根据用户描述自动生成工单分派给对应处理人。知识库统一管理通过 Vue 管理后台维护文档、分类、版本避免答案散落在聊天记录和 Excel 里。2.2 不适合什么这个系统也有明显的使用边界。需要实时性极强、准确率要求百分百的医疗、金融核心决策场景不能直接依赖大模型生成结果知识库文档格式极其复杂、包含大量扫描件和手写体时文本解析效果会受影响需要额外的 OCR 预处理对数据安全要求极高且不能调用外部模型的企业需要先确认是否自建 LLM 和 Embedding 服务。2.3 合规与安全边界使用这类 AI 客服系统必须注意上传到知识库的文档要确认具备使用和分发授权客服对话中涉及用户手机号、身份证、地址等个人信息时要做好脱敏和访问控制工单数据要按企业内部权限体系隔离。涉及人脸、声音、商标、版权素材等内容时更要在测试环境验证授权情况。工程交付时一定要把数据合规放进需求清单而不是等技术上线后再补救。3. 技术架构与核心组件3.1 整体链路整个系统的技术链路可以拆成三层。第一层是数据层。PostgreSQL 负责存储结构化业务数据同时通过 PGVector 插件保存文档片段的向量。文本先经过 Embedding 模型转成向量写入向量字段检索时把用户问题也转成向量用余弦距离或内积找回最相似的片段。第二层是服务层。Spring Boot 提供 REST API负责文件上传、文档解析、切片、向量化入库、客服对话、工单管理等。Langchain4j 在这里承担 RAG 编排和模型调用它负责把用户问题改写、调用检索器、拼装 Prompt、调用大模型并把检索片段作为上下文传给模型。第三层是表现层。Vue 前端包含客服对话窗口、知识库管理页、工单处理页、系统配置页。用户提出的问题通过后端接口进入 Langchain4j 流程最终把生成结果和引用片段返回给前端展示。3.2 Langchain4j 的角色Langchain4j 是 Java 生态里面向 LLM 应用的开发框架对标 Python 的 LangChain。项目里它负责四类事情大模型接入支持 OpenAI 兼容接口、通义千问、本地 Ollama 等多种模型供应商。Embedding 调用把文本转成向量调用嵌入模型时只需要配置 API Key 和模型名。提示词组装把用户问题、检索到的知识片段、系统指令拼成最终 Prompt。对话记忆保存多轮对话上下文让客服系统具备连续对话能力。3.3 PGVector 的定位PGVector 是 PostgreSQL 的向量检索扩展。选择它的好处是不用额外部署 Milvus、Weaviate 等独立向量数据库业务数据和向量数据可以在同一个数据库里管理。数据量在百万级以内、维度在 1024 或 1536 左右的场景PGVector 配合 IVFFlat 或 HNSW 索引足够支撑企业客服知识库的使用。4. RAG 知识库建设全流程RAG 的效果瓶颈往往不在模型而在知识库的数据质量。这个系统要建好知识库流程可以分成五步。4.1 文档加载先从 Vue 管理后台或接口上传文档支持 PDF、Word、TXT、Markdown 等常见格式。后端收到文件后需要先判断类型再用对应的解析器提取纯文本。PDF 如果本身是扫描件需要接入 OCR 组件Word 文档直接解析段落和表格TXT 和 Markdown 相对简单按行读取即可。这一步经常被低估实际项目里大部分失败案例都出在解析乱码、表格丢失、页眉页脚混入正文。建议上传后先让用户预览解析结果确认干净再入库。4.2 文本清洗解析出来的文本不一定适合直接向量化。要做的清洗包括去掉无意义的换行和多余空格过滤页眉页脚、水印、Logo 注释把表格转成可读的文本描述保持标题层级让后续切片保留语义完整性。4.3 文档切片切片策略直接决定检索召回质量。常见做法是按段落切也可以用固定窗口切窗口大小通常设定在 300 到 800 字之间并保留少量重叠。切得太短上下文不足切得太长向量表达不精准。对制度类文档更好的做法是优先识别标题层级保证一个切片尽量属于同一个章节。切完的每个片段就是一条知识记录保存内容包括标题、正文、分类、来源文档 ID 和向量。4.4 向量化入库清洗和切片完成后把每个片段文本发送给 Embedding 模型得到向量再写入 PostgreSQL。库表需要开启 vector 扩展字段类型用 vector 类型维度要和模型输出维度一致。写入完成后建立向量索引否则数据量上来后检索会明显变慢。4.5 检索召回用户提问时系统先把问题向量化然后在知识库中做相似度检索返回 Top K 片段。这里要注意不是相似度最高的片段就一定适合直接作为回答依据还需要根据业务情况设置一个最低相似度阈值。低于阈值的片段宁可不要避免大模型被不相关内容带偏答出错误信息。Top K 的数量也要根据切片长度和业务复杂度调整。知识库切片较短时Top K 可以设置在 5 到 8 之间保证上下文足够切片较长时Top K 建议减小避免上下文窗口被无关内容塞满。这里的取值没有绝对标准后续可以用评测集做对比。5. 环境准备与前置条件5.1 软件环境本地开发建议准备以下环境JDK 17 或 21Spring Boot 3.x 项目需要新版本 JDK。Node.js 16 以上用于启动 Vue 前端。PostgreSQL 14 以上并安装 PGVector 扩展。Maven 或 Gradle用于构建后端项目。一个可用的 Embedding 模型服务以及一个大模型服务。前面提到 Spring Boot 版本太高可能带来兼容性问题这一点在 Langchain4j 相关项目里尤其明显。更稳妥的做法是先看项目的 pom.xml 里 Langchain4j 版本对应支持的 Spring Boot 版本锁定基线后再升级。不要一上来就追最新的 Spring Boot 版本。5.2 数据库准备先创建数据库再启用 PGVector 扩展。以下 SQL 只是示例实际字段结构以你的项目实体为准CREATE DATABASE ai_customer; CREATE EXTENSION IF NOT EXISTS vector; CREATE TABLE knowledge_doc ( id BIGSERIAL PRIMARY KEY, title VARCHAR(255), category VARCHAR(64), content TEXT, embedding vector(1024), created_at TIMESTAMP DEFAULT now() ); CREATE INDEX ON knowledge_doc USING hnsw (embedding vector_cosine_ops);注意vector 的维度必须和 Embedding 模型的输出维度一致。示例写的是 1024如果用的是 Qwen Embedding 或其他模型要以模型文档为准。HNSW 索引适合中等数据量的精确率优先场景数据量小也可以暂时不建索引。5.3 模型服务准备Embedding 模型可以用 Qwen Embedding 等云服务也可以本地用 Ollama 拉取嵌入模型。大模型同理可以用云端兼容接口也可以本地部署。关键是把 API Key 和端点配置到后端配置文件中并确认网络连通。这一段没有给出具体显存数据因为是否吃显存完全取决于你本地是否跑模型。如果全部走云端 API开发机 16G 内存的普通配置就能跑如果本地跑 7B 以上大模型才需要重点评估显卡显存。5.4 环境常见坑Windows 下安装 PGVector 是一个高频问题。需要注意插件版本必须和 PostgreSQL 主版本一致16 和 14 的安装包不能混用。如果安装扩展时报错找不到控制文件优先检查插件目录是否被正确复制到 PostgreSQL 的 extension 目录。更省事的做法是直接用带 pgvector 的 Docker 镜像避免和本机 PostgreSQL 环境互相干扰。6. 本地部署与启动全流程6.1 后端配置以 Spring Boot 项目为例配置文件里至少要包含数据源、Langchain4j 模型配置。下面是一份示意配置属性名会随 Langchain4j 版本变化需要按实际依赖调整spring: datasource: url: jdbc:postgresql://localhost:5432/ai_customer username: postgres password: postgres driver-class-name: org.postgresql.Driver langchain4j: embedding-model: provider: qwen api-key: ${EMBEDDING_API_KEY} model: text-embedding-v2 chat-model: provider: openai-compatible api-key: ${LLM_API_KEY} model: qwen-plus base-url: ${LLM_BASE_URL}用环境变量管理 API Key不要硬编码在配置文件里提交到代码仓库。如果在本地调试可以放到 IDEA 的 Environment variables 中启动。6.2 启动后端先初始化数据库表结构。如果项目里有 Flyway 或 Liquibase 脚本直接执行迁移如果没有先把提供的 SQL 脚本在数据库客户端里跑一遍。然后启动 Spring Boot 服务# 以 Maven 为例实际命令按项目目录调整 cd backend mvn spring-boot:run启动完成后本地访问后端接口地址查看 Spring Boot 的日志输出。看到Started ... in x seconds说明启动成功。接下来先验证数据库连接正常再验证知识库表能读到数据。6.3 启动前端前端是 Vue 项目进入前端目录安装依赖并启动开发服务器cd frontend npm install npm run dev启动后按终端提示的地址访问页面。前端会通过代理把 /api 开头的请求转发到后端所以要先确认 vite.config.js 或 vue.config.js 里的代理配置指向了后端端口。常见联调问题是前端页面能打开但请求 404 或跨域优先检查代理配置。6.4 启动验证顺序建议顺序是先验证数据库再验证后端再验证前端最后验证一条完整问答链路。不要一上来就点页面里的对话测试那样出现问题很难定位是前端问题、后端问题还是模型配置问题。7. 功能测试与效果验证7.1 知识库管理功能验证先上传一份测试文档例如一份员工请假制度 PDF。上传后到知识库列表确认文档状态变为“已处理”点击预览查看解析出来的文本是否完整。然后确认切片数量合理并检查向量入库日志有没有报错。判断成功的标准文档解析无乱码切片数量符合预期数据库中能看到对应记录向量字段非空。7.2 RAG 问答验证在客服对话窗口输入问题例如“年假可以休几天”预期输出是回答内容来自知识库下方显示引用的文档片段。此时模型不仅仅是给出一个通用答案而是带着知识库片段的上下文在回答。验证时需要专门测试这几类问题可以直接从知识库回答的业务问题。知识库里没有、但模型常识可能回答的问题。知识库有相关内容但相似度较低的边缘问题。完全不在知识库范围内的无关问题。这几类问题决定 RAG 的边界好的系统应该能区分“知道”和“不知道”对不在知识库范围内的问题明确说明依据不足而不是强行编造。7.3 工单流转验证模拟一个 AI 无法回答的问题例如设备故障描述触发工单生成。检查工单是否带上了用户描述、对话上下文、分类标签并正确流转到对应处理人。然后在 Vue 的工单管理页面完成状态变更确认处理人、处理时间、处理结果都能记录。7.4 RAG 知识库指标验证很多同学问 RAG 知识库指标有哪些、怎么理解。实际测试至少要看四个维度命中率用户问题能否在知识库中检索到相关内容。命不中再好的生成能力也没用。召回质量检索返回的 Top K 片段是否相关排序是否合理。答案忠实度生成结果是否严格基于检索片段有没有自己发挥。端到端正确率把问答对整理成评测集人工判断回答是否正确。建议准备一份 50 到 100 条问题的评测集每次调整切片参数或提示词后跑一遍记录这几个指标的变化而不是靠感觉调参。7.5 多轮会话验证客服系统不是一问一答就结束。测试多轮会话时要确认系统能记住上一轮的信息。例如先问“年假有几天”再问“那病假呢”系统应该理解“呢”指代的是同类假期制度问题而不是当作一个全新问题处理。这部分依赖 Langchain4j 的对话记忆能力和 Prompt 设计如果多轮效果差优先检查记忆窗口长度和上下文压缩逻辑。8. 接口 API 与批量任务8.1 对话接口后端通常暴露一个对话接口。用 curl 快速验证curl -X POST http://localhost:8080/api/chat \ -H Content-Type: application/json \ -d {question:如何提交报销申请}返回结果一般包含 answer、references、conversationId 等字段具体以实际接口文档为准。接通后就可以把前端页面、企业微信、钉钉等入口接到同一个后端服务上。8.2 知识库批量导入批量导入知识库是生产必备能力。用 Python 脚本模拟批量上传import requests base_url http://localhost:8080/api/knowledge/upload files [ {path: ./docs/员工手册.pdf, category: HR}, {path: ./docs/产品FAQ.docx, category: 产品}, {path: ./docs/IT服务目录.pdf, category: IT}, ] for item in files: with open(item[path], rb) as f: resp requests.post( base_url, files{file: f}, data{category: item[category]}, timeout120, ) print(item[path], resp.status_code, resp.json())批量导入要注意两个问题一是文件过大时设置合理超时时间避免连接中断二是导入失败时要有重试机制和日志能够定位是哪一步失败。更规范的做法是把导入任务放进队列后台逐个处理并更新任务状态。8.3 工单接口工单接口通常包含创建、分派、更新状态、查询列表几个操作。AI 对话生成工单后人工处理人可以在工单页面更新状态。批量处理时用事务保证一致性不要出现处理人已修改但工单状态没更新的问题。8.4 接口鉴权建议对话和知识库接口如果直接暴露在公网知识库内容可能被未授权访问。更稳妥的做法是后端接口统一走登录鉴权对话接口至少做用户身份校验知识库上传和删除接口只对管理员开放。可以用 Spring Security 或 Sa-Token 这类框架实现Vue 端通过 token 携带用户信息。9. 资源占用与性能观察9.1 怎么观察资源项目启动后通过以下方式观察资源占用后端进程Windows 用任务管理器Linux 用top或htop看内存和 CPU。JVM 内存看 Spring Boot 日志里的内存配置或通过 Actuator 暴露的端点观察。PostgreSQL 查询耗时开启慢查询日志重点看向量检索 SQL 的耗时。Embedding 和 LLM 调用耗时在代码里对模型调用打点统计 P95 耗时。9.2 不同部署方式的差异如果 Embedding 和 LLM 全部走云端 API本地服务主要消耗的是 CPU 和内存对显卡没有硬性要求。文档解析和向量化入库时 CPU 会短暂升高属于正常现象。如果 LLM 部署在本地情况完全不一样。显存占用取决于模型参数量、上下文长度、并发数。同样一个模型4bit 量化和 16bit 精度对显存的要求差异很大。更稳妥的做法是先试用量化版本观察显存占用曲线再决定是否扩大上下文长度或提升并发。9.3 性能优化方向向量索引数据量上来后必须建 HNSW 或 IVFFlat 索引否则查询会线型扫描。切片长度切片太长向量表达变差太短检索上下文不足需要用评测集来定。并发控制大模型接口有并发限制后端要加信号量或线程池限流避免请求堆积。缓存常见问题的回答和检索结果可以做 Redis 缓存命中后不重复调用模型。10. 常见问题与排查方法问题现象可能原因排查方式解决方案后端启动失败数据库连接失败或 PGVector 扩展未安装查看启动日志中的异常堆栈检查数据库账号密码执行 CREATE EXTENSION vectorWindows 下 PGVector 安装失败没有对应 PostgreSQL 版本的预编译 DLL查看 PostgreSQL 版本与插件版本是否匹配下载对应版本安装包或直接用 Docker 镜像Spring Boot 版本太高导致自动配置不生效Langchain4j starter 与 Spring Boot 版本不兼容检查依赖树对比 Langchain4j 官方示例版本锁定兼容版本再升级前端页面打不开Node 依赖未安装或端口占用查看 npm 启动日志重新 npm install或修改 dev 端口对话接口 404前端代理未配置或后端端口不一致看浏览器 Network 面板请求地址修改 vite.config.js / vue.config.js 代理问答回答不在知识库内切片太粗或相似度阈值太低打印检索日志看召回片段调整切片长度、Top K 和相似度阈值知识库上传后没有内容文件解析失败或清洗异常查看后端日志确认解析步骤先预览解析结果检查 PDF 是否为扫描件批量导入任务卡住文件过大或模型接口超时查看日志是否有超时异常增加超时时间改用队列异步处理回答速度慢模型调用耗时长或查询无索引拆解耗时看是检索慢还是生成慢加缓存、建索引、限制并发工单状态更新丢失前端请求未传状态字段或事务未提交查看接口入参和后端日志完善参数校验和事务边界11. 最佳实践与使用建议第一次部署先用小参数跑通。上传一份小文档调通问答再逐步增加知识库规模不要在数据量很大的情况下边调索引边查问题。保留一套最小可运行配置。把数据库初始化 SQL、后端
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进