<?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: ArisynData</title>
    <description>The latest articles on DEV Community by ArisynData (@arisyndata).</description>
    <link>https://dev.to/arisyndata</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%2F3640833%2F877a0e7c-a59f-4ed3-baac-6bf99ad9c964.jpg</url>
      <title>DEV Community: ArisynData</title>
      <link>https://dev.to/arisyndata</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arisyndata"/>
    <language>en</language>
    <item>
      <title>Why RBAC Alone Isn't Enough for Enterprise Data Agents</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Thu, 10 Sep 2026 02:21:17 +0000</pubDate>
      <link>https://dev.to/arisyndata/why-rbac-alone-isnt-enough-for-enterprise-data-agents-3b4f</link>
      <guid>https://dev.to/arisyndata/why-rbac-alone-isnt-enough-for-enterprise-data-agents-3b4f</guid>
      <description>&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%2Fv2clghn2xkw65d52gv6d.jpg" 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%2Fv2clghn2xkw65d52gv6d.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A user can be blocked from a sensitive column and still receive sensitive information derived from data they are allowed to access.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That changes the authorization problem for enterprise data agents.&lt;/p&gt;

&lt;p&gt;Traditional access control asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can this user read this database object?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An AI analytics system also needs to ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is this user allowed to receive what the system can infer from those objects?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider a simple example.&lt;/p&gt;

&lt;p&gt;A user cannot access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;employee.salary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the same user can access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;department.total_cost
department.employee_count
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A capable data agent can derive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;estimated_average_salary
=
department.total_cost
/
department.employee_count
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No forbidden salary column was queried.&lt;/p&gt;

&lt;p&gt;The database permission model may have worked perfectly.&lt;/p&gt;

&lt;p&gt;The answer may still disclose information the policy intended to protect.&lt;/p&gt;

&lt;p&gt;This is why:&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Table access ≠ Answer access.&lt;/strong&gt;
&lt;/h1&gt;




&lt;p&gt;&lt;strong&gt;RBAC Still Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is not an argument against role-based access control.&lt;/p&gt;

&lt;p&gt;RBAC remains a critical foundation.&lt;/p&gt;

&lt;p&gt;A typical model might define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role: Sales Manager

ALLOW:
  customer
  sales_order
  product
  regional_revenue

DENY:
  employee.salary
  payroll
  compensation_detail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the database layer, those controls should continue to be enforced.&lt;/p&gt;

&lt;p&gt;The problem is that an AI agent introduces several stages above the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Natural Language
      ↓
Intent Resolution
      ↓
Semantic Resolution
      ↓
Context Retrieval
      ↓
Relationship Planning
      ↓
SQL Generation
      ↓
Execution
      ↓
Answer Generation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authorization therefore has more surfaces than a traditional application issuing predefined SQL.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Inference Gap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's formalize the salary example.&lt;/p&gt;

&lt;p&gt;Suppose policy says:&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;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"employee.salary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deny"&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;But:&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;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"department.total_cost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&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;and:&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;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"department.employee_count"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&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 agent creates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f(total_cost, employee_count)
→ estimated_average_salary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every input is authorized.&lt;/p&gt;

&lt;p&gt;The derived concept may not be.&lt;/p&gt;

&lt;p&gt;Call this the &lt;strong&gt;inference gap&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorized Inputs
      ↓
Reasoning / Aggregation
      ↓
Restricted Information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Traditional object-level authorization may not express that boundary.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Add Semantic Authorization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Users ask questions in business concepts.&lt;/p&gt;

&lt;p&gt;So policy should increasingly understand business concepts too.&lt;/p&gt;

&lt;p&gt;Instead of governing only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;employee.salary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;define a semantic concept:&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;"concept"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"employee_compensation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"direct_access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"derived_access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deny"&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;Now a request such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the average salary of the engineering team?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;can be resolved first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intent
→ Employee Compensation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then evaluated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Employee Compensation
→ DENY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;before SQL generation begins.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;semantic authorization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It lets policy operate at the same abstraction level as the user's question.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Authorization Should Start Before SQL Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Retrieve Schema
   ↓
Generate SQL
   ↓
Database Permission Check
   ↓
Execute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is that the model may already have received context it should not use.&lt;/p&gt;

&lt;p&gt;A stronger pipeline is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
      ↓
Identity
      ↓
Intent Resolution
      ↓
Semantic Policy
      ↓
Authorized Context
      ↓
Authorized Relationship Graph
      ↓
Query Planning
      ↓
SQL Generation
      ↓
Database Enforcement
      ↓
Answer Policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important change is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Authorization constrains reasoning context before it constrains execution.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Build an Authorized Context Resolver&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine the enterprise semantic layer contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue
Gross Margin
Customer Risk
Payroll Cost
Employee Compensation
Product Profitability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A generic context retriever might return all concepts semantically related to the question.&lt;/p&gt;

&lt;p&gt;That is risky.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Candidate Context
      ↓
Identity + Policy
      ↓
Authorized Context
      ↓
LLM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pseudocode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;resolve_authorized_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolve_intent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;retrieve_semantic_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;allowed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;can_use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&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="n"&gt;allowed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real implementation will need stronger policy semantics, but the architectural boundary matters.&lt;/p&gt;

&lt;p&gt;Do not give the model unauthorized context and hope the final SQL check fixes everything.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Relationships Need Authorization Too&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose relationship discovery finds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Employee
   ↓
Department
   ↓
Cost Center
   ↓
Financial Cost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The path is structurally valid.&lt;/p&gt;

&lt;p&gt;But a Sales user may not be allowed to traverse it.&lt;/p&gt;

&lt;p&gt;So distinguish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trusted Relationship
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorized Relationship
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A relationship object could carry policy metadata:&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"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"department"&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"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cost_center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"trusted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"allowed_roles"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"finance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"hr"&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;span class="p"&gt;}&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;Then query planning uses a user-specific graph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;authorized_graph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;edge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;can_traverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edge&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;This gives us another useful rule:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Valid relationship ≠ Authorized relationship.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Query Planning Should Operate on the Authorized Graph&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Assume the full relationship graph contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer ─ Order ─ Payment
Employee ─ Department ─ Cost Center
Supplier ─ Contract ─ Pricing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a Sales user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer ─ Order ─ Payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;may be available.&lt;/p&gt;

&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Employee ─ Department ─ Cost Center
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;may be removed from the planning graph.&lt;/p&gt;

&lt;p&gt;The SQL generator never sees that path.&lt;/p&gt;

&lt;p&gt;That is safer than generating the query first and rejecting it later.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Direct Access and Derived Access Are Different Policies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some concepts need two policy dimensions.&lt;/p&gt;

&lt;p&gt;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;"concept"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer_credit_risk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"direct_access"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"roles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"risk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finance"&lt;/span&gt;&lt;span class="p"&gt;]&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;span class="nl"&gt;"derived_access"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"roles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"risk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finance"&lt;/span&gt;&lt;span class="p"&gt;]&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;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;Why distinguish them?&lt;/p&gt;

&lt;p&gt;Because an organization might allow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Department Cost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but restrict:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Individual Compensation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or permit individual operational metrics while restricting a derived risk score.&lt;/p&gt;

&lt;p&gt;The derived concept may have different sensitivity from its inputs.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Answer-Level Policy Is the Final Boundary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even with pre-query authorization, a final result check is useful.&lt;/p&gt;

&lt;p&gt;The pipeline may produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL Valid               ✓
Database Access         ✓
Relationship Valid      ✓
Execution               ✓
Answer Policy           ✕
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system should not return the result.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;answer_concepts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;classify_result_semantics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query_plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;concept&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;answer_concepts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;can_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;concept&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;PolicyDenied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;concept&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not simply SQL validation.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;answer validation&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why Result Classification Is Hard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A result rarely arrives labeled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"This is sensitive compensation information."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system needs evidence from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Original Intent
Resolved Semantic Concepts
Selected Metrics
Query Plan
Aggregations
Relationship Path
Output Columns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means answer governance should not be implemented as a disconnected moderation step.&lt;/p&gt;

&lt;p&gt;It should preserve semantic provenance throughout query execution.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Preserve a Semantic Query Plan&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of storing only SQL:&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="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;store a structured plan:&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;"intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"average employee compensation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"concepts"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"employee_compensation"&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;span class="nl"&gt;"metrics"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"department_total_cost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"employee_count"&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;span class="nl"&gt;"derived_metric"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"estimated_average_salary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"expression"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"department_total_cost / employee_count"&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;span class="nl"&gt;"relationships"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"employee -&amp;gt; department"&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;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;Now authorization has something meaningful to evaluate.&lt;/p&gt;

&lt;p&gt;This is another reason production Text-to-SQL should not be treated as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question → SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intermediate query plan matters.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Add Policy to the Query Plan&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A policy-aware plan might look 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;"concept"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"employee_compensation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"authorization"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"semantic_access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"data_access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"relationship_access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"answer_access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;span class="nl"&gt;"decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deny"&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 system can stop before execution.&lt;/p&gt;

&lt;p&gt;For a different user:&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;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HR Partner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&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 same natural-language question can therefore produce different authorized query plans.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Policy-Aware Clarification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authorization can also affect clarification.&lt;/p&gt;

&lt;p&gt;Suppose a user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show employee cost.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system resolves two candidates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Department Operating Cost
Employee Compensation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user is authorized for the first but not the second.&lt;/p&gt;

&lt;p&gt;A naive clarification UI might reveal both options.&lt;/p&gt;

&lt;p&gt;That itself may leak sensitive semantic structure.&lt;/p&gt;

&lt;p&gt;Instead, candidate generation should be policy-filtered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Candidate Concepts
      ↓
Policy Filter
      ↓
Allowed Clarification Options
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authorization therefore affects not only execution but also what the system is allowed to discuss.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Explain Denials in Business Terms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A natural-language interface should not return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQLSTATE 42501
permission denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when the real issue is semantic.&lt;/p&gt;

&lt;p&gt;A better response might be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This question would reveal restricted employee compensation information. You can query department-level operating cost, but not derived salary information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This improves both security and user experience.&lt;/p&gt;

&lt;p&gt;The system can explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What category is restricted
What level is allowed
What alternative question is permitted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without exposing sensitive details.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Don't Try to Solve Every Possible Inference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is an important practical limit.&lt;/p&gt;

&lt;p&gt;If two harmless numbers can theoretically be combined into sensitive information, trying to enumerate every possible derivation can become impossible.&lt;/p&gt;

&lt;p&gt;So focus governance on high-impact semantic concepts.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Compensation
Protected Personal Information
Credit Risk
Confidential Pricing
Sensitive Forecasts
Health Information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then model known derivation patterns and business policies around those concepts.&lt;/p&gt;

&lt;p&gt;The goal is not mathematical prevention of all inference.&lt;/p&gt;

&lt;p&gt;It is business-risk-aware governance.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;A Practical Policy Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One possible abstraction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;concept&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;employee_compensation&lt;/span&gt;

&lt;span class="na"&gt;sensitivity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restricted&lt;/span&gt;

&lt;span class="na"&gt;direct_access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;allow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;hr&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;executive&lt;/span&gt;

&lt;span class="na"&gt;derived_access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;allow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;hr&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;executive&lt;/span&gt;

&lt;span class="na"&gt;related_metrics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;salary&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bonus&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;estimated_average_salary&lt;/span&gt;

&lt;span class="na"&gt;restricted_derivations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;department_cost / employee_count&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;relationship&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;employee&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cost_center&lt;/span&gt;

&lt;span class="na"&gt;trusted&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;traverse&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;allow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;finance&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;hr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes policy part of semantic and relationship metadata rather than an afterthought.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Audit the Reasoning Path&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a query is allowed or denied, log why.&lt;/p&gt;

&lt;p&gt;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"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sales_manager"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"question"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"What is the average salary in engineering?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"resolved_intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"employee_compensation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"policy_decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"derived_access_not_allowed"&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;For allowed queries, record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Semantic concepts used
Relationship path
Metrics selected
Policy decisions
Generated SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates an audit trail that is much more useful than logging SQL alone.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Test Authorization With Adversarial Questions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise data-agent security testing should include inference cases.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Direct request&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show individual employee salaries.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Derived request&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Divide engineering payroll cost by headcount.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Allowed aggregate&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show total engineering operating cost.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Relationship traversal&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Join employee records with cost-center financials.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROLE DEPENDENT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tests reveal whether the system governs meaning or only columns.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What to Measure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Useful authorization metrics could include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Direct Sensitive Query Block Rate
Derived Sensitive Query Block Rate
False Denial Rate
Unauthorized Relationship Block Rate
Policy Explanation Accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A secure system that denies every complex query is not useful.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Maximum useful access
within authorized semantic boundaries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;A Reference Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Putting everything together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Natural Language
                        ↓
                     Identity
                        ↓
                Intent Resolution
                        ↓
                Semantic Policy
                        ↓
               Authorized Context
                        ↓
          Authorized Relationship Graph
                        ↓
                 Query Planning
                        ↓
                Policy-Aware Plan
                        ↓
                 SQL Generation
                        ↓
              Database Enforcement
                        ↓
                    Execution
                        ↓
              Answer Policy Check
                        ↓
             Return / Explain / Deny
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RBAC remains underneath this architecture.&lt;/p&gt;

&lt;p&gt;The new layers do not replace database security.&lt;/p&gt;

&lt;p&gt;They extend governance into the reasoning process.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise data agents make databases easier to use because users no longer need to know schemas or SQL.&lt;/p&gt;

&lt;p&gt;That abstraction is powerful.&lt;/p&gt;

&lt;p&gt;It also means users can ask for information without knowing which fields, tables, joins, or calculations the agent will use.&lt;/p&gt;

&lt;p&gt;So authorization has to follow the same abstraction upward.&lt;/p&gt;

&lt;p&gt;From:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Who can access this table?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Who can use this business concept?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and finally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Who can receive this derived answer?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is why RBAC alone is not the whole solution for AI-powered analytics.&lt;/p&gt;

&lt;p&gt;Keep RBAC.&lt;/p&gt;

&lt;p&gt;Keep row- and column-level controls.&lt;/p&gt;

&lt;p&gt;But add governance around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intent
Semantics
Relationships
Derivations
Answers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because:&lt;/p&gt;

&lt;p&gt;Table access ≠ Answer access.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Valid relationship ≠ Authorized relationship.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A production data agent should not only know how to find an answer.&lt;/p&gt;

&lt;p&gt;It should know whether it is allowed to reveal it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llm</category>
      <category>sql</category>
    </item>
    <item>
      <title>The Semantic Cold Start Problem in Enterprise Data Agents</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Mon, 07 Sep 2026 22:00:00 +0000</pubDate>
      <link>https://dev.to/arisyndata/the-semantic-cold-start-problem-in-enterprise-data-agents-1j1m</link>
      <guid>https://dev.to/arisyndata/the-semantic-cold-start-problem-in-enterprise-data-agents-1j1m</guid>
      <description>&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%2Frcas3elpqachfcej8jwj.jpg" 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%2Frcas3elpqachfcej8jwj.jpg" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connecting an AI agent to a database is easy. Bootstrapping enough enterprise context for it to use that database correctly is the real engineering problem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A new data agent can inspect a schema almost immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tables
columns
data types
primary keys
sample values
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then a user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What was revenue by product code last quarter?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The schema alone does not tell the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What does "Revenue" mean here?
Which "product code" does the business use?
Which fields are authoritative?
How should the required tables be connected?
Which relationship candidates are trusted?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gap between &lt;strong&gt;data access&lt;/strong&gt; and &lt;strong&gt;business understanding&lt;/strong&gt; is what I call the &lt;strong&gt;semantic cold start problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For production data agents, reducing that cold-start cost may matter as much as improving the underlying LLM.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;1. Model the Problem as Knowledge Bootstrapping&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A useful bootstrap pipeline looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connect Data
     ↓
Schema Discovery
     ↓
Relationship Discovery
     ↓
Semantic Candidate Generation
     ↓
Existing Knowledge Import
     ↓
Human Confirmation
     ↓
Runtime Clarification
     ↓
Knowledge Persistence
     ↓
Reuse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important point is that no single step is expected to magically understand the enterprise.&lt;/p&gt;

&lt;p&gt;Instead, the system progressively converts different forms of evidence into reusable context.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;2. Start With a Machine-Readable Inventory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first layer is deterministic.&lt;/p&gt;

&lt;p&gt;For each data source, collect technical metadata 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;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finance_revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"columns"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"recognized_amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"decimal"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"recognition_date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"date"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"order_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bigint"&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;span class="p"&gt;]&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 makes the agent &lt;strong&gt;schema-aware&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But schema awareness is only Level 1.&lt;/p&gt;

&lt;p&gt;It tells the system what exists, not what the business means.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3. Discover Relationship Candidates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next problem is connectivity.&lt;/p&gt;

&lt;p&gt;Enterprise databases often have incomplete foreign-key definitions, so relationship discovery may need to combine several signals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Declared constraints
Column-name similarity
Compatible data types
Uniqueness
Value overlap
Value inclusion
Existing metadata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;account.customer_id
customer.customer_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;may be a strong relationship candidate even if no FK constraint exists.&lt;/p&gt;

&lt;p&gt;A candidate could be represented 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;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"account.customer_id"&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"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer.customer_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"evidence"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"type_compatible"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name_similarity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.91&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"inclusion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.98&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_uniqueness"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.99&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;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="mf"&gt;0.96&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"candidate"&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 distinction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;discovered relationship
≠
trusted relationship
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Discovery reduces manual work.&lt;/p&gt;

&lt;p&gt;Validation turns a candidate into enterprise knowledge.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;4. Generate Semantic Candidates, Not Semantic Truth&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now consider the business term:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Product Code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The schema may contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;product_master.material_id
inventory.item_code
sales_detail.sku_no
product_dim.prod_master_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An LLM or semantic retrieval system can rank candidates:&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;"term"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"candidates"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product_master.material_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.88&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inventory.item_code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.84&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sales_detail.sku_no"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.79&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;span class="p"&gt;]&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 is useful.&lt;/p&gt;

&lt;p&gt;But it should not automatically become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Product Code = material_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A semantic candidate is evidence.&lt;/p&gt;

&lt;p&gt;A business mapping is a governed decision.&lt;/p&gt;

&lt;p&gt;That separation prevents model confidence from being mistaken for organizational truth.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;5. Import What the Enterprise Already Knows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cold start should not mean starting from zero.&lt;/p&gt;

