Cropsly
Abstract network of pipes and conveyor belts with padlocks and checkmarks in muted earth tones with coral and navy accents
← Back to Blog

Building Trustworthy Data Pipelines for Production AI Agents: A Practical Framework

Hitesh Sondhi · August 13, 2026 · 10 min read

Your agent works in staging. Your agent pulls a product catalog, calls a pricing API, writes a summary, and the output looks clean. You deploy to production and within 48 hours the agent is confidently quoting prices from a cached endpoint that rotated its schema three days ago. Nobody noticed because the API returned 200 OK with a subtly different JSON shape. Your agent hallucinated the missing fields and the customer got an email with a 40% discount that doesn't exist.

This is not a model problem. What you have is a data pipeline problem. And it's the one that actually kills production agents.

MIT Technology Review recently framed the core challenge well: scaling AI agents with trustworthy data is less about model capability and more about the supply chain that feeds them (MIT Technology Review). Agents that survive production aren't the ones with the best prompts. They're the ones where every byte of context has a verifiable origin, a schema, and a fallback.

We've been building agent systems at Cropsly for long enough to have a strong opinion about this. Here's the framework we use.

Ingestion: Treat Every Data Source Like an Untrusted API

Most agent pipelines we inherit from clients treat data sources as trusted inputs. A vector database is populated from a CMS export. A tool-calling agent reads from an internal REST endpoint. A RAG pipeline pulls from Confluence. None of these sources have contracts. They have vibes.

Fixing this is straightforward but tedious. Every data source that feeds an agent needs an explicit schema, a version, and a validation gate at ingestion time. Pydantic models handle this because they give you runtime validation and static type checking in one pass. If the source returns a field you don't expect, or drops a field you need, the ingestion layer rejects it and logs the mismatch.

from pydantic import BaseModel, Field
from typing import Optional
from datetime import datetime

class ProductRecord(BaseModel):
    sku: str
    name: str
    price_cents: int = Field(ge=0)
    currency: str = Field(min_length=3, max_length=3)
    description: Optional[str] = None
    last_updated: datetime
    schema_version: str = "2.1"

That schema_version field matters more than it looks. When your CMS team ships a breaking change, the version bumps. Your ingestion layer can route to a migration function or flag the records for review. Without it, you're relying on someone in a Slack channel telling you they changed the API.

Practical implication: before you write a single prompt, map every data source your agent will touch and write a schema for each one. A source without a stable schema doesn't go into production.

Provenance: Track Where Every Token of Context Came From

Agents make decisions based on context. Once a decision goes wrong, you need to know which piece of context caused it. Obvious, until you try to implement it.

Research on agent scaling highlights that unlike isolated predictions, agents navigate sustained multi-step interactions where a single error can cascade throughout a workflow (arXiv). A bad piece of context in step 2 becomes a confident wrong answer in step 7. Without provenance, you can't trace the cascade.

We attach a provenance record to every chunk of context that enters an agent's prompt. Here's a simple struct:

class ProvenanceRecord:
    source_type: str        # "api", "vector_db", "user_input", "tool_output"
    source_id: str          # endpoint URL, collection name, tool name
    retrieved_at: datetime
    source_version: str     # API version, doc hash, model version
    confidence: float       # retrieval score or 1.0 for deterministic sources

When an agent produces output, we store the provenance records alongside it. Take a hotel guest using RunHotel who gets a wrong answer about checkout time: we can trace exactly which document chunk was retrieved, when it was indexed, and whether the source document has since been updated.

Overhead is minimal. A provenance record is maybe 200 bytes. An agent that uses 10 context chunks per interaction adds 2 KB of metadata per request. Not having it means spending three hours in a debug session trying to figure out why the agent suddenly started giving wrong answers on Tuesday afternoon.

Validation: Don't Trust the Model to Validate Its Own Inputs

Here's a pattern we see constantly: an agent calls a tool, gets a response, and passes it directly into the next LLM call. LLMs are expected to figure out whether the tool response is valid. This works until it doesn't, and when it doesn't, the failure mode is silent.

A recent analysis of enterprise agent deployments found that agents which succeed at scale are those that can remember, recover, and collaborate, with state persistence being a foundational requirement (The New Stack). Recovery implies the agent can detect when something is wrong. That detection has to happen at the data layer, not the model layer.

Validation runs at two points. First, when data enters the pipeline (ingestion validation). Second, when data is about to enter the model's context (pre-inference validation). A second check is critical because data can degrade between ingestion and use. A vector embedding that was correct at index time might reference a document that's been archived. A cached API response might be stale.

