Back to portfolio
Portfolio/Projects/Jerry — Public AI Assistant
AI & Agents · 2025

Jerry — Public AI Assistant.

A retrieval-grounded assistant that answers questions about my work in real time — built on a vector-search backend, streamed token-by-token, and tuned to never hallucinate a project that doesn't exist.

RoleSolo — design & build
TimelineMar — Jun 2025
StatusLive in production
RecognitionFeatured project · 12k+ conversations served
Addressexample.com/jerry
Built withReact · TypeScript · Supabase · pgvector · OpenAI · Edge Functions
Jerry answering a question about this very portfolio, with grounded citations.

01Overview

Most portfolio sites are static. Jerry isn't — it's a small AI assistant that lives on my site and answers visitors' questions about my projects, my stack, and how I work, in natural language.

If it can't cite it, it won't say it.

Under the hood, content is chunked, embedded, and stored in pgvector on Supabase, then streamed back token-by-token over an edge function.

02Impact

Numbers after ten weeks live

12kConversations servedsince launch
98%Answers with a citationgrounded responses
340msMedian time to first tokenp50 latency
4.8/5Helpfulness ratingn = 1,240 votes

03The interface

Answers stream in live; each cited source links back to the original project page.
Fig 1Answers stream in live; each cited source links back to the original project page.

04How it came together

Ten weeks, four milestones

  1. Week 1 · March

    Indexing pipeline

    Chunked every project page, embedded them, and loaded vectors into pgvector.

  2. Week 3 · April

    Grounded answering

    Wired retrieval into the prompt with strict citation rules and an honest fallback.

  3. Week 6 · May

    Streaming UI

    Token-by-token streaming over an edge function. TTFT under 350ms.

  4. Week 10 · June

    Public launch & tuning

    Shipped to production with per-answer helpfulness voting.

05Retrieval core

Grounding every answer

retrieve.tsTypeScript
// rank chunks by cosine similarity, then ground the promptexport async function retrieve(query: string) {  const embedding = await embed(query);  const { data } = await supabase.rpc("match_chunks", {    query_embedding: embedding,    match_threshold: 0.78,    match_count: 6,  });   if (!data?.length) return { grounded: false, sources: [] };  return { grounded: true, sources: data };}

06Screens

Across the surface

07Playground

Live, embedded

codesandbox.io/s/jerry-retrieval-demoCodeSandbox

08Your call

What should Jerry learn next?

Choose one to see the results

Ask Jerry anything about my work.

It's live on the site right now — grounded, cited, and honest when it doesn't know.

What did you think?
Go deeper

Related notes.

From lighthouseinfo.com.