跪拜 Guibai
← All articles
Frontend · JavaScript

A Six-Step RAG Pipeline That Turns a Chinese Martial-Arts Epic into a Queryable AI Encyclopedia

By 默_笙 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

This walkthrough demystifies the full RAG stack for developers who have only seen toy examples. It shows the exact parameters, schema design, and prompt engineering needed to turn a long-form text into a reliable, citation-backed Q&A system—a pattern that transfers directly to internal documentation, legal contracts, or any proprietary knowledge base.

Summary

A full RAG pipeline built in JavaScript processes the classic wuxia novel "Demi-Gods and Semi-Devils" from EPUB to answer. LangChain's EPubLoader splits the book by chapter, a RecursiveCharacterTextSplitter breaks chapters into 500-character overlapping chunks, and each chunk gets a 1024-dimension embedding before insertion into a Milvus vector database with IVF_FLAT indexing and cosine similarity search. When a user asks "What martial arts does Duan Yu know?", the system retrieves the top three semantically relevant snippets and feeds them into an LLM prompt that constrains the model to answer only from the provided text.

The pipeline is generic: swap the EPUB file or the Loader type to ingest PDFs, CSVs, or other document formats. The Milvus collection schema tracks book ID, chapter number, and chunk index alongside the vector and raw content, making it straightforward to support multiple books in a single knowledge base. The streaming approach processes one chapter at a time to avoid loading the entire book into memory.

Takeaways
EPubLoader with splitChapters: true automatically splits an EPUB into one Document per chapter, eliminating manual pre-processing.
RecursiveCharacterTextSplitter at chunkSize=500 with overlap=50 preserves semantic coherence across chunk boundaries.
Streaming chapter-by-chapter processing avoids memory pressure when ingesting large texts.
Each chunk receives a 1024-dimension embedding via OpenAI's text-embedding-v3 before insertion into Milvus.
The Milvus collection stores both the vector and metadata (book ID, chapter number, chunk index, raw content) for precise source attribution.
IVF_FLAT indexing with COSINE similarity metric keeps search latency at millisecond scale even as the dataset grows.
The retrieval step fetches the top 3 chunks by cosine similarity and injects them into a prompt that instructs the LLM to answer only from the provided excerpts.
Switching to a different book or document format requires only changing the file path or Loader type—the rest of the pipeline stays identical.
Conclusions

The prompt design is the unsung hero here: it explicitly tells the model to admit ignorance when excerpts lack relevant information, which is the difference between a trustworthy knowledge base and a hallucination-prone chatbot.

Storing chapter and chunk metadata alongside vectors turns the database into an audit trail—every answer can be traced back to a specific passage, a capability that enterprise compliance use cases demand.

The 500-character chunk size is a pragmatic sweet spot: large enough to carry context for a martial-arts move description, small enough that retrieval precision doesn't degrade into noise.

Concepts & terms
RAG (Retrieval-Augmented Generation)
A technique that retrieves relevant documents or text chunks from a knowledge base and injects them into an LLM's prompt, grounding the model's answer in specific source material rather than relying solely on its training data.
IVF_FLAT
A vector index type in Milvus that uses inverted file clustering to partition the vector space, then performs flat (exact) search within the nearest clusters. It trades a small amount of recall for much faster query times compared to brute-force search.
Cosine Similarity
A metric that measures the cosine of the angle between two vectors, commonly used in semantic search to rank how similar two pieces of text are. Values range from -1 to 1, with 1 meaning identical direction.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