Skip to content
47% off: the complete course for $79 (reg. $149)Order now →
AI Builder
Module 5Full course10 min read

Building Semantic Search into Your App

Ship a "search by meaning" feature end to end with Postgres and pgvector: indexing, querying, filtering, and a results UI users understand.

A customer types "my teammate never got the invite" into Deskmate's help center and gets zero results, because the article that answers it is called "Adding agents to your workspace." Keyword search can't bridge that gap. Search by meaning can, and it's one of the most useful AI features you can ship without any text generation at all: no hallucinations, low cost per query, and an immediate improvement users notice.

In this lesson you'll build semantic search into Deskmate end to end with Postgres and pgvector: a schema and index, an indexer that keeps vectors in sync with articles, a query that filters by workspace and language without losing results, an API route, and a results UI that sets honest expectations. By the end you'll have a feature you could ship this week and a list of the details that make it feel trustworthy.

What we're building

Deskmate customers each have a knowledge base of help articles, and their end users search it from a help widget. The feature has two paths that run at different times:

  • Indexing (when an article is created, edited, published, or deleted): split the article into sections, embed each section, and upsert the vectors with their metadata.
  • Querying (on every search): embed the query, find the nearest sections inside the right workspace and language, collapse them to one result per article, and return them with the matching section highlighted.

We index sections rather than whole articles because a 2,000-word article about "Workspace settings" covers a dozen topics, and its single averaged vector matches none of them well. One chunk per ## section is a reasonable starting point for well-structured help content; Chunking Strategies That Work covers the general problem later in this module.

The choice of store is made: pgvector, for the reasons in Choosing a Vector Store. The embedding helper is the embedTexts and embedQuery module from Embeddings in Practice, using OpenAI's text-embedding-3-small at 1,536 dimensions; any model works if you use it consistently.