Why learn this text?
one about learn how to construction your prompts to allow your AI agent to carry out magic. There are already a sea of articles that goes into element about what construction to make use of and when so there’s no want for an additional.
As an alternative, this text is one out of a sequence of articles which are about learn how to maintain your self, the coder, related within the fashionable AI coding ecosystem.
It’s about studying the strategies that allow you to excel in utilising coding brokers higher than those that blindly hit tab or copy-paste.
We’ll go into the ideas from present software program engineering practices that you have to be conscious of, and go into why these ideas are related, significantly now.
- By studying this sequence, it is best to have a good suggestion of what frequent pitfalls to search for in auto-generated code, and know learn how to information a coding assistant to create manufacturing grade code that’s maintainable and extensible.
- This text is most related for budding programmers, graduates, and professionals from different technical industries that wish to stage up their coding experience.
What we’ll cowl not solely makes you higher at utilizing coding assistants but in addition higher coders basically.
The Core Ideas
The excessive stage ideas we’ll cowl are the next:
- Code Smells
- Abstraction
- Design Patterns
In essence, there’s nothing new about them. To seasoned builders, they’re second nature, drilled into their brains by means of years of PR critiques and debugging. You ultimately attain some extent the place you instinctively react to code that “feels” like future ache.
And now, they’re maybe extra related than ever since coding assistants have turn out to be a vital a part of any builders’ expertise, be it juniors to seniors.
Why?
As a result of the handbook labor of writing code has been offloaded. The first accountability for any developer has now shifted from writing code to reviewing it. Everybody has successfully turn out to be a senior developer guiding a junior (the coding assistant).
So, it’s turn out to be important for even junior software program practitioners to have the ability to ‘review’ code. However the ones who will thrive in right this moment’s trade are those with the foresight of a senior developer.
Because of this we shall be overlaying the above ideas in order that within the very very least, you possibly can inform your coding assistant to take them under consideration, even in the event you your self don’t precisely know what you’re in search of.
So, introductions at the moment are accomplished. Let’s get straight into our first subject: Code smells.
Code Smells
What’s a code scent?
I discover it a really aptly named time period – it’s the equal of bitter smelling milk indicating to you that it’s a foul concept to drink it.
For many years, builders have learnt by means of trial and error what sort of code works long-term. “Smelly” code are brittle, susceptible to hidden bugs, and troublesome for a human or AI agent to grasp precisely what’s occurring.
Thus it’s typically very helpful for builders to find out about code smells and learn how to detect them.
Helpful hyperlinks for studying extra about code smells:
Now, having used coding brokers to construct every part from skilled ML pipelines for my 9-5 job to whole cell apps in languages I’d by no means touched earlier than for my side-projects, I’ve recognized two typical “smells” that emerge whenever you turn out to be over-reliant in your coding assistant:
- Divergent Change
- Speculative Generality
Let’s undergo what they’re, the dangers concerned, and an instance of learn how to repair it.
Divergent Change
Divergent change is when a single module or class is doing too many issues directly. The aim of the code has ‘diverged’ into many alternative instructions and so fairly than being targeted on being good at one process (Single Accountability Precept), it’s making an attempt to do every part.
This ends in a painful state of affairs the place this code is all the time breaking and thus requires fixing for numerous impartial causes.
When does it occur with AI?
When the developer just isn’t engaged with the codebase and blindly accepts the Agent output, you might be doubly prone to this.
Sure, you will have accomplished all the proper issues and made a properly structured immediate that adheres to the most recent is in immediate engineering.
However basically, in the event you ask it to “add functionality to handle X,” the agent will often do precisely as it’s informed and cram code into your present class, particularly when the prevailing codebase is already very difficult.
It’s in the end as much as you to consider the function, accountability and meant utilization of the code to provide you with a holistic strategy. In any other case, you’re very more likely to find yourself with smelly code.
Instance — ML Engineering
Beneath, now we have a ModelPipeline class from which you may get whiffs of future extensibility points.
class ModelPipeline:
def __init__(self, data_path):
self.data_path = data_path
def load_from_s3(self):
print(f"Connecting to S3 to get {self.data_path}")
return "raw_data"
def clean_txn_data(self, information):
print("Cleaning specific transaction JSON format")
return "cleaned_data"
def train_xgboost(self, information):
print("Running XGBoost trainer")
return "model"A fast warning:
We will’t discuss in absolutes and say this code is unhealthy only for the sake of it.
It all the time is dependent upon the broader context of how code is used. For a easy codebase that isn’t anticipated to develop in scope, the under is completely positive.
Additionally notice:
It’s a contrived and easy instance for instance the idea.
Don’t hassle giving this to an agent to show it may determine that is smelly with out being informed so. The purpose is for you to recognise the scent earlier than the agent makes it worse.
So, what are issues that must be going by means of your head whenever you have a look at this code?
- Knowledge retrieval: What occurs once we begin having multiple information supply, like Bigquery tables, native databases, or Azure blobs? How probably is that this to occur?
- Knowledge Engineering: If the upstream information adjustments or downstream modelling adjustments, this will even want to alter.
- Modelling: If we use totally different fashions,
LightGBMor some Neural Internet, the upstream modelling wants to alter.
You must discover that by coupling Platform, Knowledge engineering, and ML engineering considerations right into a single place, we’ve tripled the rationale for this code to be modified – i.e. code that’s starting to scent like ‘divergent change‘.
Why is that this a potential drawback?
- Operational danger: Each edit runs the chance of introducing a bug, be it human or AI. By having this class put on three totally different hats, you’ve tripled the chance of this breaking, since there’s thrice as extra causes for this code to alter.
- AI Agent Context Air pollution: The Agent sees the cleansing and coaching code as a part of the identical drawback. For instance, it’s extra more likely to change the coaching and information loading logic to accommodate a change within the information engineering, although it was pointless. In the end, this will increase the ‘divergent change’ code scent.
- Threat is magnified by AI: An agent can rewrite a whole lot of strains of code in a second. If these strains signify three totally different disciplines, the agent has simply tripled the possibility of introducing a bug that your unit exams may not catch.
Tips on how to repair it?
The dangers outlined above ought to offer you some concepts about learn how to refactor this code.
One potential strategy is as under:
class S3DataLoader:
"""Handles only Infrastructure concerns."""
def __init__(self, data_path):
self.data_path = data_path
def load(self):
print(f"Connecting to S3 to get {self.data_path}")
return "raw_data"
class TransactionsCleaner:
"""Handles only Data Domain/Schema concerns."""
def clear(self, information):
print("Cleaning specific transaction JSON format")
return "cleaned_data"
class XGBoostTrainer:
"""Handles only ML/Research concerns."""
def practice(self, information):
print("Running XGBoost trainer")
return "model"
class ModelPipeline:
"""The Orchestrator: It knows 'what' to do, but not 'how' to do it."""
def __init__(self, loader, cleaner, coach):
self.loader = loader
self.cleaner = cleaner
self.coach = coach
def run(self):
information = self.loader.load()
cleaned = self.cleaner.clear(information)
return self.coach.practice(cleaned)Previously, the mannequin pipeline’s accountability was to deal with all the DS stack.
Now, its accountability is to orchestrate the totally different modelling phases, while the complexities of every stage is cleanly separated into their very own respective lessons.
What does this obtain?
1. Minimised Operational Threat: Now, considerations are decoupled and obligations are stark clear. You possibly can refactor your information loading logic with confidence that the ML coaching code stays untouched. So long as the inputs and outputs (the “contracts”) keep the identical, the chance of impacting something downstream is lowered.
2. Testable Code: It’s considerably simpler to put in writing unit exams for the reason that scope of testing is smaller and nicely outlined.
3. Lego-brick Flexibility: The structure is now open for extension. Must migrate from S3 to Azure? Merely drop in an AzureBlobLoader. Wish to experiment with LightGBM? Swap the coach.
You in the end find yourself with code that’s extra dependable, readable, and maintainable for each you and the AI agent. When you don’t intervene, it’s probably this class turn out to be greater, broader, and flakier and find yourself being an operational nightmare.
Speculative Generality

