Skip to content
Curriculum/Day 2: Embeddings & Vector Search
Day 2Build AI Products

Embeddings & Vector Search

SQL LIKE matches characters. Vector search matches meaning. You'll learn how embeddings turn text into numbers, build similarity search from scratch, and understand when to use Pinecone, pgvector, or Chroma. You'll ship a search engine that finds 'cozy sneakers' when users type 'comfortable shoes'.

70 min(+25 min boss)★★☆☆☆
🔍
Bridge:SQL LIKE / full-text searchVector similarity search

Use this at work tomorrow

Replace a keyword-based search in your app with semantic search — users will find what they mean, not just what they type.

Learning Objectives

  • 1Understand embeddings as feature vectors (1536 dimensions → meaning)
  • 2Implement cosine similarity from scratch — then use it at scale
  • 3Generate embeddings with OpenAI's embedding API
  • 4Know when to pick Pinecone vs pgvector vs Chroma vs in-memory
  • 5Build a semantic search engine with 100+ real documents

Ship It: Semantic search engine

By the end of this day, you'll build and deploy a semantic search engine. This isn't a toy — it's a real project for your portfolio.

Before You Start — Rate Your Confidence

I can explain what embeddings are, compute cosine similarity, and build a semantic search system that matches meaning instead of keywords.

1 = no idea · 5 = ship it blindfolded
Predict First — Then Learn

How does semantic search find 'cozy sneakers' when you search 'comfortable shoes'?

From Text Search to Semantic Search

SQL LIKE queries match exact strings — 'comfortable shoes' will never match 'cozy sneakers'. Semantic search matches meaning. The magic is embeddings — turning text into vectors (arrays of 1536 numbers) where similar meanings are close together in vector space. It's like GPS coordinates for meaning.

💡Embeddings = GPS coordinates for meaning. Similar text → nearby vectors. No synonym tables needed.
Quick Pulse Check

What does an embedding convert text into?

Predict First — Then Learn

What do the 1536 numbers in an embedding vector represent?

Embeddings Are Feature Vectors You Already Understand

You've worked with feature flags, analytics dimensions, or coordinate systems. Embeddings are the same concept at scale — each of the 1536 dimensions captures a semantic feature learned by the model. 'King' and 'Queen' are close in the royalty dimension but differ on the gender dimension. You don't pick the features — the model learns them.

💡Each of the 1536 dimensions is a learned semantic feature. You don't define them — the model discovers them.
Quick Pulse Check

Who decides what each dimension in an embedding means?

Predict First — Then Learn

When should you use a dedicated vector database like Pinecone instead of in-memory arrays?

Real Vector Databases: When to Use What

For prototyping: in-memory arrays with cosine similarity (what we do today). For production with <100K docs: pgvector (add vectors to your existing Postgres). For production at scale: Pinecone (managed, fast), Weaviate (open-source, hybrid search), or Chroma (lightweight, Python-first). The interface is always the same: store vectors, query by similarity, get top-K results.

💡Prototype with in-memory arrays. Scale with pgvector (Postgres) or Pinecone. Interface is always: store → query → top-K.
Quick Pulse Check

You have a Postgres database and 50K product descriptions. What's the EASIEST way to add semantic search?

The Full Evolution

Watch one function evolve through every concept you just learned.

Production Gotchas

Embedding costs are cheap (~$0.02 per 1M tokens) but re-embedding your entire dataset on model change is expensive. Always store raw text alongside vectors — you'll need to re-embed when better models drop. Dimensionality matters: text-embedding-3-small (1536d) vs text-embedding-3-large (3072d) — more dimensions = better quality but more storage/compute. Normalize your vectors for cosine similarity.

Code Comparison

Search: SQL LIKE vs Semantic

Traditional text search vs AI-powered semantic search

SQL Text SearchTraditional
// Traditional search — matches characters
const results = await db.query(
  `SELECT * FROM products
   WHERE name ILIKE $1
   OR description ILIKE $1
   ORDER BY relevance
   LIMIT 10`,
  [`%${searchQuery}%`]
);
// "comfortable shoes"
// won't match "cozy sneakers" ✗
// won't match "comfy footwear" ✗
// won't match "easy-to-wear kicks" ✗
Semantic SearchAI Engineering
// Semantic search — matches meaning
import { embed } from "ai";
import { openai } from "@ai-sdk/openai";

// 1. Embed the query (~2ms)
const { embedding } = await embed({
  model: openai.embedding(
    "text-embedding-3-small"
  ),
  value: searchQuery,
});

// 2. Find similar vectors (top-K)
const results = await vectorDB.query({
  vector: embedding,
  topK: 10,
});
// "comfortable shoes" MATCHES:
// "cozy sneakers" ✓ (0.91 similarity)
// "comfy footwear" ✓ (0.89 similarity)
// "easy-to-wear kicks" ✓ (0.84 similarity)

KEY DIFFERENCES

  • SQL LIKE matches characters — embeddings match meaning
  • Embeddings turn text into vectors (arrays of 1536 numbers)
  • Similar meanings = close vectors (cosine similarity → 0 to 1)
  • No need to predict all synonyms — the model handles it

Bridge Map: SQL LIKE / full-text search → Vector similarity search

Click any bridge to see the translation

Hands-On Challenges

Build, experiment, and get AI-powered feedback on your code.

Real-World Challenge

Semantic Product Search Engine

Build and deploy a semantic search engine that lets users search a product catalog by meaning, not keywords. When someone searches 'comfortable shoes', they should find 'cozy sneakers'. This is the same search technology powering modern e-commerce.

~3h estimated
Next.js 14+Vercel AI SDKOpenAI text-embedding-3-smallTailwind CSSVercel (deploy)

Acceptance Criteria

  • Index 50+ products with text descriptions and metadata (price, category, etc.)
  • Generate embeddings using the OpenAI embedding API (text-embedding-3-small)
  • Implement cosine similarity search that returns top-K results ranked by relevance
  • Show similarity scores visually (progress bars or percentage badges)
  • Filter out low-quality matches below a threshold (e.g., score < 0.5)
  • Handle edge cases: empty queries, no results found, API failures
  • Deploy to a public URL (Vercel, Netlify, etc.)

Build Roadmap

0/6

Create a new Next.js app with TypeScript and Tailwind CSS. Set up your project structure with a products data file and a search API route.

npx create-next-app@latest semantic-search --typescript --tailwind --app
Create a /data/products.ts file for your product catalog

Deploy Tip

Push to GitHub and import into Vercel. Pre-compute your embeddings at build time or on first request, then cache them. Set your OPENAI_API_KEY in Vercel environment variables.

Sign in to submit your deployed project.

After Learning — Rate Your Confidence Again

I can explain what embeddings are, compute cosine similarity, and build a semantic search system that matches meaning instead of keywords.

1 = no idea · 5 = ship it blindfolded