&lt;p&gt;Useful knowledge may already exist in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business glossaries
Metric definitions
Data catalogs
BI models
Dashboard logic
Documentation
Existing SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, Finance may already define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Revenue&lt;/span&gt;

&lt;span class="na"&gt;definition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;Recognized revenue for financial reporting&lt;/span&gt;

&lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;finance_revenue&lt;/span&gt;
  &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognized_amount&lt;/span&gt;

&lt;span class="na"&gt;time_field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;recognition_date&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this definition already exists, the agent should reuse it instead of asking users to redefine Revenue.&lt;/p&gt;

&lt;p&gt;A good bootstrap system therefore needs both:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;6. Use Humans for Confirmation, Not Exhaustive Modeling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some mappings cannot be inferred safely.&lt;/p&gt;

&lt;p&gt;Instead of asking a data team to document everything manually, let the system narrow the decision first.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Product Code" has 3 likely mappings:

1. product_master.material_id
2. inventory.item_code
3. sales_detail.sku_no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A domain expert selects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;product_master.material_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Persist the decision:&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;"knowledge_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"semantic_mapping"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"term"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product Code"&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"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product_master.material_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"human_confirmation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"trusted"&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="mf"&gt;1.0&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 changes the human role from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Author everything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review high-value uncertainty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is much more scalable.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;7. Runtime Clarification Is Also a Learning Channel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some ambiguity only appears when users ask real questions.&lt;/p&gt;

&lt;p&gt;Suppose:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show revenue by product code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The semantic resolver returns:&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;"term"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ambiguous"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"candidates"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"Master Product Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"SKU Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Internal Product ID"&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;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 agent asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which product code do you mean?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The user chooses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Master Product Code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A weak implementation uses the answer only for the current query.&lt;/p&gt;

&lt;p&gt;A stronger implementation creates a knowledge event:&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;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"semantic_confirmation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user_phrase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolved_concept"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Master Product Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"physical_field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product_master.material_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"runtime_clarification"&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;Now the interaction improves future queries.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Every Correction Should Make the Next Question Cheaper&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the core learning property.&lt;/p&gt;

&lt;p&gt;Without persistence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User A asks
   ↓
System clarifies
   ↓
Answer

User B asks same concept
   ↓
System clarifies again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With reusable knowledge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User A asks
   ↓
System clarifies
   ↓
Knowledge stored
   ↓
User B asks
   ↓
Known mapping
   ↓
Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second query requires less reasoning and less human effort.&lt;/p&gt;

&lt;p&gt;That is what enterprise learning should look like.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;8. Separate Runtime State From Persistent Knowledge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not every user choice should become global enterprise truth.&lt;/p&gt;

&lt;p&gt;Suppose a user says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use invoice amount for this analysis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That may be a query-specific preference, not a new definition of Revenue.&lt;/p&gt;

&lt;p&gt;So distinguish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Session State
User Preference
Workspace Default
Governed Enterprise Knowledge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A useful persistence policy might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;persist_resolution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;save_session_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_selection&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;propose_workspace_knowledge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;approved_by_domain_owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;save_governed_knowledge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact workflow varies, but the principle matters:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Learning requires scope and governance.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Otherwise one user's temporary choice can corrupt the shared semantic layer.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;9. Track Provenance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every knowledge object should answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Where did this come from?
Who confirmed it?
When was it created?
How confident are we?
Is it still active?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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;"term"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Revenue"&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"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finance_revenue.recognized_amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finance_metric_catalog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"active"&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="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&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;For discovered relationships:&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;"relationship"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"account.customer_id -&amp;gt; customer.customer_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"relationship_discovery"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confirmed_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"data_team"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"trusted"&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;Without provenance, accumulated knowledge becomes difficult to trust.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;10. Build a Context Resolver Above the Raw Knowledge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The query runtime should not dump every known object into the prompt.&lt;/p&gt;

&lt;p&gt;Instead:&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
      ↓
Intent Extraction
      ↓
Context Resolver
      ↓
Relevant Business Terms
Relevant Metrics
Relevant Fields
Relevant Relationships
      ↓
Compact Query Context
      ↓
SQL Generation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;Revenue by product code last quarter&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;the context resolver might return:&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;"metric"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finance_revenue.recognized_amount"&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;span class="nl"&gt;"dimension"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product_master.material_id"&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;span class="nl"&gt;"relationship_path"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"product_master -&amp;gt; sales_order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"sales_order -&amp;gt; finance_revenue"&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;span class="nl"&gt;"time_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;"last_quarter"&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 model reasons over a smaller, better-defined space.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;11. Treat Knowledge Acquisition as an Event Stream&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A useful architecture is to treat semantic learning as events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;schema_discovered
relationship_candidate_found
relationship_confirmed
metric_imported
semantic_mapping_confirmed
clarification_resolved
mapping_deprecated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;"event_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"semantic_mapping_confirmed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-07T10:30:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"term"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product_master.material_id"&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;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 gives you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Auditability
Versioning
Rollback
Analytics
Learning metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also avoids hiding important enterprise knowledge inside opaque prompt history.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;12. Measure Time to Intelligence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Connection latency is easy to measure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database connected in 4 minutes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But a better enterprise metric is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time to Intelligence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Possible operational measurements include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Time until first trusted answer

% of common business terms resolved

% of critical metrics governed

% of required relationships trusted

Clarification rate

Repeated clarification rate

Manual confirmations per 100 queries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A healthy system should improve over time.&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;Week 1
Semantic coverage: 42%
Repeated clarification: 31%

Month 1
Semantic coverage: 68%
Repeated clarification: 17%

Month 3
Semantic coverage: 84%
Repeated clarification: 6%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact targets depend on the enterprise.&lt;/p&gt;

&lt;p&gt;The direction is what matters.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;13. Measure Enterprise Learning Rate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another useful concept is:&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Enterprise Learning Rate&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;How quickly does real usage produce reusable trusted knowledge?&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New trusted mappings / week
New trusted relationships / week
Clarifications converted to reusable knowledge
Repeated ambiguity reduction
Human confirmation workload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is not maximum knowledge creation.&lt;/p&gt;

&lt;p&gt;It is reducing repeated uncertainty.&lt;/p&gt;

&lt;p&gt;A useful signal might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Repeated Clarification Rate ↓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If users keep clarifying the same concepts month after month, the system is not learning effectively.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;14. A Maturity Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A data agent can be viewed as progressing through several levels.&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 0 — Connected
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can access data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Level 1 — Schema-Aware
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Understands tables and fields
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Level 2 — Relationship-Aware
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Understands how relevant data connects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Level 3 — Semantic-Aware
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Understands business terms,
metrics, and dimensions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Level 4 — Business-Aware
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Uses governed definitions,
trusted mappings, and business context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Level 5 — Learning
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Turns corrections,
confirmations, and clarifications
into reusable knowledge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most enterprise AI demos prove Levels 0 and 1.&lt;/p&gt;

&lt;p&gt;Production value increasingly appears in Levels 3 through 5.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;15. The Goal Is Not Fully Automatic Semantics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is a tempting but unrealistic objective:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connect database
↓
AI automatically understands everything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some business meaning cannot be inferred from data.&lt;/p&gt;

&lt;p&gt;If a company decides that Revenue means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recognized Revenue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invoice Amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that is an organizational decision.&lt;/p&gt;

&lt;p&gt;The system should not pretend otherwise.&lt;/p&gt;

&lt;p&gt;A more realistic architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Machine discovers
      ↓
AI proposes
      ↓
Humans confirm high-impact meaning
      ↓
System remembers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is not zero human input.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Minimum repetitive human work with preserved human authority over business meaning.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;16. Keep Enterprise Knowledge Model-Agnostic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The underlying LLM will change.&lt;/p&gt;

&lt;p&gt;Enterprise knowledge should survive those changes.&lt;/p&gt;

&lt;p&gt;Avoid storing important semantics only inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt templates
Few-shot examples
Conversation history
Model-specific instructions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, keep durable knowledge as structured objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business Terms
Metrics
Dimensions
Mappings
Relationships
Rules
Provenance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then different models can consume the same enterprise context.&lt;/p&gt;

&lt;p&gt;Models are replaceable.&lt;/p&gt;

&lt;p&gt;Enterprise knowledge compounds.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;17. A Practical Bootstrap Architecture&lt;/strong&gt;&lt;br&gt;
Putting the pieces together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              Enterprise Data
                     ↓
             Metadata Discovery
                     ↓
          Relationship Discovery
                     ↓
      Existing Knowledge Import
                     ↓
       Semantic Candidate Layer
                     ↓
            Human Confirmation
                     ↓
          Trusted Knowledge Store
                     ↑
                     │
User Question → Runtime Resolver
                     │
                     ↓
              Clarification
                     │
                     ↓
              Knowledge Event
                     │
                     └──────────→ Trusted Knowledge Store

Trusted Context
      ↓
Query Planning
      ↓
SQL Generation
      ↓
Validation
      ↓
Execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system becomes better not because the model retrains after every question, but because the &lt;strong&gt;enterprise context around the model improves&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The semantic cold start problem is easy to underestimate.&lt;/p&gt;

&lt;p&gt;A database connection gives an agent access to:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Production analytics requires:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data
+
Meaning
+
Relationships
+
Authority
+
Learning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the engineering goal should not simply be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Connect the database faster.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It should be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Reduce the amount of work required for the system to become business-aware.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That means discovering what can be discovered, importing what already exists, asking humans only where judgment matters, and turning useful corrections into durable knowledge.&lt;/p&gt;

&lt;p&gt;The most important property is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Every correction should make the next question cheaper.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is how a generic data agent starts becoming an enterprise data agent.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>data</category>
      <category>llm</category>
      <category>sql</category>
    </item>
    <item>
      <title>How I Would Benchmark a Text-to-SQL System for Production</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Wed, 02 Sep 2026 22:26:00 +0000</pubDate>
      <link>https://dev.to/arisyndata/how-i-would-benchmark-a-text-to-sql-system-for-production-59fe</link>
      <guid>https://dev.to/arisyndata/how-i-would-benchmark-a-text-to-sql-system-for-production-59fe</guid>
      <description>&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%2Fh6clukdu1gyng4h7bovo.jpg" 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%2Fh6clukdu1gyng4h7bovo.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A clean question against a clean schema is a demo. A production benchmark should deliberately test ambiguity, missing relationships, competing metrics, and SQL that executes successfully but answers the wrong business question.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most Text-to-SQL evaluations start with questions like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What was revenue last quarter?
Show sales by region.
List the top 10 customers.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tests are useful for checking whether the basic pipeline works.&lt;/p&gt;

&lt;p&gt;They are not enough to tell you whether the system is ready for enterprise production.&lt;/p&gt;

&lt;p&gt;In production, the difficult cases are rarely caused by SQL syntax alone. They come from business language, incomplete metadata, ambiguous metrics, undocumented relationships, aggregation grain, and assumptions that look reasonable but are wrong.&lt;/p&gt;

&lt;p&gt;So if I were benchmarking a Text-to-SQL system, I would build the benchmark around &lt;strong&gt;failure paths&lt;/strong&gt;, not just happy paths.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Why Execution Accuracy Is Not Enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A typical evaluation might measure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Generated SQL
   ↓
Expected SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generated SQL
   ↓
Execute
   ↓
Compare Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execution-based evaluation is better than exact SQL matching because multiple SQL statements can produce the same correct answer.&lt;/p&gt;

&lt;p&gt;But enterprise reliability requires additional questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the system understand the business term correctly?

Did it choose the authoritative metric?

Did it use the right relationship path?

Did it preserve the correct aggregation grain?

Did it recognize ambiguity?

Did it know when not to query?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A query can execute successfully and still fail every one of these tests.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;# Build a Failure-Path Benchmark&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I would create at least seven test categories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A. Ambiguous Intent
B. Business Term Mapping
C. Competing Metrics
D. Missing Relationships
E. Executable-but-Wrong SQL
F. Insufficient Intent
G. Environment Change
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each category tests a different part of the system.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Test A: Ambiguous Intent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show me our best customers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Possible interpretations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue
Profit
Growth
Retention
Lifetime Value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benchmark should not define &lt;code&gt;best&lt;/code&gt; in the question.&lt;/p&gt;

&lt;p&gt;The correct behavior depends on enterprise context.&lt;/p&gt;

&lt;p&gt;If a governed definition exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;term&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;best_customer&lt;/span&gt;
&lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;customer_lifetime_value&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;active&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the system can resolve it.&lt;/p&gt;

&lt;p&gt;If multiple valid definitions remain, the expected behavior should be:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;not:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Example benchmark case&lt;/strong&gt;&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;"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;"ambiguity_001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"question"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Show me our best customers."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"valid_metrics"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"profit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"growth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"retention"&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;span class="nl"&gt;"governed_default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expected_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"clarify"&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;&lt;strong&gt;### What to score&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ambiguity detected?
Correct candidates identified?
Clarification triggered?
Clarification options useful?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you a &lt;strong&gt;Clarification Accuracy&lt;/strong&gt; metric rather than only SQL accuracy.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Test B: Business Term Mapping&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What was revenue by product code this quarter?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now make sure the schema does not contain a field called:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;product_master.material_id
sales_detail.sku_no
inventory.item_code
product_dim.prod_master_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benchmark should contain a governed semantic mapping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;business_term&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Product Code&lt;/span&gt;

&lt;span class="na"&gt;maps_to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product_master&lt;/span&gt;
  &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;material_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Failure mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A schema-similarity system may select:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inventory.item_code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because the name looks closest.&lt;/p&gt;

&lt;p&gt;But the benchmark expects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;product_master.material_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because that is the governed enterprise definition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### What to score&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business term resolved correctly?
Correct physical field selected?
Governed mapping preferred over lexical similarity?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;# **Semantic Mapping Accuracy&lt;/strong&gt;**&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Test C: Competing Metrics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create several plausible financial fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sales_order.total_amount
invoice.invoice_amount
finance_revenue.recognized_amount
payment.received_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What was revenue last quarter?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All four fields are relevant to money.&lt;/p&gt;

&lt;p&gt;Only one represents the governed Revenue metric.&lt;/p&gt;

&lt;p&gt;Benchmark definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Revenue&lt;/span&gt;

&lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;finance_revenue&lt;/span&gt;
  &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognized_amount&lt;/span&gt;

&lt;span class="na"&gt;time_field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;finance_revenue.recognition_date&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### What to inspect&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do not only inspect the final number.&lt;/p&gt;

&lt;p&gt;Inspect the query plan.&lt;/p&gt;

&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Metric
→ Revenue

Field
→ finance_revenue.recognized_amount

Time
→ finance_revenue.recognition_date
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### What to score&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Metric resolution accuracy
Source selection accuracy
Time-field accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This catches systems that accidentally return the right number from the wrong business definition.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Test D: Missing Relationships&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Production databases often lack perfect foreign keys.&lt;/p&gt;

&lt;p&gt;Build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer
account
sales_order
finance_revenue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected relationship path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
   ↓
Account
   ↓
Order
   ↓
Revenue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then deliberately remove some database constraints.&lt;/p&gt;

&lt;p&gt;The benchmark should still contain enough data evidence for a relationship system to infer or retrieve valid relationships.&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;account.customer_id
sales_order.account_id
finance_revenue.order_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Useful relationship evidence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A relationship engine might consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Column names
Data types
Uniqueness
Value overlap
Inclusion
Known metadata
Validated relationships
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One useful inclusion signal is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inclusion(A → B)
=
|distinct(A) ∩ distinct(B)|
---------------------------
|distinct(A)|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;A&lt;/code&gt; is a candidate foreign-key-like column and &lt;code&gt;B&lt;/code&gt; is a candidate referenced column.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### What to score&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Correct tables selected?
Correct relationship path found?
Unsupported direct joins avoided?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;# **Relationship Path Accuracy&lt;/strong&gt;**&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Test E: Executable-but-Wrong SQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the test I would care about most.&lt;/p&gt;

&lt;p&gt;Suppose the schema allows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer → Order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer → Account → Order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both can generate executable SQL.&lt;/p&gt;

&lt;p&gt;But for consolidated customers, only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer → Account → Order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;preserves the correct business grain.&lt;/p&gt;

&lt;p&gt;Create two candidate queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### Query A&lt;/strong&gt;&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="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;sales_order&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_name&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;### Query B&lt;/strong&gt;&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="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;sales_order&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;account_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;account_id&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both may execute.&lt;/p&gt;

&lt;p&gt;Only Query B is business-valid for the benchmark scenario.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### What to score&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL executable?
Business relationship valid?
Aggregation grain valid?
Result semantically correct?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates an important distinction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Execution Accuracy
≠
Business Accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;## Test F: Insufficient Intent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show our best-performing products recently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The benchmark intentionally leaves unresolved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;best-performing
recently
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Possible metric candidates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue
Profit
Units Sold
Growth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Possible time candidates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7 Days
30 Days
Current Month
Current Quarter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no governed defaults exist, the expected result is not SQL.&lt;/p&gt;

&lt;p&gt;It is:&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;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"clarify"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"unresolved"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"metric"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"time_range"&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;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;&lt;strong&gt;### What to score&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the system detect missing intent?
Did it avoid premature SQL generation?
Did it ask the minimum useful clarification?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This measures:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;# **Safe Failure Accuracy&lt;/strong&gt;**&lt;/p&gt;

&lt;p&gt;A production system should not be rewarded for answering every question.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Test G: Environment Change&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Static benchmarks miss one of the largest production costs: maintenance.&lt;/p&gt;

&lt;p&gt;Start with a working environment.&lt;/p&gt;

&lt;p&gt;Then introduce changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add a table
Rename a field
Add a new metric
Deprecate an old metric
Add a new relationship
Change a semantic mapping
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;Before:
Product Code → product_master.material_id

After:
Product Code → product_dim.product_code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then rerun the benchmark.&lt;/p&gt;

&lt;p&gt;Measure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many cases break?

How much manual configuration is required?

How quickly does the system recover?

Which knowledge objects need updating?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces a metric that benchmark leaderboards rarely show:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;# **Semantic Maintenance Cost&lt;/strong&gt;**&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;# Score More Than SQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A useful benchmark report could look like:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Semantic Mapping Accuracy&lt;/td&gt;
&lt;td&gt;94%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metric Resolution Accuracy&lt;/td&gt;
&lt;td&gt;96%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relationship Path Accuracy&lt;/td&gt;
&lt;td&gt;91%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clarification Accuracy&lt;/td&gt;
&lt;td&gt;93%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SQL Execution Accuracy&lt;/td&gt;
&lt;td&gt;98%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business Answer Accuracy&lt;/td&gt;
&lt;td&gt;89%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safe Failure Accuracy&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintenance Effort&lt;/td&gt;
&lt;td&gt;3.2 min/change&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The exact metrics depend on the product.&lt;/p&gt;

