Original teaching design, checked 2026-10-11. Continues the document search system; no new trained-model results are claimed.

When a relevant document is missing, it may never have been ingested, its title may have been lost during chunking, the embedding may be unsuitable, or the evaluation may contain only easy queries. Separate these before deciding whether to repair the pipeline or train a model.

1 · Ingestion: retain provenance

Documents need IDs, revisions, sources, content times, arrival times, and access scope. Images also need processing metadata such as dimensions and processor version. Behavioral events need stable event IDs, request IDs, and occurrence times. Raw content and identity retention must follow permissions, purpose, and retention limits—not a “log everything” policy.

Situation Required handling Failure otherwise
Retried event delivery Idempotent deduplication by stable event ID One click becomes several labels
Document update Revision and replacement relationship Search and citations reference different versions
Deletion or permission withdrawal Tombstone / access event with propagation checks Old indexes or caches keep returning removed content
Parsing failure Error classification, retry, quarantine Silent loss changes the data distribution

A versioned table can do much of this in a small project. A message queue does not remove the need to define duplicates, ordering, late arrival, and replay. “We use Kafka” is not a data contract.

2 · Features: was this known at the time?

Suppose a prediction is made at 10:00. An event occurs at 09:58 but enters the system at 10:02. Replaying today's complete logs must not make it available to the 10:00 example.

For hand calculation, use integer minutes. A real pipeline also needs timezones, clock conventions, and late-arrival rules. This example looks up one feature for one entity, requiring both event and availability times to be no later than the query:

def feature_as_of(records, entity, query_time):
    eligible = [
        record for record in records
        if record["entity"] == entity
        and record["event_at"] <= query_time
        and record["available_at"] <= query_time
    ]
    return max(eligible, key=lambda record: (record["event_at"], record["available_at"]), default=None)


records = [
    {"entity": "user-a", "event_at": 590, "available_at": 591, "value": 2},
    {"entity": "user-a", "event_at": 598, "available_at": 602, "value": 3},
]
assert feature_as_of(records, "user-a", 600)["value"] == 2
assert feature_as_of(records, "user-a", 603)["value"] == 3

Assume upstream deduplication and one feature. Equal-time revisions, TTLs, and missing-value handling require additional rules. Feast point-in-time joins illustrate historical feature retrieval, but availability time must be recorded and handled by your pipeline; a feature-store setting cannot reconstruct missing history.

3 · Examples: logs are not labels

A user may not click because they never saw the result, disliked the title, already knew the answer, or found it irrelevant. Negatives need exposure, position, observation-window, and task definitions. Unseen candidates and explicit rejections should not silently become the same label.

Evidence What it offers Remaining uncertainty
Clicks and dwell Responses to displayed content Resolution of the task; position and exposure bias
Human relevance labels Query–document judgments under a rubric Agreement and coverage
Synthetic queries / teacher scores Additional candidate supervision Teacher bias, duplicates, calibration
Explicit irrelevant feedback Clearer rejection Mistakes and delayed feedback

Separate training, development, and test by appropriate sources, times, or query families. Randomly splitting neighboring chunks of one PDF may mostly measure document memorization. Each data delivery should report deduplicated size, label balance, missingness, and source changes.

4 · Models: build a diagnostic baseline

Check keyword retrieval before adding dense retrieval; their errors may differ. Screenshot queries can use an image–text encoder such as SigLIP, but its image vectors do not belong in an arbitrary text embedding space. Retrieve candidates through compatible channels, then fuse or rerank explicitly.

A retriever needs positive, negative, and false-negative checks. SFT for citation behavior needs chat-template, target-mask, and valid-token weighting checks. These are different supervision problems. See dual encoders and data to batches.

If training does not fit, account for weights, optimizer, activations, and transient memory before choosing DDP / FSDP2 / ZeRO. Before scaling, compare loss and one update on a fixed batch; afterward, inspect sample duplication, denominators, and accumulation. A faster implementation of the wrong objective is not progress.

5 · Checkpoints: recovery and deployment differ

Purpose Save or associate Acceptance test
Resume training Model, optimizer, scheduler, RNG, data cursor, update count, configuration, data revision Interrupt and compare recovered samples and updates
Serve inference Weights / adapter, base model, config, tokenizer / processor, template, precision, dependencies Fixed-input regression through the actual loader
Reproduce an experiment decision Code revision, environment, splits, metric definitions, checkpoint-selection rule Re-run the comparison

A sharded training checkpoint may not load directly into a serving engine; an adapter also requires the correct base. Export, quantization, and merging create artifacts that need their own acceptance checks. Training-time scores do not validate the deployed artifact. See save and resume.

6 · Indexes: compatible dimensions are not enough

Old encoder A and new encoder B may both output 768 dimensions. That matches shape, not coordinate meaning. Encoding queries with B and searching document vectors from A may destroy the intended alignment.

Associate the model and index in a release:

{
  "release": "search-demo-v2",
  "query_encoder": "encoder-b",
  "document_encoder": "encoder-b",
  "processor": "processor-b",
  "index": "index-b-snapshot-17",
  "document_snapshot": "documents-17",
  "ranking_config": "ranking-4",
  "evaluation_report": "eval-search-demo-v2"
}

This is a teaching manifest, not a registry's configuration format. Real identifiers should resolve to immutable revisions or content hashes. Some dual encoders intentionally use different query and document models; record the jointly trained or validated compatible pair, not a requirement for identical files.

Build the replacement index alongside the current one, check coverage, deletion, permissions, and retrieval quality, then switch read traffic. Roll back the compatible bundle together. Reverting only the query encoder may leave a broken combination.

7 · Evaluate components and the product

Fix queries and candidate eligibility, then ask separately: was the relevant document ingested, retrieved, ranked well, and used correctly in the summary? A final answer score alone cannot locate the failing module.

Layer Minimum checks Interpretation trap
Data / index Coverage, freshness, deletion, permissions More coverage does not imply better relevance
Retrieval Recall@k at fixed budgets, language and query slices Increasing k is not a free improvement
Ranking NDCG or suitable metrics, failure examples Changed labels or candidate pools break direct comparisons
Generation Support, citations, abstention, task completion Valid format does not establish factual support
Cost Latency, memory, encoding, training, index refresh One forward pass is not the whole cost

Set release gates before inspecting results and reserve the test set for final comparisons. Small samples require uncertainty and failure details, not claims of stable gains from one additional correct answer. Continue with serving, monitoring, and feedback.