Google AI Studio: Overcoming the LLM's Completion Bias ('Coding Eagerness') Through a Formal Coding Protocol

This article is also published here:

linkedin- pulse/i-wrote-constitution-my-ai-coding-assistant-changed-paul-van-cotthem-l1yke/

The Completion Bias issue

Most AI models, through their Core System Instructions, have “Completion Bias”, an eagerness to immediately generate code and make changes, even when the user hasn’t fully agreed to the approach or understood what will change.

This eagerness to help by coding assistants can be a challenge for the developer who desires a more granular level of control over the coding process.

In my custom system instructions, I’ve set up a detailed “Rules of Engagement between Code Assistant and Code User” that fosters a productive back-and-forth with the model.

This framework channels the model’s built-in urge to code through a required approval step, turning it into a strength. It’s like working with a contractor who must submit a change order before making any edits.

Acting as a “braking system,” the protocol enforces a two-step process: propose first, then only code after explicit approval, preventing the model from rushing into implementation.

Perfecting my protocol took countless iterations and meticulous fine-tuning, where every word truly mattered. Now, it works quite smoothly, with the coding assistant respecting protocol about 95% of the time.


Teaching Your AI Assistant to Wait for Permission

What I learned from months of building a governance protocol for AI-assisted coding


There’s a moment that every developer working with AI assistants knows well. You describe a problem, maybe attach some code, and before you’ve finished explaining what you actually want, the AI has already generated three hundred lines of implementation. It’s helpful, in the way that a golden retriever knocking you over with enthusiasm is helpful. The intent is good. The execution is chaos.

I spent several months solving this problem, not by switching tools or lowering my expectations, but by writing what I’ve come to call a governance protocol. It’s a document that sits between me and my AI assistant, defining exactly how we work together. And it changed everything.

This isn’t a technical guide. I’m not going to share the document itself, because the specific rules I need aren’t the rules you need. What I want to share are the principles, the underlying ideas that make such a protocol work. If you’ve ever felt like your AI assistant was a brilliant but unruly collaborator, these ideas might help you too.


The fundamental problem

AI assistants are trained to be helpful. This sounds like a virtue until you realize what “helpful” means in practice: the AI wants to give you something tangible as quickly as possible. When you describe a bug, it wants to fix the bug. When you mention a feature, it wants to build the feature. The gap between “I’m thinking about X” and “here’s a complete implementation of X” is essentially zero.

This creates two problems. First, you lose control over the decision-making process. The AI has already committed to an approach before you’ve had a chance to evaluate alternatives. Second, and more subtly, you lose the ability to think alongside the AI. The conversation becomes reactive, you’re always responding to what the AI has produced, rather than collaboratively exploring what should be produced.

The solution isn’t to make the AI less capable. It’s to introduce structure into the collaboration.


Governance versus technical standards

The first insight that clarified everything for me was the distinction between two types of rules: governance and technical standards.

Governance rules define how decisions get made. Who proposes? Who approves? What counts as agreement? When can implementation begin? These rules are about process, not code. They’re the constitutional layer of your collaboration.

Technical standards define how code gets written. Which patterns are allowed? Which libraries are forbidden? How should errors be handled? These rules are about implementation, and they can be extensive and detailed.

The mistake I made early on was mixing these together. I had one giant document where approval workflows sat next to tech stack conventions which sat next to UI component rules. The AI couldn’t tell which rules were about how we work versus how we code. And frankly, neither could I after a few weeks.

Separating these layers was transformative. The governance section became short and absolute, four or five principles that never bend. The technical section became a reference library the AI could consult when relevant. The AI started treating governance rules as immutable constraints and technical rules as contextual guidance, which is exactly the distinction I needed.


The power of explicit phases

AI assistants exist in a kind of quantum state. They’re simultaneously ready to analyze, plan, and implement. Without explicit guidance, they’ll do all three at once, producing responses that mix observations about your code with proposals for changes with actual implementation, all in a single turn.

The solution is to force the AI into distinct phases, where each phase has one job and one job only.

In my protocol, the AI operates in one of three modes. In the first mode, it can only analyze and respond to questions, no code generation allowed. In the second mode, it can propose changes and explain its reasoning, but still no code. Only in the third mode, after I’ve explicitly approved the proposal, can it actually write code.

