AI coding

Reading a Context File Aloud to a Cheap Model

Antonio Evans8 min read

A numbered checklist in the left column and a long context file in the right column.
Key points

Key points

  1. 1A cheap small model can flag obvious contradictions between a context file and a system prompt, so a person reviews a short list instead of the whole file.
  2. 2Set the pass bar before you run anything: a hand-labeled set of 40 planted contradictions, a recall floor, and a false positive budget per 1,000 lines.
  3. 3The model catches role-versus-permission and format conflicts, and misses anything needing arithmetic, cross-section joining, or knowledge of a rule the prompt never states.
  4. 4Send only flagged sections plus the prompt sentence they collide with to a reviewer, never the whole file.

Why this is an evaluation, not a chat

The sweep has three steps: read the system prompt, read the context file, compare them. The first two are cheap to mechanize. The third is expensive because a person has to hold both documents in mind and keep hunting for lines where the context file tells the agent to do something the prompt forbids or states a fact that contradicts it.

Spending a little on a model pass is worth it. Research on repository context files found that unnecessary requirements make agent tasks harder, so fixing a contradictory file has value beyond tidiness (Evaluating AGENTS.md, AlphaXiv). The failure modes of models used as judges are documented and predictable, so you can plan a review around them instead of pretending they do not exist (Evaluation-Driven Iteration for LLM Applications, arXiv).

Treat this as an evaluation. You are not asking a model for an opinion about your file. You are scoring a fixed output against fixed labels with a fixed prompt, the same way you would score any prompt change (What is prompt evaluation, Braintrust). That discipline is the difference between a check that improves and a demo that quietly lies.

A working definition: a contradiction exists when a context-file item cannot be true at the same time as a prompt item. Two sentences can mean the same thing in different words, so exact-match tests will not help (Evaluation-Driven Iteration for LLM Applications, arXiv). The task is semantic, which is why a model is the right tool and why its errors are semantic too.

What a small model can and cannot compare

Smaller models need explicit context and precise output formats, and you should expect to parse their output rather than assume it conforms (Practical prompt engineering for smaller LLMs, web.dev). Contradiction flagging is a short classification task, so it fits that constraint well.

It also has a shape small models handle badly. Most models degrade after a certain context size, and performance depends on where information sits in the window (Long Context RAG Performance of LLMs, Databricks). Self-consistency sampling, which helps on short inputs, fails and can hurt on long-context tasks (How Effective Is Self-Consistency for Long-Context Problems, arXiv). Never hand the model the prompt and the whole file together.

Split both documents into addressable units first. Give each line or short block a stable ID, pass the prompt once as fixed reference text, then send one context-file section per request and ask for a verdict on that section only. Each request stays short, output maps back to a location, and you dodge the failure where the middle of a long input gets ignored.

Contradiction typeExampleSmall model performance
Role versus forbidden actionPrompt forbids deleting rows; file says the agent cleans up stale rowsUsually caught
Format rule versus templatePrompt requires JSON only; file asks for a prose summary firstUsually caught
Direct factual conflictPrompt gives API base X; file gives YUsually caught
Overlapping date rangesTwo sections claim different freeze windows for one serviceOften caught
Numeric contradictionBudget stated as 200 credits here and 50 thereOften missed
Cross-section inferenceSection 4 grants a permission section 9 removesOften missed
Argument from silenceFile describes a workflow the prompt never authorizesAlmost always missed
Buried referenceFile says "use the release process in the shared drive"Missed until resolved

That table is the decision aid. If your file leans on the top four rows, automation pays. If it leans on the bottom four, automation gives you a false sense of coverage.

The exact prompt

The prompt assumes you already split the file and pass a section ID with its text. Keep the system prompt verbatim and complete; it is the model's only source of constraints. Use strict verdict vocabulary so results count mechanically.

You are a contradiction checker. You compare one section of a context
file against a system prompt. You do not rewrite or judge style.

SYSTEM PROMPT (authoritative, do not modify):
<system_prompt>{{SYSTEM_PROMPT}}</system_prompt>

CONTEXT FILE SECTION:
<section_id>{{SECTION_ID}}</section_id>
<section_text>{{SECTION_TEXT}}</section_text>

A contradiction means the section cannot be true at the same time as a
statement or constraint in the system prompt. Different wording is not
a contradiction. Asking for more detail is not a contradiction. A
section silent about a prompt rule is not a contradiction.

