Ask an AI coding assistant to add a new endpoint and it will confidently invent one. It will pick a naming convention that isn't yours, reach for a validation library your team abandoned two years ago, and skip the error-handling pattern every other file in the repo follows. None of this is a model failure. The assistant did exactly what you asked with the only information it had: the file open in front of it.
Most teams treat this as a prompting problem. They write longer instructions, add more examples to the chat, and hope the next session remembers. It doesn't. The fix isn't a better prompt, it's a codebase the assistant can actually read and understand without you re-explaining it every single time.
Why AI Coding Assistants Guess in the First Place
A human engineer joining your team spends their first two weeks absorbing context they never write down: which folder new features live in, which of your three HTTP client wrappers is the current one, why nobody touches the legacy billing module without a review from a specific person. An AI assistant gets none of that. It sees the files in its context window and nothing else.

Photo by Monstera Production on Pexels
When the assistant can't find an existing pattern, it doesn't ask. It generates the statistically likely version of that pattern based on its training data, which is a blend of every open-source repo it has ever seen. That's why AI-generated code often looks fine in isolation and wrong in context. It's not broken. It's just not yours.
The Files That Actually Change Assistant Behavior
Most of the leading AI coding tools now read a repo-level instructions file automatically before generating anything: a CLAUDE.md, .cursorrules, or equivalent, checked into the repository root. This single file has more influence over output quality than any amount of in-chat prompting, because it's loaded every session instead of typed once and forgotten.
What Belongs in the Instructions File
Keep it short and specific. List the frameworks and versions in use, the one correct way to do common things (which HTTP client, which test runner, which error class to raise), and the things the assistant should never touch without asking, like database migrations or auth logic. Vague guidance like "write clean code" wastes the space. Specific guidance like "use the ApiError class in lib/errors.py for all handler-level failures, never raise bare exceptions" actually changes what gets generated.
API and Schema References
If your assistant is writing code against an internal API or database schema, point it at the source of truth instead of letting it infer field names from memory. A short reference doc, even a generated OpenAPI spec sitting in the repo, cuts down on invented field names and mismatched types dramatically. This matters even more on projects that touch data integration work, where a single guessed field name can silently break a downstream sync.

Photo by Nataliya Vaitkevich on Pexels
Style and Testing Conventions
Linters and formatters do some of this work automatically, and it's worth leaning on them instead of prose. But testing conventions are harder to enforce mechanically. Note which test framework is canonical, where fixtures live, and whether the team expects unit tests, integration tests, or both for new endpoints. An assistant told nothing here will often generate no tests at all, or invent a testing pattern that doesn't match the rest of the suite.

Photo by Atlantic Ambience on Pexels
Naming conventions deserve their own line even when they feel too obvious to write down. If your team calls the input-sanitizing function cleanInput in one file and sanitizePayload in another, the assistant has no way of knowing which is canonical, so it will happily invent a third name the next time it needs one. Pick one, document it, and the drift stops compounding.
What Good Structure Looks Like in Practice
The common thread across teams that get consistently useful output from AI coding assistants isn't a longer instructions file. It's a codebase where the instructions file is short because the codebase itself is consistent. One HTTP client, not three. One error-handling pattern, applied everywhere. A folder structure that maps predictably to feature boundaries instead of growing organically for five years.
If your repo already has that consistency, the instructions file just needs to point to good examples: "follow the pattern in handlers/users.py for new API handlers." If it doesn't, writing the file first can actually surface the inconsistency, since you have to pick one canonical pattern to document. That process alone is often worth more than the file itself.
"The teams that get the most out of AI coding tools aren't the ones with the cleverest prompts, they're the ones whose codebase was already boring and consistent before the assistant ever showed up." - Dennis Traina, founder of 137Foundry
Common Mistakes Teams Make
The most common mistake is writing the instructions file once during a burst of enthusiasm and never updating it. Six months later it references a library the team migrated away from, and the assistant keeps reaching for the old one because that's what the file still says. Treat the file like any other piece of documentation: update it in the same pull request that changes the convention it describes.
The second mistake is making the file too long. A 2,000-word instructions file gets skimmed, by humans and by the token budget the assistant allocates to it. Shorter, more specific rules beat exhaustive ones. If you find yourself writing paragraphs of exceptions and edge cases, that's usually a sign the underlying pattern needs simplifying, not more documentation.
The third mistake is skipping code review on AI-generated changes because "the assistant follows the conventions now." Conventions files reduce guessing, they don't eliminate it, and a reviewer who understands the domain will still catch things the assistant can't reason about, like why a particular edge case matters to a specific customer.
A fourth, quieter mistake is writing the instructions file for an audience of one, usually whoever set it up. If the file assumes context that only the original author has, like an unstated reason a certain module is off-limits, new team members and the assistant both end up guessing anyway. Write the file as though the next reader has never seen the codebase, because for the assistant, that's exactly true every time a new session starts.

Photo by RDNE Stock project on Pexels
It also helps to separate durable rules from temporary ones. "We use PostgreSQL, not MongoDB" is durable. "We're mid-migration off the old billing service, don't add new features to it" is temporary and should have a review date attached, or it will still be in the file two years after the migration finished, quietly confusing every new contributor and every assistant session that reads it.
How to Roll This Out Without Boiling the Ocean
Start with one file at the root of the repo and one clear rule: no invented dependencies. Every library the assistant reaches for should already be in the lockfile, or it asks first. That single rule eliminates a large share of the weirdest output teams complain about.
From there, add rules as you notice repeated mistakes rather than trying to anticipate everything up front. If the assistant keeps putting business logic in route handlers instead of service classes, write that rule down. If it keeps forgetting your team uses Vitest instead of Jest, write that down too. The file should grow from real friction, not from a checklist copied off the internet.
Static analysis tools remain a useful backstop regardless of how good the instructions file gets. A static analysis pass catches the categories of mistakes that slip past both the assistant and a tired reviewer at the end of a sprint, and it doesn't care whether the code was written by a human or generated by a tool like GitHub Copilot or Cursor.
Roll it out to one team or one repository first rather than mandating it company-wide on day one. The rules that work for a frontend team maintaining a design system look nothing like the rules that work for a backend team maintaining a billing pipeline, and a single company-wide file tends to end up too generic to help either one. Let each repo own its own instructions file, and only pull shared rules up to an org-wide file once you've confirmed they actually apply everywhere.
Code Review Still Does the Heavy Lifting
None of this replaces code review. A well-structured codebase with a good instructions file just changes what review is for. Instead of catching wrong library choices and inconsistent error handling, reviewers can focus on whether the logic is actually correct for the business problem, which is the harder and more valuable thing to check anyway.
Teams that treat AI coding assistants as a reason to skip structure end up with the opposite of what they wanted: faster generation of code nobody fully understands. Teams that treat the assistant as a reason to finally document their conventions tend to end up with a cleaner codebase than they had before the tooling arrived, whether or not the assistant gets everything right the first time.
The payoff compounds too. An instructions file written well the first time keeps paying off on every session after that, for every engineer on the team and every assistant they use, whether that's Copilot, Cursor, or whatever tool replaces both of them next year. The format doesn't matter much. The discipline of writing down what used to live only in one engineer's head is the part that actually moves the needle.
If you're evaluating how AI coding tools fit into your team's workflow, or want a second opinion on whether your current setup is helping or quietly creating technical debt, our AI automation team has walked several codebases through exactly this process. You can see the broader scope of what we do on our services page, or read more about the team behind 137Foundry here.