我用 LangChain4j 给公司做了一个知识库问答系统
2026-06-14 · 项目实战
记录一次用 LangChain4j 搭建内部知识库问答系统的完整实战过程:文档切分、向量存储、检索增强、效果评估。
标签:LangChain4j、RAG、Java、大模型、知识库
背景
公司内部的文档散落在各个地方:Confluence 有技术规范,Notion 有人事制度,飞书文档有业务流程。新人入职要找个东西,得翻好几个地方,烦得要死。
我想:能不能做一个统一的问答入口?

技术选型
- 大模型:公司内网能接内部的大模型服务,也能走 OpenAI 的 API
- 框架:我选了 LangChain4j,Java 世界里模仿 LangChain 做得比较好的
- 向量库:一开始用的内存存储,后来换成了 Redis 向量搜索
- 文档切分:LangChain4j 自带的 DocumentSplitter
核心流程
1. 文档切分
先把各种文档读进来,切成若干"块"(chunk)。不能太大,不然上下文塞不下;也不能太小,不然信息不完整。我选的是 1000 字一块,重叠 200 字。
DocumentSplitter splitter = DocumentSplitters.recursive(1000, 200);
List<TextSegment> segments = splitter.split(document);
2. 向量化并入库
用 EmbeddingModel 把每一块文字变成向量,存到向量库里。
3. 构建 AI Service
这是 LangChain4j 里我觉得最好用的一个概念——AI Service。你定义一个 Java 接口,加上注解,框架会帮你生成实现。
遇到的坑
1. 文档切分太粗会丢信息
一开始我把块切得很大(2000 字),结果很多问题检索不到相关内容。切小一点之后效果好了不少,但块太小又会出现"信息被切断"的问题。这是一个需要反复调的参数。
2. 向量检索的相似度阈值不好定
相似度太高了召回不出来;太低了又会混入不相关的内容,反而影响回答质量。
3. 大模型有时候会"瞎编"
大模型经常在没有答案的时候编造一个听起来很合理的答案。我用了两个手段来缓解:在 SystemMessage 里反复强调"如果找不到答案就说找不到",以及做一个简单的"答案验证"。
效果评估
上线前我做了一个简单的评测:准备了 50 个真实的员工提问,然后由人工判断——回答准确 32 条(64%),部分正确 11 条(22%),错误 7 条(14%)。
这个结果算不上完美,但对于一个内部工具来说已经能用了。
下一步计划
- 引入多路检索:不仅仅靠向量,还要加关键词检索(BM25)
- 做引用标注:让大模型在回答中标注答案来自哪篇文档
- 加入反馈机制:用户可以给回答点"有用"或"没用"
写在最后
做这个项目给我最大的感受是:**做一个能跑起来的 AI 应用不难,但做一个好用的很难。