> Amin Khansari's Notes_

The Right Way to Code with LLM

LLM is a powerful coding assistant, but using it well means staying in the driver's seat.

Pixel art cover illustration for coding with LLM assistants

The rise of LLM for coding has changed how many developers work. These tools can write code, explain concepts, and suggest solutions in seconds. But with this power comes an important question: how should we actually use these tools? The answer matters more than most people realize.

A study shows more than 800 popular GitHub projects with code quality degrading after adopting AI tools. There is a real risk that newer models will reinforce and amplify those trends, producing even worse code over time. — Rob Bowley

You are the developer, not the LLM

The most important principle is simple: LLM is your assistant, not the one that controls you and dictates what you should do. This might sound obvious, but it is easy to fall into the opposite pattern. When you start accepting LLM suggestions without understanding them, or when you shape your work around what the LLM can produce, the roles have reversed. You have become the assistant to your own tool, trapped in an illusion of productivity.

A good relationship with LLM looks like this: you decide what to build, you set the standards and the architecture, you validate or fine-tune the output. The LLM handles the mechanical parts. Think of it like having a junior developer who types very fast but needs supervision.

Let LLM handle the repetitive work

LLM shines when the task is repetitive or well-defined. Writing boilerplate code, generating new code for known patterns, refactoring, converting and transforming. These are perfect use cases. The pattern already exists in your code or the LLM is already trained with, and you just need more of it.

Here is something many developers overlook: LLMs are trained on vast amounts of code from the internet, and most of that code is average at best. They learned from millions of mediocre examples. They are better at reproducing than creating excellent new ones.

The practical consequence? Write good code yourself first. Establish your patterns, your conventions, your architecture. Then let LLM replicate what you have created. When it has your high-quality examples as context, it produces much better results than when it works from its general training alone. New LLM tools try to add your existing code into the context before generating new code.

Grow your knowledge, don’t outsource it

It is tempting to let LLM handle everything you do not understand. Do not do that! Every time you accept code you cannot explain, you create technical debt in your own mind. You become dependent on a tool to maintain your own project.

Instead, use LLM as a learning accelerator. Ask it to explain concepts you are struggling with. Have it break down complex algorithms step by step. Use it to explore different approaches to the same problem. The goal is to understand more after each interaction, not less.

A developer who uses LLM well ends up knowing more than before. A developer who uses it poorly ends up knowing less while producing more code, a dangerous combination.

Write new things yourself first

When you are building something genuinely new, like a novel algorithm, unique business logic, your software architecture, or a creative solution, write it yourself first. Your initial version might be rough, but it will be authentically yours. It will reflect the context and your actual understanding of the problem.

Once you have working code, then bring in LLM. Ask it to review your solution. Have it suggest optimizations. Let it simplify complex sections. This approach gives you two benefits: you maintain deep understanding of your code, and you get the LLM’s help making it better while learning from it.

The reverse approach, asking LLM to write novel code from scratch, often produces something that looks right but misses important details. The LLM does not understand your specific context the way you do.

A surprisingly good Rubber Duck

Perhaps the most underrated use of LLM is as a thinking partner. Traditional “rubber duck debugging” involves explaining your problem to an inanimate object to clarify your thoughts. LLM takes this further because it actually responds.

Use LLM to organize your thoughts before writing code. Describe the domain you are modeling and ask it to identify potential challenges. Explain a problem you are stuck on and let it ask clarifying questions. Discuss different architectural options and their trade-offs.

This kind of dialogue often reveals gaps in your thinking without any code being written at all. The LLM serves as a mirror that helps you see your own ideas more clearly.

Context is everything

Here is a truth that separates effective LLM users from frustrated ones: the quality of output depends almost entirely on the quality of context you provide. An LLM without context is like a skilled contractor who shows up with no blueprints. They might build something, but probably not what you need.

Good context means giving the LLM everything it needs to understand your world. There are several ways to do this:

  • Plan mode before edit mode: Tools like Open Code offers a plan mode. Use it to discuss and validate the approach before the LLM touches any files. This back-and-forth clarifies context and catches misunderstandings early. For complex tasks, start with high-level domain context, then narrow to the specific module, then to the exact problem.
  • Grill Me Skill: Use it in plan mode for heavy tasks to force LLM asking you enough questions to enrich the context and to clarify.
  • Dedicated context files. Tools now support files like AGENTS.md or Skills in your repository. Define your architecture, conventions, documentation, and constraints once, and every LLM interaction benefits.

The investment in good context pays off quickly. You spend less time correcting mistakes and more time on work that matters. Strategic Domain-Driven Design, with its emphasis on explicit boundaries and shared understanding, shines even more in the LLM era.

The bottom line

LLM is a powerful tool, but tools do not make decisions. Developers do. Use it for repetition, not creation. Use it to learn, not to avoid learning. Let it help you think, not think for you.

The developers who will thrive are those who treat LLM as amplification of their skills rather than a replacement for them. Stay in the driver’s seat.

SEARCH POSTS

START TYPING TO SEARCH_