<?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: Ricardo Feldhaus Krisanoski</title>
    <description>The latest articles on DEV Community by Ricardo Feldhaus Krisanoski (@rkrisa).</description>
    <link>https://dev.to/rkrisa</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%2F3955754%2F6dfa9872-3be5-407e-907c-168ea2ded9c3.jpg</url>
      <title>DEV Community: Ricardo Feldhaus Krisanoski</title>
      <link>https://dev.to/rkrisa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rkrisa"/>
    <language>en</language>
    <item>
      <title>Why my first RAG layer starts in Postgres, not in a standalone vector database</title>
      <dc:creator>Ricardo Feldhaus Krisanoski</dc:creator>
      <pubDate>Sat, 13 Jun 2026 12:30:37 +0000</pubDate>
      <link>https://dev.to/rkrisa/why-my-first-rag-layer-starts-in-postgres-not-in-a-standalone-vector-database-29e0</link>
      <guid>https://dev.to/rkrisa/why-my-first-rag-layer-starts-in-postgres-not-in-a-standalone-vector-database-29e0</guid>
      <description>&lt;p&gt;When people say they are "adding RAG" to a workflow, the conversation often jumps too quickly to infrastructure choices.&lt;/p&gt;

&lt;p&gt;Should this use a vector database?&lt;br&gt;
Should there be a reranker?&lt;br&gt;
Should everything go into a knowledge graph?&lt;/p&gt;

&lt;p&gt;Those are valid questions, but they are usually not the first question.&lt;/p&gt;

&lt;p&gt;The first question is narrower:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What approved knowledge should the workflow be allowed to retrieve before an AI decision happens?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is why my first retrieval layer for operational AI workflows starts in Postgres, not in a standalone vector database.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Workflow Problem
&lt;/h2&gt;

&lt;p&gt;In operations-heavy systems, the model usually should not answer from raw memory or from a giant prompt dump.&lt;/p&gt;

&lt;p&gt;The useful context already exists somewhere else:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;approved response rules;&lt;/li&gt;
&lt;li&gt;handoff criteria;&lt;/li&gt;
&lt;li&gt;product or service notes;&lt;/li&gt;
&lt;li&gt;source or campaign guidance;&lt;/li&gt;
&lt;li&gt;operational decisions that were already made by humans.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hard part is not generating fluent text.&lt;/p&gt;

&lt;p&gt;The hard part is retrieving the right approved context, showing which source influenced the decision and refusing when no safe source exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Postgres First
&lt;/h2&gt;

&lt;p&gt;For this kind of workflow, most of the surrounding data is already relational:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;leads or conversations;&lt;/li&gt;
&lt;li&gt;workflow names;&lt;/li&gt;
&lt;li&gt;stages and owners;&lt;/li&gt;
&lt;li&gt;human review outcomes;&lt;/li&gt;
&lt;li&gt;source metadata;&lt;/li&gt;
&lt;li&gt;trace logs;&lt;/li&gt;
&lt;li&gt;document versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the first technical choice is not "where do vectors live in the abstract?"&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Where can I keep retrieval close to the operational data model?&lt;/li&gt;
&lt;li&gt;Where can I log the retrieval path and the final decision together?&lt;/li&gt;
&lt;li&gt;Where can I evolve the schema without creating a second system too early?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Postgres plus &lt;code&gt;pgvector&lt;/code&gt; is a good first answer to that set of questions.&lt;/p&gt;

&lt;p&gt;It lets me keep:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;documents and chunks;&lt;/li&gt;
&lt;li&gt;metadata such as allowed use and approval requirements;&lt;/li&gt;
&lt;li&gt;retrieval traces;&lt;/li&gt;
&lt;li&gt;cost estimates;&lt;/li&gt;
&lt;li&gt;human review outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  What The First Version Needs
&lt;/h2&gt;

&lt;p&gt;The first version does not need to be broad.&lt;/p&gt;

&lt;p&gt;It needs to be inspectable.&lt;/p&gt;

&lt;p&gt;My narrow retrieval scope looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;approved response rules;&lt;/li&gt;
&lt;li&gt;product/service notes;&lt;/li&gt;
&lt;li&gt;handoff and escalation criteria;&lt;/li&gt;
&lt;li&gt;campaign/source guidance;&lt;/li&gt;
&lt;li&gt;commercial playbooks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each retrieved chunk should carry more than text. It should also carry metadata such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;source name;&lt;/li&gt;
&lt;li&gt;document version;&lt;/li&gt;
&lt;li&gt;business domain;&lt;/li&gt;
&lt;li&gt;allowed use;&lt;/li&gt;
&lt;li&gt;whether human approval is required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That metadata matters because a workflow may be allowed to use one chunk as internal reasoning support, but not as customer-facing language.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Eval Mindset
&lt;/h2&gt;