The key insight is that transitions between phases must be explicit. The AI doesn’t get to decide when it’s time to move from proposing to implementing. I decide, by giving a specific signal. This sounds bureaucratic, but in practice it’s liberating. I can have long exploratory conversations knowing the AI won’t suddenly produce five hundred lines of code I didn’t ask for. When I’m ready for implementation, I give the signal. Not before.

This also means the AI must declare which phase it’s in. Every response starts with a status indicator. This seems like a small thing, but it creates accountability. If the AI says it’s in proposal mode and then generates code, the contradiction is immediately visible.


Consent as a password

Here’s a specific problem that drove me crazy for weeks: I would say something like “that looks good” or “yes, that makes sense” or “okay, let’s do it”, and the AI would interpret this as permission to generate code. From its perspective, I had agreed. From my perspective, I was just acknowledging that I understood the proposal.

The solution was embarrassingly simple: I defined a password. A specific word that, and only that word, authorizes code generation. If I don’t say the magic word, the AI cannot proceed to implementation, no matter how much I seem to agree.

This feels almost childish when you first implement it. But it works flawlessly. The AI is very good at pattern-matching on explicit rules. Tell it that “APPROVED” means yes and everything else means no, and it will never confuse casual acknowledgment with genuine consent.

The broader principle here is that ambiguity is the enemy. Anywhere you leave room for interpretation, the AI will interpret, and its interpretation will often be “the user probably wants me to be helpful by generating code.” Remove the ambiguity entirely.


Fighting drift with self-declaration

Long conversations create a particular challenge. AI assistants process context in a way that’s fundamentally different from human memory. As a conversation grows, earlier instructions can effectively “fade”, not because the AI forgets them, exactly, but because more recent context becomes more salient. After twenty or thirty exchanges, constraints established at the beginning can start to slip.

I call this drift, and it’s one of the most frustrating failure modes in AI collaboration. You establish clear rules, the AI follows them perfectly for a while, and then gradually, almost imperceptibly, it starts taking shortcuts. It begins generating code without waiting for approval. It stops following the naming conventions you specified. The careful structure erodes.

My solution is something I call the Heartbeat Protocol. The idea is simple: the AI must declare, at the start of every response, which rules it is currently applying. Not just its phase, but the specific constraints it’s operating under. This forces the AI to actively retrieve and acknowledge the rules, rather than passively remembering them.

There’s a second benefit too. When the AI declares it’s following certain rules and then violates them in the same response, the contradiction is immediately obvious. You can point to the declaration and say: you said you were doing X, but you did Y. This gives you a mechanism for correction that’s far more effective than vague complaints about the AI not following instructions.


The art of precise definitions

I’ve learned to treat ambiguous language as a bug, a defect in my protocol that will inevitably cause problems.

Consider the word “change.” If your protocol says the AI needs approval before making changes, what counts as a change? Is fixing a typo a change? Is reformatting code a change? Is adding a comment a change? Without explicit definition, the AI will make its own judgment calls, and those calls will often surprise you.

My protocol now has a definitions section where I establish precisely what key terms mean. A change is any modification to any file, regardless of magnitude. Approval is a specific word, nothing else. The project includes these files and excludes those. Informational requests are questions that can be answered without modifying anything.

This feels pedantic until you realize how much confusion it eliminates. The AI doesn’t have to interpret intent or make judgment calls about categories. Everything is defined in advance. The result is more consistent behavior, and when something does go wrong, you can usually trace it to a definition that needs to be tightened.


Modularity makes everything easier

As my protocol grew, it became unwieldy. I had rules about state management next to rules about authentication next to rules about file naming. The AI struggled to identify which rules applied to any given task.

The solution was to organize technical standards into discrete modules, I call them Skills, though you could call them anything. Each module has a name, a clear purpose, a trigger condition that determines when it activates, and a set of specific instructions.

This modularity has several benefits. First, it makes the protocol easier to maintain. When I need to update my authentication rules, I know exactly where to look. Second, it makes the protocol easier for the AI to navigate. Instead of searching through a wall of text, it can identify which modules are relevant and focus on those. Third, it enables the Heartbeat mechanism I mentioned earlier, the AI can declare which modules it’s applying, creating transparency about what rules are in effect.

The numbering matters too. When I say “apply Skill 7,” the AI knows exactly what I mean. This gives me a shorthand for invoking specific rule sets without having to repeat them.


