From embedding choice to a working setup, with Claude as a sounding board
A vector database is quickly installed, but the pipeline around it decides retrieval quality and operating cost. Embedding model choice, chunking strategy, and the concrete configuration of pgvector, Pinecone, or Weaviate are tightly linked, and a mistake in one place ripples through the whole chain. This article shows how Claude concretely supports each of these steps, including setup code and the most common chunk-size pitfalls.
Table of Contents
- 1. Why the pipeline matters more than the database choice
- 2. Choosing an embedding model
- 3. Working through chunking strategies for long documents
- 4. Common pitfalls: chunks that are too large or too small
- 5. pgvector setup with Claude-generated code
- 6. Pinecone setup: managed infrastructure without self-hosting
- 7. Weaviate setup: hybrid search as a built-in feature
- 8. Combining metadata filtering and hybrid search
- 9. Monitoring and reindexing in ongoing operation
- 10. Summary
- 11. FAQ
1. Why the pipeline matters more than the database choice
Many teams start planning with the question of which vector database to use, overlooking that embedding model and chunking strategy have a far bigger impact on retrieval quality than the specific database. A poorly chunked document collection produces weak results in any database, while a well-built pipeline achieves solid results even on a simple configuration.
The order should therefore be reversed: first settle on an embedding model and chunking strategy for the actual documents, then choose the database to match scale, hosting requirements, and budget. Claude is well suited to keeping this order early, since chunking decisions can be worked through concretely against real sample documents before any infrastructure is locked in.
2. Choosing an embedding model
The choice of embedding model depends on language, domain, and cost per embedded token. Multilingual document collections need a model with proven multilingual quality, and technical or legal text benefits from models trained on comparable corpora. Embedding dimensionality further affects storage footprint and search speed: higher dimensions often deliver finer distinction but cost more storage and compute at query time.
Claude is useful for producing a reasoned shortlist from a sample of the actual documents: which terms appear frequently, how much documents differ in content, and how important multilingual coverage is. That analysis does not replace a benchmark with real test queries, but it narrows down the number of candidates that need testing at all.
Prompt to Claude for an embedding model shortlist:
Here are 5 sample documents from our technical documentation
(English, some domain-specific jargon): <examples>
Which embedding model categories (general vs. domain-specific,
dimension size) are likely the best fit, and which 3 candidates
should we test against each other with a real retrieval
benchmark?
3. Working through chunking strategies for long documents
Chunking decides whether a retrieval hit contains the relevant context in full or gets cut off mid-thought. Naive chunking by fixed character count ignores paragraph and chapter boundaries and regularly tears apart information that belongs together. Semantic chunking instead follows content boundaries such as headings, paragraphs, or list structures and keeps related statements together.
Claude can suggest, based on a concrete sample document, where content breaks naturally occur and where a chunk boundary does little damage. For structured documents such as API documentation or legal text with numbered sections, that analysis often yields usable chunk boundaries that go well beyond a fixed character count.
# Chunking with overlap, boundaries derived from headings
# (boundaries were clarified with Claude against sample documents beforehand)
import re
def chunk_by_headings(text: str, max_tokens: int = 400, overlap: int = 50):
sections = re.split(r"\n(?=#{1,3}\s)", text)
chunks = []
for section in sections:
words = section.split()
if len(words) <= max_tokens:
chunks.append(section.strip())
continue
start = 0
while start < len(words):
end = start + max_tokens
chunks.append(" ".join(words[start:end]))
start = end - overlap
return [c for c in chunks if c]
4. Common pitfalls: chunks that are too large or too small
Chunks that are too large often contain several unrelated topics at once, turning the embedding into a blurred average that no longer fits any of the contained questions precisely. Retrieval rate drops because semantically relevant chunks no longer rank high enough for specific queries. A frequent symptom: search finds generally relevant documents, but the concrete answer is missing from the returned excerpt.
Chunks that are too small, on the other hand, tear apart related information, for example splitting a condition from its exception into different chunks. Claude then appears to answer correctly but incompletely, because the relevant additional context is missing from retrieval. In practice, a chunk size of 200 to 500 tokens with 10 to 20 percent overlap has worked well for most prose documents, with notable exceptions for tabular or heavily structured content.
5. pgvector setup with Claude-generated code
For teams already running PostgreSQL, pgvector is often the most pragmatic choice, since no additional infrastructure is needed. Claude reliably generates the base setup: extension, table schema with a matching index, and a sample query that finds nearest neighbors via cosine distance.
When phrasing the prompt, it matters to include the expected data volume and the target behavior, for example whether an exact or approximate index is needed, since that determines whether Claude suggests an IVFFlat or HNSW index and how the corresponding parameters are chosen.
-- pgvector: extension, schema, and HNSW index
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE document_chunks (
id BIGSERIAL PRIMARY KEY,
document_id BIGINT NOT NULL,
chunk_text TEXT NOT NULL,
metadata JSONB DEFAULT '{}',
embedding VECTOR(1536) NOT NULL
);
CREATE INDEX ON document_chunks
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- Find nearest neighbors to a query embedding
SELECT id, chunk_text, 1 - (embedding <=> $1) AS similarity
FROM document_chunks
WHERE metadata->>'status' = 'active'
ORDER BY embedding <=> $1
LIMIT 8;
6. Pinecone setup: managed infrastructure without self-hosting
Pinecone fits when running a database yourself is something to avoid and scaling to several million vectors is on the horizon. Claude generates the client setup including index creation with the right metric and namespace structure, which matters especially for multi-tenant applications.
One point Claude reliably surfaces when asked: the distinction between namespaces for tenant isolation versus metadata filters for content filtering within a tenant, since the two mechanisms are easily confused and carry different cost implications.
from pinecone import Pinecone, ServerlessSpec
pc = Pinecone(api_key="PINECONE_API_KEY")
pc.create_index(
name="support-docs",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(cloud="aws", region="us-east-1"),
)
index = pc.Index("support-docs")
index.upsert(
vectors=[
{"id": "chunk-1", "values": embedding, "metadata": {
"document_id": "42", "status": "active", "product": "checkout"
}}
],
namespace="tenant-acme",
)
results = index.query(
vector=query_embedding,
top_k=8,
namespace="tenant-acme",
filter={"status": {"$eq": "active"}},
)
7. Weaviate setup: hybrid search as a built-in feature
Weaviate combines vector search and keyword search in one system, which is especially valuable for queries with exact product names or error codes that pure semantic search occasionally misses. Claude reliably generates the schema definition including vectorizer configuration and the matching GraphQL or Python query for hybrid search.
When phrasing the prompt, it is worth explicitly asking about the alpha parameter that weighs vector search against keyword search, since that value depends heavily on the specific use case and is often left at an arbitrary default in generic examples.
import weaviate
import weaviate.classes as wvc
client = weaviate.connect_to_local()
client.collections.create(
name="DocumentChunk",
vectorizer_config=wvc.config.Configure.Vectorizer.text2vec_openai(),
properties=[
wvc.config.Property(name="text", data_type=wvc.config.DataType.TEXT),
wvc.config.Property(name="product", data_type=wvc.config.DataType.TEXT),
],
)
collection = client.collections.get("DocumentChunk")
results = collection.query.hybrid(
query="payment fails with error code 402",
alpha=0.6, # weight toward vector search, 0 = pure keyword search
limit=8,
)
8. Combining metadata filtering and hybrid search
Pure vector similarity rarely suffices in production systems. Metadata filters, for example by product area, language, or publish date, narrow the search space before the actual similarity computation runs, and keep stale or irrelevant documents out of consideration entirely. These filters should apply as early as possible in the query, not as post-processing on the result list.
For use cases involving exact terms, such as error codes, SKU numbers, or version numbers, combining vector search with keyword search delivers more reliable results than pure semantic search, since exact strings do not always sit close together in embedding space.
9. Monitoring and reindexing in ongoing operation
A vector database pipeline is not a one-time setup; it needs ongoing monitoring: retrieval quality via spot checks, search latency as data volume grows, and detection of stale chunks whose source document has changed or no longer exists. Without systematic reindexing, dead or contradictory entries accumulate over months.
Claude is useful for designing a reindexing script that includes detection of orphaned chunks, for example by comparing document IDs stored in the vector database against the current source database. On top of that, a regular spot-check with real user queries is worthwhile to catch gradual quality decline before it shows up in support tickets.
| Criterion | pgvector | Pinecone | Weaviate |
|---|---|---|---|
| Hosting | Self-hosted (PostgreSQL) | Fully managed | Self-hosted or cloud |
| Setup effort | Low with existing Postgres | Very low | Medium |
| Hybrid search | Combinable manually | Available with limits | Built in natively |
| Scaling | Bounded by Postgres instance | Very high, automatic | High, with cluster setup |
| Cost model | Existing Postgres cost | Usage-based | Self-hosted or usage-based |
| Good starting point for | Existing Postgres teams | Fast scaling without ops | Combined search requirements |
Mironsoft
AI-assisted development, agent workflows, and team processes
Using Claude or other AI tools on the team, but without a clear workflow?
We set up AI-assisted development workflows for teams, from CLAUDE.md conventions to subagent strategies to code review processes that combine human oversight with AI speed.
Workflow Setup
Cleanly set up CLAUDE.md, project conventions, and tool permissions for the team.
Agent Strategy
Build subagent and automation workflows for recurring development tasks.
Team Onboarding
Train developers in productive, safe use of AI coding assistants.
10. Summary
Vector Database Pipelines: The Essentials
Embedding model
Choose based on language, domain, and cost first, then the database.
Chunking
Semantic boundaries instead of fixed character count, 200 to 500 tokens with overlap.
Database choice
pgvector, Pinecone, and Weaviate fit different hosting and scaling needs.
Operations
Reindexing and spot checks prevent gradual quality decline.