跪拜 Guibai
← All articles
Backend

A Production-Ready RAG Knowledge Base in ~500 Lines of Spring Boot and LangChain4j

By 神奇小汤圆 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

LangChain4j’s Spring Boot starter and BOM turn a RAG pipeline from a sprawling Python service into a single JVM module that fits existing Java shop infrastructure. The multi-knowledge-base isolation pattern shown here — one metadata field, one filter — is the simplest way to avoid cross-tenant leakage without standing up separate collections.

Summary

The system chains Apache Tika for document parsing, a sliding-window chunker with 200-character overlap, and DashScope’s text-embedding-v3 model for 1024-dimension vectors stored in Milvus. Multi-tenancy comes from a `knowledgeBaseId` metadata filter on every chunk, so HR, engineering, and product knowledge bases stay isolated inside a single vector store. Retrieval uses a Top-5 similarity search with a 0.6 minimum score, and the final prompt instructs the model to answer only from the provided context.

Both synchronous and streaming (SSE) endpoints are exposed. A content-safety layer blocks prompt-injection patterns and enforces input length limits, while a unified exception handler and standard `Result<T>` envelope keep the API predictable. The whole pipeline averages 800–1200 ms latency and 500–600 tokens per query.

A tuning table maps chunk size, overlap, Top-K, minScore, and temperature to their effects on precision, recall, and cost, with concrete remedies for common failure modes like irrelevant retrieval or answers taken out of context.

Takeaways
Apache Tika handles 30+ file formats, so the ingestion endpoint accepts PDF, Word, Excel, PPT, HTML, and Markdown with no format-specific code.
Chunking uses a fixed 1000-character window with a 200-character overlap; the overlap prevents semantic breaks at chunk boundaries.
DashScope’s text-embedding-v3 produces 1024-dimension vectors and enforces a 10-text batch limit, requiring manual batching in `embedAll`.
Every chunk carries a `knowledgeBaseId` metadata field; retrieval filters with `IsEqualTo` to isolate tenants inside a single Milvus collection.
Top-5 retrieval with a 0.6 minimum similarity score balances recall and precision; lowering minScore to 0.5 fixes missed retrievals.
Prompt injection defense is a simple keyword blocklist covering both English and Chinese patterns, plus a 4000-character input cap.
Streaming responses use Spring’s `SseEmitter` with a 30-second timeout, sending partial tokens as `message` events and sources as a final `sources` event.
Average end-to-end latency is 800–1200 ms; token consumption runs 500–600 per query, dominated by the context window.
Conclusions

The architecture treats the LLM as an OpenAI-compatible drop-in — DashScope’s compatible-mode endpoint means any provider exposing that API shape works without code changes.

Multi-tenancy via a single metadata filter is operationally cheaper than per-tenant collections but leaves no hard security boundary; a bug that omits the filter silently leaks data across knowledge bases.

The content-safety blocklist is trivially bypassed by any attacker who rephrases the banned strings, so it functions as a noise filter rather than a security control.

Chunking parameters are presented as a tuning table with concrete ranges, which is more actionable than the abstract advice most RAG guides offer.

Concepts & terms
RAG (Retrieval-Augmented Generation)
A pattern that retrieves relevant documents from a vector store and injects them into the LLM’s prompt so the model can answer from provided context rather than its training data.
LangChain4j
A Java port of the LangChain framework that provides Spring Boot auto-configuration, a BOM for dependency management, and declarative `@AiService` interfaces for calling LLMs.
Milvus
An open-source vector database that stores embeddings and supports metadata-filtered similarity search, used here to isolate multiple knowledge bases within a single collection.
Apache Tika
A content detection and extraction library that parses text from 30+ file formats (PDF, Office documents, HTML, etc.) through a uniform API.
SSE (Server-Sent Events)
A unidirectional streaming protocol over HTTP where the server pushes events to the client; used here to stream LLM tokens as they are generated.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