Writing code that agents understand 🧠

There was a time when code was written for the compiler. Then we started writing it for the next developer on the team. Today there is a third reader, and a good naming convention is not enough: it counts every token. The AI agent reads your code as text to compress, not as a story to enjoy. And the quality of that compression depends entirely on how readable what you wrote actually is.
Readability is no longer an aesthetic luxury: it is an economic lever on context.
Naming as the first context compression 🏷️
A variable called d communicates nothing. One called pendingOrderCount communicates everything: type, state, meaning. When an agent processes your code, every ambiguous name triggers a mini internal consultation: what does this thing represent? Every clear name eliminates one.
Explicit naming is not pedantry: it is semantic compression. A good name saves the agent the work of deduction, and the team the work of interpretation. It works for both readers at the same time.
A clear name is a token you no longer have to spend on explanation.
The difference between processData() and validateAndPersistUserRegistration() is not length: it is information density. The second function tells you what it does before anyone reads the body. The compiler does not care, but the agent and your colleague at 5 PM do.
A common pattern that fails in both contexts: abbreviated names born from laziness, not economy. tmp, res, val are not names: they are temporary confusion encoded into code. The agent processes them, but must deduce their meaning from surrounding context. Every deduction is an extra token, added latency, a growing margin of error.
Short functions: the constraint that frees 📏
A 200-line function is a context problem, not just a style issue. When the agent needs to understand what that function does, it must process 200 lines of logic to extract the intent. With a 15-line function, the intent is in the name and the body is a confirmation.
Long, nested functions force the agent to keep too many variables in mind at once. It is no different from what happens to us humans: more active context, more room for confusion. But there is a crucial difference: we can scroll back and forth with a glance; the agent pays for every line it processes.
The practical rule is simple: if you cannot describe a function in one sentence, it is too long. It is not an aesthetic principle: it is an efficiency constraint. A short function with a good name provides the agent with exactly the context it needs, no extra noise.
A short function is an atomic context module: everything that matters, nothing more.
Cohesion: every module tells one story 🧩
A well-cohesive file has a clear responsibility. When you open a module called order_validation.go, you expect to find order validation logic. Not persistence logic, not generic error handling, not miscellaneous utilities. One thing, done well, in one place.
Cohesion reduces the number of files the agent must open to understand a concept. If every module tells a coherent story, retrieval becomes precise. The agent reads the file name, opens it, and finds exactly what it was looking for. No surprises, no treasure hunts.
In Managing context as a resource we discuss context hygiene: keeping clean what enters the context window. Code cohesion is the first tool of that hygiene. If the code is cohesive, fewer files are needed, fewer tokens are consumed, less noise enters the system.
One signal that a module has lost cohesion: when understanding a function requires opening three other files. It is not always an architectural disaster, but it is a sign that the context needed for that function has scattered. And scattered context is wasted tokens.
A practical example: a utils.go file with 40 functions of different kinds is not a utility, it is a junk drawer. The agent looking for a validation function must read the entire file to find the right one, consuming tokens for every irrelevant function it crosses. An order_validation.go file with 5 validation functions, instead, is a precise target: open, read, understand. Done.
Readability as a contract with the agent 📝
Writing readable code for an agent means making concrete choices: names that describe the domain, functions that do one thing, files with one dominant responsibility. It is no different from what The art of reading AI code recommended, but from the opposite side: it is not only about reading agent-generated code, but about writing code that the agent can read well.
There is an almost contractual aspect to all of this. When you write readable code, you are making a promise to every future reader — human and machine: this code tells you what it does, without you having to beg for it. It is a gesture of respect for whoever will work on it next, including the agents that do not have the luxury of “feeling” the code by intuition.
Readable code is a contract: fewer explanations needed, fewer tokens spent.
Comments help, but only those that explain the why, not the what. The what should be in the function name and the code structure. The why is what no name, however good, can communicate alone. In this sense, a good comment is an annotation to the contract, not an obscure clause.
Readability as a context economy 💰
Back to the economics. The more code needed to understand a concept, the more tokens you consume. The more tokens you consume, the more you pay and the longer the response time. But there is a less obvious effect: the more irrelevant code the agent processes, the worse the answer quality. Noise is not only a cost: it is poison for context.
Modularity and tokens explored this link: modularity reduces the tokens needed. Readability is the natural complement to that modularity. You can have a perfectly modular system with cryptic names and 500-line functions: the agent will still have to process everything to understand what happens.
The winning combination is: modularity to reduce the files needed, readability to reduce the content of each file. Together, they compress context exponentially. It is like having a detailed map of a small city instead of a blurry photo of a continent: less data, more clarity.
Modularity and readability are not separate principles: they are two sides of the same context compression.
In practice: small habits, big impact 🔧
Some concrete practices that make code more readable for agents and humans alike:
- Function names starting with a verb:
calculateTotal(), nottotal(). The verb is an action indicator the agent can process directly. - Parameters with descriptive names:
order *Order, noto *Order. Zero cost, constant benefit. - Files with one main responsibility: if a file handles more than three conceptually distinct concerns, it is time to separate.
- Constants with domain-explaining names:
MaxRetryAttemptsbeatsMAX_RETRIES. Not just readability: it is semantic context. - Errors that communicate intent:
ErrOrderNotFoundsays exactly what happened.ErrGenericsays nothing.
These choices do not require architectural revolutions. They require attention to the name you write, the length of the function, the responsibility of the file. It is a minimal investment with constant return, because every readable line is a token that does not need to be explained twice.
There is an empirical test that always works: try explaining out loud what a function does. If the explanation requires more than one sentence, the function probably does more than one thing. If the explanation is confused, the name is probably confused. It is not a scientific method, but it works better than many automated audits.
Conclusion: code as documentation for everyone 🎯
For a long time we wrote code thinking of a human reader. Today the reader is different, not additional. The agent does not replace the colleague: it joins them. And readability serves both, with one difference: the colleague can afford to ignore noise; the agent processes it anyway and pays for it.
Code is documentation for machines and humans. When it is readable, both pay less.
Next time you write a function, ask yourself: if an agent had to understand it without extra context, could it? If the answer is no, the problem is not the agent. It is the name, the length, the cohesion. Those are the levers you hold, and they require no special permission to use.
The beauty of all this is that no manifesto or team convention is needed. Just one question, repeated every day: does this code clearly tell what it does? If the answer is yes, the agent will understand it. Your colleague will understand it. And you, six months from now when you return to that function, will understand it too. Sometimes simplicity is the most effective revolution.