<?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: Vidyush Singh </title>
    <description>The latest articles on DEV Community by Vidyush Singh  (@singhvidyush).</description>
    <link>https://dev.to/singhvidyush</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%2F4167104%2F2e673dc3-ec7f-4114-b164-13ef4c99fb62.jpg</url>
      <title>DEV Community: Vidyush Singh </title>
      <link>https://dev.to/singhvidyush</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/singhvidyush"/>
    <language>en</language>
    <item>
      <title>From JSON to Vector Search: What I Learned Storing Structured User Data for AI</title>
      <dc:creator>Vidyush Singh </dc:creator>
      <pubDate>Tue, 06 Oct 2026 18:47:59 +0000</pubDate>
      <link>https://dev.to/singhvidyush/from-json-to-vector-search-what-i-learned-storing-structured-user-data-for-ai-1m2e</link>
      <guid>https://dev.to/singhvidyush/from-json-to-vector-search-what-i-learned-storing-structured-user-data-for-ai-1m2e</guid>
      <description>&lt;p&gt;When we were building &lt;strong&gt;&lt;a href="https://github.com/singh-vidyush/SpendWise-AI" rel="noopener noreferrer"&gt;SpendWise&lt;/a&gt;&lt;/strong&gt;, one of the things we wanted was pretty simple:&lt;/p&gt;

&lt;p&gt;The AI should know something about the user before answering them.&lt;/p&gt;

&lt;p&gt;Not in the creepy “I know everything about you” way.&lt;/p&gt;

&lt;p&gt;More like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If a user has already told us their income range, savings goal, spending habits, risk preference, and financial goals, why should the AI behave as if it is meeting them for the first time every time they ask a question?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds easy.&lt;/p&gt;

&lt;p&gt;Store the information somewhere, retrieve it later, and give it to the LLM.&lt;/p&gt;

&lt;p&gt;But this is where things got interesting.&lt;/p&gt;

&lt;p&gt;The moment you start dealing with structured user data and LLMs, you run into a question that looks much simpler than it actually is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you make structured data searchable in a way that is actually useful to an AI system?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That was one of the things I started experimenting with while working on SpendWise.&lt;/p&gt;

&lt;p&gt;And this is what I learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  The data wasn't really the problem
&lt;/h2&gt;

&lt;p&gt;Imagine that during onboarding, SpendWise asks a user questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What's your approximate monthly income?&lt;/li&gt;
&lt;li&gt;What are your major expenses?&lt;/li&gt;
&lt;li&gt;What are you saving for?&lt;/li&gt;
&lt;li&gt;What's your risk preference?&lt;/li&gt;
&lt;li&gt;Do you have investment experience?&lt;/li&gt;
&lt;li&gt;What's your short-term financial goal?&lt;/li&gt;
&lt;li&gt;What's your long-term financial goal?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The answers are naturally structured.&lt;/p&gt;

&lt;p&gt;Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"income_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"₹75k–₹1L/month"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"monthly_expenses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"₹45k"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"savings_goal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Build emergency fund"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"investment_experience"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Beginner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk_preference"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Moderate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"financial_goal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Buy a house in 5 years"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From a traditional backend perspective, this isn't particularly complicated.&lt;/p&gt;

&lt;p&gt;Put it into PostgreSQL.&lt;/p&gt;

&lt;p&gt;Create some columns.&lt;/p&gt;

&lt;p&gt;Query it when you need it.&lt;/p&gt;

&lt;p&gt;Done.&lt;/p&gt;

&lt;p&gt;But an LLM doesn't necessarily ask questions in the form of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;user_profile&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A user might ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I have some extra money this month. Should I invest it or keep it aside?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now the useful context isn't just one field.&lt;/p&gt;

&lt;p&gt;The answer could depend on several pieces of information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user's risk preference,&lt;/li&gt;
&lt;li&gt;their emergency-fund status,&lt;/li&gt;
&lt;li&gt;their financial goals,&lt;/li&gt;
&lt;li&gt;their investment experience,&lt;/li&gt;
&lt;li&gt;possibly their spending pattern.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's where I started looking at vector search.&lt;/p&gt;




&lt;h1&gt;
  
  
  The first thing I had to understand: JSON is not a vector
&lt;/h1&gt;

&lt;p&gt;This is probably the most important clarification in this entire topic.&lt;/p&gt;

&lt;p&gt;When I first thought about putting structured data into a vector database, it was tempting to think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I'll just store my JSON in the vector DB and then search it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Technically, that's not really how vector search works.&lt;/p&gt;