&lt;p&gt;The important point is that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL Accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;should be one row, not the entire benchmark.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;# Use a Multi-Stage Evaluation Harness&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of treating Text-to-SQL as one black box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
→ SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;capture intermediate artifacts.&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;"question"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Revenue by customer last quarter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"intent"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"metric"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"recognized_revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dimension"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"last_quarter"&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;span class="nl"&gt;"semantic_objects"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"metric.revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"dimension.customer"&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;span class="nl"&gt;"tables"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"account"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"sales_order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"finance_revenue"&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;span class="nl"&gt;"relationship_path"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"customer.customer_id -&amp;gt; account.customer_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;"account.account_id -&amp;gt; sales_order.account_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;"sales_order.order_id -&amp;gt; finance_revenue.order_id"&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;span class="nl"&gt;"generated_sql"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"execute"&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;Now failures become diagnosable.&lt;/p&gt;

&lt;p&gt;If the final answer is wrong, you can determine whether the failure came from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intent
Semantic Mapping
Table Selection
Relationship Resolution
Metric Selection
SQL Generation
Execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is much more useful than:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;# Build Adversarial Test Pairs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A strong benchmark should include pairs of questions that look similar but require different interpretations.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;h3&gt;
  
  
  Q1
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;What was our revenue last quarter?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected metric:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Q2
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;What was our invoiced amount last quarter?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected metric:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Another pair:&lt;/p&gt;

&lt;h3&gt;
  
  
  Q1
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Sales by customer region.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected dimension:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Q2
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Sales by billing region.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected dimension:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;These pairs test whether the system is actually resolving semantics or simply reusing the most common mapping.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;# Include Negative Tests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional benchmarks mostly contain questions that should be answerable.&lt;/p&gt;

&lt;p&gt;Production benchmarks should include questions that should not.&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;Question:
"Show profitability by happiness score."

No governed metric:
happiness_score

Expected:
Cannot resolve metric / clarification required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question:
"Join employee salary with public customer data."

Expected:
Rejected by policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact safety rules depend on the deployment.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A system should be tested on its ability to refuse invalid query plans, not only generate valid ones.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;# Test With Messy Schemas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do not benchmark only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer
orders
products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use schemas that look more like enterprise reality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t_cust_m
cust_master_old
acct_rel
f_ord_h
ord_detail_v2
fin_rev_rec
inv_hdr
inv_line
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deprecated tables
Duplicate concepts
Missing descriptions
Inconsistent naming
Cross-system IDs
Partial foreign keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the product claims to work with enterprise data, the benchmark should look like enterprise data.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;# Measure Human Setup Cost&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before the first benchmark run, track setup effort.&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;Schema descriptions:       4 hours
Metric definitions:        3 hours
Relationship configuration: 6 hours
Example SQL:                5 hours
Prompt tuning:              2 hours
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Total:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20 hours
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another system may achieve slightly lower raw accuracy but require:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4 hours
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;of setup.&lt;/p&gt;

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

&lt;p&gt;So benchmark:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cost to achieve that accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;together.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;# A More Useful Production Score&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I would think about production value approximately as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                  Accuracy × Trust × Coverage
Value  ≈  ─────────────────────────────────────
                Setup + Maintenance Cost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, this is not a universal mathematical formula.&lt;/p&gt;

&lt;p&gt;It forces the benchmark to consider what enterprises actually pay for.&lt;/p&gt;

&lt;p&gt;A system that scores 97% on 50 carefully prepared questions may be less valuable than one scoring 93% across thousands of messy tables with far less manual configuration.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;# What I Would Put in a POC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If I were designing a vendor POC, I would include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10 clear questions
10 ambiguous questions
10 semantic-alias questions
10 competing-metric questions
10 missing-relationship questions
10 multi-path join questions
10 executable-but-wrong traps
10 questions that require clarification
10 unanswerable questions
10 post-schema-change regressions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100 cases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with intentionally different failure modes.&lt;/p&gt;

&lt;p&gt;Then evaluate both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can it answer correctly?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can it recognize when it should not answer yet?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;# Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A production Text-to-SQL benchmark should not primarily test whether an LLM knows SQL.&lt;/p&gt;

&lt;p&gt;Modern models are already good at SQL generation under clean conditions.&lt;/p&gt;

&lt;p&gt;The harder questions are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did it understand the business term?

Did it select the right metric?

Did it find the right data?

Did it use the right relationship?

Did it preserve the right grain?

Did it detect ambiguity?

Did it fail safely?

How much human work was required?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those are system-level questions.&lt;/p&gt;

&lt;p&gt;So when evaluating a Text-to-SQL platform:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't benchmark the easiest route from question to SQL.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Deliberately break the assumptions.&lt;/p&gt;

&lt;p&gt;Remove the foreign key.&lt;/p&gt;

&lt;p&gt;Add three plausible revenue fields.&lt;/p&gt;

&lt;p&gt;Use business terminology that does not match the schema.&lt;/p&gt;

&lt;p&gt;Create two executable join paths where only one is correct.&lt;/p&gt;

&lt;p&gt;Ask a question that should trigger clarification.&lt;/p&gt;

&lt;p&gt;Then change the data model and run everything again.&lt;/p&gt;

&lt;p&gt;That is where you start learning whether you have a good demo—or a production system.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>data</category>
      <category>sql</category>
      <category>llm</category>
    </item>
    <item>
      <title>Building a Trustworthy Semantic Layer for Natural Language Analytics</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Mon, 31 Aug 2026 22:10:00 +0000</pubDate>
      <link>https://dev.to/arisyndata/building-a-trustworthy-semantic-layer-for-natural-language-analytics-589h</link>
      <guid>https://dev.to/arisyndata/building-a-trustworthy-semantic-layer-for-natural-language-analytics-589h</guid>
      <description>&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%2F9qtgxbvxilgkzrltaepf.jpg" 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%2F9qtgxbvxilgkzrltaepf.jpg" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Natural language analytics looks simple from the outside:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;User asks a question.&lt;br&gt;&lt;br&gt;
The system generates SQL.&lt;br&gt;&lt;br&gt;
The database returns an answer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In real enterprise environments, this breaks quickly.&lt;/p&gt;

&lt;p&gt;The reason is not just SQL generation. The reason is semantic ambiguity.&lt;/p&gt;

&lt;p&gt;When a user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show sales by product code for last month.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system needs to resolve several questions before it can safely generate a query:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does "sales" mean?&lt;/li&gt;
&lt;li&gt;Is it gross sales, net sales, recognized revenue, bookings, or paid order amount?&lt;/li&gt;
&lt;li&gt;What does "product code" mean?&lt;/li&gt;
&lt;li&gt;Is it internal product code, SKU, marketplace product code, barcode, or ERP material number?&lt;/li&gt;
&lt;li&gt;Which date field should represent "last month"?&lt;/li&gt;
&lt;li&gt;Which tables contain the right facts and dimensions?&lt;/li&gt;
&lt;li&gt;Which join path is trusted?&lt;/li&gt;
&lt;li&gt;Is the current user allowed to access the required data?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why a semantic layer is becoming a critical part of natural language analytics.&lt;/p&gt;

&lt;p&gt;But not all semantic layers are designed for the same job.&lt;/p&gt;

&lt;p&gt;Databricks is building semantic capabilities natively inside its lakehouse platform. Semora is building an independent semantic layer for complex, cross-platform enterprise data. From an engineering perspective, the interesting question is not "Which product has a better chat interface?"&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;What system architecture makes natural language analytics both fluent and accurate?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;## The Core Problem: Language Models Should Not Guess the Data Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A large language model can usually understand that these phrases are related:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;product code&lt;/li&gt;
&lt;li&gt;product ID&lt;/li&gt;
&lt;li&gt;item number&lt;/li&gt;
&lt;li&gt;SKU&lt;/li&gt;
&lt;li&gt;material number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But in a real company, those phrases may not be interchangeable.&lt;/p&gt;

&lt;p&gt;One table may contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;product_code
product_id
sku_id
barcode
platform_item_id
material_number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the system maps "product ID" to &lt;code&gt;product_code&lt;/code&gt; just because the words sound close, the answer may be fluent but wrong.&lt;/p&gt;

&lt;p&gt;On the other hand, if the system asks the user to clarify every similar term, the experience becomes painful.&lt;/p&gt;

&lt;p&gt;The engineering challenge is to build a runtime that can decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When can we answer directly?&lt;/li&gt;
&lt;li&gt;When should we show the assumption?&lt;/li&gt;
&lt;li&gt;When should we ask a lightweight clarification?&lt;/li&gt;
&lt;li&gt;When must we require explicit confirmation?&lt;/li&gt;
&lt;li&gt;How do we save the user's answer so we do not ask again?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where Semora can differentiate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Databricks: Platform-Native Semantic Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Databricks has been expanding its semantic layer and natural language analytics stack through Unity Catalog business semantics, metric views, Genie, and Genie Agents.&lt;/p&gt;

&lt;p&gt;The Databricks approach is powerful because semantic assets live close to the governed data platform.&lt;/p&gt;

&lt;p&gt;A Databricks-style flow can look 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
  -&amp;gt; Genie Agent scope
  -&amp;gt; Unity Catalog metadata
  -&amp;gt; Metric views
  -&amp;gt; Table and column descriptions
  -&amp;gt; Trusted queries and examples
  -&amp;gt; SQL generation
  -&amp;gt; Query inspection
  -&amp;gt; Governed answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works especially well when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The company already uses Databricks as the main analytical platform.&lt;/li&gt;
&lt;li&gt;Tables, permissions, lineage, and metrics are managed in Unity Catalog.&lt;/li&gt;
&lt;li&gt;Business domains are curated into focused Genie Agents.&lt;/li&gt;
&lt;li&gt;Data teams maintain metric views, examples, and trusted assets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key engineering lesson is that Databricks does not treat the language model as the only source of intelligence. It surrounds the model with governed context.&lt;/p&gt;

&lt;p&gt;That context reduces the search space.&lt;/p&gt;

&lt;p&gt;If a user is asking inside a Sales Genie Agent, "revenue" can be interpreted using sales-domain semantics. If they ask inside a Finance context, the default meaning may be different.&lt;/p&gt;

&lt;p&gt;This domain scoping is one of the most important reasons a natural language analytics experience feels smooth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Semora: Independent Semantic Runtime&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Semora has a different opportunity.&lt;/p&gt;

&lt;p&gt;Many enterprises do not have one clean analytical platform. They have multiple warehouses, operational databases, business intelligence tools, spreadsheets, and legacy systems. Field names are inconsistent. Foreign keys are missing. Business terms vary by department.&lt;/p&gt;

&lt;p&gt;In this environment, an independent semantic layer is valuable because it can sit above the data platforms instead of being tied to only one.&lt;/p&gt;

&lt;p&gt;A Semora-style flow can look 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
  -&amp;gt; Intent classification
  -&amp;gt; Role and permission scope
  -&amp;gt; Business domain routing
  -&amp;gt; Synonym and semantic retrieval
  -&amp;gt; Business concept mapping
  -&amp;gt; Certified field selection
  -&amp;gt; Relationship discovery
  -&amp;gt; Trusted question template matching
  -&amp;gt; Query generation
  -&amp;gt; Query validation
  -&amp;gt; Answer with lineage
  -&amp;gt; Clarification memory update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important word here is runtime.&lt;/p&gt;

&lt;p&gt;It is not enough to have pages for synonyms, business semantics, data definitions, question templates, and knowledge bases. Those assets must be actively retrieved, ranked, and applied while the user is asking a question.&lt;/p&gt;

&lt;p&gt;Otherwise, the product can have many semantic assets and still feel rough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Runtime Component 1: Intent Classification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first step should not be SQL generation.&lt;/p&gt;

&lt;p&gt;The first step should be intent classification.&lt;/p&gt;

&lt;p&gt;For example, the user may ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What questions can you answer for me?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not a data query. It is a capability discovery question.&lt;/p&gt;

&lt;p&gt;A poor system routes it into the query pipeline, fails to find a metric, and asks for clarification.&lt;/p&gt;

&lt;p&gt;A better system recognizes the intent and answers based on the user's role, permissions, business domains, and available question templates.&lt;/p&gt;

&lt;p&gt;Useful intent classes include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DATA_QUERY
CAPABILITY_DISCOVERY
METRIC_EXPLANATION
FIELD_EXPLANATION
DOMAIN_EXPLORATION
TEMPLATE_RECOMMENDATION
PERMISSION_SCOPE_EXPLANATION
PRODUCT_HELP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For &lt;code&gt;CAPABILITY_DISCOVERY&lt;/code&gt;, the response should be generated from available semantic assets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessible business domains&lt;/li&gt;
&lt;li&gt;Certified metrics&lt;/li&gt;
&lt;li&gt;Question templates&lt;/li&gt;
&lt;li&gt;Frequently used questions&lt;/li&gt;
&lt;li&gt;Available dimensions&lt;/li&gt;
&lt;li&gt;Permission boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example response:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Based on your current access, I can answer questions about sales, products, inventory, and channels. You can ask about sales trends, product rankings, inventory shortages, channel comparisons, and customer repeat purchase behavior.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This small routing layer can dramatically improve first-time user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Runtime Component 2: Business Domain Routing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even if Semora keeps one universal question box, the backend should not treat all data as one global space.&lt;/p&gt;

&lt;p&gt;The system should route each question into one or more business domains.&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;"sales by product code"
  -&amp;gt; Sales domain
  -&amp;gt; Product domain

"inventory risk by SKU"
  -&amp;gt; Inventory domain
  -&amp;gt; Product domain

"recognized revenue by customer"
  -&amp;gt; Finance domain
  -&amp;gt; Customer domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Domain routing should use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User role&lt;/li&gt;
&lt;li&gt;Permission scope&lt;/li&gt;
&lt;li&gt;Question text&lt;/li&gt;
&lt;li&gt;Matched metrics&lt;/li&gt;
&lt;li&gt;Matched templates&lt;/li&gt;
&lt;li&gt;Historical user behavior&lt;/li&gt;
&lt;li&gt;Business glossary terms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The user can still see one clean interface. Internally, the system should load a scoped semantic context.&lt;/p&gt;

&lt;p&gt;This reduces ambiguity before the language model starts planning the query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Runtime Component 3: Multi-Path Semantic Retrieval&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common failure mode is exact or weak lexical matching.&lt;/p&gt;

&lt;p&gt;If the physical field is called &lt;code&gt;product_code&lt;/code&gt;, and the user says "product number," the system may fail unless that synonym was manually configured.&lt;/p&gt;

&lt;p&gt;This does not scale.&lt;/p&gt;

&lt;p&gt;Semora should use multi-path retrieval:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User phrase
  -&amp;gt; Exact match
  -&amp;gt; Token match
  -&amp;gt; Synonym match
  -&amp;gt; Embedding similarity
  -&amp;gt; Field description match
  -&amp;gt; Sample value match
  -&amp;gt; Historical clarification match
  -&amp;gt; Question template match
  -&amp;gt; Domain default match
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the phrase "product code," candidates might include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business concept: Product Code
Fields:
  - dim_product.product_code
  - order_items.product_code
  - inventory_sku.sku_code
  - marketplace_items.platform_item_id
  - product_barcodes.barcode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The retrieval layer should not immediately decide. It should return candidates with evidence.&lt;/p&gt;

&lt;p&gt;Example evidence:&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;"candidate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dim_product.product_code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"business_concept"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"evidence"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"synonym_match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"product code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"item code"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"field_description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Internal product code used across sales and inventory"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"historical_confirmations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"certification_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"certified"&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;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="mf"&gt;0.93&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 gives the language model structured context instead of asking it to guess from raw schema names.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Runtime Component 4: Confidence-Based Clarification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Clarification should be a decision, not a default.&lt;/p&gt;

&lt;p&gt;A useful policy could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;confidence &amp;gt;= 0.85
  -&amp;gt; answer directly and show the assumption

0.60 &amp;lt;= confidence &amp;lt; 0.85
  -&amp;gt; answer with a lightweight change option, or ask a short clarification

confidence &amp;lt; 0.60
  -&amp;gt; require clarification

high-risk metric or high-risk join
  -&amp;gt; require confirmation even if confidence is moderate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a high-confidence case:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I interpreted "product code" as the certified Product Code concept and used the internal product code field.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For an ambiguous case:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which product identifier do you mean?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internal product code&lt;/li&gt;
&lt;li&gt;SKU number&lt;/li&gt;
&lt;li&gt;Marketplace product code&lt;/li&gt;
&lt;li&gt;Barcode&lt;/li&gt;
&lt;li&gt;ERP material number&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is better than showing raw column names to a business user.&lt;/p&gt;

&lt;p&gt;Technical users can still inspect the underlying fields, joins, and SQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Runtime Component 5: Trusted Question Templates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Question templates should not be simple prompt examples.&lt;/p&gt;

&lt;p&gt;They should be trusted analytical paths.&lt;/p&gt;

&lt;p&gt;For example, a template for:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Top-selling products in a time period&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Should include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;template_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;top_selling_products&lt;/span&gt;
&lt;span class="na"&gt;intent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ranking&lt;/span&gt;
&lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Sales Quantity&lt;/span&gt;
  &lt;span class="na"&gt;certification&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;certified&lt;/span&gt;
&lt;span class="na"&gt;dimensions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Product Code&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Product Name&lt;/span&gt;
&lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;default_field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Paid Time&lt;/span&gt;
&lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Paid Orders Only&lt;/span&gt;
&lt;span class="na"&gt;relationships&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;order_items -&amp;gt; dim_product by product_code&lt;/span&gt;
&lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;time_range&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;channel&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;category&lt;/span&gt;
&lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sales_quantity &amp;gt;= &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;product_code is not &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Sales Analytics Team&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;certified&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show last month's product code sales ranking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system should match the template first, extract parameters, and reuse the certified query path.&lt;/p&gt;

&lt;p&gt;The language model should not rebuild the business logic from scratch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Runtime Component 6: Relationship Discovery and Join Safety&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Natural language analytics systems often fail silently when joins are wrong.&lt;/p&gt;

