<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shloka</title>
    <description>The latest articles on DEV Community by Shloka (@shlokaguptaa).</description>
    <link>https://dev.to/shlokaguptaa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F476650%2Fd03cec71-18a1-4ec2-8595-675da4c69ae7.jpg</url>
      <title>DEV Community: Shloka</title>
      <link>https://dev.to/shlokaguptaa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shlokaguptaa"/>
    <language>en</language>
    <item>
      <title>Eli5: AI Agents are toddlers that need adult supervision!</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Sat, 25 Jul 2026 15:53:35 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/eli5-ai-agents-are-toddlers-that-need-adult-supervision-3ld2</link>
      <guid>https://dev.to/shlokaguptaa/eli5-ai-agents-are-toddlers-that-need-adult-supervision-3ld2</guid>
      <description>&lt;p&gt;In this fast-paced world, parents are obsessed with making their babies smart, before they can even start walking!&lt;/p&gt;

&lt;p&gt;So out come the flashcards of colors, shapes, and animals. At this stage, teaching a baby is low-stake. Most of the time, the baby gets the answers right. But once in a while, he points to a “Red” card and confidently says, "Black”. You smile, correct them, and move on. &lt;/p&gt;

&lt;p&gt;There's no real world damage. The mistake stays inside the flashcard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZHB0aWFzMGtrbjYxMHZvN2FudTVuZGY5MTJsanVuaGdmeGhrdDl5eCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/RZY1OEP5I6BRVcIQB8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img width="480" src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZHB0aWFzMGtrbjYxMHZvN2FudTVuZGY5MTJsanVuaGdmeGhrdDl5eCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/RZY1OEP5I6BRVcIQB8/giphy.gif" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Until a few years ago, this was the exact "baby" stage AI was in. Think about early chatbots... you asked a question, the model answered, and occasionally it confidently gave you the wrong answer. You corrected it, and that was it. The mistake was contained. No "actual" damage.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Toddler Phase
&lt;/h2&gt;

&lt;p&gt;Everything changes the moment a kid starts walking. Suddenly, a house designed around predictable adult behavior has a toddler running loose in it.&lt;/p&gt;

&lt;p&gt;I mean a common adult would not stick their finger in a socket, right?&lt;/p&gt;

&lt;p&gt;So, like any prepared parent, you do your research and toddler proof every corner, outlet covers, cabinet locks, stair gates. You take every precaution imaginable.&lt;/p&gt;

&lt;p&gt;And it works... right up until it doesn't. :/&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3MGh4eHE2YTJrYWY2c2J4bmgybW14M3E4MHRza2RnanNkZGZmbTlyZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/dVyRSjLEgjF2Bvf97E/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img width="480" src="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3MGh4eHE2YTJrYWY2c2J4bmgybW14M3E4MHRza2RnanNkZGZmbTlyZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/dVyRSjLEgjF2Bvf97E/giphy.gif" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why? Because toddlers are so freaking smart. Out of curiosity, they don't just walk into problems you prepped for, they invent entirely new ones!&lt;/p&gt;

&lt;p&gt;Case in point: as a kid, I took my mom’s expensive lipstick and drew on the bathroom floor with it! Ask my or your mom, and she'll tell you every single week brought a brand-new edge case she never saw coming.&lt;/p&gt;

&lt;p&gt;Now.. the &lt;em&gt;real&lt;/em&gt; shift isn't just that toddlers aren't predictable, it's that &lt;em&gt;their mistakes are no longer contained&lt;/em&gt;. One tiny decision or mistake can quickly lead to a big accident!&lt;/p&gt;

&lt;p&gt;That is precisely what happened when AI went from being a baby to a toddler i.e evolved from chat window into autonomous agent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Toddler-proofing agents
&lt;/h2&gt;

&lt;p&gt;As long as AI lived inside a chat box, the worst outcome was a wrong answer. You could ignore it, regenerate it, or start over.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3bjdpNG82MDhnNzQ2eThvaXF0aXU1M3Nhb3owZ3JpN2lhNHFhYXN1ayZlcD12MV9naWZzX3NlYXJjaCZjdD1n/HHNGqFmIawO4tjlT1f/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img width="480" src="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3bjdpNG82MDhnNzQ2eThvaXF0aXU1M3Nhb3owZ3JpN2lhNHFhYXN1ayZlcD12MV9naWZzX3NlYXJjaCZjdD1n/HHNGqFmIawO4tjlT1f/giphy.gif" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the moment we let models browse the web, call APIs, execute code, or touch production systems, their mistakes stopped being conversations and started affecting reality.&lt;/p&gt;

&lt;p&gt;Traditional software infrastructure, was build for predictable software i.e it’s deterministic: give it the exact same input, and it follows the exact same path to the exact same output every single time.&lt;/p&gt;

&lt;p&gt;And just like toddlers, AI agents don't work like that! They operate probabilistically. Every step is the model's best guess about what to do next, not a guaranteed sequence of operations.&lt;/p&gt;

&lt;p&gt;Naturally, before letting agents touch the system, engineers did the digital equivalent of toddler-proofing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prompt rules &amp;amp; system instructions&lt;/li&gt;
&lt;li&gt;Input guardrails&lt;/li&gt;
&lt;li&gt;Permission checks &amp;amp; tool restrictions&lt;/li&gt;
&lt;li&gt;Manual approval gates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are all useful and necessary.&lt;/p&gt;

&lt;p&gt;But just like toddlers, agents eventually throw an edge case nobody benchmarked for. And because agents don't just &lt;em&gt;say&lt;/em&gt; things, they &lt;em&gt;do&lt;/em&gt; things, the consequences aren't contained anymore.&lt;/p&gt;

&lt;p&gt;Consider a common scenario:- an agent invokes a tool with bad formatting. The request fails, so it retries with a slightly altered payload. Then again. And again. In seconds, it’s trapped in a recursive retry loop—racking up thousands of API calls, burning GPU compute, and blowing through your cloud budget.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNXFubzB6aTN1enN0Mm04MHplbGhsa2xwN256dWgwM2VqcGlwNXBkaCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/ASM4IvHzkop00e6sUN/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img width="480" src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNXFubzB6aTN1enN0Mm04MHplbGhsa2xwN256dWgwM2VqcGlwNXBkaCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/ASM4IvHzkop00e6sUN/giphy.gif" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's the digital equivalent of a toddler knocking over a glass lamp. except instead of sweeping up glass, you're cleaning up runaway infrastructure.&lt;/p&gt;

&lt;p&gt;And to make things worse, agentic failures are freaking hard to debug.&lt;/p&gt;

&lt;p&gt;When traditional software breaks, the logs tell a clear step-by-step story. However with agents, logs show &lt;em&gt;what&lt;/em&gt; happened, but struggle to explain &lt;em&gt;why&lt;/em&gt; the model thought that action made sense in the first place.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fix is adult supervision
&lt;/h2&gt;

&lt;p&gt;A child should NOT grab sharp tools and act on them alone. In an ideal world, the kid points to what he wants, an adult checks if it's safe, then hands it over or says "no".&lt;/p&gt;

&lt;p&gt;The kid isn't running things, but you also don't have to hover over every millisecond of his day.&lt;/p&gt;

&lt;p&gt;The same principle applies to AI. It comes down to ONE rule: &lt;strong&gt;never let a probabilistic model directly control production infrastructure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead, separate intelligence from execution using a deterministic control plane.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Propose:&lt;/strong&gt; The AI agent suggests an action, workflow step, or tool call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate:&lt;/strong&gt; A predictable, rule-based policy engine checks whether that action is valid, safe, and/or permitted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execute:&lt;/strong&gt; An underlying execution gateway carries out the operation &lt;em&gt;only&lt;/em&gt; after passing policy checks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Alongside this runtime barrier, you need multi-dimensional observability, capturing the model's full decision-making chain and memory state so you understand the reasoning path behind EVERY action.&lt;/p&gt;

&lt;p&gt;In this, humans don't disappear, nor do they sit around acting as a bottleneck for every micro-action. Automated code enforces safety at runtime, allowing human operators to act purely as high-level exception handlers who step in only when an action hits an unhandled edge case or ambiguous scenario.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus section: The Kindergarten Classroom
&lt;/h2&gt;

&lt;p&gt;Scaling up from one agent to many introduces an entirely new challenge. Imagine it’s no longer just one toddler, but FIVE kids sharing ONE single art project.&lt;/p&gt;

&lt;p&gt;Anyone who's run or observed kids in a classroom knows what happens next. Kids color over each other's drawings. Supplies go missing. Somebody grabs the marker someone else was actively using.&lt;/p&gt;

&lt;p&gt;This is what a multi-agent system looks like, several AI agents coordinating on a complex workflow.&lt;/p&gt;

&lt;p&gt;In AI infrastructure, these aren't reasoning failures, they are classic distributed systems problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conflicting updates:&lt;/strong&gt; Agents overwriting each other's shared state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stale reads:&lt;/strong&gt; Agents acting on outdated context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context drift:&lt;/strong&gt; A shared memory space degrading into chaos over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the outside, it looks like "the AI is making weird mistakes," when in reality, it's a state management and memory consistency issue.&lt;/p&gt;

&lt;p&gt;Managing a multi-agent system requires structured orchestration what engineers call an "agent control plane"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cubbies:&lt;/strong&gt; Isolated context memory so individual agent state stays clean.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rotation charts:&lt;/strong&gt; Workload routing, turn-taking, and concurrency management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layers of backup:&lt;/strong&gt; A defense-in-depth architecture combining prompt controls, tool permissions, deterministic policy checks, and human exception handlers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcTB4b2dzN3B2cnR6ejVucWh2amQwNnpyZHZhYmUzNzQyY242aGphOSZlcD12MV9naWZzX3JlbGF0ZWQmY3Q9Zw/xTuiHTcUnyYXikz0g7/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img width="480" src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcTB4b2dzN3B2cnR6ejVucWh2amQwNnpyZHZhYmUzNzQyY242aGphOSZlcD12MV9naWZzX3JlbGF0ZWQmY3Q9Zw/xTuiHTcUnyYXikz0g7/giphy.gif" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No single guardrail does the whole job. It’s the entire infrastructure stack working together that keeps multi-agent systems reliable.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Big Takeaway
&lt;/h2&gt;

&lt;p&gt;Here's the fundamental truth worth sitting with: making the underlying model smarter doesn't solve this problem. A smarter toddler still needs supervision, arguably needs it &lt;em&gt;more&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Prompting tricks and raw model intelligence are rapidly becoming table stakes. The real competitive advantage will go to whoever builds the equivalent of great parenting: a deterministic system where the AI proposes, code validates, and only safe, approved actions ever touch production.&lt;/p&gt;

&lt;p&gt;That's not a limitation on AI. It's how you let it grow up.&lt;/p&gt;




&lt;p&gt;Acknowledgement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IBM videos&lt;/li&gt;
&lt;li&gt;That one meta tech lead for his video&lt;/li&gt;
&lt;li&gt;All and any llms.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>explainlikeimfive</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Are deterministic tasks eating your tokens?</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Mon, 20 Jul 2026 19:04:57 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/are-deterministic-tasks-eating-your-tokens-2i9j</link>
      <guid>https://dev.to/shlokaguptaa/are-deterministic-tasks-eating-your-tokens-2i9j</guid>
      <description>&lt;p&gt;If you've built a system with integrated AI (or are building one now) you've probably felt the pain of a climbing token bill.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExeW1vYTBzOWN1am1uejFxaThyazJrMDhzcmMyZjB4bW1kb29lZTQ1MyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FH7xNGb7tWrtjvy9gNi%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img width="480" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExeW1vYTBzOWN1am1uejFxaThyazJrMDhzcmMyZjB4bW1kb29lZTQ1MyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FH7xNGb7tWrtjvy9gNi%2Fgiphy.gif" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When costs spike, the instinct is often to look for a cheaper model. But what if the problem &lt;em&gt;isn't&lt;/em&gt; the model but the "task" you gave it?&lt;/p&gt;

