Why learn this text?
one about easy methods 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 one more.
As an alternative, this text is one out of a collection of articles which are about easy methods to maintain your self, the coder, related within the fashionable AI coding ecosystem.
It’s about studying the methods 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 collection, you need to have a good suggestion of what widespread pitfalls to search for in auto-generated code, and know easy methods 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 need to degree up their coding experience.
What we are going to cowl not solely makes you higher at utilizing coding assistants but additionally higher coders on the whole.
The Core Ideas
The excessive degree 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 via years of PR opinions 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 grow to be an important a part of any builders’ expertise, be it juniors to seniors.
Why?
As a result of the guide 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 grow to be a senior developer guiding a junior (the coding assistant).
So, it’s grow to be important for even junior software program practitioners to have the ability to ‘evaluate’ code. However the ones who will thrive in at present’s business are those with the foresight of a senior developer.
This is the reason we will likely be protecting the above ideas in order that within the very very least, you’ll be able to inform your coding assistant to take them under consideration, even in case you your self don’t precisely know what you’re searching for.
So, introductions at the moment are carried out. 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 thought to drink it.
For many years, builders have learnt via trial and error what sort of code works long-term. “Smelly” code are brittle, vulnerable to hidden bugs, and troublesome for a human or AI agent to know precisely what’s occurring.
Thus it’s typically very helpful for builders to find out about code smells and easy methods to detect them.
Helpful hyperlinks for studying extra about code smells:
Now, having used coding brokers to construct every thing from skilled ML pipelines for my 9-5 job to whole cellular apps in languages I’d by no means touched earlier than for my side-projects, I’ve recognized two typical “smells” that emerge while you grow 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 easy methods to repair it.