&lt;p&gt;A query can run successfully and still be incorrect because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It joined at the wrong grain.&lt;/li&gt;
&lt;li&gt;It created duplicate rows.&lt;/li&gt;
&lt;li&gt;It used a weak relationship.&lt;/li&gt;
&lt;li&gt;It joined through the wrong entity.&lt;/li&gt;
&lt;li&gt;It mixed internal identifiers with external identifiers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Semora, relationship discovery should be a major differentiator.&lt;/p&gt;

&lt;p&gt;A relationship engine should evaluate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Field name similarity&lt;/li&gt;
&lt;li&gt;Data type compatibility&lt;/li&gt;
&lt;li&gt;Value overlap&lt;/li&gt;
&lt;li&gt;Inclusion ratio&lt;/li&gt;
&lt;li&gt;Cardinality&lt;/li&gt;
&lt;li&gt;Null rate&lt;/li&gt;
&lt;li&gt;Uniqueness&lt;/li&gt;
&lt;li&gt;Historical usage&lt;/li&gt;
&lt;li&gt;Human approval&lt;/li&gt;
&lt;li&gt;Domain relevance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output should be explainable:&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;"join_path"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"order_items.product_code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"dim_product.product_code"&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;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="mf"&gt;0.91&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"evidence"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"value_overlap"&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"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"right_side_uniqueness"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"strong"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"approved_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"data_owner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fanout_risk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"low"&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;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 is where independent semantic layers can create real value. Platform-native semantic layers work well when relationships are already modeled. Independent semantic layers can help discover and govern relationships where metadata is incomplete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Runtime Component 7: Query Validation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SQL generation is not the end of the pipeline.&lt;/p&gt;

&lt;p&gt;The system should validate the generated query before presenting the answer.&lt;/p&gt;

&lt;p&gt;Validation checks may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the user have permission to access every field?&lt;/li&gt;
&lt;li&gt;Is the selected metric certified?&lt;/li&gt;
&lt;li&gt;Is the date field appropriate for the metric?&lt;/li&gt;
&lt;li&gt;Are filter values valid?&lt;/li&gt;
&lt;li&gt;Is the join path approved?&lt;/li&gt;
&lt;li&gt;Is there fanout risk?&lt;/li&gt;
&lt;li&gt;Is the aggregation grain correct?&lt;/li&gt;
&lt;li&gt;Is the result within a reasonable historical range?&lt;/li&gt;
&lt;li&gt;Did the query return no rows because of a value mapping issue?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This validation layer is one of the most important differences between a demo and a production-ready product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Runtime Component 8: Clarification Memory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every clarification should become a reusable asset.&lt;/p&gt;

&lt;p&gt;If a user confirms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By "product code," I mean the internal product code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system should save:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;user_phrase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product code&lt;/span&gt;
&lt;span class="na"&gt;standard_concept&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Product Code&lt;/span&gt;
&lt;span class="na"&gt;field_mapping&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dim_product.product_code&lt;/span&gt;
&lt;span class="na"&gt;business_domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Product&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Sales&lt;/span&gt;
&lt;span class="na"&gt;confirmed_by&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user_or_owner&lt;/span&gt;
&lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user | team | organization&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;draft | reviewed | certified&lt;/span&gt;
&lt;span class="na"&gt;usage_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Over time, repeated confirmations should create candidate semantic rules. Data owners can review and promote them.&lt;/p&gt;

&lt;p&gt;This makes the system smoother with use.&lt;/p&gt;

&lt;p&gt;The goal is not to ask better clarification questions forever. The goal is to ask fewer clarification questions over time because the semantic layer is learning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## A Practical Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is a practical architecture for a natural language analytics runtime:&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      |
                         +----------+-----------+
                                    |
                                    v
                         +----------------------+
                         | Intent Classifier    |
                         +----------+-----------+
                                    |
              +---------------------+---------------------+
              |                                           |
              v                                           v
   +------------------------+                 +------------------------+
   | Non-query Intents      |                 | Data Query Intent      |
   | Help, scope, examples  |                 | Metrics, filters, SQL  |
   +------------------------+                 +-----------+------------+
                                                          |
                                                          v
                                           +---------------------------+
                                           | Domain Router             |
                                           +------------+--------------+
                                                        |
                                                        v
                                           +---------------------------+
                                           | Semantic Retrieval        |
                                           +------------+--------------+
                                                        |
                                                        v
                                           +---------------------------+
                                           | Template Matching         |
                                           +------------+--------------+
                                                        |
                                                        v
                                           +---------------------------+
                                           | Confidence Decision       |
                                           +------------+--------------+
                                                        |
                             +--------------------------+--------------------------+
                             |                                                     |
                             v                                                     v
                 +------------------------+                           +------------------------+
                 | Clarification          |                           | Query Planning         |
                 +-----------+------------+                           +-----------+------------+
                             |                                                    |
                             v                                                    v
                 +------------------------+                           +------------------------+
                 | Semantic Memory        |                           | SQL Generation         |
                 +------------------------+                           +-----------+------------+
                                                                                  |
                                                                                  v
                                                                      +------------------------+
                                                                      | Query Validation       |
                                                                      +-----------+------------+
                                                                                  |
                                                                                  v
                                                                      +------------------------+
                                                                      | Answer + Lineage       |
                                                                      +------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The language model appears in multiple places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intent classification&lt;/li&gt;
&lt;li&gt;Query planning&lt;/li&gt;
&lt;li&gt;Clarification generation&lt;/li&gt;
&lt;li&gt;Parameter extraction&lt;/li&gt;
&lt;li&gt;Result explanation&lt;/li&gt;
&lt;li&gt;Follow-up question handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the model is not operating alone. It is grounded by semantic assets, trusted templates, permissions, relationship evidence, and validation rules.&lt;/p&gt;

&lt;p&gt;That is the difference between natural language analytics as a demo and natural language analytics as enterprise infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Where Semora Can Stand Apart&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Databricks has a strong platform-native story. If a company has standardized its data and governance inside Databricks, that integration is hard to beat.&lt;/p&gt;

&lt;p&gt;Semora should not try to be a smaller version of Databricks.&lt;/p&gt;

&lt;p&gt;It should focus on the problems that appear when the enterprise data world is messy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business terms vary across teams.&lt;/li&gt;
&lt;li&gt;Field names do not match user language.&lt;/li&gt;
&lt;li&gt;Relationships are not fully documented.&lt;/li&gt;
&lt;li&gt;Metrics conflict across systems.&lt;/li&gt;
&lt;li&gt;Users need answers across multiple platforms.&lt;/li&gt;
&lt;li&gt;Clarification should become governed semantic memory.&lt;/li&gt;
&lt;li&gt;Natural language queries need explainable lineage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a valuable and distinct engineering problem.&lt;/p&gt;

&lt;p&gt;The best semantic layer is not the one that lets the model guess more freely. It is the one that gives the model enough context, evidence, and constraints to answer correctly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Natural language analytics is not solved by connecting a language model to a database.&lt;/p&gt;

&lt;p&gt;It requires a semantic runtime.&lt;/p&gt;

&lt;p&gt;That runtime must classify intent, route by business domain, retrieve semantic assets, match trusted templates, evaluate confidence, clarify only when necessary, generate governed queries, validate results, and save human feedback as reusable semantic knowledge.&lt;/p&gt;

&lt;p&gt;Databricks approaches this through a platform-native lakehouse stack.&lt;/p&gt;

&lt;p&gt;Semora's opportunity is to build an independent semantic intelligence layer for enterprises whose data, terminology, and relationships span many systems.&lt;/p&gt;

&lt;p&gt;For developers and data engineers, the lesson is clear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not make the model guess the enterprise data model. Build the semantic system that lets it reason with evidence.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>data</category>
      <category>llm</category>
      <category>sql</category>
    </item>
    <item>
      <title>Your AI Data Agent Needs a “Do Not Use” Layer</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Tue, 25 Aug 2026 02:08:09 +0000</pubDate>
      <link>https://dev.to/arisyndata/your-ai-data-agent-needs-a-do-not-use-layer-25jn</link>
      <guid>https://dev.to/arisyndata/your-ai-data-agent-needs-a-do-not-use-layer-25jn</guid>
      <description>&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%2Fhz5salsoql5w2dww1ymx.jpg" 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%2Fhz5salsoql5w2dww1ymx.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The missing layer in many enterprise AI systems is not more metadata. It is a machine-readable record of the mistakes the organization already knows not to make.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A surprising amount of enterprise data expertise sounds like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't use that table after the migration.&lt;/p&gt;

&lt;p&gt;Don't use &lt;code&gt;invoice_amount&lt;/code&gt; as recognized revenue.&lt;/p&gt;

&lt;p&gt;Don't join those two tables directly.&lt;/p&gt;

&lt;p&gt;Don't use &lt;code&gt;created_at&lt;/code&gt; for financial reporting.&lt;/p&gt;

&lt;p&gt;Don't aggregate those rows before deduplicating accounts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These rules are rarely visible in the database schema. They may not exist in the catalog. Often they live only in the heads of experienced analysts, engineers, and business owners.&lt;/p&gt;

&lt;p&gt;That worked when humans were the primary consumers of enterprise data. It becomes a serious problem when AI agents start querying data directly.&lt;/p&gt;

&lt;p&gt;The usual response is to give the model more context.&lt;/p&gt;

&lt;p&gt;But what if the missing context is not another description of what the data &lt;em&gt;is&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;What if the missing layer is a structured description of what the AI &lt;strong&gt;must not do&lt;/strong&gt;?&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## The Data Model Contains Less Knowledge Than We Think&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider:&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;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;invoice&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;invoice_id&lt;/span&gt;      &lt;span class="nb"&gt;BIGINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt;     &lt;span class="nb"&gt;BIGINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;invoice_amount&lt;/span&gt;  &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;invoice_date&lt;/span&gt;    &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;          &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&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;An AI can identify a customer reference, an amount, and a date. It can probably generate valid SQL for:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What was recognized revenue last quarter?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the enterprise may already know:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoice_amount is not recognized revenue.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That fact is not a schema fact.&lt;/p&gt;

&lt;p&gt;It is organizational knowledge.&lt;/p&gt;

&lt;p&gt;Without it, the agent can be technically competent and still wrong.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## “Do Not Use” Is a Real Data Asset&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Data platforms traditionally capture positive knowledge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What tables exist?
What do columns mean?
What is the metric definition?
How are entities related?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expert users also carry negative knowledge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which source is misleading?
Which join is dangerous?
Which field looks correct but isn't?
Which timestamp should not be used?
Which aggregation creates double counting?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This knowledge is valuable precisely because the wrong choice often looks reasonable.&lt;/p&gt;

&lt;p&gt;A production data agent therefore needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Positive Knowledge
→ What can I use?

Negative Knowledge
→ What must I avoid?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;## A “Do Not Use” Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine structured constraints attached to enterprise data objects.&lt;/p&gt;

&lt;p&gt;For a field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;object&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;column&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;invoice.invoice_amount&lt;/span&gt;

&lt;span class="na"&gt;meaning&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;business_term&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Invoice Value&lt;/span&gt;

&lt;span class="na"&gt;usage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;valid_for&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;invoice_analysis&lt;/span&gt;

  &lt;span class="na"&gt;invalid_for&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;recognized_revenue&lt;/span&gt;

&lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;Invoice value may include amounts that have&lt;/span&gt;
  &lt;span class="s"&gt;not yet met revenue recognition rules.&lt;/span&gt;

&lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;finance&lt;/span&gt;

&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;active&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a relationship:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;object&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;relationship&lt;/span&gt;

&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;customer.customer_id&lt;/span&gt;

&lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;order.customer_id&lt;/span&gt;

&lt;span class="na"&gt;constraint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;invalid_when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;account_structure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;consolidated&lt;/span&gt;

&lt;span class="na"&gt;required_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;customer&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;account&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;order&lt;/span&gt;

&lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;Direct joins can duplicate orders across child accounts.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a time field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;object&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;time_rule&lt;/span&gt;

&lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;recognized_revenue&lt;/span&gt;

&lt;span class="na"&gt;required_field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;finance_revenue.recognition_date&lt;/span&gt;

&lt;span class="na"&gt;do_not_use&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;invoice.invoice_date&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sales_order.created_at&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a blacklist.&lt;/p&gt;

&lt;p&gt;It is contextual enterprise knowledge.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Why a Blacklist Is Too Primitive&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Marking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoice.invoice_amount = forbidden
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;would be wrong.&lt;/p&gt;

&lt;p&gt;The field is perfectly valid for &lt;code&gt;Invoice Value&lt;/code&gt;. It is invalid only when interpreted as &lt;code&gt;Recognized Revenue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So the real rule is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Object + Business Intent + Context → Valid / Invalid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;invoice.invoice_amount&lt;/span&gt;

&lt;span class="na"&gt;valid_for&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;invoice_value&lt;/span&gt;

&lt;span class="na"&gt;invalid_for&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;recognized_revenue&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cash_received&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same physical field can be valid or invalid depending on the analytical task.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Put Constraints Before the LLM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A naive pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Schema Retrieval
   ↓
LLM
   ↓
SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A stronger pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Business Intent Resolution
   ↓
Candidate Retrieval
   ↓
“Do Not Use” Constraint Check
   ↓
Trusted Relationship Resolution
   ↓
Allowed Query Context
   ↓
LLM
   ↓
SQL
   ↓
Constraint Validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constraint layer appears twice.&lt;/p&gt;

&lt;p&gt;First, it prevents known-invalid data from entering the model's decision space.&lt;/p&gt;

&lt;p&gt;Second, it validates that generated SQL did not violate a known rule.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Filter Invalid Candidates Before Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose retrieval returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;finance_revenue.recognized_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;invoice.invoice_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sales_order.total_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment.received_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a recognized-revenue question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter_by_constraints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;knowledge&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;allowed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;excluded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;candidate&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;knowledge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_hard_violation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;excluded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;

        &lt;span class="n"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;excluded&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model now receives a much cleaner problem.&lt;/p&gt;

&lt;p&gt;But keep the exclusion reason:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;excluded_context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;object&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;invoice.invoice_amount&lt;/span&gt;
    &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;not valid for recognized revenue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That helps explanation and debugging.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Relationship Constraints May Matter Even More&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Wrong joins are dangerous because they can return plausible results.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer ───── Order
    │
    └──── Account ───── Order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both paths may technically exist.&lt;/p&gt;

&lt;p&gt;For consolidated accounts, the direct path may duplicate orders.&lt;/p&gt;

&lt;p&gt;Represent the rule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;constraint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;relationship_path&lt;/span&gt;

  &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;customer&lt;/span&gt;
  &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;order&lt;/span&gt;

  &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;account_structure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;consolidated&lt;/span&gt;

  &lt;span class="na"&gt;forbidden_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;customer&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;order&lt;/span&gt;

  &lt;span class="na"&gt;required_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;customer&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;account&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;order&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then build a task-specific graph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer ──X── Order
    │
    └──── Account ───── Order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;valid_graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relationship_graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply_constraints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;business_context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;valid_graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shortest_trusted_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is safer than asking an LLM to infer join topology from names every time.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Hard Rules and Soft Rules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not every constraint should block execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### Hard Constraint&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hard&lt;/span&gt;

&lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;do_not_use&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;customer_legacy&lt;/span&gt;

&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;query_date &amp;gt;= 2026-01-01&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Violation should stop or regenerate the query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### Soft Guidance&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;soft&lt;/span&gt;

&lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;prefer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;billing_region&lt;/span&gt;

&lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;registered_region&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Violation may lower ranking or trigger review.&lt;/p&gt;

&lt;p&gt;This avoids two extremes: an inflexible rule engine and a prompt that treats every rule as optional advice.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Compile Governance Into Runtime Constraints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose a governed metric says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognized_revenue&lt;/span&gt;

&lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;finance_revenue.recognized_amount&lt;/span&gt;

&lt;span class="na"&gt;time_field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;finance_revenue.recognition_date&lt;/span&gt;

&lt;span class="na"&gt;invalid_sources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;invoice.invoice_amount&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sales_order.total_amount&lt;/span&gt;

&lt;span class="na"&gt;required_filters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;status=recognized&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compile it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required_source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;finance_revenue.recognized_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required_time_field&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;finance_revenue.recognition_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;forbidden_sources&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;invoice.invoice_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sales_order.total_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;

    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required_filters&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status=recognized&lt;/span&gt;&lt;span class="sh"&gt;"&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;The same policy can shape retrieval, context construction, generation, and validation.&lt;/p&gt;

&lt;p&gt;One governed definition drives multiple runtime controls.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Validate What Must Not Appear&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After generation, parse the SQL and check the policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;violations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;forbidden_sources&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;references&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;forbidden_source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;references&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required_time_field&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
        &lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wrong_time_field&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;violations&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If violations exist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;regenerate_or_escalate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent is no longer trusted to police itself.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Where Does Negative Knowledge Come From?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the best sources is historical failure.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem:
Revenue dashboard overstated.

Root Cause:
Orders joined directly to customers.

Fix:
Use account-level relationship.

Lesson:
Never use direct Customer → Order join
for consolidated accounts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most organizations stop after fixing the dashboard.&lt;/p&gt;

&lt;p&gt;A stronger system captures the lesson:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Failure
   ↓
Root Cause
   ↓
Data Rule
   ↓
Structured Constraint
   ↓
Future Prevention
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Operational experience becomes AI infrastructure.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Ask Experts for Mistakes, Not Documentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you ask a senior analyst:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please document these 50 columns.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you may get accurate but generic descriptions.&lt;/p&gt;

&lt;p&gt;Instead ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What are the five mistakes a new analyst is most likely to make with this data?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Don't use that amount as revenue.
Don't use this table after migration.
Don't join those IDs directly.
Don't use created_at for monthly reporting.
Don't SUM before deduplicating accounts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those answers encode experience, not just definitions.&lt;/p&gt;

&lt;p&gt;They are often extremely valuable for AI.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Version and Own the Constraints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A constraint can become outdated.&lt;/p&gt;

&lt;p&gt;It should include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ID
Version
Owner
Status
Effective Date
Reason
Validation State
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;constraint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;C-REV-014&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;

  &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;invalid_for&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;object&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;invoice.invoice_amount&lt;/span&gt;
      &lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognized_revenue&lt;/span&gt;

  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;finance&lt;/span&gt;

  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;active&lt;/span&gt;

  &lt;span class="na"&gt;effective_from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;2026-01-01&lt;/span&gt;

  &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;revenue recognition follows finance_revenue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the system knows whether the rule is still authoritative.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Make the Layer Observable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Useful metrics include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Constraint Coverage
% of critical metrics with explicit negative rules

Prevented Violations
Invalid candidates removed before LLM generation