&lt;p&gt;People usually bring models into a system because they need some "thinking" done. But what if the task you handed it isn't actually a “thinking” task? what if it's just basic math? adding up a column of numbers? sorting a list alphabetically? checking if a string matches a regex pattern? scraping data off a page?&lt;/p&gt;

&lt;p&gt;For example, does a task like 2 + 2 need any “real” thinking? Nope! The answer is always going to be 4!&lt;/p&gt;

&lt;p&gt;Whether you're in 1978 or 2025, India or Japan the answer is &lt;em&gt;always&lt;/em&gt; going to be 4.&lt;/p&gt;

&lt;p&gt;When a task returns the same output for the same input, EVERY time, it's &lt;strong&gt;deterministic&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There's ZERO creativity, judgment, or opinion needed. A calculator, a basic script, or an existing library can handle a deterministic task perfectly, instantly, and for fraction of a penny. &lt;/p&gt;

&lt;p&gt;Now you may ask, “Shloka WHY are you whining and being so dramatic? Why the heck is it a problem to hand a deterministic task to an AI model when it &lt;em&gt;can&lt;/em&gt; do both deterministic and non-deterministic tasks?”&lt;/p&gt;

&lt;p&gt;Wellll……&lt;/p&gt;

&lt;p&gt;There are a bunch of problems, but for this blog, let's stick to two of em:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tokens (i.e some sweet Moolah).&lt;/strong&gt; by now we've learned that more tokens means more money. When you ask a model to do something deterministic, like "add these 50 numbers", it has to generate every step of that work. That's slow AND expensive compared to just running actual code, which does the same task in a fraction of a second for basically nothing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reliability.&lt;/strong&gt; Fun fact, models CAN get deterministic tasks wrong. Now this is a dumb example, cause we have come a long way, but to keep things simple... a calculator never miscounts. Whereas A language model, doing arithmetic by "reasoning" in text, sometimes does.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's like asking a toddler "what's 2+2?", they'll usually say 4, but every so often they'll confidently get it wrong, and you won't catch it until it's already caused a problem downstream.&lt;/p&gt;

&lt;p&gt;Now, in a real codebase, at scale, the line between "this needs a model" and "this doesn't" gets blurry FAST since AI ends up woven into a dozen different steps of a pipeline. So how do you actually draw that line?&lt;/p&gt;

&lt;p&gt;Well, the general fix isn't asking the model to do "less" thinking. It's asking it to do "different" thinking.&lt;/p&gt;

&lt;p&gt;A good system doesn't ask the model to do everything itself, instead, it gives the model the ability to call actual tools: a code interpreter, a calculator, a database query, a search function, for anything deterministic. The model's real job becomes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand what's being asked&lt;/li&gt;
&lt;li&gt;Decide which tool solves the deterministic part&lt;/li&gt;
&lt;li&gt;Hand that part off&lt;/li&gt;
&lt;li&gt;Use its own judgment only for the fuzzy, non-deterministic parts (writing, reasoning, interpreting, deciding)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is often called "tool use" or "function calling."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So how do you actually decide what gets delegated and what doesn't?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of it as a priority list, checked top to bottom, cheapest and most reliable first, most expensive and flexible last. Only move down if the step above can't do the job.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Can plain math or logic solve it?&lt;/strong&gt; Write a script. Always check this first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can an existing tool or lookup solve it?&lt;/strong&gt; Call a database, API, or search index directly instead of guessing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can simple fixed rules solve it?&lt;/strong&gt; Even a long list of "if this, then that" rules can usually be handled with plain code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does it need real understanding, language, or judgment?&lt;/strong&gt; &lt;em&gt;Now&lt;/em&gt; bring in AI.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A quick gut-check, if you forget the order is to ask yourself: would 10 different careful people all land on the exact same answer? If yes, you're probably still in script territory. If no, that's AI's job.&lt;/p&gt;

&lt;p&gt;This keeps your system fast and cheap by default, and saves the AI's "thinking" for the one thing it's actually needed for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PS: In the next blog I want to build on this and talk about how even handing AI control of deterministic tasks is not the end game.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>tokens</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Why Traditional Token Savers Fall Short on Big Coding Jobs (And How We Fix It)</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Thu, 02 Jul 2026 15:54:07 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/why-traditional-token-savers-fall-short-on-big-coding-jobs-and-how-we-fix-it-5b2b</link>
      <guid>https://dev.to/shlokaguptaa/why-traditional-token-savers-fall-short-on-big-coding-jobs-and-how-we-fix-it-5b2b</guid>
      <description>&lt;p&gt;Earlier this week, we announced that we’re launching &lt;strong&gt;DestinyAI’s Token Saver Engine&lt;/strong&gt; for free on July 24th.&lt;/p&gt;

&lt;p&gt;The internet did its magic, and almost immediately, the community started hitting us with existing token-saving tools, specifically rtk and Headroom, asking one core question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“How are you different?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fair enough! So here’s a breakdown:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;rtk&lt;/strong&gt; is great for your everyday work. It's fast. Think of it as a smart filter that sits in your command line, catches the output from your usual dev tools, and shrinks it down before sending it to an LLM. Good pick if you just want something simple and quick to cut down noisy command output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Headroom&lt;/strong&gt; is built for bigger jobs: like RAG systems or AI agents that need to process huge amounts of text (logs, raw files, big data chunks). It's an optimization layer (and also works as an MCP server) that compresses that text a lot, and can give you back the original if you need it. Basically, a heavy-duty compressor for your context window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So when should you use DestinyAI's Token Saver Engine instead?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, you would want to use our token saving engine for big coding jobs  refactoring many files, changing your app's structure, auditing a whole codebase. This is where simple text-trimming tools like rtk and Headroom struggle. They treat your code like regular text: they guess what to cut or shorten. That guessing can quietly break your code or make the AI make things up.&lt;/p&gt;

&lt;p&gt;DestinyAI works differently.&lt;/p&gt;

&lt;p&gt;It's not a text compressor  it actually understands your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's how:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It gives real facts, not guesses.&lt;/strong&gt; It reads your code properly (understands the actual structure, works with many languages) and gives your ai assistant the exact lines it needs. Word for word, with proof they came from your real files. If it's not sure about something, it says so clearly instead of pretending to know.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It double-checks the AI's work.&lt;/strong&gt; rtk and Headroom only make the &lt;em&gt;input&lt;/em&gt; smaller. DestinyAI also checks the &lt;em&gt;output&lt;/em&gt;. Before accepting any code change, it tests it on a safe copy of your project. If something breaks, it rejects the change and tells you exactly which test failed. So a wrong answer doesn't slip through.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It remembers your codebase.&lt;/strong&gt; rtk and Headroom start fresh each time. DestinyAI builds up memory of your code and patterns over time, so it gets faster and smarter the more you use it. And that memory isn't tied to one AI, switch from Claude to OpenAI anytime, and it still remembers. One memory, works with any AI, no lock-in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It keeps your code private.&lt;/strong&gt; It runs on your own computer. Your code and secrets never leave your machine. It also keeps different projects separate and hides sensitive info automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;And it saves you money everywhere, not just on big jobs.&lt;/strong&gt; For big tasks, this approach cuts costs by 50–90% (based on our own testing). For small everyday tasks, the engine just does the work itself and the AI checks it, so those get much cheaper too, with the same safety guarantee.&lt;/p&gt;

&lt;p&gt;All these claims are pointless without proof. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We didn't just guess these differences, we benchmarked them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We ran all three engines through a rigorous production-grade engineering capability evaluation on a scale of 0–100. We didn't look at lab micro-benchmarks; we tested how these tools handle serious, high-stakes engineering pipelines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;For Input/Output and Context Control:&lt;/strong&gt; rtk and Headroom score strongly on basic payload trimming (scoring 55–85). But when it comes to true codebase stability, like &lt;strong&gt;Accuracy Preservation&lt;/strong&gt; and &lt;strong&gt;Output Verification&lt;/strong&gt; (actually catching a bad AI change before it ships)—their text-based architectures score in the 15–25 range.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where DestinyAI sits:&lt;/strong&gt; Because we approach this as a local semantic compiler rather than a compressor, DestinyAI scores &lt;strong&gt;94/100 overall&lt;/strong&gt; across core engineering metrics, delivering a near-perfect 98 on exact verbatim grounding with tamper-evident proof.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy5flkuqatcl1z1vuhcpu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy5flkuqatcl1z1vuhcpu.png" alt=" " width="800" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every single capability we claim is backed by these evidence-labeled test sets.&lt;/p&gt;

&lt;p&gt;The bottom line? &lt;/p&gt;

&lt;p&gt;We aren't trying to be the best text zipper on the market. We're building a local codebase compiler that lets you ship trusted code with absolute integrity, while dropping your AI bill by 50–90%.&lt;/p&gt;

&lt;p&gt;DestinyAI’s Token Saver Engine drops for free on July 24th. Stay tuned.&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://x.com/DestinyAI_Multi?s=20" rel="noopener noreferrer"&gt;X&lt;/a&gt; &lt;/p&gt;

</description>
      <category>ai</category>
      <category>tokens</category>
      <category>mcp</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Happy women in STEM day!! &lt;3</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Wed, 11 Feb 2026 21:12:49 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/happy-women-in-stem-day-3-2115</link>
      <guid>https://dev.to/shlokaguptaa/happy-women-in-stem-day-3-2115</guid>
      <description></description>
    </item>
    <item>
      <title>Wrote a blog that explains ReAct (Reasoning + Action) through the analogy of the game "Pass the story" 

https://dev.to/shlokaguptaa/understanding-react-reasoning-action-through-a-simple-childhood-game-1b20</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Wed, 04 Feb 2026 14:34:33 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/wrote-a-blog-that-explains-react-reasoning-action-through-the-analogy-of-the-game-pass-the-2opf</link>
      <guid>https://dev.to/shlokaguptaa/wrote-a-blog-that-explains-react-reasoning-action-through-the-analogy-of-the-game-pass-the-2opf</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/shlokaguptaa/understanding-react-reasoning-action-through-a-simple-childhood-game-1b20" class="crayons-story__hidden-navigation-link"&gt;Eli5: Understanding ReAct (Reasoning + Action) through a simple game&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/shlokaguptaa" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F476650%2Fd03cec71-18a1-4ec2-8595-675da4c69ae7.jpg" alt="shlokaguptaa profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/shlokaguptaa" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Shloka
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Shloka
                
              
              &lt;div id="story-author-preview-content-3229534" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/shlokaguptaa" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F476650%2Fd03cec71-18a1-4ec2-8595-675da4c69ae7.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Shloka&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/shlokaguptaa/understanding-react-reasoning-action-through-a-simple-childhood-game-1b20" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 4&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/shlokaguptaa/understanding-react-reasoning-action-through-a-simple-childhood-game-1b20" id="article-link-3229534"&gt;
          Eli5: Understanding ReAct (Reasoning + Action) through a simple game
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag crayons-tag--filled  " href="/t/explainlikeimfive"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;explainlikeimfive&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agents"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agents&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/game"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;game&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/shlokaguptaa/understanding-react-reasoning-action-through-a-simple-childhood-game-1b20" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;21&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/shlokaguptaa/understanding-react-reasoning-action-through-a-simple-childhood-game-1b20#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              9&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Eli5: Understanding ReAct (Reasoning + Action) through a simple game</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Wed, 04 Feb 2026 05:16:01 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/understanding-react-reasoning-action-through-a-simple-childhood-game-1b20</link>
      <guid>https://dev.to/shlokaguptaa/understanding-react-reasoning-action-through-a-simple-childhood-game-1b20</guid>
      <description>&lt;p&gt;When I first moved from New York City to Philadelphia, I was starved for social interaction. So naturally, I did what any adult would do.&lt;/p&gt;

