A few years ago, software engineers spent most of their time writing code. Today, we increasingly spend our time generating it.
Whether you’re using Claude Code, Codex, Cursor, OpenCode, or another coding agent, the workflow has shifted from writing every line ourselves to describing a problem, reviewing the generated solution, and refining it through iteration. The resulting software still runs as Python, Rust, Go, Java, or any other programming language.
What has changed is how that software is produced. This apparently small shift introduces a new engineering consideration.
Generated code is no longer read only by developers and compilers. It is also read repeatedly by LLMs. Every future prompt asking an agent to fix a bug, add a feature, refactor a module, or write a test requires the model to consume parts of your repository as input. Those inputs are measured in tokens.
For software engineers, tokens influence far more than cost.
How much of your repository fits into a model’s context window.
How much relevant code an agent can retrieve before important information is dropped.
How quickly the model can understand an unfamiliar codebase.
How much repetitive boilerplate the model has to process before reaching the business logic that actually matters.
Tokens are becoming another engineering resource to optimise, just like CPU, memory, storage, and network bandwidth.
Code Has a New Reader
Traditionally, source code had two readers. The first was another developer trying to understand the system. The second was the compiler or interpreter responsible for executing it.
Coding agents introduce a third reader.
Source Code
│
┌─────────────┼─────────────┐
│ │ │
Humans Compiler LLMEach reader looks at the same code differently.
Developers care about readability, maintainability, and clear abstractions.
Compilers care about syntax, types, and correctness.
LLMs care about those things too, but they also have a constraint humans do not have. They work within a limited context window. Every unnecessary token consumes space that could have contained more relevant business logic.
This is why code structure now affects more than maintainability. It also affects how effectively an AI agent can reason about your system.
How LLMs See Your Code
A token is simply a unit produced by the model's tokenizer. Depending on the tokenizer, a token may represent a complete word, part of a word, punctuation, symbols, whitespace, or fragments of an identifier.
For example, consider the following variable name in your code. A tokenizer may split it into something similar to this.
Although developers see one identifier, the model may process five separate tokens. The same happens throughout source code.
Brackets, operators, string literals, comments, indentation, and even newlines contribute to the overall token count.
In practice, token usage is usually dominated by:
Repeated boilerplate.
Long comments that restate the code.
Duplicate validation logic.
Large configuration objects.
Verbose helper functions.
Generated code with repetitive structure.
Also, Removing three blank lines might save a handful of tokens.
Generated Code Is Usually More Verbose
One interesting observation from using coding agents is that they tend to optimise for clarity and safety rather than brevity. That behaviour makes sense.
The model does not know whether the generated code will be used as production software, teaching material, or an interview example until we define them in requirement prompts. As a result, it often generates explicit helper functions, defensive checks, intermediate variables, detailed comments, and sample data.
None of these are inherently bad. The problem appears when these patterns are repeated throughout an entire repository.
Consider this Python implementation.
There is nothing wrong with this implementation. It is readable, uses type hints, separates validation, and models the domain clearly. However, if we look beyond correctness, we can see several opportunities to reduce unnecessary structure.
Validation is separated into another function. ( off course modularity is important )
Two intermediate variables exist only to perform a single assignment.
Several objects are introduced purely to support one calculation.
Each decision is reasonable in isolation. Across thousands of files, those decisions increase the amount of code an AI agent has to read before it reaches the business logic.
The same logic can often be expressed with fewer tokens, making it cheaper for an LLM to read and reason about.
Up to this point, we have only optimised how the code is written.
The choice of programming language also influences how many tokens are needed to express the same logic.
Some languages provide more expressive constructs through their standard libraries and language features, allowing common patterns to be represented with fewer tokens. That doesn't make one language universally better than another, but it does mean the same algorithm can have very different token footprints depending on the language and how idiomatically it is written.
Idiomatic Programming Changes the Picture
Idiomatic programming means writing code the way a language was designed to be written.
It is not about clever tricks or squeezing everything into one line. It is about taking advantage of the language’s standard library, common conventions, and expressive features instead of carrying habits from another language.
Another interesting observation is that coding agents often generate code in a remarkably similar style across different programming languages. Whether the target is Python, Rust, Go, or Java, the initial implementation frequently follows the same imperative structure, introducing intermediate variables, helper functions, and explicit control flow even when the language offers more idiomatic alternatives.
The exact reason is difficult to pinpoint but it could be a combination of training data, model preferences, system prompts, or the coding harness itself.
Rust provides a good example. The language offers expressive iterator combinators and APIs such as HashMap::entry that allow the same aggregation to be expressed more directly.
I have given both style of generated code in rust below.
Non-idiomatic
Idiomatic
It follows the natural style of rust language, the less repetition it usually contains. That benefits both developers and coding agents.
Measuring Token Usage
Let’s try to measure the difference. The following script compares all 4 implementations and reports four simple metrics.
Lines of code.
Character count.
Whitespace-separated words.
Estimated LLM tokens using the same tokenizer
Code Repo : https://github.com/kannandreams/when-engineers-meet-ai/tree/main/code/token-aware-engineer
Token Efficiency Doesn't Mean Writing Shorter Code
It is easy to assume that fewer tokens simply means writing the shortest code possible. It doesn’t.
This version is compact, but it is harder to read, maintain, and explain.
The goal is not fewer characters, it is higher information density.
AI-efficient code is concise without sacrificing clarity.
In practice, that means writing code that is:
Idiomatic for the language
Free of unnecessary boilerplate
Built from small, reusable abstractions
Well named and consistently structured
Direct in its control flow
Documented with comments that explain why, not what
None of these principles are new. They have always been considered good software engineering practices. The difference today is that they benefit both humans and AI. Developers get more maintainable code, while coding agents need fewer tokens to understand the same logic.
Final Thoughts
Software engineering has always adapted to new constraints.
AI-assisted development introduces another: context.
As more code is generated instead of handwritten, its quality increasingly depends on how efficiently it can be understood by both humans and coding agents.
Idiomatic programming has always produced better software. Today, it also produces code that requires less context to retrieve, understand, and extend.
That is why idiomatic programming is more than a style preference. It is one of the first principles of becoming a Token-Aware Engineer.
Next in the series will be
Part 2: How Repository Structure Shapes AI Performance - A developer can jump between files and build a mental model. An LLM receives slices of your repository inside a context window. Why repository layout, module boundaries, naming, documentation, and code organization affect how efficiently coding agents retrieve, understand, and extend your codebase.










A nice read just in time and most needed for the hour.
But few clarifications and questions
> Each decision is reasonable in isolation. Across thousands of files, those decisions increase the amount of code an AI agent has to read before it reaches the business logic.
--> Now, here the sample optimization is human-made, I assume, but generally most of the code is AI-written; in that case, how do we optimize it? It's still token consumption, right? We try to optimize the code that AI made, and again, we consume tokens when optimization is done. Or my understanding is incorrect?