Generated SQL Violation Rate
% of queries violating known constraints

Known-Mistake Recurrence
How often a known incident repeats after its rule is encoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last metric captures the real purpose.&lt;/p&gt;

&lt;p&gt;The goal is not to create more documentation.&lt;/p&gt;

&lt;p&gt;It is to stop known mistakes from recurring.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Do Not Turn Everything Into a Rule&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not every piece of human judgment should become deterministic policy.&lt;/p&gt;

&lt;p&gt;Some decisions are ambiguous. Some rules have many exceptions. Some knowledge is uncertain.&lt;/p&gt;

&lt;p&gt;Encode negative knowledge when it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Known
Repeated
High-impact
Business-specific
Stable enough to govern
Hard for the model to infer from schema alone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Leave genuinely ambiguous reasoning to the model.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Replace AI reasoning with rules.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stop using AI reasoning for mistakes
the enterprise already knows how to prevent.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;## A More Mature Data Agent Runtime&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Putting it together:&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
      ↓
Business Intent
      ↓
Candidate Retrieval
      ↓
Positive Knowledge
      +
Negative Knowledge
      ↓
Constraint Filtering
      ↓
Trusted Relationship Planning
      ↓
Allowed Context
      ↓
LLM Reasoning / SQL Generation
      ↓
Constraint Validation
      ↓
Execution
      ↓
Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM no longer operates over everything that looks relevant.&lt;/p&gt;

&lt;p&gt;It operates inside a data space shaped by enterprise knowledge.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## The Bigger Engineering Principle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A wrong enterprise answer is not always a hallucination.&lt;/p&gt;

&lt;p&gt;Sometimes it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;valid computation over an invalid business assumption.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A bad join can execute.&lt;/p&gt;

&lt;p&gt;A wrong metric can aggregate.&lt;/p&gt;

&lt;p&gt;A deprecated table can return real rows.&lt;/p&gt;

&lt;p&gt;A wrong date field can produce a believable trend.&lt;/p&gt;

&lt;p&gt;That is why more context alone is not enough.&lt;/p&gt;

&lt;p&gt;The system also needs boundaries.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The most valuable enterprise data knowledge may not be another description of what a field means.&lt;/p&gt;

&lt;p&gt;It may be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't use this field for that metric.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't take that join path.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't use that timestamp for reporting.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those warnings represent accumulated organizational experience.&lt;/p&gt;

&lt;p&gt;If they remain in people's heads, every new AI agent can repeat old mistakes.&lt;/p&gt;

&lt;p&gt;If they become structured, versioned, and enforceable, they become something more useful:c&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;A “Do Not Use” layer for enterprise AI.&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;And that may be one of the missing pieces between an AI agent that can query data and one that can use enterprise data reliably.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>data</category>
      <category>llm</category>
      <category>sql</category>
    </item>
    <item>
      <title>Beyond SQL Accuracy: Building Evidence Chains for AI Data Agents</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Thu, 20 Aug 2026 03:10:07 +0000</pubDate>
      <link>https://dev.to/arisyndata/beyond-sql-accuracy-building-evidence-chains-for-ai-data-agents-3mfp</link>
      <guid>https://dev.to/arisyndata/beyond-sql-accuracy-building-evidence-chains-for-ai-data-agents-3mfp</guid>
      <description>&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%2Fl7z7tf8fqncl2vbilef2.jpg" 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%2Fl7z7tf8fqncl2vbilef2.jpg" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI data agents are getting good at producing executable SQL.&lt;/p&gt;

&lt;p&gt;That is useful, but executable SQL is not the same thing as a correct business answer.&lt;/p&gt;

&lt;p&gt;A query can compile, run successfully, return real rows, and still answer the wrong question because the agent selected the wrong metric definition, source table, relationship, grain, time field, or filter.&lt;/p&gt;

&lt;p&gt;For production systems, this creates a different engineering requirement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An AI data agent should not only generate an answer. It should preserve the evidence that produced it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article explores how to treat that evidence as a first-class artifact rather than an explanation generated after the fact.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 1. Why SQL Accuracy Is an Incomplete Target&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What was net revenue by region last quarter?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent generates:&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="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoice_amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;net_revenue&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;invoices&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoice_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2026-04-01'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoice_date&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;'2026-07-01'&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query is valid.&lt;/p&gt;

&lt;p&gt;But suppose the enterprise definition is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Net Revenue
=
Recognized Revenue
-
Refunds
-
Credits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and regional attribution is based on the billing account rather than the customer master.&lt;/p&gt;

&lt;p&gt;The SQL engine cannot detect this error.&lt;/p&gt;

&lt;p&gt;From the database's perspective, the query is correct.&lt;/p&gt;

&lt;p&gt;From the business's perspective, it is wrong.&lt;/p&gt;

&lt;p&gt;That gives us two different validation layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL Validity
=
Can this query execute?

Business Validity
=
Does this query represent the intended business question?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Production AI analytics needs both.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 2. The Failure Surface Is Larger Than SQL Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A useful way to model an AI data query is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Semantic Resolution
   ↓
Source Selection
   ↓
Relationship Selection
   ↓
Filter / Time Resolution
   ↓
SQL Generation
   ↓
Execution
   ↓
Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An error can occur at any stage.&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;Semantic Resolution
Revenue → Invoice Amount       ❌

Source Selection
invoices                       ✓

Relationship Selection
invoice.customer_id → customer ✓

Time Resolution
invoice_date                   ❌

SQL Generation
Valid SQL                      ✓

Execution
Success                        ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we evaluate only the final SQL syntax or execution status, the system appears healthy.&lt;/p&gt;

&lt;p&gt;The real failure happened much earlier.&lt;/p&gt;

&lt;p&gt;This is why AI data agents need &lt;strong&gt;evidence chains&lt;/strong&gt;, not just query logs.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 3. What Is an Evidence Chain?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An evidence chain records the artifacts and decisions that connect a user question to the final answer.&lt;/p&gt;

&lt;p&gt;Conceptually:&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
      │
      ▼
Business Definition
      │
      ▼
Source Data
      │
      ▼
Relationships
      │
      ▼
Filters / Time Rules
      │
      ▼
Generated SQL
      │
      ▼
Execution Result
      │
      ▼
Final Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is not to create another verbose chain-of-thought log.&lt;/p&gt;

&lt;p&gt;The goal is to preserve &lt;strong&gt;verifiable system artifacts&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Internal model reasoning is probabilistic and may not be suitable as an audit artifact.&lt;/p&gt;

&lt;p&gt;A metric identifier, relationship identifier, SQL query, data-source identifier, and execution result are inspectable.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 4. Evidence Should Be Structured&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of storing only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;question
sql
answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;store a structured evidence object.&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;"question"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"What was net revenue by region last quarter?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"semantic_resolution"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"metric_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;"net_revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"metric_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dimensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"billing_region"&lt;/span&gt;&lt;span class="p"&gt;]&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;span class="nl"&gt;"sources"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"refunds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"billing_accounts"&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;span class="nl"&gt;"relationships"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"relationship_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;"rel_orders_billing_account"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"orders.billing_account_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"billing_accounts.account_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"trusted"&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;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"time"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"settlement_date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"period"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"last_quarter"&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;span class="nl"&gt;"sql"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"query_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;"q_8271"&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;span class="nl"&gt;"execution"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"result_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;"r_4412"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&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;span class="nl"&gt;"validation"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"passed"&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;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;Now the answer has provenance.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 5. Capture Evidence During Execution, Not Afterward&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common anti-pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Agent generates answer
2. User asks "Why?"
3. LLM generates an explanation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That produces a narrative, not necessarily provenance.&lt;/p&gt;

&lt;p&gt;The model may describe what it believes happened.&lt;/p&gt;

&lt;p&gt;A stronger implementation captures evidence as each stage executes.&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 python"&gt;&lt;code&gt;&lt;span class="n"&gt;evidence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Evidence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;metric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolve_metric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metric_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;
&lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metric_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;

&lt;span class="n"&gt;dimension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolve_dimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relationship_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_trusted_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relationship_ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relationship_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;relationship_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execution_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;
&lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The evidence object is built from actual system events.&lt;/p&gt;

&lt;p&gt;That makes it much more useful for debugging and audit.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Semantic Evidence
&lt;/h2&gt;

&lt;p&gt;The first layer is semantic resolution.&lt;/p&gt;

&lt;p&gt;If the user asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What was revenue last quarter?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the system should be able to show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Term:
Revenue

Resolved Metric:
Net Revenue

Version:
3.2

Definition:
Recognized Revenue - Refunds - Credits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This matters because business terms are often ambiguous.&lt;/p&gt;

&lt;p&gt;The SQL may be technically perfect while using the wrong definition.&lt;/p&gt;

&lt;p&gt;A metric version is particularly important.&lt;/p&gt;

&lt;p&gt;If Revenue v3.1 and v3.2 differ, the evidence chain should preserve which version generated the answer.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 7. Source Evidence&lt;/strong&gt;&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Which data actually contributed to the answer?&lt;/p&gt;
&lt;/blockquote&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;orders
refunds
billing_accounts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A production evidence record may also include fields:&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"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"billing_account_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;"recognized_amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"settlement_date"&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;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 makes it possible to inspect whether the agent used an authoritative source rather than merely a semantically similar table.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 8. Relationship Evidence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Multi-table queries require another layer of provenance.&lt;/p&gt;

&lt;p&gt;Suppose the query joins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;orders
   ↓
billing_accounts
   ↓
region
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The evidence should preserve why that path was selected.&lt;/p&gt;

&lt;p&gt;At minimum:&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;"relationship_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;"rel_orders_billing_account"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"orders.billing_account_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"billing_accounts.account_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"trusted"&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;More advanced systems could include relationship evidence such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database Constraint
Naming Similarity
Value Inclusion
Uniqueness
Business Validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important point is that the agent is not silently inventing a join.&lt;/p&gt;

&lt;p&gt;The relationship is inspectable.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 9. Filter and Time Evidence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Filters are easy to overlook because they often appear as simple SQL predicates.&lt;/p&gt;

&lt;p&gt;But they can completely change the business answer.&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;"last quarter"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might resolve to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026-04-01 → 2026-06-30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and use:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;rather than:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The evidence record should preserve both.&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;"time_resolution"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"business_period"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"last_quarter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-30"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"settlement_date"&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;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 makes temporal interpretation auditable.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 10. Query Evidence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The SQL itself remains critical evidence.&lt;/p&gt;

&lt;p&gt;But do not treat SQL as the entire explanation.&lt;/p&gt;

&lt;p&gt;SQL is the executable consequence of upstream decisions.&lt;/p&gt;

&lt;p&gt;A useful query record might include:&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;"query_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;"q_8271"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sql_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-20T09:15:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"metric_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"relationship_ids"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"rel_orders_billing_account"&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;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 makes the query reproducible and connects it to the semantic and relationship state used during generation.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 11. Execution Evidence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Execution success is useful evidence, just not sufficient evidence.&lt;/p&gt;

&lt;p&gt;Capture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Execution Status
Duration
Rows Returned
Data Source
Query Timestamp
Result Identifier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Potentially:&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;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;842&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rows_returned"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result_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;"r_4412"&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 lets the system distinguish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bad SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Valid SQL + Wrong Business Interpretation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;## 12. Validation Should Check the Chain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of asking only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the SQL execute?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;validation can inspect several layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### Semantic Validation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Was an approved metric definition used?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Source Validation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Were authorized and current data sources used?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Relationship Validation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Were joins based on trusted relationships?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Filter Validation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Were required business filters applied?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Query Validation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the SQL pass syntax and safety checks?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces a richer validation 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;"semantic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"passed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"passed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"relationships"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"passed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"filters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"passed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sql"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"passed"&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;&lt;strong&gt;## 13. Why LLM-as-a-Judge Cannot Be the Only Validator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A second model can review generated SQL.&lt;/p&gt;

&lt;p&gt;That is useful.&lt;/p&gt;

&lt;p&gt;But consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent:
Revenue = invoice_amount

Judge:
The SQL correctly sums invoice_amount.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both models agree.&lt;/p&gt;

&lt;p&gt;Both can still be wrong relative to the enterprise definition.&lt;/p&gt;

&lt;p&gt;Language models are good at evaluating logical consistency inside the context they receive.&lt;/p&gt;

&lt;p&gt;They cannot recover enterprise truth that is missing from that context.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You cannot verify a data answer with language alone.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Verification needs grounded evidence from semantic definitions, metadata, relationships, executed SQL, and query results.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 14. Evidence Chains Improve Debugging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose an answer is reported as incorrect.&lt;/p&gt;

&lt;p&gt;Without structured evidence, the debugging workflow may be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reproduce Prompt
↓
Inspect Agent Logs
↓
Inspect SQL
↓
Guess What Went Wrong
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With evidence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Semantic Resolution      PASS
Source Selection         PASS
Relationship Selection   FAIL
Filter Resolution        PASS
SQL Validation           PASS
Execution                PASS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The engineering team immediately knows where to investigate.&lt;/p&gt;

&lt;p&gt;This is especially valuable because many production NL2SQL failures happen before SQL generation.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 15. Evidence Chains Improve Evaluation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Evidence also makes offline and online evaluation more granular.&lt;/p&gt;

&lt;p&gt;Instead of only measuring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exact SQL Match
Execution Accuracy
Final Answer Accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;teams can measure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Metric Resolution Accuracy
Source Selection Accuracy
Relationship Selection Accuracy
Filter Resolution Accuracy
Trusted Relationship Usage
SQL Validation Pass Rate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This turns a monolithic accuracy score into a diagnostic system.&lt;/p&gt;

&lt;p&gt;If final-answer accuracy drops, the team can determine which layer caused the regression.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 16. Evidence as an API Object&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Evidence should not exist only in the UI.&lt;/p&gt;

&lt;p&gt;It can be part of the agent API.&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;"answer"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"metric"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Net Revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;27300000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&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;span class="nl"&gt;"evidence"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"metric"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"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;"net_revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3.2"&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;span class="nl"&gt;"sources"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"refunds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"billing_accounts"&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;span class="nl"&gt;"relationships"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"rel_orders_billing_account"&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;span class="nl"&gt;"query_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;"q_8271"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"validation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"passed"&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;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;Now downstream systems can choose how much evidence to expose.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 17. Progressive Disclosure in the UI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most business users do not want to read SQL after every question.&lt;/p&gt;

&lt;p&gt;So the default UI can remain simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Net Revenue
$27.3M

✓ Evidence available
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Why this answer?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can reveal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Metric Definition
Source Data
Relationships
Filters
SQL
Validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different users can inspect different levels.&lt;/p&gt;

&lt;p&gt;An executive may stop at the answer.&lt;/p&gt;

&lt;p&gt;An analyst may inspect the metric and filters.&lt;/p&gt;

&lt;p&gt;A data engineer may inspect joins and SQL.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 18. Evidence Is Stronger Than Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is an important difference between:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;An LLM can generate a convincing explanation.&lt;/p&gt;

&lt;p&gt;An inspectable system exposes the artifacts that actually produced the answer.&lt;/p&gt;

&lt;p&gt;For enterprise data, inspectability is often the stronger trust mechanism.&lt;/p&gt;

&lt;p&gt;The user does not have to believe the explanation.&lt;/p&gt;

&lt;p&gt;They can inspect the evidence.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 19. A Practical Evidence Pipeline&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A simplified architecture could 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;User Question
      │
      ▼
Semantic Resolver
      │
      ├── metric_id
      └── dimension_ids
      │
      ▼
Relationship Resolver
      │
      └── relationship_ids
      │
      ▼
Context Builder
      │
      ▼
SQL Generator
      │
      └── query_id
      │
      ▼
SQL Validator
      │
      ▼
Query Executor
      │
      └── result_id
      │
      ▼
Answer Generator
      │
      ▼
Evidence Object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every stage contributes structured evidence.&lt;/p&gt;

&lt;p&gt;The evidence object becomes the trace that connects the original question to the final answer.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 20. What Should Be Stored?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At minimum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question ID
User Question
Resolved Metric + Version
Resolved Dimensions
Source Tables / Fields
Relationship IDs
Filters
Time Interpretation
Generated SQL / Query ID
Execution Result ID
Validation Status
Timestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on governance requirements, also consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Semantic Model Version
Relationship Model Version
Data Snapshot / Query Timestamp
Authorization Context
Agent Version
Model Version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes answers reproducible even as the system evolves.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## 21. A Better Definition of Production Readiness&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a prototype, this may be enough:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question → SQL → Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production enterprise AI, a stronger standard is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
→ Governed Interpretation
→ Trusted Data Path
→ Executable Query
→ Traceable Result
→ Evidence-Backed Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is not cosmetic.&lt;/p&gt;

&lt;p&gt;It changes how the system can be trusted, evaluated, debugged, audited, and improved.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI data agents are rapidly improving at generating SQL.&lt;/p&gt;

&lt;p&gt;But SQL generation is only one stage in a much larger correctness problem.&lt;/p&gt;

&lt;p&gt;A production system should be able to answer two questions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is the answer?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What evidence produced that answer?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That evidence should include the business definition, source data, relationships, filters, SQL, execution result, and validation state.&lt;/p&gt;

&lt;p&gt;Not because every user wants to inspect every detail.&lt;/p&gt;

&lt;p&gt;But because enterprise trust should be based on something stronger than model confidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A trustworthy data agent does not just return a number. It preserves the chain of evidence that makes the number verifiable.&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Reasoning Tax: Why AI Data Agents Waste Tokens Relearning Your Schema</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Tue, 18 Aug 2026 02:52:49 +0000</pubDate>
      <link>https://dev.to/arisyndata/the-reasoning-tax-why-ai-data-agents-waste-tokens-relearning-your-schema-3mp6</link>
      <guid>https://dev.to/arisyndata/the-reasoning-tax-why-ai-data-agents-waste-tokens-relearning-your-schema-3mp6</guid>
      <description>&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%2Fixg0xkba5ontz6nynx2w.jpg" 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%2Fixg0xkba5ontz6nynx2w.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your data agent has to rediscover metric definitions, table relationships, and trusted query paths on every request, you are spending LLM reasoning on knowledge your system should already have.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI data agents are becoming increasingly capable.&lt;/p&gt;

&lt;p&gt;A modern agent can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retrieve schemas;&lt;/li&gt;
&lt;li&gt;interpret business terms;&lt;/li&gt;
&lt;li&gt;identify candidate tables;&lt;/li&gt;
&lt;li&gt;infer joins;&lt;/li&gt;
&lt;li&gt;generate SQL;&lt;/li&gt;
&lt;li&gt;validate queries;&lt;/li&gt;
&lt;li&gt;execute them;&lt;/li&gt;
&lt;li&gt;explain the result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That looks like progress.&lt;/p&gt;

