Data Pipelines for AI
From source files to a fresh index, reliably
Turning source documents into a searchable index is a pipeline: ingest, clean, chunk, embed, write. Reliable pipelines are idempotent, incremental and observable — the same discipline as classic data engineering, applied to vector data.
What you will learn
- Design an ingest→embed→index pipeline with idempotent stages
- Support incremental updates and backfills without corruption
- Add observability at each stage boundary
What is this?
A vector-data pipeline moves documents from sources (CMS, S3, databases, web) through extraction, chunking, embedding and index writes. Production discipline from data engineering applies directly: idempotent stages so re-runs are safe, incremental modes so you don't re-embed everything daily, and per-stage counters so failures are localized.
Why do you need it?
- Re-embedding a 2M-chunk corpus on every small change is a waste of tokens and time.
- A duplicate chunk from a non-idempotent re-run silently corrupts retrieval rankings.
- Embedding SDK version bumps require a full re-embed; a versioned pipeline makes that safe.
- Per-stage counts turn 'search is stale' into 'the embed stage failed at 01:22'.
Mental model
Versioned deployment for an app
A data pipeline for your index
You deploy an app in stages with rollback and monitoring, not by copying files at random. An index deserves the same: versioned content, staged writes, rollback, and alarms when a stage stalls.
How it works
- Ingest detects new/changed documents via a cursor (created_at, events) or full-export diff.
- The chunk stage is idempotent: content hash → chunk ids, so re-processing identical docs is a no-op.
- The embed stage batches with bounded concurrency and logs usage/per-version.
- The index stage upserts by chunk id and deletes stale chunks for re-processed docs.
- Observability: per-stage counters, freshness timestamps, and alert on staleness.
An idempotent vector pipeline.
In production
- A docs platform increments from a webhook cursor, embedding only changed pages and deleting their stale chunks.
- A nightly pipeline accepts an embedding-version flag so SDK bumps trigger a controlled full re-embed.
- An inventory bot re-ingests 200k products incrementally, with count-variance alerts flagging a broken source feed.
Best practices
- Key chunks by content hash, not by paragraph position — edits change positions.
- Make every stage idempotent so retries and backfills are safe.
- Log the embedding model + version with each index write; re-embed when it changes.
- Alert on index freshness, not just job completion.
Common mistakes
- Building a full-rebuild-only pipeline and paying tokens for every tweak.
- Chunk ids based on positions, so edits duplicate rather than replace chunks.
- No version tag on embeddings — mixed vectors from two model versions poison similarity.
- Assuming the scheduler ran: 'complete' isn't 'fresh'.
Common issues
Duplicated chunks in the indexPosition-based chunk ids changed after an edit, creating new ids instead of replacing
Switch to content-hash chunk ids and run a dedup repair pass.
Index silently mixes two embedding model versionsVersion not tracked with the writes
Tag every write with model+version and quarantine/re-embed any mixed range.
Backfill writes rows twice on retryNon-idempotent append stage
Make the index stage an upsert keyed by chunk id.
Debugging tips
- If the index has duplicates, check chunk-id stability across re-runs.
- Stale search but green jobs — check freshness timestamp vs the last successful embed.
- Embedding count drops — diff source cursor values to find the silent-dropped range.
Interview checkpoint
Quick quiz
What makes a pipeline stage safe to retry and backfill?
Mixing vectors from two embedding model versions is harmless.