&lt;p&gt;I do not think a retrieval layer is real until it has failure criteria.&lt;/p&gt;

&lt;p&gt;So the public prototype includes a small golden-question set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the expected source appear in the top results?&lt;/li&gt;
&lt;li&gt;Does the workflow return no-answer or handoff when the source is missing?&lt;/li&gt;
&lt;li&gt;Does customer-facing language come only from allowed chunks?&lt;/li&gt;
&lt;li&gt;Can I review which chunks influenced the decision later?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That matters more than announcing that the system has embeddings.&lt;/p&gt;

&lt;p&gt;Without retrieval checks, a RAG layer can look sophisticated while still pulling the wrong context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observability Is Part Of The Design
&lt;/h2&gt;

&lt;p&gt;The retrieval step and the AI decision step should be traceable together.&lt;/p&gt;

&lt;p&gt;I want the same review surface to show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retrieved chunk IDs;&lt;/li&gt;
&lt;li&gt;similarity or retrieval score;&lt;/li&gt;
&lt;li&gt;model name;&lt;/li&gt;
&lt;li&gt;token and cost estimates;&lt;/li&gt;
&lt;li&gt;final decision;&lt;/li&gt;
&lt;li&gt;handoff reason;&lt;/li&gt;
&lt;li&gt;human review outcome.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the bridge between "the system answered" and "the system answered for a defensible reason."&lt;/p&gt;

&lt;h2&gt;
  
  
  When I Would Add More Infrastructure
&lt;/h2&gt;

&lt;p&gt;I am not against standalone vector databases.&lt;/p&gt;

&lt;p&gt;I would add one later if the system needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more search traffic;&lt;/li&gt;
&lt;li&gt;more complex filtering boundaries;&lt;/li&gt;
&lt;li&gt;separate deployment requirements;&lt;/li&gt;
&lt;li&gt;recall/latency needs that justify the extra moving parts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But before that point, I prefer a smaller stack that makes retrieval, evaluation and auditability visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Practical Lesson
&lt;/h2&gt;

&lt;p&gt;For AI workflows in revenue or operations contexts, the first retrieval layer should optimize for control, review and schema clarity.&lt;/p&gt;

&lt;p&gt;Not for maximum architectural novelty.&lt;/p&gt;

&lt;p&gt;That is why my first RAG layer starts in Postgres:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;closer to operational data;&lt;/li&gt;
&lt;li&gt;easier to trace;&lt;/li&gt;
&lt;li&gt;easier to evaluate;&lt;/li&gt;
&lt;li&gt;easier to keep human-in-the-loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The public case study is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rkrisa/portfolio-ai-ops/tree/main/cases/operational-knowledge-retrieval-layer" rel="noopener noreferrer"&gt;https://github.com/rkrisa/portfolio-ai-ops/tree/main/cases/operational-knowledge-retrieval-layer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>postgres</category>
      <category>architecture</category>
    </item>
    <item>
      <title>I added a context resolver before an AI sales agent replies</title>
      <dc:creator>Ricardo Feldhaus Krisanoski</dc:creator>
      <pubDate>Thu, 28 May 2026 05:38:41 +0000</pubDate>
      <link>https://dev.to/rkrisa/i-added-a-context-resolver-before-an-ai-sales-agent-replies-2o5f</link>
      <guid>https://dev.to/rkrisa/i-added-a-context-resolver-before-an-ai-sales-agent-replies-2o5f</guid>
      <description>&lt;p&gt;Most AI sales agents fail before the model writes a single word.&lt;/p&gt;

&lt;p&gt;The failure is not always the prompt. It is usually the context.&lt;/p&gt;

&lt;p&gt;In a real chat-commerce workflow, a lead can arrive with several competing signals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the latest customer message;&lt;/li&gt;
&lt;li&gt;CRM stage and owner;&lt;/li&gt;
&lt;li&gt;previous conversation history;&lt;/li&gt;
&lt;li&gt;campaign or source data;&lt;/li&gt;
&lt;li&gt;product/category assumptions;&lt;/li&gt;
&lt;li&gt;approved response rules;&lt;/li&gt;
&lt;li&gt;handoff and support policies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If all of that gets dumped into a prompt, the model may produce a fluent answer based on the wrong clue.&lt;/p&gt;

&lt;p&gt;That is not an AI problem in the abstract. It is an operating-system problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I was designing an AI reception agent for a chat-driven commerce operation.&lt;/p&gt;

&lt;p&gt;The goal was simple: help the business reply faster and more consistently without losing the commercial context behind each lead.&lt;/p&gt;