&lt;p&gt;But from an engineering perspective, there is an uncomfortable question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How much of this work is genuinely new reasoning, and how much is the agent repeatedly rediscovering facts the enterprise already knows?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That repeated work creates a hidden cost: &lt;strong&gt;the reasoning tax&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## A Typical Data Agent Does Too Much at Query Time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What was revenue by customer last quarter?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A typical agent pipeline may 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;User Question
      ↓
Intent Detection
      ↓
Schema Retrieval
      ↓
Business Term Resolution
      ↓
Candidate Table Selection
      ↓
Relationship Discovery
      ↓
Join Path Selection
      ↓
Metric Construction
      ↓
SQL Generation
      ↓
SQL Validation
      ↓
Execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;Show customer revenue for Q2.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The analytical intent is almost identical.&lt;/p&gt;

&lt;p&gt;But many implementations repeat most of the pipeline.&lt;/p&gt;

&lt;p&gt;The agent may again retrieve schemas, resolve Revenue, identify Customer, compare join paths, and choose the reporting date.&lt;/p&gt;

&lt;p&gt;This is wasteful because much of that information is not query-specific.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Separate Query-Time Reasoning From Reusable Knowledge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A useful engineering distinction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reusable Enterprise Knowledge
vs.
Query-Specific Reasoning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Reusable Enterprise Knowledge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

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

Customer = canonical customer entity

Revenue Date = recognition_date

Customer → Order = trusted relationship

Order → Revenue = validated query path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These should not be probabilistically reconstructed on every request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### Query-Specific Reasoning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Examples:&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 the user asking?

Does "last quarter" mean fiscal or calendar quarter?

Should results be grouped by customer or customer segment?

Is the user asking for a comparison?

What should be investigated next?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These genuinely depend on the current request.&lt;/p&gt;

&lt;p&gt;The design principle is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retrieve the known. Reason about the unknown.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;## Why the Reasoning Tax Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are three immediate engineering consequences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### 1. Token Usage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose schema retrieval returns 30 tables, each with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;table descriptions;&lt;/li&gt;
&lt;li&gt;columns;&lt;/li&gt;
&lt;li&gt;data types;&lt;/li&gt;
&lt;li&gt;comments;&lt;/li&gt;
&lt;li&gt;sample values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent may receive thousands of tokens before reasoning even starts.&lt;/p&gt;

&lt;p&gt;If every query repeatedly includes the same structural information, token consumption scales with query volume.&lt;/p&gt;

&lt;p&gt;A rough model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total Token Cost
≈
Requests
×
(Context Tokens + Reasoning Tokens + Output Tokens)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reducing repeated context has a direct effect on cost.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;### 2. Latency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agent workflows often involve multiple model or tool calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Retrieve
→ Classify
→ Resolve
→ Plan
→ Generate
→ Validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if each step takes only a small amount of time, the total latency accumulates.&lt;/p&gt;

&lt;p&gt;If a trusted metric definition can be returned from a deterministic service in milliseconds, there is little value in asking an LLM to infer it again.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;### 3. Inconsistency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repeated reasoning also introduces variability.&lt;/p&gt;

&lt;p&gt;One request may produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue → invoice_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue → recognized_revenue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue → order_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model may be behaving reasonably in all three cases.&lt;/p&gt;

&lt;p&gt;The architecture is simply asking it to repeatedly solve an ambiguous problem.&lt;/p&gt;

&lt;p&gt;Govern the definition once and retrieve it consistently.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Schema Retrieval Is Necessary, but It Is Not Enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common NL2SQL architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Embedding Search
   ↓
Relevant Tables
   ↓
LLM
   ↓
SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is much better than sending the entire warehouse schema.&lt;/p&gt;

&lt;p&gt;But table retrieval still leaves unresolved questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which metric is authoritative?

Which entity is canonical?

Which relationship is trusted?

Which date field should be used?

Which join path is safe?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Retrieval that returns only schema is still forcing the LLM to reconstruct business knowledge.&lt;/p&gt;

&lt;p&gt;A richer query context should return something closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;question&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;revenue&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;by&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;customer&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;last&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;quarter"&lt;/span&gt;

&lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;revenue&lt;/span&gt;
  &lt;span class="na"&gt;definition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognized_revenue&lt;/span&gt;
  &lt;span class="na"&gt;aggregation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SUM&lt;/span&gt;

&lt;span class="na"&gt;dimensions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;customer&lt;/span&gt;

&lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognition_date&lt;/span&gt;

&lt;span class="na"&gt;tables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;customer&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sales_order&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;finance_revenue&lt;/span&gt;

&lt;span class="na"&gt;trusted_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;customer&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sales_order&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;finance_revenue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the LLM is not discovering the data model.&lt;/p&gt;

&lt;p&gt;It is using it.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Precompute Relationship Knowledge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Relationship inference is a major source of unnecessary query-time reasoning.&lt;/p&gt;

&lt;p&gt;Suppose the agent needs to connect:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It may discover several candidate paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer → Order → Invoice → Payment

Customer → Account → Payment

Customer → Contract → Invoice → Payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the organization has already validated the first path for this analytical scenario, there is no reason to compare all three paths again.&lt;/p&gt;

&lt;p&gt;Relationship knowledge can be discovered ahead of time using evidence such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Primary / Foreign Keys
Column Naming
Value Overlap
Uniqueness
Inclusion Ratio
Historical Query Patterns
Business Validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;A = order.customer_id
B = customer.customer_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A useful signal is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inclusion(A → B)
=
|distinct(A) ∩ distinct(B)|
---------------------------
|distinct(A)|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Relationship candidates can then move through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Discovered
    ↓
Candidate
    ↓
Validated
    ↓
Trusted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Query-time agents should preferentially retrieve the trusted result.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Move Metric Resolution Out of the Prompt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Metric definitions are another common source of repeated reasoning.&lt;/p&gt;

&lt;p&gt;Instead of embedding this in every system prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;When the user says revenue, use recognized_amount
from finance_revenue unless...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;maintain a governed metric 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;"metric"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aggregation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"finance_revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"column"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"recognized_amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"time_field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"recognition_date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"active"&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 agent calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_metric_definition("revenue")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and receives the current definition.&lt;/p&gt;

&lt;p&gt;This has several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one definition across agents;&lt;/li&gt;
&lt;li&gt;easier versioning;&lt;/li&gt;
&lt;li&gt;easier auditing;&lt;/li&gt;
&lt;li&gt;less prompt complexity;&lt;/li&gt;
&lt;li&gt;fewer tokens;&lt;/li&gt;
&lt;li&gt;less ambiguity.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;## Build Query Context Before Calling the LLM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A useful architecture is:&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
                     │
                     ▼
          ┌────────────────────┐
          │ Context Resolver   │
          ├────────────────────┤
          │ Business Terms     │
          │ Metrics            │
          │ Metadata           │
          │ Relationships      │
          │ Trusted Paths      │
          └─────────┬──────────┘
                    │
                    ▼
             Trusted Context
                    │
                    ▼
                  LLM
                    │
             Reason / Generate
                    │
                    ▼
                   SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM receives only what is relevant.&lt;/p&gt;

&lt;p&gt;This changes the role of the model.&lt;/p&gt;

&lt;p&gt;Before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LLM = Data Discovery + Business Interpretation + Reasoning + SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data Layer = Known Enterprise Facts

LLM = Intent + Reasoning + SQL / Analysis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;## A Simple Context Resolver&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Conceptually, the resolver could work like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_query_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;concepts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolve_business_terms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;metrics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_metric_definitions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;concepts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;entities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_business_entities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;concepts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_relevant_metadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;entities&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;entities&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;relationships&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_trusted_relationships&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tables&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;metrics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;entities&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;metadata&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;relationships&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;relationships&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build_query_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact implementation will vary.&lt;/p&gt;

&lt;p&gt;The architectural point is that the model does not have to infer every layer of enterprise knowledge itself.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Cache Stable Knowledge at the Right Level&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not all knowledge changes at the same frequency.&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;Table Schema
→ changes occasionally

Metric Definition
→ changes occasionally

Trusted Relationship
→ changes occasionally

User Question
→ changes every request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This suggests different caching and refresh strategies.&lt;/p&gt;

&lt;p&gt;A system might maintain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Metadata Cache
Semantic Cache
Relationship Cache
Query Context Cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with invalidation triggered by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Schema Change
Metric Version Change
Relationship Update
Governance Update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is more efficient than treating every query as a completely new reasoning problem.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## MCP Can Expose the Known Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For agent-based architectures, MCP can provide a clean interface to reusable enterprise knowledge.&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;get_metric_definition

get_business_entity

get_table_metadata

get_trusted_relationships

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

&lt;/div&gt;



&lt;p&gt;The agent workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Agent
   ↓
MCP Tools
   ↓
Enterprise Data Intelligence
   ↓
Trusted Context
   ↓
LLM Reasoning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP does not remove the need for semantic or relationship intelligence.&lt;/p&gt;

&lt;p&gt;It gives agents a standardized way to access it.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Do Not Confuse Precomputation With Hard-Coding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Moving knowledge out of query-time reasoning does not mean freezing the data model.&lt;/p&gt;

&lt;p&gt;Enterprise knowledge changes.&lt;/p&gt;

&lt;p&gt;Schemas evolve.&lt;/p&gt;

&lt;p&gt;Metrics change.&lt;/p&gt;

&lt;p&gt;Relationships change.&lt;/p&gt;

&lt;p&gt;The reusable layer therefore needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Discover
   ↓
Detect Change
   ↓
Evaluate Impact
   ↓
Validate
   ↓
Version
   ↓
Publish
   ↓
Invalidate Cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The objective is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Never reason about the data model again.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Do not reason about the same established data knowledge on every request.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;## Measure the Reasoning Tax&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams can make this problem observable.&lt;/p&gt;

&lt;p&gt;Useful metrics might include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### Context Tokens per Query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Average tokens sent before generation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Reasoning Calls per Query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Average LLM calls required before SQL execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Schema Candidates per Query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many tables / columns must the model evaluate?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Relationship Resolution Rate&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% of queries using prevalidated relationships
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Metric Resolution Rate&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% of business metrics resolved without LLM inference
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Time to First SQL&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question received
→
Executable SQL generated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These metrics can reveal whether the agent is spending most of its time solving analytical problems or reconstructing the enterprise data model.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## The Optimization Target Changes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common optimization question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which model gives the best SQL accuracy?&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;But production systems should also ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How much unnecessary reasoning are we forcing the model to perform?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A more capable model may hide poor architecture by successfully reasoning through large amounts of noisy context.&lt;/p&gt;

&lt;p&gt;That does not make the architecture efficient.&lt;/p&gt;

&lt;p&gt;The better system may be the one that gives the model less to figure out.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI agents are good at reasoning.&lt;/p&gt;

&lt;p&gt;Reasoning is also probabilistic, expensive, and slower than deterministic lookup.&lt;/p&gt;

&lt;p&gt;So use it where it adds value.&lt;/p&gt;

&lt;p&gt;If Revenue already has a governed definition:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;retrieve it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If Customer already has a canonical entity:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;retrieve it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a join path is already trusted:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;retrieve it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then let the model solve the genuinely new problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;what the user is asking and how to analyze it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next generation of enterprise data agents may not win by thinking harder.&lt;/p&gt;

&lt;p&gt;They may win by knowing what they no longer need to think about.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>data</category>
      <category>sql</category>
    </item>
    <item>
      <title>Why Every AI Agent Shouldn't Have to Rediscover Your Data Model</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Fri, 14 Aug 2026 10:23:00 +0000</pubDate>
      <link>https://dev.to/arisyndata/why-every-ai-agent-shouldnt-have-to-rediscover-your-data-model-3fn9</link>
      <guid>https://dev.to/arisyndata/why-every-ai-agent-shouldnt-have-to-rediscover-your-data-model-3fn9</guid>
      <description>&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%2Fxaajxm2iqkzleu6huc6g.jpg" 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%2Fxaajxm2iqkzleu6huc6g.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enterprise AI is moving toward a multi-agent architecture.&lt;/p&gt;

&lt;p&gt;Instead of one general-purpose assistant, organizations are starting to build specialized agents for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sales;&lt;/li&gt;
&lt;li&gt;finance;&lt;/li&gt;
&lt;li&gt;operations;&lt;/li&gt;
&lt;li&gt;customer support;&lt;/li&gt;
&lt;li&gt;analytics;&lt;/li&gt;
&lt;li&gt;management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That creates an engineering problem that is easy to miss.&lt;/p&gt;

&lt;p&gt;If every agent independently receives database schemas, retrieves metadata, learns metric definitions, discovers join paths, and builds its own interpretation of the business, then every new agent becomes another data-modeling project.&lt;/p&gt;

&lt;p&gt;The result is not only duplicated engineering work.&lt;/p&gt;

&lt;p&gt;It is duplicated &lt;strong&gt;enterprise understanding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A better architecture is to separate agent reasoning from shared data intelligence.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## The Problem With Agent-Local Data Knowledge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A simple data agent often looks something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  ↓
Agent
  ├── System Prompt
  ├── Schema Retrieval
  ├── Metric Definitions
  ├── Join Instructions
  ├── SQL Tool
  └── LLM
        ↓
    Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a single proof of concept, this is reasonable.&lt;/p&gt;

&lt;p&gt;Now imagine five teams building five agents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sales Agent
Finance Agent
Supply Chain Agent
Support Agent
Analytics Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each team has to solve the same problems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which tables are relevant?

What does "Customer" mean?

Which definition of Revenue is authoritative?

How should Customer connect to Order?

Which data source should be trusted?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation may be different, but the underlying enterprise knowledge is largely the same.&lt;/p&gt;

&lt;p&gt;If that knowledge lives inside each agent, duplication begins immediately.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Example: Five Agents, Three Definitions of Revenue&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose an enterprise contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sales_order.total_amount
finance_invoice.invoice_amount
finance_revenue.recognized_amount
payment.received_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A sales agent might map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue → sales_order.total_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A finance agent might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue → finance_revenue.recognized_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An analytics agent might retrieve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue → finance_invoice.invoice_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three agents may generate syntactically correct SQL.&lt;/p&gt;

&lt;p&gt;All three queries may execute successfully.&lt;/p&gt;

&lt;p&gt;But the organization now has three AI systems answering the same business question differently.&lt;/p&gt;

&lt;p&gt;The problem is not LLM reasoning.&lt;/p&gt;

&lt;p&gt;The problem is that business meaning was implemented locally inside each agent.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Business Knowledge Should Be an Enterprise Dependency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agent-specific knowledge and enterprise-wide knowledge should be separated.&lt;/p&gt;

&lt;p&gt;An agent may legitimately own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;task instructions;&lt;/li&gt;
&lt;li&gt;workflow logic;&lt;/li&gt;
&lt;li&gt;persona;&lt;/li&gt;
&lt;li&gt;tool selection;&lt;/li&gt;
&lt;li&gt;planning strategy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But definitions such as these should not be duplicated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
Revenue
Active Customer
Inventory Balance
Gross Margin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same applies to data relationships:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
   ↓
Order
   ↓
Invoice
   ↓
Payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are enterprise data assets.&lt;/p&gt;

&lt;p&gt;They should be reusable dependencies.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Thick Agents vs. Thin Agents&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A thick agent contains a large amount of enterprise-specific intelligence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
├── LLM
├── Business Semantics
├── Metrics
├── Schema Knowledge
├── Relationship Knowledge
├── Business Rules
├── Query Logic
└── Tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates coupling.&lt;/p&gt;

&lt;p&gt;If the Revenue definition changes, multiple agents may need to change.&lt;/p&gt;

&lt;p&gt;If a trusted join path changes, multiple prompts or tools may need to be updated.&lt;/p&gt;

&lt;p&gt;If the organization switches models, important business knowledge may be buried inside model-specific implementation.&lt;/p&gt;

&lt;p&gt;A thinner design looks different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
├── LLM
├── Task Logic
├── Planning
└── Tools
      ↓
Shared Data Intelligence
├── Business Semantics
├── Metrics &amp;amp; Dimensions
├── Metadata
├── Trusted Relationships
└── Query Context
      ↓
Enterprise Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the agent does not need to rediscover the enterprise every time it answers a question.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## What Should the Shared Data Layer Expose?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The shared layer does not have to be one monolithic service.&lt;/p&gt;

&lt;p&gt;It can expose several reusable capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### 1. Metadata Retrieval&lt;/strong&gt;&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;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sales_order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"columns"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"order_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;"customer_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;"order_date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"total_amount"&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;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;But raw metadata alone is not enough.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;### 2. Business Semantics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The agent should be able to resolve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"recognized revenue"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;revenue&lt;/span&gt;
&lt;span class="na"&gt;definition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognized revenue&lt;/span&gt;
&lt;span class="na"&gt;aggregation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SUM&lt;/span&gt;
&lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;finance_revenue&lt;/span&gt;
  &lt;span class="na"&gt;column&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognized_amount&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This definition can then be reused by every authorized agent.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;### 3. Relationship Discovery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose the agent needs Customer and Payment data.&lt;/p&gt;

&lt;p&gt;It should not have to guess the join path from raw schemas.&lt;/p&gt;

&lt;p&gt;A relationship service could return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
   ↓ customer_id
Order
   ↓ order_id
Invoice
   ↓ invoice_id
Payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;along with evidence or confidence information.&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;"path"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"sales_order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"invoice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"payment"&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;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"trusted"&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;&lt;strong&gt;### 4. Query Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of sending an entire warehouse schema into the prompt, the agent can receive only the relevant context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Resolve Business Concepts
   ↓
Retrieve Relevant Metadata
   ↓
Retrieve Trusted Relationships
   ↓
Generate Query Context
   ↓
LLM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reduces unnecessary context and gives the model more targeted information.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Why Schema Retrieval Alone Is Not Enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common pattern today is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Embedding Search
   ↓
Relevant Tables
   ↓
LLM
   ↓
SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful.&lt;/p&gt;

&lt;p&gt;It solves the problem of sending thousands of tables to the model.&lt;/p&gt;

&lt;p&gt;But it does not answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which metric definition is authoritative?

Which relationship is trusted?

