# Dan Ryland. Is. Supabase Vector Database.

*Published 2023-10-10, by Dan Ryland.*

> From Hackathons to hammers, I explore how to leverage Supabase's vector database to create an AI version of myself.

- Canonical URL: https://danryland.com/blog/dan-ryland-is-supabase-vector-database/
- Category: Build
- Tags: Supabase, AI, Vectors, Hackathon

We've all seen _that_ Office episode.

Dwight can't contain the excitment of his promotion.

He leaps onto the table, punches into the air and shouts:

"Dwight Schrute. Is. Manager."

The office swiftly follows with applause.

![Dwight Schrute. Is. Manager. meme](https://danryland.com/images/dwight-schrute-manager.gif)

Well, what if...

_\*\*Jumps onto desk_\*\*

Dan Ryland. Is. Supabase Vector Database!?

I've been a massive fan of [Supabase](https://supabase.com) for a while.

The community, the auth, the databases, storage, image transformations, edge functions, launch weeks, the hackathons and now?

Those sweet vector fields.

I entered my first ever hackathon for their Launch Week 7 with my [Groove AI](https://groove-ai.netlify.app/) app.

Groove AI generates drum patterns for you to play, customise and even download as MIDI.

To my absolute surprise, [I won silver](https://supabase.com/blog/launch-week-7-hackathon-winners#most-fun--best-easter-egg)!

I couldn't believe it.

But silver wasn't enough.

I had to try better.

I wanted that _sweet_ gold.

![Homer from The Simpsons drool meme](https://danryland.com/images/homer-the-simpsons.gif)

Launch week 8 comes.

This time I've come for gold.

Blending the visual style of Rick and Morty with the well known talent competition XFactor, I designed and built [Supafactor](https://supafactor.netlify.app/).

Supafactor is now _the_ way to judge hackathon entries.

Through four criteria: creativity, functionality, Supabase-ness and fun, our Supafactor judge (Simon Cowell) gives realtime feedback on the README of your hackathon entry.

The result?

[GOLD](https://supabase.com/blog/launch-week-8-hackathon-winners#most-fun--best-easter-egg)

Beautiful gold.

I did it.

I was so happy I did many an Anchorman celebratory jump.

![Anchorman jump meme](https://danryland.com/images/anchorman-jump.gif)

Fast forward to today and I'm pushing Supabase's features further.

Let's set the scene.

I co-host the podcast, [Don't be a Doorstop](https://dontbeadoorstop.com/)

Why the name?

Yes, a hammer can be a good doorstop, but its _real_ purpose is to hammer nails.

[![Thor hammer as doorstop](https://danryland.com/images/thor-hammer-doorstop.webp)](https://www.reddit.com/r/marvelstudios/comments/6khyds/doorstops_at_marvel/)

So Hammer, don’t be a doorstop. Let’s go find you some nails.

Don't be a Doorstop is about purpose, mindset and entrepreneurship.

Let's jump to AI characters, AI therapists and AI girlfriends.

Inspired by these AI characters, I thought, what if I could create an AI version of myself as a coach?

Enter our Coach AI, or it's cute character name, 'Hammer'

<div style="max-width:600px">
<img src="https://danryland.com/images/hammer.svg" width="150" height="226" style="margin:0 auto 16px auto;display:block;text-align:center">
</div>

Using the podcast episodes, I transcribed my half of the audio with Open AI's Whisper.

I broke those text transcriptions into smaller, overlapping chunks.

After some reading, I decided to 'chunk' the transcripts into 6 sentences each with 2 sentences as overlap to keep some context continuation.

I then used Open AI's `text-embedding-ada-002` model to create embeddings for each of the chunks.

After some clean up, this resulted in 1,040 rows in my Supabase database, each with its own vector value.

![Screenshot of my supabase database](https://danryland.com/images/vector-embeddings.png)

Now comes the interesting part.

I built a simple [Quasar app](https://quasar.dev/) to take a question as input, converted the question to an vector embed then query the database using the vector value via a custom Postgres function.

```
CREATE OR REPLACE FUNCTION match_snippets (
  query_embedding vector(512),
  match_threshold float,
  match_count int
)
RETURNS TABLE (
  id bigint,
  content text,
  similarity float
)
LANGUAGE SQL STABLE
AS $$
  SELECT
    snippets.id,
    snippets.content,
    1 - (snippets.embedding <=> query_embedding) AS similarity
  FROM snippets
  WHERE 1 - (snippets.embedding <=> query_embedding) > match_threshold
  ORDER BY similarity DESC
  LIMIT match_count;
$$;
```

This returns 20 relevant snippets from the podcast that can now be used as context to answer the original question.

With a good `system prompt` I fed it: the task I wanted it to perform, the original question and the returned snippets for its context.

This then returns a beautiful answer driven from pod content.

It's beautiful.

I've codified myself into a vector database and made myself into a cute hammer.

![Screenshot of Hammer protoype](https://danryland.com/images/ask-hammer.png)

Now, I'd like to take this further:

Telegram bot and audio responses - that could actually sound like me.

I'm now working on shifting this into a Supabase Edge Function and integrating it with [grammY](https://grammy.dev/), an open source Telegram bot framework.

Supabase has a [great walkthrough](https://supabase.com/docs/guides/functions/examples/telegram-bot) on how to get you going.

Here's proof Hammer lives:

![Screenshot of Hammer Telegram bot](https://danryland.com/images/hammer-telegram-bot.png)

If you're interested in following my progress [follow me on X](https://x.com/realdanryland)

And if you haven't used Supabase yet, I highly recomend you [try Supabase today](https://supabase.com/).

Until next time, keep hammering those nails.

---

- Home: https://danryland.com/
- About: https://danryland.com/about/
- Contact: https://danryland.com/contact/
- Privacy: https://danryland.com/privacy/
- The Forge (weekly note): https://danryland.com/forge/
- Agent overview: https://danryland.com/llms.txt
- Sitemap: https://danryland.com/sitemap.xml
- RSS: https://danryland.com/rss.xml
- Email: dan@ryland.consulting