&lt;p&gt;A vector database doesn't magically understand JSON.&lt;/p&gt;

&lt;p&gt;The important object is the &lt;strong&gt;embedding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You take some piece of content, pass it through an embedding model, and get a numerical representation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Text / representation
        ↓
Embedding model
        ↓
[0.021, -0.183, 0.742, ...]
        ↓
Vector database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The vector is what enables semantic similarity search.&lt;/p&gt;

&lt;p&gt;The original information can still be stored alongside that vector as metadata, payload, or another source of truth.&lt;/p&gt;

&lt;p&gt;So there are actually two different things happening:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Semantic representation
        ↓
     Embedding
        ↓
   Vector search


Original structured data
        ↓
 JSON / database record
        ↓
 Metadata / source of truth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSON is a representation of structured data.&lt;br&gt;&lt;br&gt;
An embedding is a representation of semantic meaning.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They are not the same thing.&lt;/p&gt;


&lt;h1&gt;
  
  
  So what did we actually want?
&lt;/h1&gt;

&lt;p&gt;Our actual requirement in SpendWise was not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let's put JSON into a vector database."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The requirement was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let's make previously collected user context retrievable when it is relevant to a new question."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a much better way to think about the problem.&lt;/p&gt;

&lt;p&gt;For example, suppose the user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I want to start investing, but I don't want to take too much risk."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI might need context such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"investment_experience"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Beginner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk_preference"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Moderate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"financial_goal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Buy a house in 5 years"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting part is that the AI doesn't necessarily need &lt;strong&gt;every piece of user information&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It needs the &lt;strong&gt;relevant&lt;/strong&gt; information.&lt;/p&gt;

&lt;p&gt;And that distinction becomes extremely important as the system grows.&lt;/p&gt;




&lt;h1&gt;
  
  
  One approach: represent the structured data semantically
&lt;/h1&gt;

&lt;p&gt;One thing you can do is take the structured information and create a semantic representation of it.&lt;/p&gt;

&lt;p&gt;For example, instead of embedding this directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"income_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"₹75k–₹1L/month"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"savings_goal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Build emergency fund"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"investment_experience"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Beginner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk_preference"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Moderate"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you could represent the same information as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The user earns approximately ₹75k–₹1L per month.
They are currently focused on building an emergency fund.
They are a beginner investor.
Their risk preference is moderate.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then generate an embedding from that representation.&lt;/p&gt;

&lt;p&gt;Why might this help?&lt;/p&gt;

&lt;p&gt;Because embedding models are generally designed to capture semantic relationships in content.&lt;/p&gt;

&lt;p&gt;Natural language gives the model more context than arbitrary field names and values.&lt;/p&gt;

&lt;p&gt;But there's an important caveat:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This isn't a universal rule that natural language is always better than JSON.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Embedding models and data formats vary.&lt;/p&gt;

&lt;p&gt;If you're building something serious, the correct answer is to test it.&lt;/p&gt;

&lt;p&gt;You could compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw JSON
vs
Natural-language representation
vs
A structured + natural-language hybrid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and measure retrieval quality.&lt;/p&gt;

&lt;p&gt;That's much more useful than blindly following the assumption that one format is always superior.&lt;/p&gt;




&lt;h1&gt;
  
  
  But then I ran into another problem
&lt;/h1&gt;

&lt;p&gt;Let's say we successfully embed our user information.&lt;/p&gt;

&lt;p&gt;Now imagine the user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Show me all my expenses above ₹10,000 from last month."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Should I use vector search?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;p&gt;This is where the idea of &lt;strong&gt;putting everything into a vector database&lt;/strong&gt; starts falling apart.&lt;/p&gt;

&lt;p&gt;Because some questions aren't semantic-search problems.&lt;/p&gt;

&lt;p&gt;They're database-query problems.&lt;/p&gt;

&lt;p&gt;If I need:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;expenses &amp;gt; ₹10,000&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;SQL is extremely good at that.&lt;/p&gt;

&lt;p&gt;Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;expenses&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2026-09-01'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;'2026-10-01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no reason to ask an embedding model to solve something that a database can solve deterministically.&lt;/p&gt;

&lt;p&gt;And this led me to a much more useful way of thinking about the architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  SQL and Vector Search aren't competitors
&lt;/h1&gt;