Which business entity does this table represent?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Retrieval answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What looks relevant?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A shared data intelligence layer must also answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is valid for this business question?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That distinction matters more as the number of agents grows.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Relationship Knowledge Should Be Evidence-Based&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise relationships are often not fully represented by foreign keys.&lt;/p&gt;

&lt;p&gt;A relationship engine can use several signals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database constraints
Naming similarity
Value overlap
Uniqueness
Inclusion relationships
Validated business mappings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A = order.customer_id
B = customer.customer_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we can calculate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inclusion(A → B)
=
|distinct(A) ∩ distinct(B)|
---------------------------
|distinct(A)|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A high inclusion ratio can provide evidence that &lt;code&gt;A&lt;/code&gt; references &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But discovered relationships should not automatically become business truth.&lt;/p&gt;

&lt;p&gt;A safer lifecycle is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Discovered
    ↓
Candidate
    ↓
Validated
    ↓
Trusted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agents should preferentially consume trusted relationships rather than independently inventing joins.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## MCP Fits Here — But It Is Not the Data Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MCP gives agents a standardized way to discover and call tools.&lt;/p&gt;

&lt;p&gt;That makes it a natural interface for shared data capabilities.&lt;/p&gt;

&lt;p&gt;For example, an enterprise data MCP server could expose tools such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_metric_definition()

get_table_metadata()

discover_relationships()

get_query_context()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An agent could then call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓
MCP
  ↓
Shared Data Intelligence Services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But MCP itself does not determine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What Revenue means

Which customer definition is authoritative

Which join path is trusted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those decisions come from the data intelligence behind the interface.&lt;/p&gt;

&lt;p&gt;A useful distinction is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;MCP standardizes access. Shared data intelligence standardizes understanding.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;## Centralization Does Not Mean Static Knowledge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Moving enterprise knowledge into a shared layer solves duplication, but it creates another responsibility:&lt;/p&gt;

&lt;p&gt;the shared knowledge must stay current.&lt;/p&gt;

&lt;p&gt;Enterprise systems continuously change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New tables
New columns
New metrics
New business rules
New relationships
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the shared layer needs its own lifecycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Discover
   ↓
Detect Change
   ↓
Evaluate Impact
   ↓
Validate
   ↓
Version
   ↓
Publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise the organization simply replaces many stale agent configurations with one stale central configuration.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## What Happens When a Metric Changes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue v1
=
SUM(invoice_amount)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;changes to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue v2
=
SUM(recognized_amount)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With agent-local knowledge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sales Agent → update
Finance Agent → update
Analytics Agent → update
Management Agent → update
Support Agent → maybe update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Someone has to discover every dependency.&lt;/p&gt;

&lt;p&gt;With shared semantics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue Definition
       ↓
Version Update
       ↓
Shared Data Intelligence
       ↓
All Authorized Agents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The enterprise changes the definition once.&lt;/p&gt;

&lt;p&gt;Agents consume the updated version.&lt;/p&gt;

&lt;p&gt;That is a much cleaner dependency model.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Shared Data Intelligence Also Reduces Agent Coupling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is another benefit.&lt;/p&gt;

&lt;p&gt;Agent frameworks are changing quickly.&lt;/p&gt;

&lt;p&gt;Organizations may switch between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;models;&lt;/li&gt;
&lt;li&gt;orchestration frameworks;&lt;/li&gt;
&lt;li&gt;agent runtimes;&lt;/li&gt;
&lt;li&gt;application interfaces.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Business knowledge should survive those changes.&lt;/p&gt;

&lt;p&gt;If metric definitions, data relationships, and business mappings are independent of the agent implementation, agents become easier to replace.&lt;/p&gt;

&lt;p&gt;That suggests an architectural principle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agents = Replaceable Compute / Reasoning

Enterprise Data Intelligence = Durable Knowledge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The enterprise should own its understanding of itself.&lt;/p&gt;

&lt;p&gt;Not the current agent framework.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## A Practical Multi-Agent Data Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A simplified architecture might 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;               Sales Agent
                    │
              Finance Agent
                    │
             Analytics Agent
                    │
             Operations Agent
                    │
                    ▼
        ┌──────────────────────┐
        │ Shared Data          │
        │ Intelligence Layer   │
        ├──────────────────────┤
        │ Business Semantics   │
        │ Metrics &amp;amp; Dimensions │
        │ Metadata             │
        │ Relationships        │
        │ Trusted Query Paths  │
        └──────────────────────┘
                    │
                    ▼
             Enterprise Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shared layer does not replace agents.&lt;/p&gt;

&lt;p&gt;It makes them thinner.&lt;/p&gt;

&lt;p&gt;It does not replace the LLM.&lt;/p&gt;

&lt;p&gt;It gives the LLM a consistent representation of the enterprise.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;## Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first generation of enterprise agents focused on making individual agents more capable.&lt;/p&gt;

&lt;p&gt;The multi-agent era creates a different engineering problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do many agents share one consistent understanding of enterprise data?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If every agent independently discovers schemas, defines metrics, and guesses relationships, organizations will create duplicated logic and inconsistent answers.&lt;/p&gt;

&lt;p&gt;The better pattern is separation of concerns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agents reason.

Shared data intelligence defines what the enterprise means.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Models will change.&lt;/p&gt;

&lt;p&gt;Agents will change.&lt;/p&gt;

&lt;p&gt;Frameworks will change.&lt;/p&gt;

&lt;p&gt;Your enterprise should not have to rediscover its own data model every time they do.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>data</category>
      <category>sql</category>
      <category>llm</category>
    </item>
    <item>
      <title>Semantic Drift: The Hidden Failure Mode of Enterprise AI Analytics</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Wed, 12 Aug 2026 13:18:00 +0000</pubDate>
      <link>https://dev.to/arisyndata/semantic-drift-the-hidden-failure-mode-of-enterprise-ai-analytics-161c</link>
      <guid>https://dev.to/arisyndata/semantic-drift-the-hidden-failure-mode-of-enterprise-ai-analytics-161c</guid>
      <description>&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%2Fwppfii0eb9hpxwvurvto.jpg" 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%2Fwppfii0eb9hpxwvurvto.jpg" alt=" " width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enterprise AI systems rarely fail only because the model is weak.&lt;/p&gt;

&lt;p&gt;A more subtle failure happens when the model is working correctly, the SQL executes successfully, and the result looks reasonable — but the system is reasoning over an outdated representation of the business.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;semantic drift&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As more teams put semantic layers between LLMs and enterprise data, maintaining those semantics becomes a production engineering problem rather than a one-time modeling task.&lt;/p&gt;

&lt;p&gt;The database changes.&lt;/p&gt;

&lt;p&gt;Business definitions change.&lt;/p&gt;

&lt;p&gt;Relationships change.&lt;/p&gt;

&lt;p&gt;If the AI's understanding does not change with them, accuracy degrades quietly.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;A Semantic Layer Is Runtime Infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common AI analytics architecture looks roughly 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
     ↓
LLM / Query Agent
     ↓
Semantic Layer
     ↓
Enterprise Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The semantic layer may contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business terms;&lt;/li&gt;
&lt;li&gt;metric definitions;&lt;/li&gt;
&lt;li&gt;dimensions;&lt;/li&gt;
&lt;li&gt;mappings to physical tables and columns;&lt;/li&gt;
&lt;li&gt;relationships used to generate queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helps prevent an LLM from guessing directly from raw schemas.&lt;/p&gt;

&lt;p&gt;But there is an important consequence:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Once AI depends on the semantic layer at query time, stale semantics become a runtime failure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The problem is that semantic models are often maintained as if they were documentation.&lt;/p&gt;

&lt;p&gt;Define them once.&lt;/p&gt;

&lt;p&gt;Review them.&lt;/p&gt;

&lt;p&gt;Publish them.&lt;/p&gt;

&lt;p&gt;Then assume they remain correct.&lt;/p&gt;

&lt;p&gt;Enterprise data does not behave that way.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Failure Mode 1: Schema Drift&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose a metric is mapped to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer.customer_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a warehouse migration, the organization introduces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;account_customer.customer_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The old table may remain available for compatibility.&lt;/p&gt;

&lt;p&gt;That creates a dangerous situation.&lt;/p&gt;

&lt;p&gt;Nothing necessarily breaks.&lt;/p&gt;

&lt;p&gt;The old query can still execute.&lt;/p&gt;

&lt;p&gt;The semantic mapping is simply pointing to a representation that is no longer authoritative.&lt;/p&gt;

&lt;p&gt;Traditional schema monitoring may tell you that a column was added.&lt;/p&gt;

&lt;p&gt;AI analytics needs to answer a harder question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this schema change invalidate any business meaning used by the AI?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That requires connecting physical metadata changes to semantic dependencies.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Failure Mode 2: Semantic Drift&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Semantic drift happens even when the schema does not change.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Active Customer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Version 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer.status = 'ACTIVE'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, the business changes the definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer with &amp;gt;= 1 completed order in the last 90 days
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database can remain exactly the same.&lt;/p&gt;

&lt;p&gt;But the meaning has changed.&lt;/p&gt;

&lt;p&gt;An AI system using the old definition may continue returning perfectly valid SQL and perfectly wrong business answers.&lt;/p&gt;

&lt;p&gt;This is why execution success is a weak validation signal for enterprise AI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL succeeded != business meaning is correct
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Failure Mode 3: Relationship Drift&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This problem becomes more interesting when queries span multiple tables.&lt;/p&gt;

&lt;p&gt;Imagine the original analytical path is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
   ↓ customer_id
Order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After an ERP redesign:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
   ↓
Account
   ↓
Order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The old join may still work because legacy identifiers remain populated.&lt;/p&gt;

&lt;p&gt;But the organization has changed the business relationship.&lt;/p&gt;

&lt;p&gt;An LLM that sees both paths now has multiple executable options.&lt;/p&gt;

&lt;p&gt;Which one is correct?&lt;/p&gt;

&lt;p&gt;This cannot be solved reliably with schema retrieval alone.&lt;/p&gt;

&lt;p&gt;The system needs maintained relationship knowledge.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why Embeddings Do Not Solve Drift&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common approach is to embed schema metadata and retrieve relevant tables for each question.&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 Question
     ↓
Embedding Search
     ↓
Relevant Tables / Columns
     ↓
LLM
     ↓
SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful for reducing schema size.&lt;/p&gt;

&lt;p&gt;But semantic similarity does not tell us whether a definition is current.&lt;/p&gt;

&lt;p&gt;Embedding search may find:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoice_amount
recognized_revenue
payment_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for the term:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;All three are semantically related.&lt;/p&gt;

&lt;p&gt;Only business governance can determine which one currently represents the metric.&lt;/p&gt;

&lt;p&gt;Likewise, embeddings may identify two similar identifiers, but similarity does not prove that they form the trusted join path.&lt;/p&gt;

&lt;p&gt;Retrieval solves relevance.&lt;/p&gt;

&lt;p&gt;It does not solve validity.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Treat Semantic Assets Like Versioned Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If semantic definitions affect AI-generated answers, they should be treated more like production code than documentation.&lt;/p&gt;

&lt;p&gt;A metric definition should have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;revenue&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;active&lt;/span&gt;
&lt;span class="na"&gt;definition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognized revenue&lt;/span&gt;
&lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;finance_revenue&lt;/span&gt;
  &lt;span class="na"&gt;column&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;recognized_amount&lt;/span&gt;
&lt;span class="na"&gt;valid_from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-07-01&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A relationship should also carry explicit evidence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;relationship&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;customer.customer_id&lt;/span&gt;
  &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;account.customer_id&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;business_validated&lt;/span&gt;
&lt;span class="na"&gt;confidence&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.97&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;active&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact format is less important than the engineering principle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Meaning needs identity, state, history, and validation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without versioning, it becomes difficult to answer basic production questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which definition generated this answer?&lt;/li&gt;
&lt;li&gt;When did that definition change?&lt;/li&gt;
&lt;li&gt;Which queries are affected?&lt;/li&gt;
&lt;li&gt;Can we roll back?&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Detect Changes Before They Become Wrong Answers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A living semantic system needs change detection.&lt;/p&gt;

&lt;p&gt;At the physical layer, monitor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New table
Column added
Column removed
Type changed
Constraint changed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the relationship layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New candidate relationship
Join coverage changed
Identifier uniqueness changed
Relationship confidence changed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the semantic layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Metric definition changed
Mapping became ambiguous
Business term changed
New semantic version published
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is not generating more alerts.&lt;/p&gt;

&lt;p&gt;It is calculating &lt;strong&gt;impact&lt;/strong&gt;.&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;finance_invoice.invoice_amount changed
                 ↓
revenue metric mapping affected
                 ↓
12 query templates affected
                 ↓
AI queries using Revenue require validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now schema monitoring becomes useful to AI governance.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Relationship Discovery Should Produce Candidates, Not Truth&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Automatically discovering relationships can help keep a data model current.&lt;/p&gt;

&lt;p&gt;Signals may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;declared primary/foreign keys;&lt;/li&gt;
&lt;li&gt;naming similarity;&lt;/li&gt;
&lt;li&gt;value overlap;&lt;/li&gt;
&lt;li&gt;uniqueness;&lt;/li&gt;
&lt;li&gt;inclusion ratio;&lt;/li&gt;
&lt;li&gt;historical joins.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For two columns &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;, a simple inclusion signal could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inclusion(A → B)
=
|distinct(A) ∩ distinct(B)|
---------------------------
|distinct(A)|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A high value can indicate a possible relationship.&lt;/p&gt;

&lt;p&gt;But it should not automatically become trusted business logic.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Relationship Detected
        ↓
Candidate
        ↓
Evidence / Confidence
        ↓
Validation
        ↓
Trusted Relationship
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Automated discovery improves coverage.&lt;/p&gt;

&lt;p&gt;Governance establishes trust.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Human-in-the-Loop Is a Feature, Not a Failure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise semantics often cannot be inferred safely from technical metadata alone.&lt;/p&gt;

&lt;p&gt;If the system finds:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;mapped plausibly to both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sales_order.total_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;finance_revenue.recognized_amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the correct behavior may be to ask for clarification.&lt;/p&gt;

&lt;p&gt;A useful workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ambiguity Detected
       ↓
Candidate Definitions
       ↓
Human Review
       ↓
Validate With Query
       ↓
Publish New Version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal of automation is not to eliminate domain experts.&lt;/p&gt;

&lt;p&gt;It is to stop asking them to manually rediscover every schema and relationship change.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;A Practical Living Data Model Loop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Putting the pieces together, the lifecycle looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Discover metadata
        ↓
2. Detect schema and relationship changes
        ↓
3. Identify impacted semantic assets
        ↓
4. Generate candidate updates
        ↓
5. Validate ambiguous business meaning
        ↓
6. Version and publish
        ↓
7. Use validated semantics for AI queries
        ↓
8. Repeat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is fundamentally different from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build semantic layer → Done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The semantic model becomes an operational system.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What Should Be Monitored?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A few useful signals include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semantic Coverage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How much of the active analytical surface has governed meaning?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;governed metrics / queried metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Relationship Coverage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How many required multi-table query paths are backed by trusted relationships?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ambiguity Rate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How often does a business term map to multiple plausible definitions?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stale Mapping Rate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How many semantic mappings reference changed or deprecated physical assets?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validation Failure Rate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How often do proposed semantic or relationship updates fail business validation?&lt;/p&gt;

&lt;p&gt;These metrics tell you more about production readiness than simply measuring whether SQL execution succeeds.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Key Engineering Shift&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first generation of LLM analytics focused heavily on query generation.&lt;/p&gt;

&lt;p&gt;The next engineering challenge is maintaining the data knowledge used to generate those queries.&lt;/p&gt;

&lt;p&gt;A stronger model cannot compensate for a stale business definition.&lt;/p&gt;

&lt;p&gt;A larger context window cannot determine whether an old join path is still authoritative.&lt;/p&gt;

&lt;p&gt;And better embeddings cannot decide when the organization changed the meaning of revenue.&lt;/p&gt;

&lt;p&gt;The system needs a maintained layer of enterprise data knowledge.&lt;/p&gt;

&lt;p&gt;Not static metadata.&lt;/p&gt;

&lt;p&gt;Not a one-time semantic project.&lt;/p&gt;

&lt;p&gt;A living model.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your AI analytics system depends on business semantics, those semantics are production infrastructure.&lt;/p&gt;

&lt;p&gt;Treat them accordingly.&lt;/p&gt;

&lt;p&gt;Monitor changes.&lt;/p&gt;

&lt;p&gt;Track relationships.&lt;/p&gt;

&lt;p&gt;Version definitions.&lt;/p&gt;

&lt;p&gt;Detect ambiguity.&lt;/p&gt;

&lt;p&gt;Validate business meaning.&lt;/p&gt;

&lt;p&gt;Because the most dangerous enterprise AI failure is not always a broken query.&lt;/p&gt;

&lt;p&gt;Sometimes the query works perfectly — against yesterday's understanding of the business.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>semantic</category>
      <category>data</category>
      <category>sql</category>
    </item>
    <item>
      <title>Building AI Analysts: Why Enterprise Analytics Needs More Than BI Dashboards</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Mon, 10 Aug 2026 12:46:00 +0000</pubDate>
      <link>https://dev.to/arisyndata/building-ai-analysts-why-enterprise-analytics-needs-more-than-bi-dashboards-490a</link>
      <guid>https://dev.to/arisyndata/building-ai-analysts-why-enterprise-analytics-needs-more-than-bi-dashboards-490a</guid>
      <description>&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%2Floh8bbx2olfcan5ic6a7.jpg" 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%2Floh8bbx2olfcan5ic6a7.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For decades, enterprises have relied on dashboards as the primary way to consume business data.&lt;/p&gt;

&lt;p&gt;A typical workflow looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business Question
↓
Find the Right Dashboard
↓
Select Filters
↓
Review Metrics
↓
Human Analysis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This model works well for predefined questions.&lt;/p&gt;

&lt;p&gt;But modern businesses increasingly ask questions that were never designed into dashboards:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why did sales decline in East China last month?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Answering this requires combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sales data;&lt;/li&gt;
&lt;li&gt;customer data;&lt;/li&gt;
&lt;li&gt;product data;&lt;/li&gt;
&lt;li&gt;regional information;&lt;/li&gt;
&lt;li&gt;order history.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A dashboard can show what happened.&lt;/p&gt;

&lt;p&gt;But understanding why it happened requires deeper analysis.&lt;/p&gt;

&lt;p&gt;This is where AI Analysts become valuable.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;From BI Dashboards to AI Analysts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI changes the interaction model.&lt;/p&gt;