Show, don’t just tell

AI assistants are remarkably good at pattern-matching. If you show them an example of what you want, they’ll replicate that example far more reliably than if you describe what you want in abstract terms.

My protocol includes a section of reference implementations, canonical examples of how configuration files should look, how components should be structured, how errors should be handled. These aren’t explanations of principles; they’re concrete artifacts the AI can copy and adapt.

This has been especially valuable for consistency. When ten different parts of my codebase need to handle errors the same way, pointing to a reference implementation is far more effective than describing the error handling approach in prose.


The forbidden list

Positive instructions tell the AI what to do. Negative instructions tell it what not to do. Both are necessary, but I’ve found that negative instructions are often more effective for preventing specific problems.

My protocol includes an explicit list of forbidden patterns, things the AI must never do under any circumstances. No generating code without approval. No using certain type declarations. No importing from unauthorized sources. No mixing certain concerns.

The forbidden list serves as a final check. Even if the AI somehow misinterprets a positive instruction, the forbidden list acts as a guardrail. It can’t do the thing I’ve explicitly prohibited, regardless of how it interprets everything else.


Beginning with a handshake

Before any real work begins, I require the AI to acknowledge that it has read and understood the protocol. This handshake serves several purposes.

First, it confirms that the protocol is actually in context. AI assistants can have instructions attached in various ways, and sometimes things go wrong. The handshake verifies that the AI can see the protocol and is ready to follow it.

Second, it creates a clean starting point. Whatever happened in previous conversations, whatever assumptions the AI might have been building up, the handshake resets everything. We’re starting fresh, with explicit agreement on the terms of engagement.

Third, it prevents the AI from immediately diving into attached materials. Without a handshake requirement, the AI might see code I’ve attached and start analyzing it before I’ve explained what I want. The handshake says: ignore everything else in this message, just confirm you understand the rules, and wait for my next instruction.


The protocol is never finished

My most important realization is that a governance protocol is a living document. The first version will have gaps. Things you thought were clear will turn out to be ambiguous. Scenarios you didn’t anticipate will arise. The AI will find creative interpretations you never imagined.

This isn’t failure; it’s the process. Every time the AI does something unexpected, that’s information. It’s revealing a weakness in your protocol — a rule that’s too vague, an edge case you didn’t consider, a contradiction between two principles.

Version your protocol. When something goes wrong, update the document before simply correcting the AI. If you only correct the AI, you’ll have to correct it again the next time the same situation arises. If you update the protocol, the problem is solved permanently.

I’m on version 3.3 of my protocol now. The journey from version 1.0 to here involved dozens of refinements, most of them prompted by unexpected AI behavior. Each refinement made the collaboration smoother. The protocol I have now is qualitatively different from where I started — not because I had a grand vision, but because I kept fixing what didn’t work.


What you actually get

When people hear about governance protocols, they sometimes worry that structure will make AI collaboration feel bureaucratic or slow. In my experience, the opposite is true.

With a good protocol, I spend less time correcting mistakes. I spend less time re-explaining constraints. I spend less time reviewing code that went in the wrong direction. The AI and I have a shared understanding of how we work, and that understanding makes everything faster.

More importantly, I can trust the AI in a way I couldn’t before. When it proposes a change, I know it has actually thought through the proposal rather than just generating the first thing that came to mind. When I approve implementation, I know exactly what I’m approving. When something goes wrong, I have a clear framework for diagnosing why.

The goal isn’t to constrain the AI, it’s to channel it. A river without banks is a swamp. A river with banks is a powerful, directed force. Your governance protocol is the banks that let the AI’s capabilities flow where you need them to go.


Getting started

If you’ve read this far and you’re thinking about writing your own protocol, here’s my advice: start small. Don’t try to anticipate every scenario. Write the minimum rules you need to establish the basic workflow, phases, consent mechanism, a few critical technical standards.

Then use it. Pay attention to what goes wrong. Update the protocol. Use it again.

The protocol you end up with won’t look like mine, because your projects aren’t my projects and your preferences aren’t my preferences. But the underlying principles — separation of concerns, explicit phases, unambiguous consent, self-declaration, precise definitions, modularity, examples, forbidden lists, handshakes, and continuous iteration — these principles apply regardless of what you’re building.

Your AI assistant wants to be helpful. Your job is to define what helpful actually means.