Rules:
1. Judge only this section against the system prompt.
2. Use no knowledge outside these two texts.
3. If the section conflicts with a rule, quote the exact prompt sentence.
4. If unsure, return verdict "unclear" rather than "contradiction".
5. Do not flag a section for being long, vague, or off-topic.

Return JSON only:
{"section_id": "...", "verdict": "contradiction" | "none" | "unclear",
 "prompt_quote": "...", "section_quote": "...",
 "category": "role_permission" | "format" | "fact" | "date" | "numeric"
            | "cross_section" | "silence" | "other",
 "confidence": 0.0-1.0}

Three details carry the weight. The "unclear" verdict gives the model a legal way out, which cuts manufactured conflicts. Quoting both sides forces it to point at evidence, which speeds your human review. The category field lets you measure misses by type.

Small models vary in how well they honor a JSON contract, so parse defensively and treat malformed output as a non-answer, not a pass (Practical prompt engineering for smaller LLMs, web.dev). If you run this often, watch input tokens per call, since prompt growth is easy to miss as template edits pile up (How to track LLM token usage, Braintrust).

Pass criteria: the bar you set first

The bar needs two numbers and one process. On 40 hand-labeled planted contradictions, recall (flagged or marked unclear) decides whether the tool is worth running. On clean sections, false positives per 1,000 lines decide whether a reviewer can stand reading the output.

A reasonable starting bar for a small model is recall of at least 25 of 40, with no more than 15 flags per 1,000 clean lines. That allows misses because flags go to a person, so a miss becomes an ordinary manual discovery; a flood of false positives burns trust and gets the tool switched off.

Build the labeled set deliberately. Take a real file, plant contradictions in the categories above at roughly five per category, and label each location and the prompt sentence it conflicts with. Without labels you have anecdotes, and the point of an eval is evidence over assumption (What is prompt evaluation, Braintrust).

MetricDefinitionStarting bar
Recall overallPlanted contradictions flagged or unclear, out of 4025 of 40 (62%)
Recall on role and formatSame, restricted to those two categories9 of 10
False positivesFlags on clean lines per 1,00015 or fewer
Unclear rateSections returned unclear per 1,000Report, do not cap
Parse failuresMalformed outputs per 1,000 callsTrack and fix prompt

Track recall by category, not just overall. A file scoring 70 percent overall but 0 percent on numeric contradictions tells you exactly where the human must look, which beats a single number.

A worked example on a sample context file

Take a 120-line context file and a 30-line prompt stating four constraints: reply in JSON only, never modify the billing table, the reporting API base is https://reports.internal.example, and the freeze runs March 1 to March 15. Plant eight contradictions.

  1. Line 12 lets the agent remove stale billing rows. Role versus permission.
  2. Line 27 asks for prose before the JSON block. Format.
  3. Line 41 gives a different reporting host. Fact.
  4. Line 55 says the freeze ends March 10. Date conflict.
  5. Line 63 says write permissions follow an external release process. Silence.
  6. Line 74 gives 3 retries per job, line 98 gives 5. Cross-section numeric.
  7. Line 88 sets the credit cap at 40, line 104 at 60. Numeric.
  8. Line 110 claims 80 GB total while listing 45 GB and 50 GB. Arithmetic.

Expect a small model to flag items 1 through 4, catch 5 only if you pass the process text alongside, and miss 6 through 8. Catching 5 of 8 with 2 clean-section flags is 62.5 percent recall at the bar, with about 17 false positives per 1,000 lines, just over budget. The fix is rarely a bigger model; split numeric checks into a script.

The arithmetic matters more than the guess: 40 plus 60 equals 100, not 80, and 45 plus 50 equals 95. No model call is needed for those, and a five-line assertion does it better.

import re

def numeric_conflicts(text):
    flags, seen = [], {}
    pat = re.compile(r"(?P<key>[a-z ]{3,30}) is (?P<n>\d+)")
    for line_no, line in enumerate(text.splitlines(), 1):
        for m in pat.finditer(line):
            key, n = m.group("key").strip(), int(m.group("n"))
            if key in seen and seen[key][0] != n:
                flags.append((seen[key][1], line_no, key, seen[key][0], n))
            seen.setdefault(key, (n, line_no))
    return flags

Run that before the model pass and you convert a category the model misses into one it never sees. Models for meaning, regular expressions for numbers, people for judgment.