While ‘Divergent Change‘ happens most frequently in an already massive and complex codebase, ‘Speculative Generality‘ appears to happen whenever you begin out creating a brand new challenge.
This code scent is when the developer tries to future-proof a challenge by guessing how issues will pan out, leading to pointless performance that solely will increase complexity.
We’ve all been there:
“I’ll make this model training pipeline support all kinds of models, cross validation and hyperparameter tuning methods, and make sure there’s human-in-the-loop feedback for model selection so that we can use this for all of our training in the future!”
solely to search out that…
- It’s a monster of a job,
- code seems flaky,
- you spend an excessive amount of time on it
- while you’ve not been in a position to construct out the easy LightGBM classification mannequin that you just wanted within the first place.
When AI Brokers are prone to this scent
I’ve discovered that the most recent, excessive performing coding brokers are most prone to this scent. Couple a robust agent with a imprecise immediate, and also you rapidly find yourself with too many modules and a whole lot of strains of latest code.
Maybe each line is pure gold and it’s precisely what you want. After I skilled one thing like this lately, the code definitely appeared to make sense to me at first.
However I ended up rejecting all of it. Why?
As a result of the agent was making design selections for a future I hadn’t even mapped out but. It felt like I used to be shedding management of my very own codebase, and that it might turn out to be an actual ache to undo sooner or later if the necessity arises.
The Key Precept: Develop your codebase organically
The mantra to recollect when reviewing AI output is “YAGNI” (You ain’t gonna want it). It’s a precept in software program growth that means it is best to solely implement the code you want, not the code you foresee.
Begin with the best factor that works. Then, iterate on it.
This can be a extra pure, natural means of rising your codebase that will get issues accomplished, while additionally being lean, easy, and fewer prone to bugs.
Revisiting our examples
We beforehand checked out refactoring Instance 1 (The “Do-It-All” class) into Instance 2 (The Orchestrator) to reveal how the unique ModelPipeline code was smelly.
It wanted to be refactored as a result of it was topic to too many adjustments for too many impartial causes, and in its present state the code was too brittle to take care of successfully.
Instance 1
class ModelPipeline:
def __init__(self, data_path):
self.data_path = data_path
def load_from_s3(self):
print(f"Connecting to S3 to get {self.data_path}")
return "raw_data"
def clean_txn_data(self, information):
print("Cleaning specific transaction JSON format")
return "cleaned_data"
def train_xgboost(self, information):
print("Running XGBoost trainer")
return "model"Instance 2
class S3DataLoader:
"""Handles only Infrastructure concerns."""
def __init__(self, data_path):
self.data_path = data_path
def load(self):
print(f"Connecting to S3 to get {self.data_path}")
return "raw_data"
class TransactionsCleaner:
"""Handles only Data Domain/Schema concerns."""
def clear(self, information):
print("Cleaning specific transaction JSON format")
return "cleaned_data"
class XGBoostTrainer:
"""Handles only ML/Research concerns."""
def practice(self, information):
print("Running XGBoost trainer")
return "model"
class ModelPipeline:
"""The Orchestrator: It knows 'what' to do, but not 'how' to do it."""
def __init__(self, loader, cleaner, coach):
self.loader = loader
self.cleaner = cleaner
self.coach = coach
def run(self):
information = self.loader.load()
cleaned = self.cleaner.clear(information)
return self.coach.practice(cleaned)Beforehand, we implicitly assumed that this was manufacturing grade code that was topic to the varied upkeep adjustments/function additions which are incessantly made for such code. In such context, the ‘Divergent Change’ code scent was related.
However what if this was code for a brand new product MVP or R&D? Would the identical ‘Divergent Change’ code-smell apply on this context?