&lt;p&gt;I downloaded Hinge.&lt;/p&gt;

&lt;p&gt;Just kidding. I downloaded Meetup. And for my first social outing, I went to a writers’ meetup. Now the funny thing about a group of adult strangers meeting is that to kill the awkwardness we end up playing childhood games as ice breakers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3N2tnbDlnYWU0aGwzdWEyeWppeTY3cWdjcG50MDE0M28zMmRiMWppayZlcD12MV9naWZzX3NlYXJjaCZjdD1n/rUQQIvyqQGuB4MK0Wy/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3N2tnbDlnYWU0aGwzdWEyeWppeTY3cWdjcG50MDE0M28zMmRiMWppayZlcD12MV9naWZzX3NlYXJjaCZjdD1n/rUQQIvyqQGuB4MK0Wy/giphy.gif" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the game we played at this meetup is called &lt;em&gt;“Pass the Story.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To refresh your memory, about the game, here’s how it works, there’s a sheet of paper. One person writes a line and passes it on. The next person reads what’s written and adds the next line. This continues until, collectively, the group creates a story. Simple, right?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3OTc3YXo4a3IwbWtibHM5NTN3NDFzM3lpaTExcWxsenkzazdnd2RodyZlcD12MV9naWZzX3JlbGF0ZWQmY3Q9Zw/3o7aCYrqFvwqNPiDi8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3OTc3YXo4a3IwbWtibHM5NTN3NDFzM3lpaTExcWxsenkzazdnd2RodyZlcD12MV9naWZzX3JlbGF0ZWQmY3Q9Zw/3o7aCYrqFvwqNPiDi8/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now here’s the interesting part: If you’ve played this game before, you already understand ReAct.&lt;/p&gt;

&lt;h3&gt;
  
  
  But... what is ReAct?
&lt;/h3&gt;

&lt;p&gt;ReAct is a model Observing + Reasoning + Acting, (or you can also say, seeing, thinking, and doing) to solve a problem step by step until it reaches an end goal.&lt;/p&gt;

&lt;p&gt;To understand the words “observing, reasoning, and acting” better, let’s map our game “Pass the Story” game to these words.&lt;/p&gt;

&lt;p&gt;The first line written on the page?&lt;/p&gt;

&lt;p&gt;That’s the &lt;em&gt;query&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5d62f0k43hahkedhsip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5d62f0k43hahkedhsip.png" width="655" height="627"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a person receives the paper, they:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Observe.&lt;/strong&gt; The person &lt;em&gt;sees&lt;/em&gt; what the story so far says.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reason.&lt;/strong&gt; The person &lt;em&gt;thinks&lt;/em&gt; about how to continue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action.&lt;/strong&gt; The person &lt;em&gt;writes&lt;/em&gt; the next line and pass it along.&lt;/li&gt;
&lt;li&gt;The person passes the paper to the net person till the reach their &lt;em&gt;goal&lt;/em&gt; of having a completed story.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1he2m9mxlnd2vrj46r6n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1he2m9mxlnd2vrj46r6n.png" alt=" " width="548" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now here’s the most important part.&lt;/p&gt;

&lt;p&gt;The person you pass the paper to has no idea what the story is until they read it.&lt;/p&gt;

&lt;p&gt;And just like the players in the game, models are stateless. They have no inherent memory. They don’t remember your previous API call. They don’t remember your previous conversation.&lt;/p&gt;

&lt;p&gt;They start fresh every single time.&lt;/p&gt;

&lt;p&gt;Like Ghajini. (Yes, the Bollywood movie.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiagtqt71cu5qwx9wgou9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiagtqt71cu5qwx9wgou9.png" alt=" " width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Passing that sheet of paper forward, the full story so far, is exactly like sending the conversation history back to the LLM in your next API call.&lt;/p&gt;

&lt;p&gt;The story so far in the paper is the context.&lt;/p&gt;

&lt;p&gt;Now, ReAct is awesome. Most agentic AI systems lean on it. Heavily.&lt;/p&gt;

&lt;p&gt;But it has it’s goddam flaws.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExaGg4anN1czg3cnJpd3F2MTBqbmx1a2w4MjA0Z3dreWlob244dTE5byZlcD12MV9naWZzX3NlYXJjaCZjdD1n/2Q1ge7FOf5cbfGU4Td/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExaGg4anN1czg3cnJpd3F2MTBqbmx1a2w4MjA0Z3dreWlob244dTE5byZlcD12MV9naWZzX3NlYXJjaCZjdD1n/2Q1ge7FOf5cbfGU4Td/giphy.gif" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The "Infinite Loop" Trap.
&lt;/h3&gt;

&lt;p&gt;Imagine you’re playing this game with a toddler who only knows one sentence:&lt;/p&gt;

&lt;p&gt;_“Cats and dogs are animals. Animals are cats and dogs.”&lt;br&gt;
_&lt;/p&gt;

&lt;p&gt;And they keep writing it. Over and over again. Not cause they mean to. They just have limited vocabulary.&lt;/p&gt;

&lt;p&gt;In AI, this happens too. It’s called infinite looping.&lt;/p&gt;

&lt;p&gt;Sometimes the observation doesn’t provide new useful information. The agent reasons the same thing. Takes the same action. Gets the same result. Repeat.&lt;/p&gt;

&lt;p&gt;Solution? You set a limit.&lt;/p&gt;

&lt;p&gt;For example: “Only allow 5 iterations.”&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Context Window &amp;amp; "Token Fatigue"
&lt;/h3&gt;

&lt;p&gt;Imagine, people are really enjoying the game and the story becomes 100 pages long.&lt;/p&gt;

&lt;p&gt;The next person can’t possibly read all of it before adding their line. &lt;/p&gt;

&lt;p&gt;They’ll skim. They’ll miss context. They’ll get tired. LLMs have the same limitation, and it's called &lt;strong&gt;context windows&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every Observe → Reason → Act loop adds more tokens to the prompt. This:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increases cost&lt;/li&gt;
&lt;li&gt;Slows response time&lt;/li&gt;
&lt;li&gt;Risks hitting context limits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The solution? Context pruning&lt;/p&gt;

&lt;p&gt;Instead of passing the entire history every time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep the last few steps&lt;/li&gt;
&lt;li&gt;Maintain a high-level summary of earlier steps&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.ReAct vs. ReWOO (Plan First, Execute Later)
&lt;/h3&gt;

&lt;p&gt;“Pass the Story” is fun. But you know what’s more efficient? Everyone agreeing on an outline &lt;em&gt;before&lt;/em&gt; writing.&lt;/p&gt;

&lt;p&gt;In ReAct, you think after every step.&lt;/p&gt;

&lt;p&gt;In ReWOO,you think deeply once, generate a structured plan, and then execute it.&lt;/p&gt;

&lt;p&gt;It’s the difference between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improvising a story line by line vs.&lt;/li&gt;
&lt;li&gt;Agreeing on the plot first, then writing chapters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are useful. One is reactive. The other is strategic.&lt;/p&gt;

&lt;p&gt;Opinion:&lt;br&gt;
THINGS ARE MOVING FAST! I feel like I am on a never ending roller coaster ride!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3c3F6cnM2MzdmcmxxOW4weXFhNDluM3ZqdzFneTA2azVnN2JldDkzcyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/XV19cKyELuzELgwXRW/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3c3F6cnM2MzdmcmxxOW4weXFhNDluM3ZqdzFneTA2azVnN2JldDkzcyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/XV19cKyELuzELgwXRW/giphy.gif" width="374" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And, I believe that ReWOO is what the IBM video meant by "2026 is the age for multiple agents". Maybe towards the end of this year, this blog won't even be relevant. :')&lt;/p&gt;

&lt;p&gt;But in the mean time, I hope it was a decent insight into how the ReAct loop works and that you won't be shy to reach out about your thoughts!&lt;/p&gt;

&lt;p&gt;xoxo! &lt;/p&gt;

&lt;p&gt;Rolling credits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The awesome people of Philly write up group who have welcomed me!&lt;/li&gt;
&lt;li&gt;Reddit&lt;/li&gt;
&lt;li&gt;LLMs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExNnhuanF5bWRsdHdkcXExZDlicjk0NWgyOXVlbjA0b29wNWNzdWxwYyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FxT5LMOU99iXOmGVqmI%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExNnhuanF5bWRsdHdkcXExZDlicjk0NWgyOXVlbjA0b29wNWNzdWxwYyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FxT5LMOU99iXOmGVqmI%2Fgiphy.gif" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>explainlikeimfive</category>
      <category>ai</category>
      <category>game</category>
    </item>
    <item>
      <title>January started out strong. I put out 4 blogs, which I would like to think caused a ripple effect, and inspired 4 other people in my network to use Devto and start blogging. YAY!</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Sun, 25 Jan 2026 16:26:49 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/january-started-out-strong-i-put-out-4-blogs-which-i-would-like-to-think-caused-a-ripple-effect-26oe</link>
      <guid>https://dev.to/shlokaguptaa/january-started-out-strong-i-put-out-4-blogs-which-i-would-like-to-think-caused-a-ripple-effect-26oe</guid>
      <description></description>
      <category>devjournal</category>
      <category>devto</category>
      <category>motivation</category>
      <category>writing</category>
    </item>
    <item>
      <title>ELi5 : AI Workflows vs AI Agents, Explained with LEGOs</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Fri, 23 Jan 2026 02:58:04 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/ai-workflows-vs-ai-agents-explained-with-legos-581g</link>
      <guid>https://dev.to/shlokaguptaa/ai-workflows-vs-ai-agents-explained-with-legos-581g</guid>
      <description>&lt;p&gt;Ever dumped a pile of LEGOs on the floor?&lt;/p&gt;

&lt;p&gt;Yes?&lt;/p&gt;

&lt;p&gt;Well then, you are already a step closer to understanding the difference between AI workflows and AI agents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNzMzd3poanl3OGs3NjM2N3E4bWNlYWd4NHlnYmR0ZXNpazZmaTUxaCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/9DQrS7PS31tss/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNzMzd3poanl3OGs3NjM2N3E4bWNlYWd4NHlnYmR0ZXNpazZmaTUxaCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/9DQrS7PS31tss/giphy.gif" width="320" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  AI workflows: LEGO manual builds
&lt;/h3&gt;

&lt;p&gt;An AI workflow is like opening a LEGO house kit and following the instruction manual from step 1 to step 12.&lt;/p&gt;

&lt;p&gt;You know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;exactly which piece snaps where&lt;/li&gt;
&lt;li&gt;the order of the steps&lt;/li&gt;
&lt;li&gt;and what the final house will look like&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing is left to chance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fivq0rzy4eyjzt782ma47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fivq0rzy4eyjzt782ma47.png" alt=" " width="389" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI workflows work the same way. They follow a &lt;em&gt;fixed control path&lt;/em&gt;,  a predefined sequence of steps.&lt;/p&gt;

&lt;p&gt;But why do we even need workflows in the first place?&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Models Alone Aren’t Enough
&lt;/h4&gt;

&lt;p&gt;Models are really good at tasks like drafting emails, writing text messages, generating blog content, creating images, onverting text to voice, and other stuff&lt;/p&gt;

&lt;p&gt;For example, if I ask an LLM:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Hey, can you draft me a text to ask Sam out on a date?”&lt;/em&gt;&lt;br&gt;
An LLM (based application) like ChatGPT or Gemini will do a great job...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7j2phrphj4lavj192r3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7j2phrphj4lavj192r3s.png" alt=" " width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;...but sometimes, they kinda suck!&lt;/p&gt;

&lt;p&gt;Say, I ask chat:&lt;br&gt;
 "When is my date with Sam?"&lt;br&gt;
It won’t have a clue.&lt;/p&gt;

&lt;p&gt;But what makes LLMs/Models kinda suck sometimes?&lt;/p&gt;

&lt;p&gt;While, it's true that they have been trained on massive public datasets, they don’t have access to your personal or proprietary data. Stuff like your calendar,  emails, company’s internal documents, etc.&lt;/p&gt;

&lt;p&gt;So what’s the solution?&lt;br&gt;
Give the model access to your data.(Not all of it. Be careful. Duh!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo673ymf8joevwby65bk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo673ymf8joevwby65bk1.png" alt=" " width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, when the LLM gets questions around time like:&lt;br&gt;
&lt;em&gt;“When is my date with Sam?”&lt;/em&gt;&lt;br&gt;
OR&lt;br&gt;
&lt;em&gt;"When is my lunch?"&lt;/em&gt;&lt;br&gt;
OR&lt;br&gt;
&lt;em&gt;"When is my meeting?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;it will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Query your calendar&lt;/li&gt;
&lt;li&gt;Extract the relevant event&lt;/li&gt;
&lt;li&gt;Summarize it&lt;/li&gt;
&lt;li&gt;Respond to you&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s an AI workflow!&lt;/p&gt;

&lt;p&gt;Note that over here the model is NOT deciding what to do, it’s following a pre-wired path:&lt;br&gt;
Input → Retrieve → Process → Respond&lt;/p&gt;

&lt;p&gt;Just like a LEGO manual, the logic and path is fixed!&lt;/p&gt;

&lt;h4&gt;
  
  
  What makes workflows awesome
&lt;/h4&gt;

&lt;p&gt;AI workflows are awesome because of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Predictable behavior&lt;/li&gt;
&lt;li&gt;Easy to reason about&lt;/li&gt;
&lt;li&gt;Cheap and efficient (Like really cost friendly)&lt;/li&gt;
&lt;li&gt;Same input → same output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You have a ballpark figure of how many “pieces” (API calls, LLM calls, compute) it will take.&lt;/p&gt;

&lt;h4&gt;
  
  
  The downside
&lt;/h4&gt;

&lt;p&gt;If you didn’t plan for a step, the system breaks.&lt;/p&gt;

&lt;p&gt;Just like realizing mid-build that the manual requires a rare LEGO piece you lost under the couch. Everything stops until a human fixes it. :/&lt;/p&gt;

&lt;p&gt;Say, in the AI workflow above, you ask:&lt;br&gt;
“What should I wear for my date, given the weather?”&lt;/p&gt;

&lt;p&gt;The workflow will fail! Not because the question is hard, but because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it doesn’t have access to a weather API&lt;/li&gt;
&lt;li&gt;it doesn’t know how to fetch outfits&lt;/li&gt;
&lt;li&gt;it wasn’t designed for this path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sure, you can fix this by adding a weather API, adding an image generation model, wiring everything together&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5j6mgh90fvytq49rkhb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5j6mgh90fvytq49rkhb.png" alt=" " width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But no matter how many modules you add, it’s &lt;strong&gt;still just a workflow&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is still a fixed, predefined path.&lt;/p&gt;

&lt;p&gt;No matter how many extra tools you glue on, the workflow still can’t decide to change the plan. When you need the system to rethink the plan itself, you don’t need more steps, you need something with a goal and autonomy. That’s where agents come in.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Agents: Free Builds With a Goal
&lt;/h3&gt;

&lt;p&gt;An AI agent is like dumping a pile of LEGOs in front of a kid and saying:&lt;/p&gt;

&lt;p&gt;“Build me something I can live in."&lt;/p&gt;

&lt;p&gt;You don’t give the kid instructions. You give them a &lt;em&gt;goal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The kid then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inspects the available pieces&lt;/li&gt;
&lt;li&gt;decides to build a house&lt;/li&gt;
&lt;li&gt;realizes they’re missing roof tiles&lt;/li&gt;
&lt;li&gt;pivots to a cabin… or a cave&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They reason their way to the goal using whatever resources they have.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmn2bh0vx7pke6w1b6256.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmn2bh0vx7pke6w1b6256.png" alt=" " width="419" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn93fxgsy0gaxpl7ejqmj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn93fxgsy0gaxpl7ejqmj.png" alt=" " width="425" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, with agents, you don’t give the Model a pre defined path, you give:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;goal&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;set of tools&lt;/strong&gt; (APIs, vector databases, workflows, search)&lt;/li&gt;
&lt;li&gt;permission to decide what to do next&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you give models tools, a goal, and permission to decide what to do next, that’s when they start acting like agents.&lt;/p&gt;

&lt;p&gt;In a workflow, you decide this once at design time. In an agent, the LLM decides this at runtime.&lt;/p&gt;

&lt;p&gt;But the awesomeness of agents comes at a cost &lt;/p&gt;

&lt;p&gt;Every decision , “Should I search the web?” , “Should I call this API?”, “Do I need another refinement loop?” is another LLM reasoning step.&lt;/p&gt;

&lt;p&gt;Think of it like hiring a brilliant architect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;incredible ideas&lt;/li&gt;
&lt;li&gt;lots of sketches&lt;/li&gt;
&lt;li&gt;very expensive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agents rarely crash outright. instead, they might give you something technically valid but very wrong.&lt;/p&gt;

&lt;p&gt;Like a LEGO jail, when all you wanted was a small cabin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExY2tpeW5hZWl6MWh2dnVuZHBnYWw4ZHF4MDZ4aGxpMHVxaDU0M2FwMyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/U4Rmm6LiffrzpzLUCk/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExY2tpeW5hZWl6MWh2dnVuZHBnYWw4ZHF4MDZ4aGxpMHVxaDU0M2FwMyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/U4Rmm6LiffrzpzLUCk/giphy.gif" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  So When Should You Use Which?
&lt;/h4&gt;

&lt;p&gt;If you need certainty and repeatability, workflows are your friend.&lt;br&gt;
You know exactly what pieces exist, exactly how they fit together, and exactly how the system behaves. Basically, when you need a factory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3dHp4OWxxbHhuMWpqeGU4bXI5cmU3dnJ4ZzAzbzFmY3djbXlmYmVsZCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/if8GIU966zj62BkScR/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3dHp4OWxxbHhuMWpqeGU4bXI5cmU3dnJ4ZzAzbzFmY3djbXlmYmVsZCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/if8GIU966zj62BkScR/giphy.gif" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you need adaptability in messy environments, agents make sense.&lt;br&gt;
They can reason around missing pieces, try alternative approaches, and still deliver something when the path isn’t clear. &lt;/p&gt;

&lt;p&gt;But the most practical pattern is hybrid.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let workflows handle the predictable assembly line&lt;/li&gt;
&lt;li&gt;Drop agents into the steps that truly need flexible reasoning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach is called, Agentic Workflows, and it’s how most real-world AI systems are being built today.&lt;/p&gt;

&lt;p&gt;Manual where possible. Free build where necessary. Just like LEGOs.&lt;/p&gt;




&lt;p&gt;Rolling Credits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;YouTube videos&lt;/li&gt;
&lt;li&gt;LLMs&lt;/li&gt;
&lt;li&gt;Reddit&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>lego</category>
      <category>explainlikeimfive</category>
    </item>
    <item>
      <title>Vector Embeddings (with OpenAI and Supabase) - Part 3 (storing &amp; searching)</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Fri, 16 Jan 2026 04:43:20 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/vector-embeddings-with-openai-and-supabase-part-3-1171</link>
      <guid>https://dev.to/shlokaguptaa/vector-embeddings-with-openai-and-supabase-part-3-1171</guid>
      <description>&lt;p&gt;Hey there! In the last two blogs, we talked about what vector embeddings are and how to set up OpenAI and Supabase locally so you have a solid playground to experiment in. So incase you want to check out the theory or have your set up up and running, go to the blogs below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt;&amp;nbsp;– &lt;a href="https://dev.to/shlokaguptaa/vector-databases-with-openai-and-supabase-1-4jco"&gt;The theory (what embeddings are and why they matter)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;&amp;nbsp;– &lt;a href="https://dev.to/shlokaguptaa/vector-database-with-supabase-and-openai-part-2-setup-49o9"&gt;Setup ( set up OpenAI client + Supabase + pgvector)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3&lt;/strong&gt;&amp;nbsp;– Vector database &amp;amp; search (👈 YOU ARE HERE)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4&lt;/strong&gt;&amp;nbsp;– A chatbot (proof of concept)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This post is where we actually put everything to work: we’ll turn plain text into vectors, store them in a pgvector‑powered table, and run semantic searches over that data using a custom SQL function. From there, we’ll refactor the logic into small, reusable functions and add the Chat Completions API so the final experience feels like a friendly, grounded assistant instead of a raw database query.&lt;/p&gt;

&lt;p&gt;Also, it may look a little overwhelming for now, but trust me, if I can do it, &lt;em&gt;you&lt;/em&gt;. I believe in you!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3aHBkamZxanl5MnJkaXlnOXBpbXJ2cnY0NjlvODloYThhZTg5cXF3ayZlcD12MV9naWZzX3NlYXJjaCZjdD1n/l2YOC9BjeXhCybEaI/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3aHBkamZxanl5MnJkaXlnOXBpbXJ2cnY0NjlvODloYThhZTg5cXF3ayZlcD12MV9naWZzX3NlYXJjaCZjdD1n/l2YOC9BjeXhCybEaI/giphy.gif" width="500" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So! We’ll walk through this blog in three sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part A&lt;/strong&gt;: Storing data in Supabase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part B&lt;/strong&gt;: Querying&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part C&lt;/strong&gt;: Adding chat completions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get this party started!&lt;/p&gt;

&lt;h3&gt;
  
  
  A. Storing Data in Supabase
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Creating a basic embedding
&lt;/h4&gt;

&lt;p&gt;Now, being able to create an embedding is one of the most important building blocks in any vector database workflow. So let’s start by learning how to use OpenAI’s embeddings API from our Node project.&lt;/p&gt;

&lt;p&gt;If you go to &lt;a href="https://platform.openai.com/docs/guides/embeddings" rel="noopener noreferrer"&gt;OpenAI’s vector embeddings&lt;/a&gt; page, you’ll see that the API expects three main things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The text you want to embed&lt;/li&gt;
&lt;li&gt;The embedding model to use&lt;/li&gt;
&lt;li&gt;The encoding format, which determines how you receive the vectors (as a float array or compressed base64)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkwv2y9xj8q1lxb87mmp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkwv2y9xj8q1lxb87mmp.png" alt=" " width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our previous blog, in our project, we already set up an OpenAI client in&amp;nbsp;&lt;strong&gt;&lt;code&gt;config.js&lt;/code&gt;&lt;/strong&gt;, so we just import it and call the embeddings API from index.js&lt;/p&gt;

&lt;p&gt;And we are going to tweak the code given to us, a bit, to extract the embeddings vector i.e &lt;code&gt;embedding.data[0].embedding&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create an embedding for a given text string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your text string goes here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;encoding_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;float&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Output
[
  0.005132983,
  -0.03028705,
  -0.0016865017,
  0.017242905,
  ...
  -0.020154044,
  -0.048173763
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note that:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;input&lt;/em&gt; can be a single string or an array of strings.&lt;/li&gt;
&lt;li&gt;Regardless of text length, the embedding vector size for &lt;code&gt;text-embedding-3-small&lt;/code&gt; is 1536, from Open AI vector embedding model response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can experiment by changing the&amp;nbsp;&lt;code&gt;input&lt;/code&gt;&amp;nbsp;value and observing how the vector changes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Embeddings for multiple items
&lt;/h4&gt;

&lt;p&gt;If you pass an array of strings, each element gets its own embedding vector, and the response is a list of embedding objects.&lt;/p&gt;

&lt;p&gt;The response contains an array where each entry corresponds to one input string’s embedding&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create an embedding for a given text string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;be good to earth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;encoding_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;float&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Output
PS &amp;gt; node index.js
[
  0.0090422972,  0.02994411,  -0.00023611961,  0.063080595,
  0.043438736,   0.0212318581, 0.0535876,      0.016274985,
  0.025267525,   0.012582723,  0.023231698,    0.034558498,
  0.02852485,    0.011034184,  -0.026081856,
  ...
  1436 more items
]

PS &amp;gt; node index.js
{
  object: 'list',
  data: [
    { object: 'embedding', index: 0, embedding: [Array] },
    { object: 'embedding', index: 1, embedding: [Array] },
    { object: 'embedding', index: 2, embedding: [Array] }
  ],
  model: 'text-embedding-3-small',
  usage: { prompt_tokens: 6, total_tokens: 63 }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make this more fun, let’s work with a small music list&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Taylor Swift : The Fate of Ophelia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Taylor Swift : Cruel Summer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Taylor Swift : Love Story&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Harry Styles : Daylight&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Harry Styles : As It Was&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Harry Styles : Watermelon Sugar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Elvis Presley : Can't Help Falling in Love&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Elvis Presley : Blue Christmas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bruno Mars : I Just Might&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bruno Mars : Die With A Smile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Frank Sinatra : My Way&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Frank Sinatra : Fly Me To The Moon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Create an embedding for a given text string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;encoding_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;float&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To keep things tidy, move the array into a separate file &lt;code&gt;content.js&lt;/code&gt; and import it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//content.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Taylor Swift : The Fate of Ophelia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Taylor Swift : Cruel Summer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Taylor Swift : Love Story&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Harry Styles : Daylight&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Harry Styles : As It Was&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Harry Styles : Watermelon Sugar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Elvis Presley : Can't Help Falling in Love&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Elvis Presley : Blue Christmas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bruno Mars : I Just Might&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bruno Mars : Die With A Smile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Frank Sinatra : My Way&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Frank Sinatra : Fly Me To The Moon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//index.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./content.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import the music array&lt;/span&gt;

&lt;span class="c1"&gt;// Create an embedding for a given text string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;encoding_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;float&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also print each item together with its own embedding, with forEach.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./content.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import the music array&lt;/span&gt;

&lt;span class="c1"&gt;// Create an embedding for a given text string&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;encoding_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;float&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Embedding for "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;":`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;music&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Setting up Supabase with pgvector
&lt;/h4&gt;

&lt;p&gt;In the previous blog, you set up Supabase with pgvector to store and query vector embeddings. Now you need a table to store vectors and their corresponding text, and it can be created directly from Supabase’s docs with a few tweaks.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to: &lt;a href="https://supabase.com/docs/guides/ai/vector-columns" rel="noopener noreferrer"&gt;https://supabase.com/docs/guides/ai/vector-columns&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You will see: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv6txrs3lv6i3b5098f7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv6txrs3lv6i3b5098f7j.png" alt=" " width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy the example table, then tweak it to match this project.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create table documents (
  id bigserial primary key,
  content text,          -- the text chunk
  embedding vector(1536) -- 1536 for OpenAI 'text-embedding-3-small'
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here,&amp;nbsp;&lt;code&gt;content&lt;/code&gt;&amp;nbsp;combines the “title + body” into a single text field, and the vector size is 1536 because that’s the embedding dimension for&amp;nbsp;&lt;code&gt;text-embedding-3-small&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your Supabase project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u94k9xeop7kw844q5sm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u94k9xeop7kw844q5sm.png" alt=" " width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click on &lt;strong&gt;SQL Editor&lt;/strong&gt;, in the side bar&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the code we copied and modified.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswlf9xz76pfadajqof19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswlf9xz76pfadajqof19.png" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After running this, you should see “Success. No rows returned”, and under &lt;strong&gt;Table Editor, in the side bar,&lt;/strong&gt; you’ll see the new &lt;code&gt;documents&lt;/code&gt; table..&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthr7yzk0kfaacy6i86m7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthr7yzk0kfaacy6i86m7.png" alt=" " width="800" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tibwjdcbdz4wjuceei3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tibwjdcbdz4wjuceei3.png" alt=" " width="800" height="706"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Inserting embeddings into Supabase
&lt;/h4&gt;

&lt;p&gt;The process is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pass your data through OpenAI’s embedding model.&lt;/li&gt;
&lt;li&gt;Insert the text and embedding, received from OpenAI,  into Supabase&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You already did step 1 when you generated embeddings for your music list, so now you can focus on inserting those into the&amp;nbsp;&lt;strong&gt;&lt;code&gt;documents&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;table.&lt;/p&gt;

&lt;p&gt;First, here is the original&amp;nbsp;&lt;strong&gt;&lt;code&gt;forEach&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;version, from our code in index.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./content.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import the music array&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;encoding_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;float&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Embedding for "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;":`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;music&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Insert all your rows at once&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use&amp;nbsp;&lt;strong&gt;&lt;code&gt;map&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;instead of&amp;nbsp;&lt;strong&gt;&lt;code&gt;forEach&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Build an array of&amp;nbsp;&lt;strong&gt;&lt;code&gt;{ content, embedding }&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;objects.&lt;/li&gt;
&lt;li&gt;Wrap everything in&amp;nbsp;&lt;strong&gt;&lt;code&gt;Promise.all&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Insert the whole&amp;nbsp;&lt;strong&gt;&lt;code&gt;data&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;array into Supabase in a single call.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./content.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import the music array&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Build an array of { content, embedding } using map&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embeddingResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;encoding_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;float&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;embeddingResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;// Key names must match your SQL table: content, embedding&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Insert all rows at once&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;documents&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error inserting embeddings (batch):&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Embeddings inserted successfully (batch)!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;music&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;When you go back to your table, in your Supabase you will see that all your songs, will be in your table. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff91ael0vouvkv65u4jfq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff91ael0vouvkv65u4jfq.png" alt=" " width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;YAY! We are done with part A. The hard part is behind us now.&lt;/p&gt;

&lt;p&gt;To summarize Part A&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fch8hnys2rwfc3nczzdxf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fch8hnys2rwfc3nczzdxf.png" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  B. Querying
&lt;/h3&gt;

&lt;p&gt;Now that your data is in the database, the next step is search. At a high level, you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A user question (query).&lt;/li&gt;
&lt;li&gt;A way to convert that query into an embedding using OpenAI.&lt;/li&gt;
&lt;li&gt;A similarity function that compares the query embedding to stored embeddings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  A user question / query
&lt;/h4&gt;

&lt;p&gt;Start fresh in&amp;nbsp;&lt;strong&gt;&lt;code&gt;index.js&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;with an example question based on your data. Let’s say, “What song of Taylor’s is about Summer?”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import OpenAI and Supabase clients&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./content.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import the music array&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What Taylor swift song is aboout summer?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Convert the query into a &lt;strong&gt;vector embedding&lt;/strong&gt; using OpenAI
&lt;/h4&gt;

&lt;p&gt;Next, just like we converted our data in create single embedding, we are going to convert our query into an embedded vector&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import OpenAI and Supabase clients&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;music&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./content.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import the music array&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What Taylor swift song is aboout summer?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have an embedding representing the user’s question.&lt;/p&gt;

&lt;h4&gt;
  
  
  Defining the match function in SQL
&lt;/h4&gt;

&lt;p&gt;To search over your embeddings, you can use a helper SQL function based on cosine similarity provided by Supabase’s pgvector extension&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb71wiegsrl95pgzefows.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb71wiegsrl95pgzefows.png" alt=" " width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And before this sounds scary, you don’t have to write this function. It already exists. To search over your embeddings, you can use a helper SQL function based on cosine similarity provided by Supabase’s pgvector extension&lt;/p&gt;

&lt;p&gt;You can head over to the docs at &lt;a href="https://supabase.com/docs/guides/ai/vector-columns" rel="noopener noreferrer"&gt;https://supabase.com/docs/guides/ai/vector-columns&lt;/a&gt;, where there is a ready-made SQL helper for semantic search that you can copy and tweak.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0ldkislt2lwey5q2nof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0ldkislt2lwey5q2nof.png" alt=" " width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are going to tweak the code provided to us on supabase just a little because  the function must reference your table and columns exactly. In our code, the table name is&amp;nbsp;&lt;strong&gt;&lt;code&gt;documents&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;and the columns are&amp;nbsp;&lt;strong&gt;&lt;code&gt;id&lt;/code&gt;&lt;/strong&gt;,&amp;nbsp;&lt;strong&gt;&lt;code&gt;content&lt;/code&gt;&lt;/strong&gt;, and&amp;nbsp;&lt;strong&gt;&lt;code&gt;embedding&lt;/code&gt;&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;replace&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;match_documents&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;query_embedding&lt;/span&gt; &lt;span class="nf"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1536&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;match_threshold&lt;/span&gt; &lt;span class="nx"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;match_count&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="nf"&gt;table &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;similarity&lt;/span&gt; &lt;span class="nx"&gt;float&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;language&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt; &lt;span class="nx"&gt;stable&lt;/span&gt;
&lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;$$&lt;/span&gt;
  &lt;span class="nx"&gt;select&lt;/span&gt;
    &lt;span class="nx"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;similarity&lt;/span&gt;
  &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;documents&lt;/span&gt;
  &lt;span class="nx"&gt;where&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;match_threshold&lt;/span&gt;
  &lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="nx"&gt;by&lt;/span&gt; &lt;span class="nx"&gt;similarity&lt;/span&gt; &lt;span class="nx"&gt;desc&lt;/span&gt;
  &lt;span class="nx"&gt;limit&lt;/span&gt; &lt;span class="nx"&gt;match_count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;$$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this in Supabase:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your project and go to the SQL Editor.&lt;/li&gt;
&lt;li&gt;Create a new query, paste this function, and click&amp;nbsp;&lt;strong&gt;Run&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You should see “Success. No rows returned”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F64iagcnmxh39az24e23y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F64iagcnmxh39az24e23y.png" alt=" " width="800" height="614"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Calling the function from your code
&lt;/h4&gt;

&lt;p&gt;Once the function exists, Supabase exposes it as an RPC, which you can call from anywhere in your code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//index.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// User query&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What Taylor Swift song talks about summer?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Convert the query to an embedding&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embeddingResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;embeddingResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Ask Supabase for the most similar documents&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rpc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;match_documents&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;match_threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// tune this based on your data&lt;/span&gt;
        &lt;span class="na"&gt;match_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// top 1 match&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Matches:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;query_embedding&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;is the vector for the user’s query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;match_threshold&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;is a value from 0 to 1 that controls how similar a match must be to be returned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;match_count&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;is how many top matches you want back.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once it runs, you will see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS&amp;gt; node index.js
Matches: [
  {
    id: 5,
    content: 'Taylor Swift : Cruel Summer',
    similarity: 0.685700174742966
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which makes sense. Because that is the Taylor swift song in our database about summer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3azR5ZTNlZ285Y3JvMjZnYWQ0YmlkZjZrdnUyNXJ0bDc2dW9ld2JseSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/63xUbMdKnuzwsVlR95/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3azR5ZTNlZ285Y3JvMjZnYWQ0YmlkZjZrdnUyNXJ0bDc2dW9ld2JseSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/63xUbMdKnuzwsVlR95/giphy.gif" width="468" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  C. Adding chat completions
&lt;/h3&gt;

&lt;p&gt;The semantic search already works, but the output is just a JSON row from the database. To make the experience feel conversational, you can pass the matched content plus the original question to OpenAI’s Chat Completions API and ask it to generate a short answer.&lt;/p&gt;

&lt;h4&gt;
  
  
  Refactoring the code
&lt;/h4&gt;

&lt;p&gt;At this point, the logic to create embeddings, call Supabase, and handle the user query is all in one place, which makes it harder to read and reuse. A small refactor into separate functions keeps responsibilities clear: one function creates the embedding, one talks to Supabase, and one coordinates the whole flow&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// User query&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What Taylor swift song is about Summer?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Bring all function calls together&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createEmbedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;findNearestMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getChatCompletion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create an embedding vector representing the input text&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createEmbedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embeddingResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;encoding_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;float&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;embeddingResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Query Supabase and return a semantically matching text chunk&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;findNearestMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rpc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;match_documents&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;match_threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;match_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using OpenAI to make the response conversational&lt;/p&gt;

&lt;p&gt;Now add a small chat layer on top of the search result&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chatMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are enthusiastic and love recommending music to people. &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You will be given some context about a song and a question. &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your main job is to formulate a short answer to the question using the provided context. &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;If you are unsure and cannot find the answer in the context, say, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Sorry, I don't know the answer.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please do not make up the answer.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getChatCompletion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sorry, I don't know the answer.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;chatMessages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Context: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\nQuestion: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// or any chat model you prefer&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;chatMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;frequency_penalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in place, the flow looks like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take a natural‑language query.&lt;/li&gt;
&lt;li&gt;Convert it into an embedding with OpenAI.&lt;/li&gt;
&lt;li&gt;Use Supabase’s&amp;nbsp;&lt;strong&gt;&lt;code&gt;match_documents&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;function to find the most similar row.&lt;/li&gt;
&lt;li&gt;Feed that row and the original query into Chat Completions.&lt;/li&gt;
&lt;li&gt;Return a short, friendly answer to the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The complete code for querying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// User query&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What Taylor swift song is about Summer?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Bring all function calls together&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createEmbedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;findNearestMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getChatCompletion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create an embedding vector representing the input text&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createEmbedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embeddingResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;encoding_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;float&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;embeddingResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Query Supabase and return a semantically matching text chunk&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;findNearestMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rpc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;match_documents&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;match_threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;match_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chatMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are enthusiastic and love recommending music to people. &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You will be given some context about a song and a question. &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your main job is to formulate a short answer to the question using the provided context. &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;If you are unsure and cannot find the answer in the context, say, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Sorry, I don't know the answer.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please do not make up the answer.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getChatCompletion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sorry, I don't know the answer.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;chatMessages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Context: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\nQuestion: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// or any chat model you prefer&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;chatMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;frequency_penalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you run this you will see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS&amp;gt; node index.js
The Taylor Swift song about summer is "Cruel Summer."

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What you built
&lt;/h3&gt;

&lt;p&gt;In this blog, you went from basic embeddings to a full semantic search pipeline over your own data, powered by OpenAI and Supabase. You created a documents table with pgvector, generated and stored embeddings in bulk, wrote a custom SQL function for similarity search, refactored your code into small helper functions, and layered Chat Completions on top so the final result feels like a tiny, polite assistant instead of a raw SQL query.&lt;/p&gt;

&lt;p&gt;I AM SO PROUD OF YOU! You made it to the end.&lt;/p&gt;

&lt;p&gt;I know it was probably a little overwhelming, but I think knowing that you have these tools in you tool box and knowing how to work them, is a W!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcWtzNzZqbDY2dnMwcXB4Nmo4MGt4d213cmVheGYyMnFjOHF3c25kcCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/fdyZ3qI0GVZC0/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcWtzNzZqbDY2dnMwcXB4Nmo4MGt4d213cmVheGYyMnFjOHF3c25kcCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/fdyZ3qI0GVZC0/giphy.gif" width="499" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Credits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scrimba&lt;/li&gt;
&lt;li&gt;LLMs to help me fix this&lt;/li&gt;
&lt;li&gt;Random posts on reddit&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>database</category>
      <category>openai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Vector Database (OpenAI and Supabase )-Part 2 (Setup)</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Sun, 11 Jan 2026 22:42:56 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/vector-database-with-supabase-and-openai-part-2-setup-49o9</link>
      <guid>https://dev.to/shlokaguptaa/vector-database-with-supabase-and-openai-part-2-setup-49o9</guid>
      <description>&lt;p&gt;Remember how I said there were only going to be 2 parts to “Vector Databases (with Supabase and OpenAI)”? 😬&lt;/p&gt;

&lt;p&gt;Well… slight change of plans, there are 4 parts now.&lt;br&gt;
And before you start screaming at me through the screen,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNzRnZ2Vmbnd1cW9lYjh3ejNhdHl0dWpsdDQ2eXkwbG1nYTdpbzVndyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/SJFxePZk4ezHcX0c7O/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNzRnZ2Vmbnd1cW9lYjh3ejNhdHl0dWpsdDQ2eXkwbG1nYTdpbzVndyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/SJFxePZk4ezHcX0c7O/giphy.gif" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I split the series up because I go into these steps in excruciating detail. Cause what if there is somewhere out there is someone doing this for the very first time? And the goal is to make every step feel approachable, not overwhelming.&lt;/p&gt;

&lt;p&gt;To keep things digestible, I’m “chunking” the series into four smaller posts instead of one giant wall of text.&lt;/p&gt;

&lt;p&gt;And they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/shlokaguptaa/vector-databases-with-openai-and-supabase-1-4jco"&gt;Part 1&lt;/a&gt; – The theory &lt;/li&gt;
&lt;li&gt;Part 2 – Setup (👈 YOU ARE HERE)&lt;/li&gt;
&lt;li&gt;Part 3 – Vector database &amp;amp; search&lt;/li&gt;
&lt;li&gt;Part 4 – A chatbot (proof of concept)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, before doing anything fancy with vector databases, you need three things: a Supabase project, an OpenAI API key, and a Node project that can talk to both.&lt;/p&gt;

&lt;p&gt;We are going to set up the above in under easy 9 steps. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Supabase project&lt;/li&gt;
&lt;li&gt;Enable the vector extension&lt;/li&gt;
&lt;li&gt;Get your Supabase URL and anon key&lt;/li&gt;
&lt;li&gt;Set up your OpenAI API account&lt;/li&gt;
&lt;li&gt;Create a Node project&lt;/li&gt;
&lt;li&gt;Store your secrets in .env&lt;/li&gt;
&lt;li&gt;Create reusable OpenAI and Supabase clients&lt;/li&gt;
&lt;li&gt;Test everything with a tiny script&lt;/li&gt;
&lt;li&gt;Where you are now&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Create a Supabase project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; and sign in with GitHub or email&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt1sg631tr0yal1rfs9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt1sg631tr0yal1rfs9y.png" alt=" " width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the dashboard, click &lt;strong&gt;New project&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rc7z4lkzo7uap666gxp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rc7z4lkzo7uap666gxp.png" alt=" " width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You will be prompted to create an organization.&lt;/li&gt;
&lt;li&gt;Fill in:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: anything you like (your name, side‑project, or company).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type of organization&lt;/strong&gt;: Personal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing plan&lt;/strong&gt;: Free.&lt;/li&gt;
&lt;li&gt;Click Create&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjg8k8p5gqqcd7b5p20in.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjg8k8p5gqqcd7b5p20in.png" alt=" " width="800" height="683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next you will have to set up your project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under &lt;strong&gt;Organization&lt;/strong&gt;, pick the one you just created&lt;/li&gt;
&lt;li&gt;Set a &lt;strong&gt;Project name&lt;/strong&gt; (for example, vector-embeddings).&lt;/li&gt;
&lt;li&gt;Choose a strong &lt;strong&gt;Database password&lt;/strong&gt; (this is for Postgres, not your login).&lt;/li&gt;
&lt;li&gt;Pick a &lt;strong&gt;Region&lt;/strong&gt; close to you/users for better latency.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create new project&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcba6rqsdnhqoqbz534k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcba6rqsdnhqoqbz534k.png" alt=" " width="800" height="728"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once it’s ready, click on your new project card in the dashboard to enter the Studio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F378op00jzzythujl0tuh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F378op00jzzythujl0tuh.png" alt=" " width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Enable the vector extension
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Next, we need to enable Vector extension. To store embeddings efficiently, Supabase uses the vector (pgvector) extension in Postgres&lt;/li&gt;
&lt;li&gt;In your project sidebar, go to &lt;strong&gt;Database &amp;gt; Extensions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Search for &lt;strong&gt;vector&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click to &lt;strong&gt;Enable&lt;/strong&gt; the vector extension.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbj6072ih9fy073ov8mef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbj6072ih9fy073ov8mef.png" alt=" " width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Get your Supabase URL and anon key
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In the sidebar, click &lt;strong&gt;Project Settings &amp;gt; API Keys&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faq9ybaa65irn1iqvpp5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faq9ybaa65irn1iqvpp5u.png" alt=" " width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under &lt;strong&gt;Legacy anon, service_role API keys&lt;/strong&gt;, find &lt;strong&gt;anon public&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Copy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;This is the key you will use in your Node app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;_NOTE: Never share the **service_role&lt;/strong&gt; key publicly_**&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1doiplwp1wljrdcm7ob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1doiplwp1wljrdcm7ob.png" alt=" " width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In &lt;strong&gt;Project Settings&lt;/strong&gt;, open the &lt;strong&gt;Data API&lt;/strong&gt; (or &lt;strong&gt;API&lt;/strong&gt; section depending on UI).&lt;/li&gt;
&lt;li&gt;Copy the value labeled &lt;strong&gt;Project URL&lt;/strong&gt; (the one that looks like &lt;a href="https://xyzcompany.supabase.co" rel="noopener noreferrer"&gt;https://xyzcompany.supabase.co&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy8efgfemk9zbl64uxgl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy8efgfemk9zbl64uxgl.png" alt=" " width="786" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Store both these values somewhere safe, you will paste them into your .env file in a minute&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Set up your OpenAI API account&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Uhmm, this is the part where I need your 5 dollars. Well, not &lt;em&gt;me&lt;/em&gt;, but Open AI. And yes, I know it sounds expensive, but hear me out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It’s pay-as-you-go. There are no automatic charges unless you explicitly enable auto-pay.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;$5 goes a long way. I’ve been using OpenAI’s API for weeks now, started with $5, and I’m still on $5.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And before you ask, “I already pay $20 for ChatGPT, can I just use that?”&lt;/p&gt;

&lt;p&gt;Unfortunately, that's not how it works. Paying for ChatGPT is like buying a fully built car, it’s a finished product. Paying for OpenAI’s API is like paying for the engine, the part you can actually build things with.&lt;/p&gt;

&lt;p&gt;So, let’s get to it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in to your OpenAI account.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;API platform&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4uhcr6kh1udy5k4x68i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4uhcr6kh1udy5k4x68i.png" alt=" " width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the sidebar (or using the search bar), go to &lt;strong&gt;Billing&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbuvxbh9z3xh0h9x1mx8t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbuvxbh9z3xh0h9x1mx8t.png" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a payment method and purchase credits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(At the time of writing, the minimum preload for new API users is 5 USD)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;- Keep **auto‑recharge&lt;/strong&gt; disabled**&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjes96z0dx20688yrwwto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjes96z0dx20688yrwwto.png" alt=" " width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the dashboard, search for &lt;strong&gt;API keys&lt;/strong&gt; and open the &lt;strong&gt;API keys&lt;/strong&gt; page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv76nerorpdff6h857z6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv76nerorpdff6h857z6l.png" alt=" " width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Create new secret key&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdr7cupdbqsv1ovcnicjh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdr7cupdbqsv1ovcnicjh.png" alt=" " width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give it a name and select the &lt;strong&gt;Default project&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcsnobdwpbazclgqodki1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcsnobdwpbazclgqodki1.png" alt=" " width="800" height="845"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Create secret key&lt;/strong&gt; and copy it immediately, you will not be able to see it again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cwqdyxwj80orbjlvbh0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cwqdyxwj80orbjlvbh0.png" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;*&lt;em&gt;NOTE: Treat this key like a password. Never post it online or commit it to GitHub. If it leaks, delete it and create a new *&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Create a Node project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open your terminal and create a fresh folder for this project:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mkdir my-ai-project &amp;amp;&amp;amp; cd my-ai-project&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Initialize a Node project with a &lt;code&gt;package.json&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;npm init -y&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faaziyd0tmd6e13x6ualx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faaziyd0tmd6e13x6ualx.png" alt=" " width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the official OpenAI SDK and the Supabase JavaScript client:
 &lt;code&gt;npm install openai @supabase/supabase-js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If you want to use a &lt;code&gt;.env&lt;/code&gt; file for secrets (recommended), also install dotenv:
 &lt;code&gt;npm install dotenv&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xjrcbfmddrd275tpm9o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xjrcbfmddrd275tpm9o.png" alt=" " width="800" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open package.json and ensure it looks like this (only showing the important parts):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
{

"name": "my-ai-project",

"version": "1.0.0",

"main": "index.js",

"type": "module",

"scripts": {

"start": "node index.js"

}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycv3ofj3ytjac5bf9j3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycv3ofj3ytjac5bf9j3w.png" alt=" " width="800" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6.Store your secrets in .env
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a file named .env in the root of my-ai-project&lt;/li&gt;
&lt;li&gt;Replace the placeholders with the values you copied from OpenAI and Supabase.

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OPENAI_API_KEY=your-openai-secret-key&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SUPABASE_URL=your-supabase-project-url&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SUPABASE_API_KEY=your-supabase-anon-key&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Do NOT wrap them in quotes.&lt;/li&gt;

&lt;li&gt;Do NOT commit this file to GitHub; &lt;code&gt;.env&lt;/code&gt; should stay private.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3fgrk59m7whxd9as6cx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3fgrk59m7whxd9as6cx.png" alt=" " width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Create reusable OpenAI and Supabase clients
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a new file called &lt;code&gt;config.js&lt;/code&gt; and add this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import OpenAI from "openai";
import { createClient } from "@supabase/supabase-js";
import "dotenv/config";

export const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

export const supabase = createClient(
  process.env.SUPABASE_URL,
  process.env.SUPABASE_API_KEY
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F384wrzopg65j788fgfsx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F384wrzopg65j788fgfsx.png" alt=" " width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Test everything with a tiny script
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a file index&lt;code&gt;.js&lt;/code&gt; with a minimal test, for example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`import { openai } from "./config.js";

async function main() {
  const response = await openai.responses.create({
    model: "gpt-4.1-mini",
    input: "Say hello from my Node project.",
  });

  console.log(response.output[0].content[0].text);
}

main();`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This script sends a tiny test request to the OpenAI API so you can verify that your key and project setup works&lt;/li&gt;
&lt;li&gt;Make sure you are in the project folder in your terminal and run:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;node index.js&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;If everything is set up correctly, you should see a short greeting printed in the terminal from the model.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhnwdsaqvqw0rvkw9mfi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhnwdsaqvqw0rvkw9mfi.png" alt=" " width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Where you are now
&lt;/h3&gt;

&lt;p&gt;At the end of Part 2, you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Supabase project with the vector extension enabled&lt;/li&gt;
&lt;li&gt;A safe place to copy your Supabase URL and anon key&lt;/li&gt;
&lt;li&gt;An OpenAI API key with a small prepaid balance and no auto‑recharge required.&lt;/li&gt;
&lt;li&gt;A Node project where node index.js can successfully call the OpenAI API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next part, i.e. Part 3 of the series,, you can build on this by creating a documents table with a vector column in Supabase, generating embeddings with OpenAI, and storing them for semantic search&lt;/p&gt;

&lt;p&gt;Until then,&lt;br&gt;
&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZTJuZXBhbWhoZWtneHF1aTBnaGx0dXZoMXNhcHdjY242MWtsa2ZwYSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/63yCTfVQOd8c/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZTJuZXBhbWhoZWtneHF1aTBnaGx0dXZoMXNhcHdjY242MWtsa2ZwYSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/63yCTfVQOd8c/giphy.gif" width="245" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vectordatabase</category>
      <category>openai</category>
      <category>supabase</category>
      <category>rag</category>
    </item>
    <item>
      <title>Vector Databases (with OpenAI and Supabase) - Part 1</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Fri, 09 Jan 2026 22:11:02 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/vector-databases-with-openai-and-supabase-1-4jco</link>
      <guid>https://dev.to/shlokaguptaa/vector-databases-with-openai-and-supabase-1-4jco</guid>
      <description>&lt;p&gt;It’s the early 2010s, Apple Music (iTunes) is strongly dominating the market. And services like Pandora, Rhapsody, and Last.fm are all fighting for user attention.&lt;/p&gt;

&lt;p&gt;The music streaming space is already crowded, and competing with a tech giant like Apple seems almost impossible.&lt;/p&gt;

&lt;p&gt;But then, a &lt;em&gt;tiny&lt;/em&gt; European startup emerges.&lt;/p&gt;

&lt;p&gt;In just five years, it goes from zero to tens of millions of users, eventually becoming the number one music streaming platform in the world.&lt;/p&gt;

&lt;p&gt;Today, on the same platform, created by the European startup, when you click on shuffle, it recommends the exact beats you’re looking for, and you love it. Somehow, it just gets &lt;em&gt;your&lt;/em&gt; taste.&lt;/p&gt;

&lt;p&gt;And towards the end of every year, you receive a wrapped that tells you you’ve spent 60,000 minutes listening to music.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafk3nhlxjuxb3ofxw9cl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafk3nhlxjuxb3ofxw9cl.png" alt=" " width="761" height="1371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yep. The “tiny European startup” is… Spotify!!!&lt;/p&gt;

&lt;p&gt;But how did Spotify do that? &lt;em&gt;How&lt;/em&gt; did it beat a tech giant?&lt;br&gt;
&lt;em&gt;How&lt;/em&gt; did it recommend music you didn’t even know you wanted?&lt;/p&gt;

&lt;p&gt;Well, one of the secret sauces behind Spotify’s success is vector databases.&lt;/p&gt;

&lt;p&gt;Now, before going into details about vector databases, though, I want to talk about relational databases. So that we know where we were and where we are at now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcmQ3c2Uxc2tlYTRyMjc2MXdjdW9vZ3hiNnc3b2JncmlxdjQ0ZDd4MSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/cvV0kwc3B1FWzS6Icy/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcmQ3c2Uxc2tlYTRyMjc2MXdjdW9vZ3hiNnc3b2JncmlxdjQ0ZDd4MSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/cvV0kwc3B1FWzS6Icy/giphy.gif" width="480" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Relational Database
&lt;/h3&gt;

&lt;p&gt;I want you to think for a second about, how you would store the song APT by Bruno mars and Rose in a relational database?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjBydXlzYnh3dTg5Mzc3bmQ5eGY1emxmZWY5ZnduamdmcG1lMnRoZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/htAMDLwwR1VSl4DG5Q/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjBydXlzYnh3dTg5Mzc3bmQ5eGY1emxmZWY5ZnduamdmcG1lMnRoZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/htAMDLwwR1VSl4DG5Q/giphy.gif" width="480" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course ,you would store the audio file itself, under the name apt.mp3., along with metadata such as the artist (&lt;em&gt;Bruno Mars, Rose&lt;/em&gt;), the release date, the genre, and maybe a few tags like Pop, R&amp;amp;B, or Dance.&lt;/p&gt;

&lt;p&gt;And how would you search for the song APT in the database? You would perform a &lt;em&gt;lexical&lt;/em&gt; search. It might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;WHERE artist = 'Bruno Mars'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;OR&lt;/p&gt;

&lt;p&gt;&lt;code&gt;WHERE title ILIKE '%APT%'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This works fine, as long as you know exactly what you’re looking for.&lt;/p&gt;

&lt;p&gt;BUT what if you want to search for “late-night city drive vibes” or “smooth, confident, feel-good energy”?&lt;/p&gt;

&lt;p&gt;Your query will fail!&lt;/p&gt;

&lt;p&gt;WHY?!&lt;/p&gt;

&lt;p&gt;Because your database only understands hard-coded labels like Pop or R&amp;amp;B. It has no way of knowing that APT feels like a "feel-good energy" song.&lt;/p&gt;

&lt;p&gt;Relational databases don’t understand similarity beyond what you explicitly define in columns, tags, or foreign keys.&lt;/p&gt;

&lt;p&gt;This limitation is called the &lt;em&gt;semantic gap&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So, how is this solved? Well, with the help of a &lt;em&gt;vector embedings&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vector Embeddings
&lt;/h2&gt;

&lt;p&gt;Let’s start with an example.&lt;/p&gt;

&lt;p&gt;Consider some popular the songs you may have come across on the radio or tik tok. Like, fate of ophelia, manchild, end of beginning, etc.&lt;/p&gt;

&lt;p&gt;Now imagine plotting these songs on a graph based on two characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Danceability (x-axis)&lt;/li&gt;
&lt;li&gt;Energy (y-axis)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After plotting them, each song gets a pair of numerical values, its position on the graph.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvs7izer4ys9gakum8wi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvs7izer4ys9gakum8wi.png" alt=" " width="544" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Song Title&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Artist&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Danceability (X)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Energy (Y)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The Fate of Ophelia&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Taylor Swift&lt;/td&gt;
&lt;td&gt;0.42&lt;/td&gt;
&lt;td&gt;0.38&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Golden&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HUNTR/X feat. EJAE&lt;/td&gt;
&lt;td&gt;0.81&lt;/td&gt;
&lt;td&gt;0.76&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ordinary&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Alex Warren&lt;/td&gt;
&lt;td&gt;0.35&lt;/td&gt;
&lt;td&gt;0.44&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Manchild&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sabrina Carpenter&lt;/td&gt;
&lt;td&gt;0.78&lt;/td&gt;
&lt;td&gt;0.68&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Luther&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Kendrick Lamar &amp;amp; SZA&lt;/td&gt;
&lt;td&gt;0.65&lt;/td&gt;
&lt;td&gt;0.52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;End of Beginning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Djo&lt;/td&gt;
&lt;td&gt;0.68&lt;/td&gt;
&lt;td&gt;0.45&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So now, every song is represented as a pair of numbers i.e [danceability, energy]&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manchild → [0.78, 0.68]&lt;/li&gt;
&lt;li&gt;Ordinary → [0.35, 0.44]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That pair of numbers is a &lt;em&gt;vector&lt;/em&gt; and the process of converting a song, with something abstract like danceability and energy into numbers is called an &lt;em&gt;embedding.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Putting it together
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Embeddings&lt;/strong&gt; are numerical representations of data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vectors&lt;/strong&gt; are those numbers organized into arrays (like &lt;code&gt;[x, y]&lt;/code&gt;, or even hundreds of dimensions)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So a &lt;strong&gt;vector embedding&lt;/strong&gt; is simply:&lt;/p&gt;

&lt;p&gt;Storing real-world data in the form of numbers, arranged as vectors, so that similar things end up close to each other in space.&lt;/p&gt;

&lt;p&gt;In this space, songs with similar energy and danceability appear near each other, making it possible to recommend music based on "vibe", not just tags or keywords.&lt;/p&gt;

&lt;p&gt;An important thing to note is though, in reality, Spotify doesn’t use just two dimensions like &lt;em&gt;energy&lt;/em&gt; and &lt;em&gt;danceability&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A real embedding might have &lt;strong&gt;hundreds or even thousands of dimensions&lt;/strong&gt;, capturing tempo, rhythm patterns, vocal style, instrumentation, and more.&lt;/p&gt;

&lt;p&gt;But the idea remains the same.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating Embedding
&lt;/h4&gt;

&lt;p&gt;Whenever math is involved, I get a little scared &lt;/p&gt;

&lt;p&gt;Plotting in 2D, is fine 3D is manageable but, thousands of dimensions?!! That’s where my brain is like "Oh hell no"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExYXN2dnNpdXg1dDlnYmszcmpoOG5xeXhwMzJkdWVyYm8yOG1sMzcwbyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/OIBjJZHpzbcR2/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExYXN2dnNpdXg1dDlnYmszcmpoOG5xeXhwMzJkdWVyYm8yOG1sMzcwbyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/OIBjJZHpzbcR2/giphy.gif" width="500" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thankfully, we don’t actually need to visualize or manually compute vectors. There are &lt;strong&gt;embedding models&lt;/strong&gt; that do all the heavy lifting for us.&lt;/p&gt;

&lt;p&gt;Some common embedding models are: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CLIP for Images (and image–text similarity)&lt;/li&gt;
&lt;li&gt;GloVe for Text&lt;/li&gt;
&lt;li&gt;Wav2Vec for Audio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Frameworks like Hugging Face provide many pre-trained embedding models for text, images, audio, and more.&lt;/p&gt;

&lt;p&gt;But no matter the data type, the process remains the same:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take &lt;strong&gt;your data&lt;/strong&gt; (text, image, audio, etc.)&lt;/li&gt;
&lt;li&gt;Pass it through an &lt;strong&gt;embedding model&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Get back a &lt;strong&gt;vector embedding&lt;/strong&gt; (an array of numbers)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuad6lhy7wp8qjnghi1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuad6lhy7wp8qjnghi1y.png" alt=" " width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Text Embeddings with OpenAI
&lt;/h4&gt;

&lt;p&gt;This code snippet, in JavaScript, from OpenAI converts text into a vector embedding.&lt;br&gt;
(Don't get scared of it, we will get into the code in the next blog.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz79f9bledyu98umy4itd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz79f9bledyu98umy4itd.png" alt=" " width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use other languages as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqtjl2zekw9k3wr7iveh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqtjl2zekw9k3wr7iveh.png" alt=" " width="800" height="817"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, as you can see, the text “Your text string goes here” is converted into a vector with 1536 dimensions.&lt;/p&gt;

&lt;p&gt;Remember, no matter how long or short your text is, the output vector always has the same fixed size of 1536.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vector Databases
&lt;/h3&gt;

&lt;p&gt;Once you’ve created vector embeddings, the next step is storing them in a &lt;strong&gt;vector database&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fla6s4fidezru8962bzej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fla6s4fidezru8962bzej.png" alt=" " width="682" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When data is stored as embeddings, similar vectors naturally form clusters in vector space. These clusters are then indexed. The process is known as vector indexing. Indexing allows the database to retrieve similar vectors quickly and efficiently, even as the dataset grows.&lt;/p&gt;

&lt;p&gt;At a high level, a vector database does three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store embeddings&lt;/li&gt;
&lt;li&gt;Indexes them efficiently&lt;/li&gt;
&lt;li&gt;Retrieves similar vectors with low latency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vector embeddings are what makes semantic search, recommendations, and RAG systems possible. &lt;/p&gt;

&lt;p&gt;All of this sounds good. But so far, everything we’ve discussed lives mostly in theory.&lt;/p&gt;

&lt;p&gt;In the next blog, we’ll get hands-on and walk through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating embeddings using OpenAI&lt;/li&gt;
&lt;li&gt;Storing those embeddings in SupaBase&lt;/li&gt;
&lt;li&gt;Querying the database to find similar results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And turn theory into code.&lt;/p&gt;

&lt;p&gt;See you in the next blog. In the mean time &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNXM5emhnMWQ5OTlnZnFiOGx3bW11Y3JxYnhmZzd6aThjMTZjeTUwZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/63yCTfVQOd8c/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNXM5emhnMWQ5OTlnZnFiOGx3bW11Y3JxYnhmZzd6aThjMTZjeTUwZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/63yCTfVQOd8c/giphy.gif" width="245" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Credits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scrimba&lt;/li&gt;
&lt;li&gt;IBM's video&lt;/li&gt;
&lt;li&gt;LLMs for correcting the errors.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>database</category>
      <category>openai</category>
    </item>
    <item>
      <title>What the heck Is a Single-Page Application Anyway?</title>
      <dc:creator>Shloka</dc:creator>
      <pubDate>Thu, 18 Dec 2025 22:02:35 +0000</pubDate>
      <link>https://dev.to/shlokaguptaa/what-the-heck-is-a-single-page-application-anyway-47op</link>
      <guid>https://dev.to/shlokaguptaa/what-the-heck-is-a-single-page-application-anyway-47op</guid>
      <description>&lt;p&gt;When I first started learning React, every friend and every YouTube tutorial seemed to say the same damn thing:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"React is used to build Single-Page Applications (SPAs)!"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I'd always pretend I actually knew what a Single-Page Application was, because who wants to sound dumb, right? Honestly, it reminded me of when I'd say, "An object is an instance of a class" without really understanding what it meant.&amp;nbsp;:')&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZmZxcGY5ZTR1OXl2cXZjYjhiczJ4ZnN2bHljNTd4YzZ1bmM2dTFpdSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/26gsccje7r5WUrXsA/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZmZxcGY5ZTR1OXl2cXZjYjhiczJ4ZnN2bHljNTd4YzZ1bmM2dTFpdSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/26gsccje7r5WUrXsA/giphy.gif" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would like to tell you, dear reader, after some Reddit scrolling and LLM-ing (or as the common person says, "ChatGPT-ing"), I finally figured it out! And if you've ever been confused about Single-Page Applications or are just curious, I hope this little blurb helps clarify things.&lt;/p&gt;

&lt;p&gt;But before we can really get to understanding what Single-Page Applications are, we need to take a detour and understand Multi-Page Applications (MPAs).&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Page Applications (MPAs)
&lt;/h3&gt;

&lt;p&gt;Let's pretend that "blahblahblah.com" (yes, I could not come up with a better name) is a traditional application.&lt;br&gt;
Here's what will happen when you go to blahblahblah.com on your device/browser (the client):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. When the page initially loads&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you first visit blahblahblah.com, your browser (the client) will send a request to blahblahblah.com's server for the homepage.&lt;/p&gt;

&lt;p&gt;Once the server receives the request, it gets to work, gathers everything it needs, such as HTML, CSS, JavaScript, and maybe some data from databases or APIs. Once it's got everything ready, it bundles it up and sends a fully rendered homepage in the form of an HTML file back to your browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xhtc6kra278g4d3tc60.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xhtc6kra278g4d3tc60.png" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Navigating to Another Page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let's say you head to the About page of blahblahblah.com. Your browser will send another request to blahblahblah.com's server. The server repeats the same process, builds the About page from scratch (HTML, CSS, JS, data), and sends the resulting About page as an HTML file back to your browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd41z98csi8m96127i2an.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd41z98csi8m96127i2an.png" alt=" " width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When your browser receives the About page, it throws out the previous homepage and fully replaces it with the About page. Everything reloads from scratch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xza1by1y64ipjrifak3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xza1by1y64ipjrifak3.png" alt=" " width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Returning to Home Page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, when you navigate back to the homepage, the whole process repeats: another request, another page rebuild, another full reload in your browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi72go40js3ziddeovkyq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi72go40js3ziddeovkyq.png" alt=" " width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Moreover, most pages like Home, About, and Contact share common elements like headers and footers, but the browser still reloads everything each time.&lt;/p&gt;

&lt;p&gt;This constant back-and-forth, where the browser requests an entirely new HTML file from the server for every single "page" change&amp;nbsp;, is the essence of Multi-Page Application (MPA) architecture.&lt;/p&gt;

&lt;p&gt;The clearest sign you're dealing with an MPA is the brief flicker or white screen you see during navigation as the browser unloads the old page and loads the new one.&lt;/p&gt;

&lt;p&gt;Now as you can tell there are some obvious flaws with MPA, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Re-rendering the same shared content, repeatedly&lt;/li&gt;
&lt;li&gt;Extra server requests&lt;/li&gt;
&lt;li&gt;Increased load time and heavier server strain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So how are single page applications different? Well…&lt;/p&gt;

&lt;h3&gt;
  
  
  Single-Page Applications (SPAs)
&lt;/h3&gt;

&lt;p&gt;Here's the Twist:&lt;/p&gt;

&lt;p&gt;A Single-Page Application doesn't actually mean you're stuck with a never ending page. 😅&lt;/p&gt;

&lt;p&gt;Instead, the whole starts pretty much with the same process as a multi-page application: you open your browser and head over to blahblahblah.com, and your browser asks the server for the site.&lt;/p&gt;

&lt;p&gt;Now, here's the important part: remember how in multi-page applications, every time you went to a new page, your browser would send a new request to the server and the server would build the page on its end and send the whole thing back?&lt;/p&gt;

&lt;p&gt;Well, in a Single-Page Application, on that very first request, the server hands over a single HTML file, along with the entire application bundle (the core JavaScript, CSS, and framework code like React).&lt;/p&gt;

&lt;p&gt;This entire application framework loads into your browser, and from then on, when you "navigate" to a new section (like About or Contact), the JavaScript on the client-side simply intercepts the request and dynamically updates the view without a full page reload&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgitcjn9542kv1bpolxi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgitcjn9542kv1bpolxi.png" alt=" " width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, the browser isn't totally disconnected from the server, it still fetches just the right bits of data as needed. All of this adds up to fewer server requests, less repeated content, and smoother navigation for users.&lt;/p&gt;

&lt;p&gt;And…. that's Single Page Applications architecture for you!&lt;/p&gt;

&lt;p&gt;Now, despite all the cool stuff SPAs have to provide, I still have some lingering questions, for example, what if only part of the app was sent, or if super-frequently visited pages could be delivered separately to make things even faster? There's clearly plenty more to learn.&lt;br&gt;
If you've wondered about SPAs and MPAs too, or just want to share your thoughts, feel free to reach out on X or LinkedIn. It's always good to swap ideas with others on this stuff.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcHNxamY0MnhyamF5OTJxNXAxOXlkbXFsdTJtMTR0ZHRlZTc3dmUzaCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/t6lGyl8QLylqFQJkiA/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcHNxamY0MnhyamF5OTJxNXAxOXlkbXFsdTJtMTR0ZHRlZTc3dmUzaCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/t6lGyl8QLylqFQJkiA/giphy.gif" width="500" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;xoxo!&amp;nbsp;:)&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