The contradictions it misses, and why

Each miss has a mechanical cause, and the cause tells you whether to fix the prompt, add a script, or route to a person.

Arithmetic. The model reads three unremarkable phrases and does not simulate the sum. Small models are unreliable calculators. Fix with a script.

Cross-section inference. A permission granted in one line and revoked in another is consistent with the prompt line by line. Section-at-a-time input removes any chance to join them (Long Context RAG Performance of LLMs, Databricks). Fix by pairing sections that share a key and asking a second question about the pair.

Arguments from silence. There is no sentence to quote, and the prompt tells the model not to flag silence, so it complies. Fix with a second pass that asks which prompt constraint, if any, the section violates.

Buried references. A line pointing at a document the model has not seen cannot be checked. Resolve references first, or flag every unresolved one for a human.

Position effects. Where a conflicting sentence sits changes whether it is used, and self-consistency sampling does not repair this (How Effective Is Self-Consistency for Long-Context Problems, arXiv). Keep inputs short.

Judge biases. Position bias, verbosity bias and self-preference are catalogued failure modes of model-as-judge setups (Evaluation-Driven Iteration for LLM Applications, arXiv). Measure them by re-running your label set after every prompt edit. One study saw extraction pass rates fall from 100 to 90 percent when generic rules replaced task-specific prompts, so treat your checker prompt as versioned (Evaluation-Driven Iteration for LLM Applications, arXiv).

Wiring it into a review people can finish

Output should be a table sorted by section ID, showing only contradiction and unclear rows with the exact prompt quote. The reviewer sees ten to twenty rows, each a conflicting pair, not the original file.

Two operational notes. Measure cost per run in tokens and check whether input or output dominates, since that tells you whether to trim sections or the prompt (How to track LLM token usage, Braintrust). Keep the run reportable, with recall on the forty-item set, false positives per 1,000 lines, unclear rate and parse failures, so a prompt change can be judged rather than assumed.

Run the check on every change to the prompt or file, the way a pull request triggers review. Where those files live in a repository, ownership conventions are the hook: owners get pulled in on changes to code they own, and the same logic applies to prompt artifacts you treat as owned (About code owners, GitHub).

If you would rather point one harness at many models instead of maintaining a client per provider, Quanta Inference offers text models through one OpenAI-compatible API (https://quantaintelligence.ai/inference). That is harness convenience, not a requirement for the technique.

FAQ

FAQ

Can a cheap model reliably flag contradictions at all?

Yes, for single-section semantic conflicts: a role that clashes with a forbidden action, a format rule that disagrees with a template, an explicit factual conflict, and many date clashes. It is unreliable for arithmetic, cross-section inference and anything the prompt never states. Use it for the first group and route the rest to scripts and people.

How do I know my prompt is good enough before trusting it?

Build a hand-labeled set of 40 planted contradictions across the categories that matter, then score recall and false positives per 1,000 lines before the tool touches a real file. That is the same evidence-over-assumption discipline as any prompt evaluation (What is prompt evaluation, Braintrust). Without labels you have impressions, and impressions do not survive a prompt edit.

Should I send the whole file and prompt in one call?

No. Long inputs degrade model performance unpredictably, and the drop-off point differs by model (Long Context RAG Performance of LLMs, Databricks). One section at a time against a fixed prompt keeps requests short, makes output traceable to a line, and avoids losing the middle of a long document.

What about the numeric contradictions the model misses?

Remove them from the model's job. A short script that extracts "key is number" pairs catches budget, cap and total mismatches more reliably than a small model. Put both outputs in one report so the reviewer sees semantic and numeric flags together.

How do I keep reviewer trust as the file grows?

Cap the false positive rate, re-score the label set after every prompt change, and send only flagged rows with both quotes. If a run exceeds your budget, tune the prompt or split out a category rather than asking the reviewer to filter more noise. Keep the run report next to the file version so the decision stays inspectable.

Sources

Sources

  1. Evaluating AGENTS.md: Are Repository-Level Context ...
  2. Evaluation-Driven Iteration for LLM Applications A ...
  3. What is prompt evaluation? How to test prompts with metrics ...
  4. Practical prompt engineering for smaller LLMs | Articles
  5. Long Context RAG Performance of LLMs
  6. How Effective Is Self-Consistency for Long-Context ...
  7. How to track LLM token usage (2026): Prompt, completion ...
  8. About code owners
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles