Skip to main content

Deterministic Collectors: Code for Data, LLMs for Judgment

Goal

Separate mechanical work (100% reliable code) from analytical work (LLM judgment) so that deterministic tasks never fail probabilistically.

What the User Gets

Without this: the LLM generates Gmail links, formats tables, and tracks state. It follows the rule for the first 10 items, then drops a link on item 11. You write “NO EXCEPTIONS” in the prompt. It still fails. 90% reliability over 20 items means visible failures twice per day. Trust is destroyed. With this: code handles URLs, formatting, and state (100% reliable). The LLM reads pre-formatted data and adds judgment, classification, and enrichment. Links are never wrong because the LLM never generates them.

Implementation

The Architecture

File Structure

Where the Pattern Applies

The Principle

If a piece of output MUST be present and MUST be formatted correctly every time, generate it in code. If a piece of output requires judgment, context, or creativity, generate it with the LLM. Don’t ask the LLM to do both in the same pass.

Tricky Spots

  1. LLMs forget links — bake them in code. The LLM will follow the “include a Gmail link” rule for the first 10 items, then silently drop it on item 11. No amount of prompt engineering fixes probabilistic formatting over long outputs. The fix: generate every link in the collector script. The LLM reads pre-formatted markdown where links are already embedded. It can’t forget what it didn’t generate.
  2. Noise filtering must be deterministic. Regex-based noise detection (newsletters, automated receipts, marketing) belongs in the collector, not the LLM. The LLM might classify a newsletter as “possibly important” on one run and “noise” on the next. Code classifies the same input the same way every time.
  3. Atomic writes prevent corruption. The collector writes to a state file (state.json) that tracks which messages have been seen. If the script crashes mid-write, the state file can be corrupted. Write to a temp file first, then rename atomically. This also prevents the LLM from reading a partial digest if the cron fires during a collection run.

How to Verify

  1. Run the collector and check every link. Execute the collector script manually. Open the generated digest. Click every [Open in Gmail] link (or equivalent). Every single link must resolve to the correct item. If any link is broken or missing, the collector has a bug.
  2. Verify noise filtering is consistent. Run the collector twice on the same input data. The noise classification (is_noise field) must be identical both times. If it varies, a probabilistic element leaked into the deterministic layer.
  3. Verify the LLM reads structured output. Run the full pipeline (collector then LLM). Check that the LLM’s analysis references data from the structured digest, not from its own generation. The links in the final output should be identical to the links in the digest file.

Part of the ModusBrain Skillpack.