&lt;p&gt;Instead of searching for reports, users can directly express business questions.&lt;br&gt;
&lt;/p&gt;

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

↓

AI Understanding

↓

Data Discovery

↓

Multi-dimensional Analysis

↓

Business Insight
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is not simply generating charts.&lt;/p&gt;

&lt;p&gt;The goal is helping users understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happened?&lt;/li&gt;
&lt;li&gt;Why did it happen?&lt;/li&gt;
&lt;li&gt;What factors contributed?&lt;/li&gt;
&lt;li&gt;What should be investigated next?&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Why Building AI Analysts Is Difficult&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Connecting an LLM to a database is not enough.&lt;/p&gt;

&lt;p&gt;Enterprise analytics requires understanding the business behind the data.&lt;/p&gt;

&lt;p&gt;An AI Analyst needs to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business concepts;&lt;/li&gt;
&lt;li&gt;data relationships;&lt;/li&gt;
&lt;li&gt;analytical logic.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Understanding Business Concepts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Business users do not think in tables.&lt;/p&gt;

&lt;p&gt;They ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show me high-value customers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But enterprises may have:&lt;br&gt;
&lt;/p&gt;

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

account_table

crm_customer

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

&lt;/div&gt;



&lt;p&gt;The AI needs to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which customer definition is correct?&lt;/li&gt;
&lt;li&gt;Which attributes define value?&lt;/li&gt;
&lt;li&gt;Which data source should be trusted?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A business concept is not always a table.&lt;/p&gt;

&lt;p&gt;It is a combination of entities, metrics, rules, and relationships.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Understanding Data Relationships&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise analysis rarely depends on one table.&lt;/p&gt;

&lt;p&gt;A typical path may involve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
↓
Order
↓
Contract
↓
Payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, enterprises often contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple applications;&lt;/li&gt;
&lt;li&gt;duplicated entities;&lt;/li&gt;
&lt;li&gt;different identifiers;&lt;/li&gt;
&lt;li&gt;historical data models.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A database may allow many joins.&lt;/p&gt;

&lt;p&gt;But only some relationships represent business logic.&lt;/p&gt;

&lt;p&gt;The important question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can these tables be joined?&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Is this the correct business relationship?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Moving From Answers to Analysis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional systems answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the number?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI Analysts should answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why is this number changing?&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Sales decreased last month. Why?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system should analyze:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;regional changes;&lt;/li&gt;
&lt;li&gt;customer changes;&lt;/li&gt;
&lt;li&gt;product changes;&lt;/li&gt;
&lt;li&gt;historical trends.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This requires dynamic analysis instead of fixed dashboards.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Architecture Behind AI-Native Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A future analytics system is not simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
↓
LLM
↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A more reliable architecture requires:&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

↓

AI Understanding

↓

Semantic Layer

↓

Relationship Intelligence

↓

Query Generation

↓

Analysis Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI needs to understand:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Business Semantics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What does the data mean?&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;revenue definition;&lt;/li&gt;
&lt;li&gt;active customer definition;&lt;/li&gt;
&lt;li&gt;inventory calculation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Data Relationships&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How is enterprise data connected?&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;customer to order;&lt;/li&gt;
&lt;li&gt;order to invoice;&lt;/li&gt;
&lt;li&gt;invoice to payment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Analytical Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What analysis should happen next?&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;comparison;&lt;/li&gt;
&lt;li&gt;trend analysis;&lt;/li&gt;
&lt;li&gt;root cause exploration.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;The Future of Enterprise Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next generation of analytics will combine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;large language models;&lt;/li&gt;
&lt;li&gt;semantic understanding;&lt;/li&gt;
&lt;li&gt;relationship intelligence;&lt;/li&gt;
&lt;li&gt;enterprise data governance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The future is not about creating more dashboards.&lt;/p&gt;

&lt;p&gt;It is about creating AI systems that can become intelligent partners in business analysis.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional BI helped enterprises understand what happened.&lt;/p&gt;

&lt;p&gt;AI Analysts will help enterprises understand why it happened.&lt;/p&gt;

&lt;p&gt;But this requires more than connecting an LLM to a database.&lt;/p&gt;

&lt;p&gt;AI needs to understand business concepts, data relationships, and analytical context.&lt;/p&gt;

&lt;p&gt;Only then can enterprise AI move from answering questions to supporting real analysis.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>data</category>
      <category>sql</category>
      <category>llm</category>
    </item>
    <item>
      <title>Beyond Data Lineage: Building Observability for AI-Generated Queries</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Wed, 05 Aug 2026 11:20:00 +0000</pubDate>
      <link>https://dev.to/arisyndata/beyond-data-lineage-building-observability-for-ai-generated-queries-1hcm</link>
      <guid>https://dev.to/arisyndata/beyond-data-lineage-building-observability-for-ai-generated-queries-1hcm</guid>
      <description>&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%2F1x3zy0p87swuqrlpbwx9.jpg" 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%2F1x3zy0p87swuqrlpbwx9.jpg" alt=" " width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enterprise AI is moving from experimentation to production.&lt;/p&gt;

&lt;p&gt;Organizations are deploying AI assistants that can query databases, generate reports, and analyze business data.&lt;/p&gt;

&lt;p&gt;The first challenge was making AI capable of answering questions.&lt;/p&gt;

&lt;p&gt;The next challenge is making those answers trustworthy.&lt;/p&gt;

&lt;p&gt;When an AI system provides an answer, enterprises need to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What data did AI use?&lt;/li&gt;
&lt;li&gt;Why did AI choose those tables?&lt;/li&gt;
&lt;li&gt;Which business definitions were applied?&lt;/li&gt;
&lt;li&gt;How was the final answer generated?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where traditional data observability needs to evolve.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Traditional Data Observability Was Built for Data Pipelines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For years, enterprises focused on understanding how data moved.&lt;/p&gt;

&lt;p&gt;A typical lineage looks like:&lt;br&gt;
&lt;/p&gt;

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

↓

ETL Pipeline

↓

Data Warehouse

↓

BI Report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Organizations needed to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where did data come from?&lt;/li&gt;
&lt;li&gt;Which pipeline transformed it?&lt;/li&gt;
&lt;li&gt;Which reports depend on it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This became the foundation of modern data governance.&lt;/p&gt;

&lt;p&gt;However, AI introduces a different type of data consumption.&lt;/p&gt;

&lt;p&gt;AI does not only move data.&lt;/p&gt;

&lt;p&gt;AI interprets data.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;AI Creates a New Observability Challenge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider a question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why did sales decrease last month?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An AI assistant may:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand the question.&lt;/li&gt;
&lt;li&gt;Select relevant data sources.&lt;/li&gt;
&lt;li&gt;Generate SQL.&lt;/li&gt;
&lt;li&gt;Execute the query.&lt;/li&gt;
&lt;li&gt;Explain the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The final answer may look reasonable.&lt;/p&gt;

&lt;p&gt;But enterprises need more visibility.&lt;/p&gt;

&lt;p&gt;They need to understand:&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

↓

AI Interpretation

↓

Business Definition

↓

Selected Data Sources

↓

Relationship Path

↓

Generated SQL

↓

Final Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is different from traditional data lineage.&lt;/p&gt;

&lt;p&gt;It is AI reasoning lineage.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why AI Query Results Need Explainability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional BI systems use predefined reports.&lt;/p&gt;

&lt;p&gt;Users usually know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which metric is used;&lt;/li&gt;
&lt;li&gt;which data source is connected;&lt;/li&gt;
&lt;li&gt;how calculations are performed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI-powered analytics changes this.&lt;/p&gt;

&lt;p&gt;The query path can be generated dynamically.&lt;/p&gt;

&lt;p&gt;The selected tables may change.&lt;/p&gt;

&lt;p&gt;The SQL may be different for different questions.&lt;/p&gt;

&lt;p&gt;Therefore, AI systems need to explain not only the answer, but also the reasoning behind the answer.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Four Layers of AI Data Observability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI data observability extends traditional data governance with new capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Query Lineage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional lineage asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Where did this data come from?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI query lineage asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How did AI produce this answer?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It should capture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user question;&lt;/li&gt;
&lt;li&gt;generated SQL;&lt;/li&gt;
&lt;li&gt;selected tables;&lt;/li&gt;
&lt;li&gt;filters;&lt;/li&gt;
&lt;li&gt;returned datasets.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;2. Semantic Lineage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise concepts often have multiple meanings.&lt;/p&gt;

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

&lt;p&gt;Revenue may mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sales revenue;&lt;/li&gt;
&lt;li&gt;recognized revenue;&lt;/li&gt;
&lt;li&gt;invoice amount;&lt;/li&gt;
&lt;li&gt;payment amount.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI observability needs to record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which business definition was used;&lt;/li&gt;
&lt;li&gt;which metric mapping was applied;&lt;/li&gt;
&lt;li&gt;which semantic rules affected the answer.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;3. Relationship Lineage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise queries often depend on relationships:&lt;br&gt;
&lt;/p&gt;

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

↓

Order

↓

Invoice

↓

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

&lt;/div&gt;



&lt;p&gt;AI needs to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which relationship path was selected;&lt;/li&gt;
&lt;li&gt;why this path was chosen;&lt;/li&gt;
&lt;li&gt;whether the relationship is trusted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A valid SQL join does not always represent a valid business relationship.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;4. Answer Explainability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise users need more than a result.&lt;/p&gt;

&lt;p&gt;They need to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;where the data came from;&lt;/li&gt;
&lt;li&gt;what logic was applied;&lt;/li&gt;
&lt;li&gt;what assumptions were made.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is critical in industries where decisions depend on reliable data.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;From Data Governance to AI Governance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional data governance focused on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data quality;&lt;/li&gt;
&lt;li&gt;metadata;&lt;/li&gt;
&lt;li&gt;lineage;&lt;/li&gt;
&lt;li&gt;ownership.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI introduces new requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI query traceability;&lt;/li&gt;
&lt;li&gt;semantic consistency;&lt;/li&gt;
&lt;li&gt;relationship validation;&lt;/li&gt;
&lt;li&gt;answer transparency.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The question is changing from:&lt;/p&gt;

&lt;p&gt;"Can we manage enterprise data?"&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;"Can we trust how AI uses enterprise data?"&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI can generate answers quickly.&lt;/p&gt;

&lt;p&gt;But enterprises need more than speed.&lt;/p&gt;

&lt;p&gt;They need confidence.&lt;/p&gt;

&lt;p&gt;Traditional data lineage helped organizations understand how data moved.&lt;/p&gt;

&lt;p&gt;AI observability will help organizations understand how AI reasons over data.&lt;/p&gt;

&lt;p&gt;The future of enterprise AI will belong to systems that are not only intelligent, but also transparent and trustworthy.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>data</category>
      <category>sql</category>
      <category>llm</category>
    </item>
    <item>
      <title>Building Data Intelligence for Reliable Enterprise AI</title>
      <dc:creator>ArisynData</dc:creator>
      <pubDate>Mon, 03 Aug 2026 11:41:00 +0000</pubDate>
      <link>https://dev.to/arisyndata/building-data-intelligence-for-reliable-enterprise-ai-1gl1</link>
      <guid>https://dev.to/arisyndata/building-data-intelligence-for-reliable-enterprise-ai-1gl1</guid>
      <description>&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%2Fstxsina13vmytyjaxamo.jpg" 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%2Fstxsina13vmytyjaxamo.jpg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Large language models are becoming more capable every year.&lt;/p&gt;

&lt;p&gt;They can generate SQL, write code, analyze documents, and interact with enterprise systems through tools.&lt;/p&gt;

&lt;p&gt;However, when organizations move AI applications from prototypes to production, a common problem appears:&lt;/p&gt;

&lt;p&gt;AI can access enterprise data.&lt;/p&gt;

&lt;p&gt;But access does not mean understanding.&lt;/p&gt;

&lt;p&gt;Many enterprise AI failures are not caused by weak models.&lt;/p&gt;

&lt;p&gt;They are caused by the fact that enterprise data was designed for applications and humans, not for AI systems.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Data Access Is Not Data Intelligence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern enterprises already have mature data platforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;relational databases;&lt;/li&gt;
&lt;li&gt;data warehouses;&lt;/li&gt;
&lt;li&gt;data lakes;&lt;/li&gt;
&lt;li&gt;BI systems;&lt;/li&gt;
&lt;li&gt;metadata management platforms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These systems solve an important problem:&lt;/p&gt;

&lt;p&gt;How do we store and access data?&lt;/p&gt;

&lt;p&gt;AI introduces a different challenge:&lt;/p&gt;

&lt;p&gt;How does AI understand and use this data correctly?&lt;/p&gt;

&lt;p&gt;A database can tell an AI system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;this is a customer table;&lt;/li&gt;
&lt;li&gt;this is a revenue column;&lt;/li&gt;
&lt;li&gt;this field contains an identifier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it usually cannot explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which customer definition is trusted;&lt;/li&gt;
&lt;li&gt;what revenue means in this business context;&lt;/li&gt;
&lt;li&gt;how data from different systems should be connected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference is the gap between data access and data intelligence.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why Traditional Metadata Is Not Enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many enterprise AI systems start by providing metadata to LLMs.&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;Table: customer

Columns:
customer_id
customer_name
create_time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This information helps AI discover available data.&lt;/p&gt;

&lt;p&gt;But it does not provide enough business understanding.&lt;/p&gt;

&lt;p&gt;Consider a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Who are our most valuable customers?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An enterprise may have:&lt;br&gt;
&lt;/p&gt;

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

erp_customer

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

&lt;/div&gt;



&lt;p&gt;All three tables may contain customer information.&lt;/p&gt;

&lt;p&gt;The challenge is not finding these tables.&lt;/p&gt;

&lt;p&gt;The challenge is understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are they the same business entity?&lt;/li&gt;
&lt;li&gt;Which one is authoritative?&lt;/li&gt;
&lt;li&gt;How should they be related?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without this knowledge, AI has to guess.&lt;/p&gt;

&lt;p&gt;And guessing creates unreliable answers.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Data Intelligence Starts With Business Meaning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise data contains many ambiguous concepts.&lt;/p&gt;

&lt;p&gt;A common example is:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It may represent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sales revenue;&lt;/li&gt;
&lt;li&gt;recognized revenue;&lt;/li&gt;
&lt;li&gt;invoice amount;&lt;/li&gt;
&lt;li&gt;payment amount;&lt;/li&gt;
&lt;li&gt;contract value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From a database perspective, all of these are valid fields.&lt;/p&gt;

&lt;p&gt;From a business perspective, they answer different questions.&lt;/p&gt;

&lt;p&gt;Humans resolve this ambiguity through experience.&lt;/p&gt;

&lt;p&gt;AI needs this business meaning to be explicitly available.&lt;/p&gt;

&lt;p&gt;This is why semantic understanding is a fundamental requirement for enterprise AI.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Relationships Are the Hidden Challenge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise data is not a collection of isolated tables.&lt;/p&gt;

&lt;p&gt;Business processes connect data together.&lt;/p&gt;

&lt;p&gt;A simple example:&lt;br&gt;
&lt;/p&gt;

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

↓

Order

↓

Invoice

↓

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

&lt;/div&gt;



&lt;p&gt;However, real enterprise environments are much more complex.&lt;/p&gt;

&lt;p&gt;Organizations often have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple systems;&lt;/li&gt;
&lt;li&gt;duplicated entities;&lt;/li&gt;
&lt;li&gt;inconsistent identifiers;&lt;/li&gt;
&lt;li&gt;historical data models.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A database may allow many possible joins.&lt;/p&gt;

&lt;p&gt;But only some relationships represent real business logic.&lt;/p&gt;

&lt;p&gt;A technically valid join does not always mean a business-valid relationship.&lt;/p&gt;

&lt;p&gt;For AI applications, trusted relationships matter.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why Bigger LLMs Are Not Enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common assumption is:&lt;/p&gt;

&lt;p&gt;"If the model becomes smarter, it will solve enterprise data problems."&lt;/p&gt;

&lt;p&gt;Better models definitely improve reasoning capabilities.&lt;/p&gt;

&lt;p&gt;But models cannot automatically know enterprise-specific knowledge.&lt;/p&gt;

&lt;p&gt;They cannot magically determine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which data source the company trusts;&lt;/li&gt;
&lt;li&gt;which metric definition is correct;&lt;/li&gt;
&lt;li&gt;which relationship represents the real business process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem is not only intelligence.&lt;/p&gt;

&lt;p&gt;The problem is the intelligence available around the data.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Building an AI-Ready Data Intelligence Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reliable enterprise AI requires more than connecting an LLM to a database.&lt;/p&gt;

&lt;p&gt;It requires data intelligence capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Business Entity Understanding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI needs to understand important business objects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customer;&lt;/li&gt;
&lt;li&gt;Product;&lt;/li&gt;
&lt;li&gt;Supplier;&lt;/li&gt;
&lt;li&gt;Contract;&lt;/li&gt;
&lt;li&gt;Project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not just as database tables.&lt;/p&gt;

&lt;p&gt;As business entities.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Data Semantic Understanding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI needs to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business terms;&lt;/li&gt;
&lt;li&gt;metric definitions;&lt;/li&gt;
&lt;li&gt;calculation logic;&lt;/li&gt;
&lt;li&gt;organizational language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same field name can represent different meanings across organizations.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Trusted Data Relationships&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI needs to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which entities are connected;&lt;/li&gt;
&lt;li&gt;which relationships are reliable;&lt;/li&gt;
&lt;li&gt;which data paths should be used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This enables AI to generate answers based on trusted enterprise knowledge.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Future of Enterprise AI Data Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional data platforms answered:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Where is the data?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI requires a deeper answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What does this data mean?&lt;/p&gt;

&lt;p&gt;How is it connected?&lt;/p&gt;

&lt;p&gt;Can AI trust it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The next generation of enterprise data architecture will not replace databases, warehouses, or lakes.&lt;/p&gt;

&lt;p&gt;Instead, it will add intelligence that makes enterprise data understandable and usable for AI systems.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise AI is not only a model problem.&lt;/p&gt;

&lt;p&gt;It is also a data intelligence problem.&lt;/p&gt;

&lt;p&gt;Large language models provide reasoning capabilities.&lt;/p&gt;

&lt;p&gt;Data intelligence provides the foundation that allows those capabilities to work reliably.&lt;/p&gt;

&lt;p&gt;The future of enterprise AI will not only depend on smarter models.&lt;/p&gt;

&lt;p&gt;It will depend on smarter data.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>data</category>
      <category>sql</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