&lt;p&gt;But the first automated reply had a hidden risk.&lt;/p&gt;

&lt;p&gt;A customer might send a short message like "hi" or "I want more information." On its own, that message is weak. The stronger signal may be the campaign, source, CRM stage, product page, previous conversation or approved sales rule.&lt;/p&gt;

&lt;p&gt;If the AI agent receives all possible context at once, it still has to decide what matters.&lt;/p&gt;

&lt;p&gt;That decision should not be left entirely to generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Design Choice
&lt;/h2&gt;

&lt;p&gt;I added a context-resolution step before the AI response.&lt;/p&gt;

&lt;p&gt;Instead of asking the model to inspect every clue and improvise, the workflow first resolves a smaller object:&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;"source_priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"campaign_or_crm_or_message_or_fallback"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"resolved_commercial_category"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high_or_medium_or_low"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"selected_directive"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"one_approved_response_rule"&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 important part is not the exact schema. It is the order of decisions.&lt;/p&gt;

&lt;p&gt;The system first decides which commercial context is most trustworthy. Only then does the AI agent write the reply.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;The workflow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Incoming chat lead.&lt;/li&gt;
&lt;li&gt;CRM and conversation lookup.&lt;/li&gt;
&lt;li&gt;Campaign or source-context lookup.&lt;/li&gt;
&lt;li&gt;Context resolver.&lt;/li&gt;
&lt;li&gt;Resolved commercial context.&lt;/li&gt;
&lt;li&gt;AI response agent.&lt;/li&gt;
&lt;li&gt;Structured response and routing decision.&lt;/li&gt;
&lt;li&gt;Customer reply or human handoff.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The resolver is intentionally boring.&lt;/p&gt;

&lt;p&gt;It is a control layer, not a creativity layer.&lt;/p&gt;

&lt;p&gt;It exists to answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the lead probably asking about?&lt;/li&gt;
&lt;li&gt;Which source should win when signals conflict?&lt;/li&gt;
&lt;li&gt;Is confidence high enough to answer directly?&lt;/li&gt;
&lt;li&gt;Which approved sales rule should be used?&lt;/li&gt;
&lt;li&gt;Should the system reply, ask a clarifying question or hand off to a human?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;In business workflows, "more context" is not always better.&lt;/p&gt;

&lt;p&gt;More context can mean more ambiguity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;old messages compete with new ones;&lt;/li&gt;
&lt;li&gt;generic playbooks compete with campaign-specific offers;&lt;/li&gt;
&lt;li&gt;product assumptions compete with what the customer actually asked;&lt;/li&gt;
&lt;li&gt;internal rules compete with customer-facing language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The context resolver reduces that ambiguity before the model responds.&lt;/p&gt;

&lt;p&gt;The AI layer becomes easier to debug because every reply can be traced back to a chosen context, confidence level and directive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guardrails
&lt;/h2&gt;

&lt;p&gt;The workflow keeps several guardrails around the AI response:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;low confidence triggers a consultative fallback;&lt;/li&gt;
&lt;li&gt;sensitive commercial cases can be routed to human review;&lt;/li&gt;
&lt;li&gt;approved response rules are selected before generation;&lt;/li&gt;
&lt;li&gt;the agent receives a compact context package instead of a noisy dump;&lt;/li&gt;
&lt;li&gt;the system logs what context was used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not about making the AI sound more impressive.&lt;/p&gt;

&lt;p&gt;It is about making the operational decision safer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Would Measure Next
&lt;/h2&gt;

&lt;p&gt;The current public version keeps metrics as &lt;code&gt;metrics to collect&lt;/code&gt;, because I do not want to publish numbers that are not validated.&lt;/p&gt;

&lt;p&gt;The useful metrics would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lead volume handled by the context resolver;&lt;/li&gt;
&lt;li&gt;reduction in wrong-context replies;&lt;/li&gt;
&lt;li&gt;human handoff rate by risk category;&lt;/li&gt;
&lt;li&gt;response-time impact;&lt;/li&gt;
&lt;li&gt;manual review time saved.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Lesson
&lt;/h2&gt;

&lt;p&gt;For AI agents in revenue workflows, the prompt is only one part of the system.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;What should the model be allowed to know, trust and act on?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is why I prefer designing AI agents as operating workflows: context resolution, retrieval, guardrails, structured outputs, human review and observability.&lt;/p&gt;

&lt;p&gt;The public case study is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rkrisa/portfolio-ai-ops/tree/main/cases/context-aware-ai-reception-agent" rel="noopener noreferrer"&gt;https://github.com/rkrisa/portfolio-ai-ops/tree/main/cases/context-aware-ai-reception-agent&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>crm</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