In such a state of affairs, choosing instance 2 may very well be the smellier selection.
If the scope of the challenge is to contemplate one information supply, or one mannequin, constructing three separate lessons and an orchestrator could rely as ‘pre-solving’ issues you don’t but have.
Thus, in MVP/R&D conditions the place detailed deployment issues are unknown and there are particular enter information/output mannequin necessities, instance 1 may very well be extra applicable.
The Overarching Lesson
What these two code smells reveal is that software program engineering is never about “correct” code. It’s about context.
A coding agent can write excellent Python in each operate and syntax, nevertheless it doesn’t know your whole enterprise context. It doesn’t know if the script it’s writing is a throwaway experiment or the spine of a multi-million greenback manufacturing pipeline revamp.
Effectivity tradeoffs
You may argue that we will merely feed the AI each little element of enterprise context, from the conferences you’ve needed to the tea-break chats you had with a fellow colleague. However in follow, that isn’t scalable.
If you must spend half and hour writing a “context memo” simply to get a clear 50-line operate, have you ever actually gained effectivity? Or have you ever simply remodeled the handbook labor of writing code into that of writing prompts?
What makes you stand out from the remaining
Within the age of AI, your worth as a knowledge scientist has basically modified. The handbook labour of writing code has now been eliminated. Brokers will deal with the boilerplating, the formatting, and unit testing.
So, to make your self stand out from the opposite information scientists who’re blindly copy pasting code, it’s worthwhile to have the structural instinct to information a coding agent in a course that’s related on your distinctive state of affairs. This ends in higher reliability, efficiency, and outcomes which are mirrored on you, making you stand out.
However to realize this, it’s worthwhile to construct this instinct that comes years of expertise by figuring out the code smells we’ve mentioned, and the opposite two ideas (design patterns, abstraction) that we are going to delve into in subsequent articles.
And in the end, with the ability to do that successfully offers you extra headspace to concentrate on the issue fixing and architecting an answer an issue – i.e. the actual ‘fun’ of information science.
Associated Articles
When you favored this text, see my Software program Engineering Ideas for Knowledge Scientists sequence, the place we broaden on the ideas most related for Knowledge Scientists