&lt;p&gt;I think this is one of the easiest mistakes to make when building AI applications.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"We're building an AI application, so everything should go into a vector database."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not really.&lt;/p&gt;

&lt;p&gt;SQL and vector databases solve different problems.&lt;/p&gt;

&lt;p&gt;If I need an exact value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is my monthly income?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A structured database is perfect.&lt;/p&gt;

&lt;p&gt;If I need a range:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Show transactions above ₹20,000.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SQL is perfect.&lt;/p&gt;

&lt;p&gt;If I need semantic similarity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Have I made any unusually large purchases recently?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vector search might be useful, depending on how the data is represented.&lt;/p&gt;

&lt;p&gt;And if I need both?&lt;/p&gt;

&lt;p&gt;That's where things get interesting.&lt;/p&gt;




&lt;h1&gt;
  
  
  The approach I like more: hybrid retrieval
&lt;/h1&gt;

&lt;p&gt;Instead of asking one database to do everything, we can let each system do what it is good at.&lt;/p&gt;

&lt;p&gt;A simplified architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    User Question
                          │
                          ▼
                    Query Analysis
                          │
              ┌───────────┴───────────┐
              ▼                       ▼
        Structured Query        Semantic Search
              │                       │
              ▼                       ▼
             SQL                  Vector DB
              │                       │
              └───────────┬───────────┘
                          ▼
                  Relevant Context
                          │
                          ▼
                         LLM
                          │
                          ▼
                       Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;"I've been spending a lot lately. Based on my financial goals, am I still on track?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are potentially two different types of information involved.&lt;/p&gt;

&lt;p&gt;The structured side might tell us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Monthly income
Monthly expenses
Savings amount
Current savings goal
Transaction totals
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The semantic side might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The user is trying to build an emergency fund
The user prefers moderate investment risk
The user wants to buy a house within five years
The user previously expressed concern about unnecessary spending
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the LLM receives a much more useful context window.&lt;/p&gt;

&lt;p&gt;Not the entire database.&lt;/p&gt;

&lt;p&gt;Not every piece of telemetry.&lt;/p&gt;

&lt;p&gt;Not every conversation.&lt;/p&gt;

&lt;p&gt;Just the information relevant to the current question.&lt;/p&gt;




&lt;h1&gt;
  
  
  And that's the real problem: relevance
&lt;/h1&gt;

&lt;p&gt;This changed how I think about vector databases.&lt;/p&gt;

&lt;p&gt;Initially, the interesting part was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I store this data?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But that's actually not the hard part.&lt;/p&gt;

&lt;p&gt;The harder question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"How do I retrieve the right data at the right time?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can have a beautiful vector database with millions of embeddings and still build a terrible AI system.&lt;/p&gt;

&lt;p&gt;Because if retrieval gives the LLM the wrong context, the LLM will confidently work with the wrong context.&lt;/p&gt;

&lt;p&gt;That gives us a simple chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bad retrieval
      ↓
Bad context
      ↓
Bad reasoning
      ↓
Bad answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And throwing a bigger model at the final step doesn't necessarily fix it.&lt;/p&gt;




&lt;h1&gt;
  
  
  What about storing the JSON itself?
&lt;/h1&gt;

&lt;p&gt;There is still a perfectly valid reason to keep the original JSON or structured record around.&lt;/p&gt;

&lt;p&gt;In fact, I would argue that you usually should.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk_preference"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"moderate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"investment_experience"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"beginner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"financial_goal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"buy_house"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target_year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2031&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structured representation is useful because your application can directly access exact fields.&lt;/p&gt;

&lt;p&gt;Your vector record could then look conceptually like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vector:
[0.12, -0.03, 0.81, ...]

