最近在帮一家金融企业搭建内部知识库问答系统时,我选择了Java技术栈配合LangChain4j框架实现RAG(检索增强生成)方案。这个选择主要基于两点考虑:一是企业现有系统基本都是Java技术栈,二是LangChain4j 1.0.0版本对Java生态的RAG支持已经相当成熟。
这个系统的主要功能是将企业内部的各种合规文档(PDF、Word等)转化为可查询的知识库,员工可以直接用自然语言提问获取精准答案,而不是在成堆的文档中手动查找。比如可以问"员工出差报销标准是多少?"或者"违反数据安全规定的处罚措施有哪些?",系统会基于上传的文档内容给出准确回答。
RAG(检索增强生成)相比纯LLM方案有几个明显优势:
在实际测试中,我们对比了直接提问大模型和使用RAG的效果。当问"我司2024年新修订的差旅标准是什么?"时:
选择LangChain4j而不是Python版的LangChain,主要考虑:
使用Ollama本地部署模型,避免数据外泄风险:
对比了三种方案后选择PGVector:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| PGVector | 无需额外运维,与企业现有PG兼容 | 性能不如专用向量库 | 文档量<100万 |
| Milvus | 高性能,支持高级检索 | 运维复杂 | 超大规模向量 |
| Chroma | 开发友好 | 不适合生产 | 原型开发 |
文档处理是RAG系统的核心,我们的管道设计如下:
解析阶段:
切片阶段:
向量化阶段:
存储阶段:
基础检索容易遇到两个问题:
我们的解决方案:
java复制// 混合检索配置
DefaultRetrievalAugmentor.builder()
.queryTransformer(new CompressingQueryTransformer(chatModel)) // 问题重写
.contentRetriever(vectorRetriever)
.reranker(new BgeReranker()) // 重排序
.build();
使用AiServices的声明式接口大大简化了代码:
java复制@AiService
public interface ComplianceAssistant {
@SystemMessage("""
你是一位专业的企业合规顾问,回答必须:
1. 严格基于提供的文档内容
2. 未找到内容时明确说明
3. 引用具体文档来源
""")
String ask(String question);
}
针对大文档处理做了以下优化:
异步处理:
批量处理:
缓存机制:
通过以下措施提升问答准确率:
Prompt工程:
参数调优:
后处理:
问题表现:
解决方案:
问题表现:
解决方案:
java复制if(retrieveResults.isEmpty()) {
return "未找到相关规定";
}
问题表现:
解决方案:
生产环境部署方案:
code复制[前端]
↓ HTTP
[Spring Boot API] ←→ [PGVector]
↓ gRPC
[Ollama集群]
├─ Qwen3:8B (对话)
└─ Nomic-embed-text (向量化)
关键配置:
上线后的关键指标:
| 指标 | 目标 | 实际 |
|---|---|---|
| 问答准确率 | >85% | 92% |
| 平均响应时间 | <3s | 1.8s |
| 并发能力 | 50+ | 100+ |
| 文档处理速度 | 100页/分钟 | 150页/分钟 |
典型用户问题示例:
问:"销售团队差旅报销标准是什么?"
答:
code复制根据《2023年差旅费用管理办法》第三章第五条规定:
1. 国内出差:
- 一线城市:住宿费≤600元/晚
- 其他城市:≤400元/晚
- 餐饮补贴:100元/天
2. 国际出差:
- 欧美地区:≤150美元/晚
- 亚洲地区:≤100美元/晚
(来源:财务部2023年12月修订版)
现有系统还可以进一步扩展:
多模态支持:
智能推荐:
权限控制:
反馈学习:
这个项目让我深刻体会到,在企业级应用中,RAG方案相比纯LLM有显著优势,特别是在数据安全和答案准确性方面。Java生态虽然AI工具链不如Python丰富,但通过LangChain4j也能构建出强大的生产级应用。