Software Engineering Practices (are also) Useful for Token Reduction

Software engineering practices were (at least when I'm pushing them) all about minimizing things for humans:

  • minimize how much a person needs to read to understand the meaning of something,
  • how many things a person needs to change to add, change or remove a feature,
  • how many times a person needs to test something manually,
  • how many times we repeat the same mistake,
  • how many times we need to communicate the meaning of something
  • etc etc.

Person cycles are now agent cycles

Which are today, measured in token cycles.

All the invisible busy-work that used to hide in the shadows and we were always wondering where the time goes, why isn't this thing ready yet - it's mostly visible in tokens now.

When an agent tries something multiple times, you can see it in the tokens. when it generates or changes huge amounts of code again and again, you can see. When you keep telling it over and over again and it keeps misunderstanding, this costs us our precious tokens.

And so we get:

The rise of re-discovered software engineering principles

Long held by many but loosely adopted my many more. Perhaps engineering principles are (a) killer feature for agents , at least for the near future as agents remain very effective yet incredibly unreliable coding machines.

Agents with engineering principles guidance and prompts show remarkable improvement for token consumption (at least for me). Here are a few principles I use (and many more exist):

Basic Principles - Huge Token Savings

I've been using these while working on and with lowkey and reposwarm (and a bunch of others)

  • "Apply DRY/extract function/extract/class": Don't repeat yourself.
    You tell the agent to not repeat itself in the code so instead of having 12 places where it checks if something is true or not, it extracts a reusable function.
    • Next time it needs to update that logic, it only has to spend 12th of the tokens it would have needed to change the code without DRY principles.
    • which also leads to..
  • "Apply Readable functions and class names, single responsibility principle"
    • Next time the LLM needs to reason on a codebase and understand where it needs to change things and where it does NOT need to change things, and what's risky and what's less risky , it's more likely to :
      • spend less time going over the wrong places (starts in more likely places)
      • make less mistakes by changing the wrong code or creating it in the wrong place
      • more likely to repeat the good patterns it has seen before (readability, DRY etc.
  • "Apply Fully Automated tests that can be run by CLI repeatedly":
    • Allow the agent know when it's "done' or if there's a new issue it broke
    • which leads to :
  • "Use Red-Green TDD":
    • Agents are more likely to write better tests and code that actually works for them if they start with a failing test, then make it pass by writing production code.
    • which leads to..
  • "Apply Refactoring as part of the TDD cycle":
    • which brings us back to DRY, and readable code.
    • which leads to..
  • (implicitly you get) Interface Segregation & Dependency inversion:
    • Agent can work on something without needing to change other things (aka shotgun surgery) or even understanding other things.
  • (implicitly you get) Small commits with good messages
    • allow agents to reason on changes - basically act as "session summaries" for future agents to look at when no agents.md are around, and get compressed context this way.
    • prevent agents from repeating past mistakes or getting better context on future changes
  • Apply CI/CD pipelines
    • a broader use of agent feedback loops, not just at the local level but at the integration and e2e level
  • "use Pattern-Name here": Design Patterns and pattern names
    • Calling something as using a "Strategy Pattern" compresses a lot of agent built in knowledge on something that would have taken many tokens to express or read for the agent.
  • Type Systems and strong typing:
    • Types are compressed documentation. Instead of the agent reading 500 lines to infer what shape data has, it reads a 5-line type definition.
    • compiler errors are cheaper feedback than runtime errors (shorter error messages, more precise location)
  • Doc-strings:
    • used to be hell because nobody updated them, but agents can update them easily and read them easily - but ONLY if they are used with good reason.
  • API Contracts / OpenAPI Specs
    • A spec file is a compressed representation of an entire service structure. Agent reads 100 lines of spec instead of 5000 lines of implementation to know how to integrate.
  • Feature Flags
    • Changing behavior via config = changing 1 line