After months of building with AI coding tools, I found the difference between generated code that works and generated code that ships comes down to how you communicate with the AI. I have been sharing these lessons in a talk called "It's Dangerous to Code Alone! Take This: Developer's AI Survival Guide" and people keep asking me to write them down. How big is the gap? An MIT study across 100,000+ developers found that AI agents boosted code written by ~180%, while code that actually shipped to production rose by only ~30%.
To demonstrate these tips, I built a link-sharing platform so my teammates can share resources without juggling multiple QR codes. I generated the frontend with Codex GPT 5.6 Sol and Figma MCP, and I am adding an AWS Blocks backend to swap out local mocks with real cloud infrastructure. You can find all the prompts in this repository.
All of these tips are applicable to greenfield projects as well. I can't promise you it is going to have the 42 effect :)
Each model reacts to prompts differently. The clearer you get, the faster you achieve your goal.
You also need to remember that now we don't only have models, we also have effort levels. If you are not mindful about which model you are running with which effort level, you will have a hard time getting the results you want.
Here are some general rules I follow (you can check the BUILDPROMPT.md and the AWS Blocks skill in the repo for the full picture):
Show examples. Input, output. Input, output. The model picks up the shape. Research shows the format matters more than whether the examples are perfectly correct.
In my BUILDPROMPT.md, I use this for the service registry pattern. I show the AI what an implementation swap looks like:
When I ask the AI to build the AWS Blocks backend, it sees this pattern and knows the target: create a BlocksAnalyticsStore, BlocksLinkStore, and BlocksVisitTracker that implement the same interfaces, then swap them in index.ts. I do not need to explain the concept of dependency injection. The example IS the explanation.
Force the model to reason step by step before acting. For debugging, architecture decisions, or anything multi-step, this cuts logical errors significantly.
The AI produces a plan I can review before it writes a single line of code. Without this step, it would just start building and often pick the wrong storage pattern for a given query.
Use words like MUST, NEVER, ALWAYS, and STRICTLY FORBIDDEN. Avoid weak phrasing like "Please try to," "It is preferred," or "Usually we do."
Here is a comparison from my project. The frontend BUILDPROMPT.md sets boundaries like this:
Telling the AI what NOT to do is often more effective than listing everything it should do.
You need to steer the agent in the correct direction. AI tools have dedicated files for this purpose: AGENTS.md CLAUDE.md Kiro steering files (.kiro/steering/) Kiro skills (.kiro/skills/)
Some of these are loaded every session (steering files), giving the AI persistent rules. Others are loaded on demand (skills), giving the AI specialized knowledge only when it needs it. Both keep your context window lean.
For the frontend, I have an AGENTS.md at the root that covers the full Next.js application:
I also have two Kiro steering files that enforce cross-cutting rules regardless of the task:
