Building a RAG Pipeline with LangChain: From Document Processing to Vector Search

Jun 15, 2026·
杨劲松
杨劲松
· 3 min read
blog

Retrieval-Augmented Generation (RAG) has become the standard approach for building AI applications that need to access specific knowledge bases. This guide walks through building a complete RAG pipeline from scratch using LangChain.

Above: Production RAG Pipeline — Document Ingestion → Embedding → Retrieval → Augmented Generation → Output

Table of Contents

  1. What is RAG?
  2. Document Processing
  3. Vector Storage
  4. Retrieval Strategies
  5. Hallucination Prevention
  6. Streaming Interface
  7. Production Considerations

What is RAG?

RAG combines the power of large language models with external knowledge retrieval:

User Query → Retrieval → Context + Query → LLM → Answer

This approach solves the core problem of LLMs: they can only answer based on their training data. RAG allows them to access up-to-date, domain-specific, or private information.

Document Processing

The first step is preparing your documents for retrieval:

from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import TokenTextSplitter

# Load documents
loader = PyPDFLoader("knowledge_base.pdf")
documents = loader.load()

# Split into chunks
text_splitter = TokenTextSplitter(
    chunk_size=500,
    chunk_overlap=50,
    encoding_name="cl100k_base"  # OpenAI tokenizer
)

chunks = text_splitter.split_documents(documents)

Key Considerations

  1. Chunk Size - Balance between context and retrieval accuracy
  2. Overlap - Prevent important information from being split across chunks
  3. Metadata - Preserve source information for attribution

Vector Storage

Store embeddings for efficient similarity search:

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Redis

# Initialize embeddings
embeddings = OpenAIEmbeddings()

# Create vector store
vector_store = Redis.from_documents(
    documents=chunks,
    embedding=embeddings,
    redis_url="redis://localhost:6379",
    index_name="knowledge_base"
)

Choosing a Vector Store

StorePerformanceFeaturesBest For
RedisHighReal-time updatesProduction
PineconeHighManaged serviceEnterprise
FAISSMediumLocal, freeDevelopment
ChromaMediumSimple setupPrototyping

Retrieval Strategies

Implement smart retrieval with LangChain:

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

# Basic similarity search
retriever = vector_store.as_retriever(
    search_type="similarity",
    search_kwargs={"k": 5}
)

# Advanced: Contextual compression
compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=retriever
)

Hallucination Prevention

Critical for production RAG systems:

from langchain.prompts import ChatPromptTemplate

system_prompt = """You are an agricultural expert. Answer questions based ONLY on the provided context. If the context doesn't contain enough information, say "I don't have enough information to answer this question."

Context: {context}
"""

prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    ("human", "{input}")
])

Three-Layer Prevention

  1. Retrieval Filtering - Only pass high-relevance documents
  2. Prompt Engineering - Force model to cite sources
  3. Output Validation - Verify responses against source data

Streaming Interface

Implement real-time responses with FastAPI:

from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import asyncio

app = FastAPI()

@app.post("/chat")
async def chat(query: str):
    async def generate():
        async for chunk in chain.astream({"input": query}):
            yield f"data: {chunk.content}\n\n"
            await asyncio.sleep(0.01)  # Simulate typing
        yield "data: [DONE]\n\n"
    
    return StreamingResponse(
        generate(),
        media_type="text/event-stream"
    )

Production Considerations

1. Error Handling

try:
    response = await chain.ainvoke({"input": query})
except Exception as e:
    logger.error(f"RAG error: {e}")
    return {"error": "Failed to generate response"}

2. Caching

from langchain.cache import RedisCache

cache = RedisCache(redis_url="redis://localhost:6379")
llm = OpenAI(cache=cache)

3. Monitoring

Track key metrics:

  • Retrieval accuracy
  • Response latency
  • User satisfaction
  • Hallucination rate

Conclusion

Building a production RAG system requires attention to:

  • Document Quality - Good preprocessing is crucial
  • Retrieval Strategy - Balance precision and recall
  • Hallucination Prevention - Multi-layered approach
  • User Experience - Streaming and error handling

The complete code is available on GitHub.


Questions? Reach out on GitHub or email me at yjs_0831@qq.com!

杨劲松
Authors
Java后端工程师 / AI应用开发

Java后端起步,正在转型AI应用/Agent开发者,让大模型落地到真实业务。

  • 🖥️ 技术方向 — Spring Boot微服务 + AI Agent应用
  • 🤖 当前专注 — 多智能体协同调度、RAG知识库
  • 🎯 目标 — 让企业软件从「点击操作」走向「自然对话」