惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
WordPress大学
WordPress大学
B
Blog RSS Feed
T
The Blog of Author Tim Ferriss
F
Fortinet All Blogs
aimingoo的专栏
aimingoo的专栏
MongoDB | Blog
MongoDB | Blog
博客园 - Franky
C
Check Point Blog
P
Proofpoint News Feed
H
Help Net Security
月光博客
月光博客
博客园_首页
Stack Overflow Blog
Stack Overflow Blog
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
Recent Announcements
Recent Announcements
人人都是产品经理
人人都是产品经理
U
Unit 42
美团技术团队
I
InfoQ
A
About on SuperTechFans

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Your AI Agent Is Failing Because of Your Data Layer, Not ...
Ismail Haddou · 2026-06-03 · via DEV Community

Ismail Haddou

Here's a pattern I keep seeing: a team builds an AI agent, the demo works, they ship it, and within a few weeks the outputs are unreliable. Someone opens a ticket about hallucinations. Someone else suggests switching to a better model.

The model isn't the issue. The data feeding the model is.

The actual failure anatomy

Multi-agent frameworks like OpenHands and MetaGPT show failure rates above 85% in production-like conditions. The failures cluster around one root cause: the agent received ambiguous, inconsistent, or semantically wrong context — and produced a confident answer based on it.

Three patterns account for most of what I see:

1. Undocumented schemas

Your agent is calling a database tool and getting back rows from a table called accounts. What does status mean in that table? What are the valid values? Does null mean inactive, never set, or pending review?

The model doesn't know. It infers from context. Sometimes it guesses right. Often it doesn't.

The fix is a schema registry — a structured description of every field your agent will query, written in natural language and attached as system context.

SCHEMA_REGISTRY = {
    "accounts": {
        "status": {
            "type": "enum",
            "values": ["active", "pending", "churned", "suspended"],
            "null_means": "record created but onboarding not completed",
            "notes": "EU records use 'suspended' for GDPR-deleted accounts, not 'churned'"
        },
        "revenue_usd": {
            "type": "float",
            "notes": "6-month trailing average as of last ETL run. NOT point-in-time.",
            "freshness_sla_hours": 24
        }
    }
}

def build_agent_context(table_name: str, rows: list) -> str:
    schema = SCHEMA_REGISTRY.get(table_name, {})
    schema_block = "\n".join(
        f"- {col}: {meta.get('notes', '')} | null_means: {meta.get('null_means', 'unknown')}"
        for col, meta in schema.items()
    )
    return f"Schema context for {table_name}:\n{schema_block}\n\nData:\n{rows}"

2. No normalization before inference

If your agent draws from more than one data source — and it almost certainly does — those sources use different conventions. One vendor sends dates as MM/DD/YYYY. Your internal system uses ISO 8601. Your CRM exports currency as $1,234.56. Your warehouse stores it as a float in cents.

def normalize_record(record: dict, source: str) -> dict:
    normalized = record.copy()

    # Normalize dates to ISO 8601
    for field in ["created_at", "updated_at", "contract_end"]:
        if field in normalized and normalized[field]:
            normalized[field] = parse_date_any_format(normalized[field])

    # Normalize currency to float USD
    if "revenue" in normalized:
        val = str(normalized["revenue"]).replace("$", "").replace(",", "").strip()
        if source == "crm_legacy":
            normalized["revenue"] = float(val) / 100  # legacy stores in cents
        else:
            normalized["revenue"] = float(val)

    normalized["_source"] = source
    return normalized

3. No freshness tracking

Your agent is confident. It's using your pricing data to answer a customer question. That pricing data was last updated 72 hours ago and there was a change yesterday. The agent doesn't know.

def get_data_with_freshness(table: str, db_conn) -> dict:
    rows = db_conn.query(f"SELECT * FROM {table}")
    last_updated = db_conn.query(f"SELECT MAX(updated_at) as ts FROM {table}")[0]["ts"]
    age_hours = (datetime.utcnow() - last_updated).total_seconds() / 3600
    freshness_sla = SCHEMA_REGISTRY.get(table, {}).get("freshness_sla_hours", 24)

    return {
        "data": rows,
        "freshness": {
            "last_updated": last_updated.isoformat(),
            "age_hours": round(age_hours, 1),
            "within_sla": age_hours <= freshness_sla,
            "warning": f"Data is {age_hours:.0f}h old (SLA: {freshness_sla}h)" if age_hours > freshness_sla else None
        }
    }

Pass the freshness metadata to the model. Tell it to caveat answers when data is stale.

The build order that actually works

When we take on an AI deployment at Nu Terra Labs, the first two weeks are almost entirely data infrastructure. Schema audit, normalization pipeline, freshness monitoring, validation sets. The actual agent code comes third.

This feels backwards to most clients. They hired us to build AI, not to document database fields. But this sequencing is why the things we build work in month six the way they worked in week one.

Build your data layer first. Your model doesn't need to be smarter. It needs better inputs.


If you're hitting this in production and want a second set of eyes, feel free to DM me — happy to dig in.