Dec 12, 2025
Semantic Product Search
H
Hyperfold TeamSearchAgents
Understanding Embeddings
Semantic search uses vector embeddings to find products based on meaning, not just keywords. This enables natural language queries like "waterproof shoes for running in rain" to match relevant products.
Hyperfold uses Vertex AI's text-embedding model to generate 768-dimensional vectors for each product.
Catalog Indexing
Index your products with semantic embeddings:
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Semantic indexing with Vertex AIimport { VertexAI } from '@google-cloud/vertexai'; const vertexAI = new VertexAI({ project: 'your-project' });const embeddingModel = vertexAI.preview.getGenerativeModel({ model: 'text-embedding-004',}); async function indexProduct(product: Product) { // Create rich text for embedding const textToEmbed = [ product.name, product.description, product.attributes.brand, product.semantics.category, ...product.semantics.usage_context, ...product.semantics.visual_tags, ].join(' '); // Generate embedding const response = await embeddingModel.generateContent({ contents: [{ role: 'user', parts: [{ text: textToEmbed }] }], }); const embedding = response.response.candidates[0].content.parts[0].embedding; // Store in Firestore with vector index await db.collection('products').doc(product.product_id).set({ ...product, embedding: FieldValue.vector(embedding), });}Run bulk indexing with
hyperfold catalog optimize --embedto generate embeddings for your entire catalog.Search Queries
Handle semantic search requests from buyer agents:
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// Semantic search implementation@OnACPEvent('search')async handleSearch(request: SearchRequest) { const { query, filters, limit = 10 } = request; // Generate query embedding const queryEmbedding = await generateEmbedding(query); // Vector similarity search const results = await db.collection('products') .findNearest({ vectorField: 'embedding', queryVector: queryEmbedding, limit: limit * 2, // Fetch extra for filtering distanceMeasure: 'COSINE', }); // Apply filters let filtered = results.docs.map(doc => doc.data()); if (filters?.price_max) { filtered = filtered.filter(p => p.pricing.list_price <= filters.price_max); } if (filters?.in_stock) { filtered = filtered.filter(p => p.inventory.quantity > 0); } return { results: filtered.slice(0, limit), total_count: filtered.length, semantic_confidence: calculateConfidence(results), };}Filtering Results
Combine semantic similarity with structured filters:
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Search with filtersconst results = await search({ query: "running shoes for marathon", filters: { price_max: 200, size: "10", color_preference: ["blue", "black"], in_stock: true, }, buyer_context: { loyalty_tier: "gold", location: "US", },});Search Optimization
Tips for improving search quality:
- Rich product descriptions: Include usage contexts and attributes
- Consistent taxonomy: Use standardized category names
- Regular re-indexing: Update embeddings when descriptions change
- Query expansion: Add synonyms and related terms