Hybride zoeken in Pinecone en pgvector
Configureer hybride zoekopdrachten in Pinecone met de sparse-dense-indexmodus en in pgvector met parallelle queries en RRF-samenvoeging, en benchmark de retrievalkwaliteit op uw dataset.
Hybride zoeken in Pinecone en pgvector is een gratis AI Engineering Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject AI Engineering Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus AI Engineering Academy bevat in totaal 4 lessen.
Ingebouwd hybride zoeken in vectordatabases
Hoewel je hybride zoeken zelf kunt implementeren met twee afzonderlijke indexen en RRF-fusie, bieden vectordatabases voor productie steeds vaker ingebouwd hybride zoeken dat schaarse en dichte retrieval in één query afhandelt. Zowel Pinecone als pgvector ondersteunen hybride modi, maar met verschillende architectuurkeuzes en afwegingen. Als je beide opties begrijpt, kun je het juiste hulpmiddel voor je infrastructuur kiezen.
Pinecone-modus voor schaarse en dichte indexen
Pinecone ondersteunt een schaarse-dichte index waarin elk vectorrecord zowel een dichte embedding (als een array met floats) als een schaarse vector (als een woordenboek met token-ID's en gewichten) opslaat. Queries kunnen zowel een dichte queryvector als een schaarse queryvector specificeren, waarna Pinecone de resultaten samenvoegt met een gewogen lineaire combinatie. Dit verschilt van RRF: Pinecone gebruikt fusie van onbewerkte scores met configureerbare gewichten die alpha worden genoemd.
from pinecone import Pinecone, ServerlessSpec
pc = Pinecone(api_key='YOUR_API_KEY')
# Create a sparse-dense index
pc.create_index(
name='hybrid-index',
dimension=1536, # dense vector dimension
metric='dotproduct', # must use dotproduct for hybrid
spec=ServerlessSpec(cloud='aws', region='us-east-1'),
)
index = pc.Index('hybrid-index')Schaarse vectoren genereren met SPLADE
Om de schaarse-dichte modus van Pinecone te gebruiken, moet je voor elk document schaarse vectoren genereren. De effectiefste aanpak is SPLADE (Sparse Lexical and Expansion), een neuraal model dat geleerde schaarse representaties met uitbreiding produceert. Het voegt semantisch verwante termen toe aan de schaarse vector naast de termen die letterlijk in de tekst voorkomen. Je kunt ook eenvoudige BM25-termgewichten als schaarse vectoren gebruiken.
from transformers import AutoTokenizer, AutoModelForMaskedLM
import torch
# Load SPLADE model
tokenizer = AutoTokenizer.from_pretrained('naver/splade-cocondenser-ensembledistil')
model = AutoModelForMaskedLM.from_pretrained('naver/splade-cocondenser-ensembledistil')
def generate_sparse_vector(text: str) -> dict:
tokens = tokenizer(text, return_tensors='pt', truncation=True, max_length=512)
with torch.no_grad():
output = model(**tokens)
logits = output.logits
# Max-pool over sequence length and apply log1p activation
sparse = torch.max(torch.log1p(torch.relu(logits)), dim=1).values.squeeze()
# Return non-zero indices and values as a sparse dict
nz_indices = sparse.nonzero().squeeze().tolist()
nz_values = sparse[nz_indices].tolist()
return {'indices': nz_indices, 'values': nz_values}Hybride vectoren upserten naar Pinecone
Elk Pinecone-record in een hybride index bevat een id, een dichte array values, een woordenboek sparse_values met indices en values, en optionele metadata. Upsert records in batches van 100 om de doorvoer te maximaliseren en binnen de limieten voor de aanvraaggrootte van Pinecone te blijven.
def upsert_hybrid_docs(index, documents: list[dict], batch_size: int = 100):
records = []
for doc in documents:
dense_vec = embed(doc['text']) # OpenAI embedding
sparse_vec = generate_sparse_vector(doc['text']) # SPLADE
records.append({
'id': doc['id'],
'values': dense_vec,
'sparse_values': sparse_vec,
'metadata': {'text': doc['text'], 'source': doc['source']},
})
for i in range(0, len(records), batch_size):
batch = records[i:i + batch_size]
index.upsert(vectors=batch)
print(f'Upserted batch {i//batch_size + 1}')De hybride Pinecone-index bevragen
Een hybride query geeft zowel een dichte vector als een sparse_vector door aan de Pinecone-query-API. De alpha-parameter (0 tot 1) bepaalt de balans: alpha=1.0 is volledig dicht, alpha=0.0 is volledig schaars en alpha=0.5 geeft beide hetzelfde gewicht. Stem alpha af op een validatieset; optimale waarden liggen meestal tussen 0,3 en 0,7.
def hybrid_query_pinecone(index, query: str, alpha: float = 0.5, top_k: int = 5):
dense_vec = embed(query)
sparse_vec = generate_sparse_vector(query)
# Scale vectors by alpha for weighted fusion
scaled_dense = [v * alpha for v in dense_vec]
scaled_sparse = {
'indices': sparse_vec['indices'],
'values': [v * (1 - alpha) for v in sparse_vec['values']],
}
results = index.query(
vector=scaled_dense,
sparse_vector=scaled_sparse,
top_k=top_k,
include_metadata=True,
)
return results.matchespgvector: zoeken naar vectoren in PostgreSQL
De extensie pgvector voegt een kolomtype vector en afstandsoperatoren toe aan PostgreSQL. Voor hybride zoeken voer je twee queries parallel uit: een query voor benaderde naaste buren op de vectorkolom en een query voor zoeken in volledige tekst met PostgreSQL's ingebouwde tsvector en tsquery. Vervolgens voeg je de resultaten samen met RRF in je applicatiecode.
-- Setup: enable extensions
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
-- Create hybrid-capable table
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
embedding vector(1536),
content_tsv tsvector GENERATED ALWAYS AS (to_tsvector('english', content)) STORED
);
-- Indexes for both search modes
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);
CREATE INDEX ON documents USING GIN (content_tsv);Dichte en schaarse queries uitvoeren in pgvector
Voer met pgvector de dichte query uit met de cosinusafstandoperator <=> om de naaste buren van de query-embedding te vinden, en de schaarse query met ts_rank_cd tegen de kolom tsvector om overeenkomsten met trefwoorden te scoren. Haal beide resultatensets onafhankelijk op en voeg ze vervolgens met RRF samen in Python.
import psycopg2
import json
def pgvector_hybrid_search(conn, query: str, top_k: int = 5):
dense_vec = embed(query)
tsquery = ' & '.join(query.split()) # simple AND query
# Dense query
dense_sql = '''
SELECT id, content, 1 - (embedding <=> %s::vector) AS score
FROM documents
ORDER BY embedding <=> %s::vector
LIMIT 20
'''
# Sparse query
sparse_sql = '''
SELECT id, content, ts_rank_cd(content_tsv, to_tsquery('english', %s)) AS score
FROM documents
WHERE content_tsv @@ to_tsquery('english', %s)
ORDER BY score DESC
LIMIT 20
'''
with conn.cursor() as cur:
cur.execute(dense_sql, [json.dumps(dense_vec), json.dumps(dense_vec)])
dense_rows = cur.fetchall()
cur.execute(sparse_sql, [tsquery, tsquery])
sparse_rows = cur.fetchall()
return fuse_with_rrf(dense_rows, sparse_rows, top_k)RRF toepassen op pgvector-resultaten
Nadat je gerangschikte rijen uit beide PostgreSQL-queries hebt verzameld, pas je RRF toe door document-ID's in rangorde uit elke resultatenset te halen en het fusi algoritme uit te voeren. De uiteindelijke samengevoegde lijst geeft je de top-K-documenten die het relevantst zijn voor zowel de semantische betekenis als de overlap van trefwoorden.
def fuse_with_rrf(dense_rows, sparse_rows, top_k: int = 5, k: int = 60):
from collections import defaultdict
doc_texts = {}
scores = defaultdict(float)
for rank, row in enumerate(dense_rows, start=1):
doc_id, text, _ = row
scores[doc_id] += 1.0 / (k + rank)
doc_texts[doc_id] = text
for rank, row in enumerate(sparse_rows, start=1):
doc_id, text, _ = row
scores[doc_id] += 1.0 / (k + rank)
doc_texts[doc_id] = text
ranked = sorted(scores.items(), key=lambda x: x[1], reverse=True)
return [{'id': doc_id, 'text': doc_texts[doc_id], 'rrf_score': s}
for doc_id, s in ranked[:top_k]]De kwaliteit van retrieval benchmarken
Benchmark hybride zoeken na de implementatie grondig ten opzichte van je basislijn met alleen dichte retrieval. Gebruik een gouden testset met minstens 100 queries waarvan de relevante documenten bekend zijn. Meet NDCG@5, MRR en hit rate@3. Typische verbeteringen door hybride zoeken liggen voor NDCG@5 tussen 5 en 20 procent, met de grootste winst bij queries met exacte technische termen die dichte modellen missen.
def evaluate_retrieval(search_fn, test_queries, golden_relevant, k=5):
ndcg_scores = []
hit_count = 0
for query, relevant_ids in zip(test_queries, golden_relevant):
results = search_fn(query, top_k=k)
retrieved_ids = [r['id'] for r in results]
# Hit rate
if any(rid in relevant_ids for rid in retrieved_ids):
hit_count += 1
# Simplified NDCG (binary relevance)
dcg = sum(
1.0 / (i + 1)
for i, rid in enumerate(retrieved_ids)
if rid in relevant_ids
)
idcg = sum(1.0 / (i + 1) for i in range(min(len(relevant_ids), k)))
ndcg_scores.append(dcg / idcg if idcg > 0 else 0)
return {
'hit_rate': hit_count / len(test_queries),
'ndcg': sum(ndcg_scores) / len(ndcg_scores),
}Alpha afstemmen in de hybride modus van Pinecone
Voor de alpha-parameter in de hybride query van Pinecone is systematische afstemming nodig. Stratificatie op querytype is een bruikbare aanpak: classificeer je testqueries als overwegend semantisch (parafrases, conceptueel) of overwegend lexicaal (exacte termen, codes) en meet de optimale alpha afzonderlijk voor elke groep. Sommige productiesystemen gebruiken dynamische alpha-selectie, waarbij de query tijdens runtime wordt geclassificeerd en automatisch de juiste alpha wordt gekozen.
def find_optimal_alpha(index, test_queries, golden_relevant, alphas=None):
if alphas is None:
alphas = [0.0, 0.2, 0.4, 0.5, 0.6, 0.8, 1.0]
best_alpha, best_score = 0.5, 0
for alpha in alphas:
hits = 0
for query, relevant in zip(test_queries, golden_relevant):
results = hybrid_query_pinecone(index, query, alpha=alpha, top_k=5)
if any(r['id'] in relevant for r in results):
hits += 1
hit_rate = hits / len(test_queries)
print(f'alpha={alpha}: hit_rate={hit_rate:.3f}')
if hit_rate > best_score:
best_score, best_alpha = hit_rate, alpha
return best_alphaKiezen tussen hybride Pinecone en pgvector
Gebruik hybride Pinecone wanneer je beheerde infrastructuur en automatische schaalvergroting nodig hebt en de complexiteit van het genereren van schaarse vectoren aan één API wilt uitbesteden. Gebruik hybride pgvector wanneer je al PostgreSQL-infrastructuur hebt, transactionele consistentie tussen documenten en hun metadata nodig hebt, volledige SQL-flexibiliteit voor filtering wilt of afhankelijkheid van één leverancier wilt vermijden. Beide benaderingen leveren bij een juiste afstemming uitstekende hybride retrievalkwaliteit.
Korte controle
Test je begrip van de implementatie van hybride zoeken uit deze les.
Samenvatting van de les
In deze les heb je geleerd: de schaarse-dichte modus van Pinecone slaat zowel dichte als schaarse vectoren per record op en voegt ze samen met een configureerbare alpha-parameter, hybride zoeken met pgvector combineert zoeken in volledige SQL-tekst met vectorqueries die in applicatiecode met RRF worden samengevoegd, en het afstemmen van alpha op een validatieset is essentieel om de optimale balans voor je queryverdeling te vinden. Hierna verkennen we retrieval in twee fasen met herordening.
Leer Python met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 30
- Lessen
- 120
Veelgestelde vragen
Is de les “Hybride zoeken in Pinecone en pgvector” gratis?
Ja — de volledige tekst van “Hybride zoeken in Pinecone en pgvector” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus AI Engineering Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus AI Engineering Academy bevat in totaal 4 lessen.
Wat leer ik in “Hybride zoeken in Pinecone en pgvector”?
Configureer hybride zoekopdrachten in Pinecone met de sparse-dense-indexmodus en in pgvector met parallelle queries en RRF-samenvoeging, en benchmark de retrievalkwaliteit op uw dataset. Je oefent met AI Engineering Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met AI Engineering Academy te beginnen?
Ervaring vooraf is niet nodig. AI Engineering Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.
Hoe lang duurt de les “Hybride zoeken in Pinecone en pgvector”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over AI Engineering Academy?
Ja. Elke les over AI Engineering Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Dense versus sparse retrieval: afwegingen
- BM25-zoekopdrachten op trefwoorden implementeren
- Reciprocal Rank Fusion voor het samenvoegen van scores
- Hybride zoeken in Pinecone en pgvector