news 2026/10/10 2:43:45

从 Java 后端到大模型应用:我把公司知识库问答从 0 到 1 搭了起来

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从 Java 后端到大模型应用:我把公司知识库问答从 0 到 1 搭了起来

去年公司要做智能客服知识库问答,这个活儿落到了我这个纯 Java 后端头上。从 “没碰过大模型” 到上线一套可用的 RAG 问答系统,过程记录在这里 —— 架构怎么设计、代码怎么写、坑怎么踩,Java 工程师可以直接参考。
一、需求与架构:先想清楚再动手
需求: 客服人员输入问题,系统基于公司知识库(产品手册、FAQ、流程文档)给出带来源的回答。
技术选型: RAG(检索增强生成)—— 不微调模型,给大模型外挂一个可检索的知识库。理由:随时更新、可溯源、成本低。
整体架构:
文档入库:Word/PDF → 解析 → 切分 → 向量化 → 存入向量库
在线问答:问题 → 向量检索TopK → 拼Prompt → 调大模型 → 回答(带来源)
服务层:Spring Boot 统一封装(API/超时/重试/成本监控)

二、文档入库:切分是第一个坑
文档切分看着简单,做错全盘皆输:
// DocChunker.java - 按段落切分+重叠窗口
public class DocChunker {
public List split(String doc, int chunkSize, int overlap) {
List chunks = new ArrayList<>();
String[] paragraphs = doc.split(“\n\n”); // 先按段落边界
StringBuilder buffer = new StringBuilder();

for (String p : paragraphs) { if (buffer.length() + p.length() > chunkSize) { chunks.add(buffer.toString()); // 保留尾部重叠,避免一句话被拦腰切断 buffer = new StringBuilder( buffer.substring(Math.max(0, buffer.length() - overlap))); } buffer.append(p).append("\n\n"); } if (buffer.length() > 0) chunks.add(buffer.toString()); return chunks; }

}

踩坑记录 1: 一开始按固定 500 字符切,产品参数表被切成两半,检索出来 “报价在表格下半截”。改成按段落边界切 + 重叠窗口后,检索质量明显提升。
三、向量检索:TopK 别拍脑袋
// Retriever.java - 向量化+相似度检索
@Service
public class Retriever {
private final EmbeddingClient embeddingClient;
private final VectorStore vectorStore;

public List<RetrievedDoc> retrieve(String question, int topK) { float[] qVec = embeddingClient.embed(question); List<RetrievedDoc> docs = vectorStore.search(qVec, topK); // 加Rerank重排:交叉编码器对结果二次排序,精度更高 return reranker.rerank(question, docs); }

}

踩坑记录 2: TopK=3 漏答案、TopK=10 全是噪声。最后建了 20 条测试问答做评测集,K=5 + 重排组合效果最好。没有评测集的调参,都是碰运气。
四、问答组装:系统提示词是关键
回答质量一半在提示词。核心是 “约束 + 溯源”:
// RagService.java - 完整问答链路
@Service
public class RagService {

public String answer(String question) { List<RetrievedDoc> contexts = retriever.retrieve(question, 5); String prompt = """ 你是企业知识库助手,只依据以下资料回答: 【资料】 %s 【问题】 %s 要求: 1. 资料中没有的信息,必须回答"未找到相关资料",不要编造 2. 回答时标注引用的资料来源(文档名+段落) 3. 回答控制在150字以内,客服口径,口语化 """.formatted( contexts.stream() .map(d -> "[" + d.source() + "] " + d.content()) .collect(Collectors.joining("\n---\n")), question); return llmClient.chat(prompt); }

}

踩坑记录 3: 没写 “没有就说没有” 之前,模型经常一本正经编答案;加上这条约束 + 强制标来源后,幻觉明显减少,客服反馈 “可信多了”。
五、工程化收尾:Java 后端的看家本领
大模型接入只是第一步,真正体现 Java 工程能力的在后面:
// 1. 统一封装:超时+错误码+退避重试
@Configuration
public class LlmConfig {
@Bean
public RestClient llmClient() {
return RestClient.builder()
.baseUrl(System.getenv(“LLM_API_URL”))
.defaultHeader(“Authorization”, "Bearer " + System.getenv(“LLM_API_KEY”))
.requestFactory(client -> client
.connectTimeout(Duration.ofSeconds(10))
.readTimeout(Duration.ofSeconds(60)))
.build();
}
}

// 2. 成本监控:token用量记录
@Component
public class TokenMeter {
private final MeterRegistry registry;

public void record(String model, int promptTokens, int completionTokens) { registry.counter("llm.tokens.prompt", "model", model).increment(promptTokens); registry.counter("llm.tokens.completion", "model", model).increment(completionTokens); // 按日聚合,超预算告警 }

}

// 3. 结果缓存:相同问题不重复调模型
@Cacheable(cacheNames = “qa”, key = “#question”)
public String answerCached(String question) {
return answer(question);
}

要点: 密钥走环境变量、请求全量超时、重试限次退避、token 记账、结果缓存 —— 这套工程规范,是 Java 后端做 AI 应用的核心优势。
六、复盘:Java 工程师学 AI 应用,到底学什么

能力重要度说明
大模型 API 调用★★★HTTP 封装,半天上手
RAG 检索增强★★★★★企业落地标配,本次核心
Prompt 设计★★★★约束 + 溯源,决定回答质量
上下文管理★★★★滑动窗口 + 摘要,多轮不爆
工程化★★★★★Java 后端天生优势

这套能力我是在 Java AI 实训里体系化补的 ——8 个月 32 周 7 阶段,14 个真实项目从 LangChain、RAG、Agent 到大模型应用,再到 Java 全栈微服务,把 “会调 API” 练成了 “能交付系统”。学 AI 应用对后端工程师来说,不是转行,是升级:把大模型工程化地接进业务系统,正是我们的活。
下一个版本,我准备给系统加 Agent 能力(让模型会调用内部工具查订单、算指标)。这条路,越走越宽。

Q:Java 做 AI 应用需要重新学语言吗?
A:不需要。大模型 API 就是 HTTP 接口,Java 工程能力(Spring Boot、缓存、监控)直接复用。企业系统接大模型,Java 反而是主力。
Q:RAG 系统和 “直接问大模型” 有什么区别?
A:大模型不知道公司私有资料。RAG 给模型外挂知识库:检索相关资料再回答,可更新、可溯源、成本低。企业落地 90% 场景是 RAG。
Q:检索质量怎么调?
A:三步:文档按语义边界切分、TopK 用评测集调、加 Rerank 重排。缺任何一步,检索都是碰运气。
Q:怎么减少模型幻觉?
A:系统提示词写 “没有就说没有”+ 强制标注来源 + 回答限长。三条一起上,幻觉显著减少。这是客服场景的必备配置。
本文为 Java 后端 AI 应用实践记录,观点仅代表个人。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 2:41:01

蓝牙芯片驱动开发-第3章第10题-PCM接口的时钟同步机制如何实现

蓝牙面试题解析:PCM 接口的时钟同步机制如何实现? 难度:⭐⭐⭐⭐ 较难 | 场景:社招二面/三面、蓝牙音频驱动 | 高频:🔥🔥🔥🔥 标准答案 PCM(脉冲编码调制)接口通过 主从模式 + 帧同步信号(FRM)+ 位时钟(BCLK) 实现精确的音频数据传输同步: ① PCM 接口信…

作者头像 李华
网站建设 2026/10/10 2:40:10

第二章 CAS机制(乐观锁的底层实现,面试核心)

定位&#xff1a;CAS 是乐观锁最典型的实现方式&#xff0c;也是整个JUC并发包的基石&#xff1b;原子类、自旋锁、ConcurrentHashMap都基于它。1. 什么是 CAS全称&#xff1a;Compare And Swap&#xff0c;比较并交换&#xff0c;是一条CPU硬件级别的原子指令。一次CAS操作包含…

作者头像 李华
网站建设 2026/10/10 2:39:48

连续机制演化下的因果表征学习:方法、实验与工程实践

因果表征学习这几年是越来越热了&#xff0c;但大部分人做的场景都是静态的&#xff1a;环境固定&#xff0c;机制不变&#xff0c;数据一趟学完。可真实世界里几乎没有一成不变的机制——政策会变、设备会老化、用户偏好会漂移。这类非平稳场景里&#xff0c;很多方法还是沿用…

作者头像 李华