Building RAG with Pinecone vector database
Let's face it: when your corporate knowledge base grows to hundreds of thousands of documents, plain full-text search stops working — relevant documents drown in noise, and synonymous terms are ignored. RAG (Retrieval-Augmented Generation) with a vector database is the only way to maintain fast access to the right information. We build end-to-end RAG pipelines with Pinecone: from choosing the embedding model to production monitoring. Get a project estimate within a day: send us a description of your data and use cases. Get a consultation for your scenario — we'll evaluate your data in 1 day.
Why Pinecone Serverless?
Serverless mode eliminates cluster management: no pod reservations, no autoscaling configuration. You pay only for write, read, and storage operations — ideal for projects with variable load. Pinecone supports hybrid search (dense + sparse via BM25), which is critical for domains with high term precision (legal, medical). We use BM25Encoder to build sparse vectors without additional infrastructure. Typical infrastructure savings range from 20% to 40% compared to self-hosted solutions.
How we initialize the index
from pinecone import Pinecone, ServerlessSpec
from openai import OpenAI
pc = Pinecone(api_key="...")
# Creating a serverless index
pc.create_index(
name="corporate-knowledge-base",
dimension=3072, # text-embedding-3-large
metric="cosine",
spec=ServerlessSpec(
cloud="aws",
region="us-east-1"
)
)
index = pc.Index("corporate-knowledge-base")
Indexing documents with metadata
from langchain_openai import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
import hashlib
embeddings_model = OpenAIEmbeddings(model="text-embedding-3-large")
def index_documents(documents: list, batch_size: int = 100):
splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=64)
chunks = splitter.split_documents(documents)
for i in range(0, len(chunks), batch_size):
batch = chunks[i:i + batch_size]
texts = [c.page_content for c in batch]
vectors = embeddings_model.embed_documents(texts)
records = []
for chunk, vector in zip(batch, vectors):
doc_id = hashlib.md5(chunk.page_content.encode()).hexdigest()
records.append({
"id": doc_id,
"values": vector,
"metadata": {
"text": chunk.page_content,
"source": chunk.metadata.get("source", ""),
"page": chunk.metadata.get("page", 0),
"doc_type": chunk.metadata.get("doc_type", "general"),
"date": chunk.metadata.get("date", ""),
}
})
index.upsert(vectors=records)
print(f"Indexed batch {i//batch_size + 1}: {len(records)} chunks")
Querying with metadata filtering
def rag_query(
query: str,
doc_type_filter: str = None,
top_k: int = 5
) -> dict:
query_vector = embeddings_model.embed_query(query)
filter_dict = {}
if doc_type_filter:
filter_dict["doc_type"] = {"$eq": doc_type_filter}
results = index.query(
vector=query_vector,
top_k=top_k,
include_metadata=True,
filter=filter_dict if filter_dict else None
)
context_chunks = []
for match in results["matches"]:
context_chunks.append({
"text": match["metadata"]["text"],
"source": match["metadata"]["source"],
"score": match["score"]
})
return context_chunks
Implementing Hybrid Search
Pinecone supports hybrid search through built-in BM25. We train BM25 on the document corpus and use sparse vectors in queries. According to Pinecone Hybrid Search Guide, for this we use pinecone_text.sparse.BM25Encoder.
from pinecone_text.sparse import BM25Encoder
bm25 = BM25Encoder()
bm25.fit(all_texts)
def hybrid_query(query: str, alpha: float = 0.5, top_k: int = 5) -> list:
"""
alpha=1.0: only dense
alpha=0.0: only sparse (BM25)
alpha=0.5: equal weight
"""
dense_vector = embeddings_model.embed_query(query)
sparse_vector = bm25.encode_queries(query)
results = index.query(
vector=dense_vector,
sparse_vector=sparse_vector,
top_k=top_k,
include_metadata=True,
alpha=alpha,
)
return results["matches"]
Hybrid search gives a 15–30% recall boost over pure dense for domains with high terminological precision.
Case study: retailer corporate knowledge base
Scale: 45,000 SKU descriptions, 3,200 pages of regulations, 800 FAQ entries. Total ~180,000 vectors. Our client is a retail chain with 5+ years of automation experience.
Configuration: Pinecone Serverless (aws/us-east-1), dimension=1536 (text-embedding-3-small for cost savings), metric=cosine.
Usage pattern: 15,000 queries/day, peak load 200 RPS during sales events.
Results:
- Latency P95 for retrieval: 180 ms
- Latency P95 for full RAG response: 2.1 s (including GPT-4o-mini)
- Context recall (found relevant document): 0.87
- Answer accuracy (LLM-judge): 0.83
Optimizations:
- Namespace separation: products/regulations/FAQ in separate namespaces – allows filtering without overhead
- Metadata-only queries: for certain queries, filtering by metadata suffices without vector search
- Cache popular queries: Redis cache for top-500 frequent questions (~30% hit rate)
Pinecone vs alternatives
| Criteria | Pinecone | Weaviate | Chroma |
|---|---|---|---|
| Managed type | Fully | SaaS/self-hosted | Self-hosted |
| Hybrid search | Built-in BM25 | Built-in BM25 | Via external libraries |
| Serverless | Yes | No | No |
| Metadata filtering | Yes (all types) | Yes | Limited |
| Relative cost | Low | Medium | Free (self-host) + infra |
Pinecone outperforms Weaviate in variable load scenarios due to serverless, and Chroma lags in filtering functionality.
How to evaluate retrieval quality?
For objective retrieval evaluation, we use precision@k, recall@k, and NDCG metrics. On a test set of 500 queries with labeled relevant documents, we automatically compute these. Optimal values: precision@5 >= 0.85 and recall@10 >= 0.9. Additionally, we apply LLM-as-judge: GPT-4o evaluates whether the context is sufficient for answering. This helps identify chunking issues or embedding errors.
Checklist before launching RAG into production
- Verify metadata coverage: all documents have doc_type, source, date. - Tune alpha for hybrid search on a validation set. - Set budget guardrails: LLM token limits and number of retrieval results. - Configure monitoring: latency p99 retrieval, HTTP error rate, embedding drift. - Conduct load testing: target 80% of peak load.What's included in the work
- Data audit: source analysis, chunking strategy, metadata schema design.
- Index schema design: dimension, metric, serverless configuration.
- Indexing pipeline development: batch processing, deduplication, metadata enrichment.
- RAG pipeline: integration with LLM (GPT-4o, Claude, LLaMA), prompt engineering, hallucination guardrails.
- Testing and monitoring: precision/recall, latency p99, LLM-as-judge.
- Documentation and training: model card, developer guide, access transfer.
- Maintenance: 3-month warranty, SLA for incidents.
Estimated timelines
| Stage | Duration |
|---|---|
| Pinecone setup + ingestion pipeline | 3–5 days |
| RAG pipeline with quality evaluation | 1–2 weeks |
| Production optimization | 1–2 weeks |
| Total | 2–5 weeks |
Pricing is calculated individually based on data volume, number of sources, and integration complexity. Contact us for a project estimate — we'll discuss details and prepare a commercial proposal within a day.







