Top 5 Tips for Writing Code With AI
ChatGPT Prompt: Create a lousy image to promote a blog post about ai coding tips [Note: I kind of like it]
Ready or not, the era of AI software development is in full swing. Last, year Google’s CEO announced that 25% of Google’s code is being written by AI. Microsoft’s CEO recently announced a similar number in the 25-30% range. Top AI coding models such as Claude 3.7 Sonnet and Gemini 2.5 Pro are breaking coding benchmarks. Cursor, one of the most popular AI coding editors, has surpassed 1 million users and is generating north of $100 million in annual recurring revenue (ARR).
On the other side of the hype spectrum, while AI won’t eliminate software engineering jobs, there is growing evidence that it is affecting the software engeering job industry. Besides very niche specialists, generalist software engineers simply have no choice but to embrace AI coding solutions to compete from an efficiency standpoint.
Quick terminology aside: I consider the way that I work with AI code generation tools different from pure vibe coding. Vibe coding, where you either don’t understand the code at all or don’t bother to read any of it, is great for creating demos and prototypes. At it’s current state, this is mostly a dead end for developing highly complex, production grade applications that will continually grow and change over time.
My AI Coding Setup
I currently use AI coding tools in two different capacities:
Backend development - I do my development in VSCode, and while there exists IDE integrations such as GitHub Copilot, I prefer to use AI outside of the IDE and make requests directly within Claude, ChatGPT and Gemini interfaces. The reason? My main backend codebase is very large, highly customized and difficult to debug. In my opinion, it’s currently too risky to let AI write more than isolated methods and functions for highly complex, very large backend applications. For smaller, basic CRUD style applications then it’s probably fine.
Frontend development - I find that developing directly with Cursor helps me move more quickly writing code with the most common frontend web frameworks such as Next.js. Just for page prototyping and design tweaks alone, it’s worth using to get an initial draft of a page or component built.
With this in mind, here are my top 5 tips for working more effectively with AI coding tools:
AI Coding Tip #1: Too much context can be just as bad as not enough context
Getting the most out of AI models for coding assistance is all about providing the right context. The theory of coding tools built into your IDE such as Cursor is that it can make better decisions with the full context. This is partially true, but even when using models with giant context windows, providing too much context has a lot of downsides:
The longer the context, the longer it takes models to process
Recall decreases to varying degrees as context grows. Benchmarks that show otherwise are probably only measuring specific tasks.
The more advanced reasoning models tend to “overthink” and can make unwanted changes when reasoning through a large codebase
The tools models use to search and update files have a greater tendency to break with larger files
The best option is to selectively include the specific relevant context for your update. If you are working directly with a model, share the relevant class, function, error message, etc. Don’t share anything that is not necessary to understand the problem at hand.
In Cursor, you can highlight specific lines from files or logs. This is very helpful if a file or logs are extremely large.
AI Coding Tip #2: Don’t be afraid to switch models frequently, and don’t be afraid to “downgrade”
Having trouble getting good results with your preferred model? Simply try another. Sometimes the more advanced models, in particular the reasoning models, tend to “overthink” more straightforward requests. Switching to a less advanced model can often work better, with an added bonus that it will likely generate results much faster.
In Cursor in particular, if your preferred model is struggling to generate successful results after a few minutes and several attempts, try reverting back to the beginning of your request with a different model. More often than not, this is better than going too far down a likely broken path. If you are still not getting results, try simplifying your request, providing smaller context, or start to develop the solution yourself and then ask for more discrete help along the way.
AI Coding Tip #3: Take time to periodically refactor
AI models will rarely generate code in the most reusable fashion. If you ask for it to write or update a function, it will probably add all of the updates in that same function. If you ask for it to add a new feature to a webpage, it will probably write a lot of code in the same file, even if that code should be best refactored into a separate component.
After enough revisions, you might end up with files that are thousands of lines of code. When this happens, the models start to become less effective as they struggle to understand the full context of the file at once. They end up spending a lot of time searching for the right context in the file, and may even generate duplicate code because it did not find relevant existing code.
When this starts to happen, it’s time to clean up your mess. Consider refactoring code into smaller, more reusable files. You can do this manually of course, but one option using Cursor in particular is to highlight a section of code and ask the agent to refactor to a different file. Providing the target filename and location can be helpful, along with specifying that you simply want to re-organize the code and not dramatically change it’s structure or functionality.
AI Coding Tip #4: Testing, testing testing
One of the worst things you can do as a software engineer is to make too many changes at once without testing. When you do this, you run the risk of making it very difficult and time consuming to debug. There is a reason why most large software teams have mandates to push small, frequent updates - it helps prevent big breaking changes that can’t be quickly reverted and fixed.
Working with AI tools where you don’t thoroughly understand every line of code makes this practice even more important. Make a small, discrete change. Test the change. Test it again. Do a full end to end test even for a small change just to make sure. Commit your code and only then move on to the next thing.
Cursor has a built in restore checkpoint feature that is very helpful. If you have an update that seems to have made too many changes drastic changes at once or has a few bugs, don’t hesitate to restore to the previous checkpoint and try again.
AI Coding Tip #5: Actually, you don’t need to understand it all
It’s easy for me to sit here and say “don’t commit any line of code generated by an AI that you don’t understand”. Sometimes this is absolutely true but I actually don’t think this is necessary 100% of the time. Remember, the whole point of these AI tools is that they have the potential to save us a lot of time. If you read every single line of code written by the AI, ponder it’s meaning, read the source library, read the documentation and write your own examples to confirm your understanding, you might not save yourself any time at all.
We can’t all be experts on everything. If the code in questions is fairly discrete - meaning it is easily testable and isolated - then you might not have to truly understand every nuance. Software purists won’t like it, but this is going to be how much of the world’s software is written going forward.