← Selected work
Embeddings + pgvector · Project 3
Site Search Agent
Semantic product search that solves vocabulary mismatch — "footwear for jogging" finds running shoes even though those words don't appear in any product name.
New Concept This Project
Real embeddings + pgvector. Text converted to 512 numbers that capture meaning.
"footwear for jogging" and "running shoes" become similar vectors — found via cosine similarity.
Two-phase pipeline: index once, query every search.
Two-Phase RAG Pipeline
Phase 1 — Indexing (once)
50 product descriptions
↓
Voyage AI API (input_type: "document")
↓
512-dimensional vector per product
↓
Stored in Neon pgvector
Phase 2 — Querying (every search)
User query text
↓
Voyage AI API (input_type: "query")
↓
Query vector
↓
Cosine similarity search in pgvector
↓
Ranked results → Claude → response
System Prompt
You are a helpful product search assistant for an online store. When a user searches for products: 1. ALWAYS call search_products first with their natural language query 2. If user mentions price limits → call filter_results with max_price 3. If user asks about a specific product → call get_product_detail 4. Present results in a friendly, helpful way with key details Available categories: shoes, electronics, clothing, sports, books
Tool Definitions
[
{
"name": "search_products",
"description": "Search catalog using semantic similarity. ALWAYS call first.",
"input_schema": {
"properties": {
"query": { "type": "string" },
"category": { "type": "string" },
"limit": { "type": "number" }
},
"required": ["query"]
}
},
{
"name": "filter_results",
"description": "Filter and sort results by price, rating, category",
"input_schema": {
"properties": {
"results": { "type": "array" },
"max_price": { "type": "number" },
"min_price": { "type": "number" },
"min_rating": { "type": "number" },
"sort_by": { "type": "string" },
"top_n": { "type": "number" }
},
"required": ["results"]
}
},
{
"name": "get_product_detail",
"description": "Get full details of a specific product by ID",
"input_schema": {
"properties": {
"product_id": { "type": "string" }
},
"required": ["product_id"]
}
}
] End-to-End Flow
👤 User Input
"comfortable running shoes under $50"
🧠 LLM Response — Turn 1
{
"stop_reason": "tool_use",
"content": [{
"type": "tool_use",
"id": "tool_001",
"name": "search_products",
"input": {
"query": "comfortable running shoes",
"category": "shoes",
"limit": 10
}
}],
"usage": { "input_tokens": 420, "output_tokens": 85 }
} 🔢 Voyage AI Embedding Request
POST https://api.voyageai.com/v1/embeddings
{
"model": "voyage-3-lite",
"input": ["comfortable running shoes"],
"input_type": "query"
}
Response:
{
"data": [{ "embedding": [0.021, 0.185, -0.041, 0.308, ...] }]
}
// 512 numbers representing the meaning of the query 🔍 pgvector Similarity Search
Neon Postgres + pgvector
SELECT name, price, rating,
1 - (embedding <=> '[0.021, 0.185, ...]'::vector) AS similarity
FROM products
WHERE category = 'shoes'
ORDER BY embedding <=> '[0.021, 0.185, ...]'::vector
LIMIT 10
Results:
Nike Air Zoom Pegasus $47.99 similarity: 0.9421
Brooks Ghost 15 $44.99 similarity: 0.9187
Hoka Clifton 9 $49.99 similarity: 0.9043
New Balance 1080 $64.99 similarity: 0.8876
Adidas Ultraboost $89.99 similarity: 0.8654 🧠 LLM Response — Turn 2 (filter by price)
{
"stop_reason": "tool_use",
"content": [{
"type": "tool_use",
"id": "tool_002",
"name": "filter_results",
"input": {
"results": [...10 products...],
"max_price": 50,
"sort_by": "relevance",
"top_n": 3
}
}],
"usage": { "input_tokens": 890, "output_tokens": 120 }
} LLM detected "under $50" in the query → used max_price filter.
🧠 LLM Response — Turn 3 (Final)
{
"stop_reason": "end_turn",
"content": [{
"type": "text",
"text": "Here are 3 comfortable running shoes under $50:\n\n1. Nike Air Zoom Pegasus 40 — $47.99 ⭐ 4.5\n Lightweight daily trainer with responsive cushioning.\n\n2. Brooks Ghost 15 — $44.99 ⭐ 4.4\n Versatile everyday shoe, works for all runner types.\n\n3. Hoka Clifton 9 — $49.99 ⭐ 4.7\n Maximum cushion road shoe, great for recovery runs."
}],
"usage": { "input_tokens": 1240, "output_tokens": 185 }
} Vocabulary Mismatch — The Key Proof
Keyword search: "footwear for jogging" → looks for "footwear" "jogging" → NONE found ❌
Vector search: "footwear for jogging" → Voyage AI embeds → [0.019, 0.181, ...]
→ Nike Air Zoom similarity: 0.89 ✅ → Brooks Ghost similarity: 0.86 ✅
Same meaning, different words. Vector search handles it. Keyword search cannot.
Token Cost
Turn
Input
Output
Cost
Turn 1 (search)
420
85
$0.0000026
Turn 2 (filter)
890
120
$0.0000045
Turn 3 (final)
1240
185
$0.0000065
Total
2,550
390
~$0.000014