Coding Agents Don't Need Bigger Context Windows — They Need a Context Compiler

ai-assisted codingcode skeletonizationcoding agentscontext compilercontext engineeringcontext windowsdependency resolutionllmprompt engineeringreachability analysis

TL;DR

I built a three-pass Context Compiler in pure Python. Before sending anything to the model, it identifies what your target file actually depends on, trims non-essential code down to pure interfaces, and discards everything unreachable.

Tested on two real Python repos, it cut prompt sizes by 69–74% and ran in under 75 ms. All numbers stem from captured terminal runs—if the tool couldn't determine something with certainty, it explicitly marked it rather than guessing.

Compilers Don't Just Compile Code

Compilers are filters that know what to keep. Given an entry point and a codebase, they trace what actually gets called, discard dead weight, and output an intermediate representation with only the detail the next step needs—nothing extra.

Most coding agents don't treat prompt construction like a compiler. They build a repository map, gather files they deem relevant, and send them to the model with minimal structural reduction. Larger context windows help, but they don't eliminate irrelevant context. That extra context competes for attention with the code that matters. When window sizes shrink, bloat triggers compaction. Compaction sounds like routine cleanup until it happens mid-task: the agent summarizes its own context to make room, then spends the next few turns trying to reconstruct implementation details from a lossy summary of a summary. Half the time an agent “forgets” something, it's just its own memory management degrading recall.

I wanted to see what happens if you build prompts with the discipline of a compiler rather than just retrieving more stuff.

The Context Compiler: A Three-Pass Pipeline

I built a Context Compiler: a three-pass pipeline written entirely with the Python standard library. It resolves what a target file actually reaches, trims those dependencies down to interfaces, and drops everything else.

Across two real Python repos, it cut prompt sizes by 69–74% with compile times under 75 ms. Every number here comes from captured terminal runs of the actual code, not estimates. You can explore the source and run the demos yourself at https://github.com/Emmimal/context-compiler/.

Flowchart showing a 5-step data processing pipeline: Repository, Pass 1 Reachability, Pass 2 Skeletonization, Pass 3 Tier Assembly, Prompt
The whole pipeline in one figure: each pass narrows the repository down by one more degree before anything reaches the model. Image by the author, generated with Gemini.

A note on timing: on July 18, 2026, OpenAI quietly reduced the default context window for Codex models from 372k to 272k tokens. Whether it's a billing correction or a capability trim, it points to the same reality: you don't own the context window size—you only control what you feed into it.

Context Compilation vs. Context Engineering

In 2025, Andrej Karpathy coined “context engineering” to describe the overarching work of deciding what goes into a model's prompt. Context compilation is a specific application of that concept to source code. Given a known codebase and a target file, it determines which files the edit truly relies on, then shrinks everything else to the smallest usable form.

This project doesn't aim to cover all of context engineering—I assume you're already familiar with how context management differs from basic prompt engineering or retrieval. Let's dive into how the compiler actually works.

Pass 1: Reachability Analysis

Pass 1 answers one basic question: starting from the file you're editing, what else in the repo actually matters? It traces explicit imports first. If a call like .save() can't be explained by an import, it falls back to a repo-wide symbol table, expanding outward breadth-first. This ensures that every symbol referenced in the target file is accounted for, either by import resolution or by global symbol lookup.

The output is a reachability graph—a precise map of dependencies, not a guess based on filename heuristics. If a file has no connection to the target, it's excluded outright.

Pass 2: Interface Skeletonization

Pass 2 takes the reachable files and strips them down to their signatures. For each function, method, or class, it keeps the def line, decorators, docstrings, and type hints, but removes the entire body. The result is a skeleton that communicates what each piece does—its name, parameters, and expected behavior—without dragging in implementation details.

This is a critical step: the model doesn't need to see the internal logic of every dependency to reason about how to use it. It needs the contract, not the code.

Pass 3: Tiered Assembly

The final pass assembles the prompt by tier. The target file goes in full—every line. Its direct dependencies go in skeletonized form. Indirect dependencies are summarized to a single line, and anything else is dropped or flagged as [UNRESOLVED] if the tool couldn't verify it.

This tiering mimics how a compiler would organize intermediate representations: high-fidelity for the code being worked on, low-fidelity for peripheral context. The result is a prompt that's lean, structured, and fully auditable—no opaque black-box filtering.

Results and Implications

Testing on two real Python repos (a CLI tool and a small web service) produced prompt size reductions of 69% and 74%, respectively, with compile times of 72 ms and 68 ms. These numbers are from actual runs, captured in terminal logs, so you can reproduce them.

The gains reflect two factors: eliminating irrelevant files via reachability analysis, and slimming down kept files via skeletonization. Even in modest codebases, this can mean the difference between fitting comfortably in a 32k context window or spilling into compaction territory.

Related Work and Where This Fits

Context compilation complements other techniques like retrieval-augmented generation (RAG) and agentic memory. While RAG pulls relevant chunks from a vector store, the Context Compiler works locally: it computes relevance from the code's actual structure, not semantic similarity. That makes it deterministic—the output is reproducible, which is crucial for debugging agent behavior.

It also pairs well with compaction strategies. If you must compact, doing it after context compilation means you're summarizing a minimal prompt, not a bloated one, reducing the lossy step's impact.

Next Steps

The current implementation is Python-only, but the principles generalize to any language with an AST (JavaScript, Rust, Go). I'm also exploring integration with agent frameworks like LangChain and AutoGPT, where the Context Compiler could serve as a pluggable pre-processor.

The main limitation is handling dynamic Python constructs like eval, exec, or __import__, which can't be statically resolved. For those, the tool defaults to marking everything as potentially reachable—conservative, but safe.

Conclusion

The race to bigger context windows misses the point. What agents truly need is better context management. The Context Compiler demonstrates that disciplined, compiler-style reduction can shrink prompts by over two-thirds while retaining all essential information. As context windows continue to fluctuate in size across providers, this approach offers a practical hedge.

Try it out, break it, and contribute. The repo is live on GitHub, and feedback is welcome.

via Towards Data Science

Related