Metadata:
{
  "user_id": "123",
  "profile_type": "financial_profile"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And somewhere else, PostgreSQL can remain the authoritative source for the structured profile.&lt;/p&gt;

&lt;p&gt;This gives you a useful separation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL stores what the system knows.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vector search helps find what is semantically relevant.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That distinction is subtle, but it makes the architecture much easier to reason about.&lt;/p&gt;




&lt;h1&gt;
  
  
  There are actually three approaches here
&lt;/h1&gt;

&lt;p&gt;After looking at the problem this way, I think structured data + AI retrieval can broadly be approached in three ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Structured data + embeddings
&lt;/h2&gt;

&lt;p&gt;Keep your structured data as structured data, but create embeddings for the parts that benefit from semantic retrieval.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PostgreSQL
    │
    ├── income
    ├── expenses
    ├── goals
    ├── risk preference
    └── investment experience

             +

Vector DB
    │
    ├── semantic profile representation
    ├── user context
    └── relevant historical information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works well when you have a combination of exact and semantic questions.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. SQL-first retrieval
&lt;/h2&gt;

&lt;p&gt;Sometimes you don't need vectors at all.&lt;/p&gt;

&lt;p&gt;If most of your questions look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How much did I spend last month?
&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;What's my average monthly expense?
&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;How much have I saved this year?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then SQL is probably the better tool.&lt;/p&gt;

&lt;p&gt;Adding a vector database just because the application contains an LLM would add complexity without solving a real problem.&lt;/p&gt;

&lt;p&gt;That's an important engineering lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI doesn't automatically make deterministic systems obsolete.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes the best AI architecture contains a lot of boring SQL.&lt;/p&gt;

&lt;p&gt;And that's okay.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Hybrid retrieval
&lt;/h2&gt;

&lt;p&gt;This is probably the most interesting approach for systems like SpendWise.&lt;/p&gt;

&lt;p&gt;Use SQL for deterministic information.&lt;/p&gt;

&lt;p&gt;Use vector search for semantic information.&lt;/p&gt;

&lt;p&gt;Then combine the retrieved context before sending it to the LLM.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User:
"Can I afford to invest more aggressively right now?"

             │
             ▼
      Query understanding
             │
       ┌─────┴─────┐
       ▼           ▼
      SQL        Vector
       │           │
       ▼           ▼
Current       Financial
financial     goals + relevant
numbers       user context
       │           │
       └─────┬─────┘
             ▼
      Context assembly
             │
             ▼
            LLM
             │
             ▼
          Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the LLM isn't responsible for retrieving everything itself.&lt;/p&gt;

&lt;p&gt;The application does the retrieval work first.&lt;/p&gt;

&lt;p&gt;That's a much healthier architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  One experiment I'd definitely run
&lt;/h1&gt;

&lt;p&gt;If I were rebuilding this from scratch, there's one experiment I'd want to run properly.&lt;/p&gt;

&lt;p&gt;Take the same set of user profiles and create three representations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Version A — Raw JSON
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk_preference"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"moderate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"investment_experience"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"beginner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"goal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"buy a house"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Version B — Natural language
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The user is a beginner investor with a moderate risk preference.
Their primary financial goal is to buy a house.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Version C — Hybrid representation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Financial profile:
- Risk preference: moderate
- Investment experience: beginner
- Primary goal: buy a house

The user is relatively new to investing and prefers moderate risk.
Their long-term financial objective is purchasing a house.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then test the same set of queries against all three.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I don't want to take too much risk."

"Would a high-risk investment make sense for me?"

"What should I prioritize financially?"

"How should I invest for my house?"

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

&lt;/div&gt;



&lt;p&gt;Then measure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did the correct profile get retrieved?&lt;/li&gt;
&lt;li&gt;How many relevant records were retrieved?&lt;/li&gt;
&lt;li&gt;Were irrelevant records included?&lt;/li&gt;
&lt;li&gt;How much context was passed to the LLM?&lt;/li&gt;
&lt;li&gt;How much did latency change?&lt;/li&gt;
&lt;li&gt;Did the final answer actually improve?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you're no longer saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I think this works."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You're measuring it.&lt;/p&gt;

&lt;p&gt;And that's the point where an AI experiment starts becoming an engineering experiment.&lt;/p&gt;




&lt;h1&gt;
  
  
  A mistake I would avoid
&lt;/h1&gt;

&lt;p&gt;One thing I wouldn't recommend is embedding every single field just because you can.&lt;/p&gt;

&lt;p&gt;For example, imagine storing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User ID
Age
Country
Currency
Account ID
Created At
Updated At
Risk Preference
Income
Goal
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and embedding the entire thing.&lt;/p&gt;

&lt;p&gt;You might end up paying the cost of vector storage and retrieval without getting much semantic value from it.&lt;/p&gt;

&lt;p&gt;Some information is simply better represented as structured metadata.&lt;/p&gt;

&lt;p&gt;Some information benefits from semantic embeddings.&lt;/p&gt;

&lt;p&gt;Some information doesn't need to be retrieved at all.&lt;/p&gt;

&lt;p&gt;The goal isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Put everything into the vector database."&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Make the right information available to the model when it needs it."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those sound similar.&lt;/p&gt;

&lt;p&gt;They're actually very different engineering decisions.&lt;/p&gt;




&lt;h1&gt;
  
  
  The part I found most interesting
&lt;/h1&gt;

&lt;p&gt;The more I worked through this, the more I realized that vector databases aren't really the main story.&lt;/p&gt;

&lt;p&gt;The main story is &lt;strong&gt;representation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The same user can exist in multiple representations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                User
                 │
       ┌─────────┼─────────┐
       ▼         ▼         ▼
   SQL record   JSON    Embedding
       │         │         │
       │         │         │
 exact data   structured  semantic
              context     similarity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;None of these representations is inherently "the correct one."&lt;/p&gt;

&lt;p&gt;They are useful for different jobs.&lt;/p&gt;

&lt;p&gt;SQL is great at answering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is the value?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;JSON is great at representing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What does this object look like?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An embedding is useful for:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What information is semantically similar to this query?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once I started thinking about the problem this way, the architecture became much clearer.&lt;/p&gt;




&lt;h1&gt;
  
  
  So, what would I do in a production system?
&lt;/h1&gt;

&lt;p&gt;For something like SpendWise, I wouldn't choose between SQL and a vector database.&lt;/p&gt;

&lt;p&gt;I'd probably use both.&lt;/p&gt;

&lt;p&gt;Something along these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ┌───────────────────┐
                    │      User         │
                    └─────────┬─────────┘
                              │
                              ▼
                         User Query
                              │
                              ▼
                    ┌───────────────────┐
                    │ Retrieval Layer   │
                    └─────────┬─────────┘
                              │
                  ┌───────────┴───────────┐
                  │                       │
                  ▼                       ▼
            Structured                 Semantic
             Retrieval                Retrieval
                  │                       │
                  ▼                       ▼
              PostgreSQL              Vector DB
                  │                       │
                  └───────────┬───────────┘
                              ▼
                       Context Builder
                              │
                              ▼
                             LLM
                              │
                              ▼
                           Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact architecture would obviously depend on the application.&lt;/p&gt;

&lt;p&gt;But the principle is what matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't make the vector database your source of truth.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't make SQL responsible for semantic similarity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't make the LLM responsible for retrieving everything.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Give each component a job.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I took away from building this
&lt;/h1&gt;

&lt;p&gt;The biggest lesson for me wasn't about JSON, embeddings, or even vector databases.&lt;/p&gt;

&lt;p&gt;It was this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI systems are often less about how much information you store and more about how intelligently you retrieve it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can give an LLM a huge amount of context and still get a worse answer.&lt;/p&gt;

&lt;p&gt;You can give it a small amount of carefully selected context and get a much better one.&lt;/p&gt;

&lt;p&gt;That's why I think the question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Where should I store this data?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;is often the wrong first question.&lt;/p&gt;

&lt;p&gt;A better sequence is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What kind of data is this?
        ↓
What kind of questions will I ask about it?
        ↓
Do those questions require exact lookup or semantic retrieval?
        ↓
What representation works best?
        ↓
How do I retrieve only the relevant context?
        ↓
How do I measure whether retrieval actually helped?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And only then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which database should I use?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Final thought
&lt;/h1&gt;

&lt;p&gt;When we started working on SpendWise, the original problem felt like a storage problem.&lt;/p&gt;

&lt;p&gt;We had user information.&lt;/p&gt;

&lt;p&gt;We needed to save it.&lt;/p&gt;

&lt;p&gt;We needed the AI to use it later.&lt;/p&gt;

&lt;p&gt;Simple enough.&lt;/p&gt;

&lt;p&gt;But once you start building the retrieval layer, you realize that &lt;strong&gt;storage is the easy part&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The interesting engineering problem is deciding what information the AI actually needs, how to represent that information, how to retrieve it, and how to prevent irrelevant context from polluting the answer.&lt;/p&gt;

&lt;p&gt;That's where SQL, JSON, metadata, embeddings, vector databases, and LLMs start fitting together.&lt;/p&gt;

&lt;p&gt;Not as replacements for each other.&lt;/p&gt;

&lt;p&gt;As different pieces of the same system.&lt;/p&gt;

&lt;p&gt;And honestly, that's the part I find much more interesting about building AI applications.&lt;/p&gt;

&lt;p&gt;It's not just about making the model smarter.&lt;/p&gt;

&lt;p&gt;It's about making the &lt;strong&gt;system around the model smarter.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vectordatabase</category>
      <category>database</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