Divergent Change
Divergent change is when a single module or class is doing too many issues without delay. The aim of the code has ‘diverged’ into many various instructions and so quite than being targeted on being good at one job (Single Duty Precept), it’s making an attempt to do every thing.
This leads to a painful scenario the place this code is all the time breaking and thus requires fixing for varied unbiased causes.
When does it occur with AI?
When the developer isn’t engaged with the codebase and blindly accepts the Agent output, you’re doubly prone to this.
Sure, you’ll have carried out all the right issues and made a properly structured immediate that adheres to the most recent is in immediate engineering.
However on the whole, in case you ask it to “add performance to deal with X,” the agent will often do precisely as it’s advised and cram code into your present class, particularly when the present codebase is already very difficult.
It’s finally as much as you to take note of the position, accountability and supposed utilization of the code to give you a holistic method. In any other case, you’re very prone to find yourself with smelly code.
Instance — ML Engineering
Beneath, we now 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, knowledge):
print("Cleansing particular transaction JSON format")
return "cleaned_data"
def train_xgboost(self, knowledge):
print("Working XGBoost coach")
return "mannequin"
A fast warning:
We will’t discuss in absolutes and say this code is dangerous only for the sake of it.
It all the time will depend on the broader context of how code is used. For a easy codebase that isn’t anticipated to develop in scope, the under is completely nice.
Additionally be aware:
It’s a contrived and easy instance for example the idea.
Don’t trouble giving this to an agent to show it may possibly determine that is smelly with out being advised 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 via your head while you have a look at this code?
- Information retrieval: What occurs after we begin having multiple knowledge supply, like Bigquery tables, native databases, or Azure blobs? How possible is that this to occur?
- Information Engineering: If the upstream knowledge adjustments or downstream modelling adjustments, this may even want to vary.
- Modelling: If we use completely different fashions,
LightGBMor some Neural Internet, the upstream modelling wants to vary.
It is best to discover that by coupling Platform, Information engineering, and ML engineering considerations right into a single place, we’ve tripled the explanation 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 danger of introducing a bug, be it human or AI. By having this class put on three completely different hats, you’ve tripled the danger of this breaking, since there’s thrice as extra causes for this code to vary.
- 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 prone to change the coaching and knowledge loading logic to accommodate a change within the knowledge engineering, despite the fact that it was pointless. Finally, this will increase the ‘divergent change’ code scent.
- Threat is magnified by AI: An agent can rewrite a whole bunch of traces of code in a second. If these traces signify three completely different disciplines, the agent has simply tripled the possibility of introducing a bug that your unit checks may not catch.
repair it?
The dangers outlined above ought to provide you with some concepts about easy methods to refactor this code.
One potential method is as under:
class S3DataLoader:
"""Handles solely Infrastructure considerations."""
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 solely Information Area/Schema considerations."""
def clear(self, knowledge):
print("Cleansing particular transaction JSON format")
return "cleaned_data"
class XGBoostTrainer:
"""Handles solely ML/Analysis considerations."""
def practice(self, knowledge):
print("Working XGBoost coach")
return "mannequin"
class ModelPipeline:
"""The Orchestrator: It is aware of 'what' to do, however not 'how' to do it."""
def __init__(self, loader, cleaner, coach):
self.loader = loader
self.cleaner = cleaner
self.coach = coach
def run(self):
knowledge = self.loader.load()
cleaned = self.cleaner.clear(knowledge)
return self.coach.practice(cleaned)
Previously, the mannequin pipeline’s accountability was to deal with the whole DS stack.
Now, its accountability is to orchestrate the completely 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 tasks are stark clear. You may refactor your knowledge loading logic with confidence that the ML coaching code stays untouched. So long as the inputs and outputs (the “contracts”) keep the identical, the danger of impacting something downstream is lowered.
2. Testable Code: It’s considerably simpler to jot down unit checks because the scope of testing is smaller and properly outlined.
3. Lego-brick Flexibility: The structure is now open for extension. Have to migrate from S3 to Azure? Merely drop in an AzureBlobLoader. Wish to experiment with LightGBM? Swap the coach.
You finally find yourself with code that’s extra dependable, readable, and maintainable for each you and the AI agent. In case you don’t intervene, it’s possible this class grow to be larger, 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 while you begin out creating a brand new mission.
This code scent is when the developer tries to future-proof a mission 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 mannequin coaching pipeline help every kind of fashions, cross validation and hyperparameter tuning strategies, and ensure there’s human-in-the-loop suggestions for mannequin choice in order that we will use this for all of our coaching sooner or later!”
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 capable of 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 strong agent with a obscure immediate, and also you rapidly find yourself with too many modules and a whole bunch of traces of recent code.
Maybe each line is pure gold and it’s precisely what you want. Once 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 decisions 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 could grow 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 you need to solely implement the code you want, not the code you foresee.
Begin with the only factor that works. Then, iterate on it.
This can be a extra pure, natural means of rising your codebase that will get issues carried out, 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 show 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 unbiased 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, knowledge):
print("Cleansing particular transaction JSON format")
return "cleaned_data"
def train_xgboost(self, knowledge):
print("Working XGBoost coach")
return "mannequin"
Instance 2
class S3DataLoader:
"""Handles solely Infrastructure considerations."""
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 solely Information Area/Schema considerations."""
def clear(self, knowledge):
print("Cleansing particular transaction JSON format")
return "cleaned_data"
class XGBoostTrainer:
"""Handles solely ML/Analysis considerations."""
def practice(self, knowledge):
print("Working XGBoost coach")
return "mannequin"
class ModelPipeline:
"""The Orchestrator: It is aware of 'what' to do, however not 'how' to do it."""
def __init__(self, loader, cleaner, coach):
self.loader = loader
self.cleaner = cleaner
self.coach = coach
def run(self):
knowledge = self.loader.load()
cleaned = self.cleaner.clear(knowledge)
return self.coach.practice(cleaned)
Beforehand, we implicitly assumed that this was manufacturing grade code that was topic to the assorted upkeep adjustments/characteristic additions which are regularly 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 situation, choosing instance 2 may very well be the smellier selection.
If the scope of the mission is to think about one knowledge supply, or one mannequin, constructing three separate lessons and an orchestrator might 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 knowledge/output mannequin necessities, instance 1 could possibly be extra applicable.
The Overarching Lesson
What these two code smells reveal is that software program engineering is never about “right” code. It’s about context.
A coding agent can write good 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 observe, that isn’t scalable.
If it’s important to 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 reworked the guide 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 an information scientist has essentially modified. The guide 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 knowledge scientists who’re blindly copy pasting code, it is advisable to have the structural instinct to information a coding agent in a path that’s related in your distinctive scenario. This leads to higher reliability, efficiency, and outcomes which are mirrored on you, making you stand out.
However to attain this, it is advisable 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 finally, with the ability to do that successfully provides you extra headspace to give attention to the issue fixing and architecting an answer an issue – i.e. the true ‘enjoyable’ of information science.
Associated Articles
In case you appreciated this text, see my Software program Engineering Ideas for Information Scientists collection, the place we broaden on the ideas most related for Information Scientists