def validate_context_for_inference(
    chunks: list[ContextChunk],
    max_age_hours: int = 24
) -> list[ContextChunk]:
    valid = []
    for chunk in chunks:
        age = datetime.now() - chunk.provenance.retrieved_at
        if age.total_seconds() > max_age_hours * 3600:
            logger.warning(
                f"Stale context chunk from {chunk.provenance.source_id}, "
                f"age={age}, refreshing"
            )
            chunk = refresh_chunk(chunk)
        if chunk.provenance.confidence < 0.5:
            continue
        valid.append(chunk)
    return valid

Models never see invalid context. If a chunk fails validation, it either gets refreshed or dropped. Agent prompts shrink. That's fine. A shorter prompt with valid context beats a longer prompt with garbage.

Monitoring: Measure Data Drift, Not Just Model Latency

Standard LLM observability tracks token counts, latency, and cost. These are necessary but insufficient for agents. Real failure modes in production agents involve data drift: the sources feeding the agent change shape or content without anyone noticing, and the agent's outputs degrade slowly over weeks.

IBM's guidance on scaling agentic AI identifies data strategy as a distinct step, separate from architecture and opportunity assessment (IBM). That separation is correct. Your model architecture can be perfect and your data strategy can still be broken.

Our monitoring tracks three data-specific signals for every agent in production.

Schema violation rate. Every time the ingestion layer rejects a record, we log it. A violation rate on a source that jumps from 0.1% to 5% overnight means someone changed the source API without telling us. Our approach has caught breaking changes from third-party vendors before they affected a single user interaction. Our typical schema violation baseline sits around 0.2% on well-maintained sources, and anything above 1% triggers an alert (Cropsly internal monitoring).

Context freshness distribution. Our team tracks the age of context chunks at inference time. A climbing median age means our ingestion pipeline is falling behind. For our on-device AI work, where we're running Qwen3-8B on edge hardware, stale context is especially dangerous because the model has less capacity to reason around bad inputs.

Output consistency under identical inputs. Each agent has a golden set of 50 to 100 test inputs that we run on every deployment. Significant shifts in the output distribution mean something in the data pipeline changed. This isn't about model regression. What matters is detecting when the data the model sees has drifted enough to change behavior.

The Feedback Loop: Closing the Circuit

Agents that scale successfully learn from multiple stakeholder feedback while maintaining consistency (Aishwarya Srinivasan). Feedback is a data source too, and it needs the same treatment: schema, validation, provenance.

When a user corrects an agent's output, that correction enters a feedback queue. That correction doesn't go straight into the prompt. Each correction gets validated (is the correction actually correct?), attributed (who said this, and are they a domain expert?), and versioned. Then it enters the context pipeline through the same ingestion layer as everything else.

Sounds heavy in theory. In practice, it's a few hundred lines of Python and a Postgres table. Without this, you're left with ad-hoc feedback that lives in Slack messages and engineer memories, which doesn't scale.

What This Looks Like in Practice

For our AI agents work with EU and UK clients, the data pipeline is typically 40% of the codebase. Not the model integration, not the prompt engineering, not the UI. That pipeline ingests, validates, versions, and monitors the data the agent relies on.

Scoping a new agent project, the first conversation isn't about which model to use. Those conversations focus on what data the agent needs, where that data lives, how often it changes, and who owns it. Without answers to those questions, we don't write any agent code. Instead, ingestion and validation code comes first, and our cost estimator models the data volume implications before committing to an architecture.

For voice AI specifically, the pipeline constraints are tighter. A voice agent has 200 to 500 milliseconds to respond. There's no time for runtime schema validation against a remote source. Everything has to be pre-validated and cached with a freshness guarantee. Pipelines have to be more aggressive about ingestion frequency and more conservative about staleness thresholds.

For custom models, the pipeline feeds training data, not just inference context. Same principles apply but the stakes are higher. A schema violation in training data doesn't cause one bad response. What you get is a model that systematically produces bad responses until you retrain.

The Cost of Skipping This

Our audits of agent systems have found teams that spent six months on prompt engineering and model selection, then shipped to production with no data validation layer. Agents worked 85% of the time. Another 15% was silent failures: wrong prices, outdated policies, hallucinated product specs. Each failure required a manual investigation because there was no provenance to trace.

Fixing it took three weeks. Three weeks of schema definitions, validation gates, and provenance tracking to take an agent from "works most of the time" to "works reliably and tells you when it doesn't." Models didn't change. Prompts didn't change. What changed was the data pipeline.

If you're building production agents and your data pipeline is an afterthought, let's talk. We'd rather help you build it right the first time than audit it after a customer-facing failure.

Sources

ShareTwitterLinkedIn
data-pipelinesproduction-aiai-opstrustworthy-ai

Working on an AI project?

We build production-grade AI systems: agents, voice, on-device, and the product around them.

Get Weekly AI Insights

Join founders and CTOs getting our AI engineering newsletter.

By subscribing, you agree to our Privacy Policy. Unsubscribe anytime.