Ai
Getting the Most Out of AI Coding Tools Without Losing Control
September 10, 2026 · 7 min read
Most developers today either already use an AI coding assistant or plan to. That part isn't interesting anymore. What's interesting — and what actually separates teams — is the gap between "asking AI a question" and using it deliberately enough to ship faster without quietly eating your quality and security budget.
As someone managing an engineering team in a regulated fintech environment, I've had to think about this less as a personal productivity hack and more as a team practice. Here's what's actually worked, with concrete examples instead of platitudes.
1. AI is a partner, not a replacement for review
The rule that gets repeated the most is also the one teams break the fastest under deadline pressure: AI-generated code still needs a human in the loop, especially for anything touching money, auth, or user data. "Engineer-in-the-loop" — AI drafts, a human validates — is the only version of this that holds up over time.
Concrete example: in a payments-adjacent codebase, I've seen an AI assistant confidently generate a discount calculation that looked correct, passed a quick glance, and rounded in the wrong direction for exactly one currency edge case. Nobody caught it in the diff because the diff looked like ordinary arithmetic. It only surfaced because a reviewer ran it against a real transaction, not because the code looked wrong. That's the whole argument for review in one incident: AI output that reads as clean is not the same as AI output that is correct.
2. Break the task into stages instead of one big prompt
Developers who've actually gotten good at this stop asking AI to build an entire module in one shot. The workflow that holds up looks more like:
- Ask for an outline of the approach first — no code yet.
- Ask for pseudocode at a level you can actually review.
- Read it, correct the logic, then let it write real code.
- Generate in small, independently testable chunks.
- Integrate and refine by hand.
A concrete before/after: instead of prompting "build the retry logic for our payment webhook handler," a staged version looks like:
Step 1: "Outline the failure modes for a payment webhook handler that must
be idempotent under duplicate delivery. Don't write code yet."
Step 2: "Given that outline, write pseudocode for the retry + backoff logic
only. Flag anywhere you're guessing about our idempotency key strategy."
Step 3: (after I fix the idempotency key assumption) "Now implement just
the retry function in Go, with a table-driven test for each failure mode
from Step 1."
That third prompt is short and precise because the first two did the thinking. Skipping straight to it produces code that's confidently wrong about the one thing you actually needed it to get right.
AI is also increasingly useful as an adversarial tester — asked explicitly to find edge cases the original author didn't think of, rather than just to write the happy-path test.
3. Treat prompts as a team asset, not a personal habit
One shift worth taking seriously: prompts you reuse — for code review, test generation, PR summaries — deserve the same treatment as production code. An owner, a version history, a reviewable change process. Not something retyped from memory in a chat window every time.
A few practices that help:
-
Keep a shared, version-controlled prompt library. A prompt that works well for reviewing Go services shouldn't live only in one engineer's chat history — put it in the repo, in Git, where the rest of the team can reuse and improve it.
-
Separate the layers of information. Don't collapse the product spec (what the feature should do), the instructions (how to do this one task), the runtime context (actual input/data), and the evaluation criteria (how to judge success) into one long paragraph. For example, a code-review prompt should structure as:
## Task Review this diff for correctness bugs only. ## Context This service processes payment reconciliation; a silent off-by-one here means a real money discrepancy, not just a display bug. ## Output format List each finding as: file:line, the bug, and the failing scenario.Mixing all of that into "please review this code for a payment thing, thanks" produces vague, inconsistent results.
-
Ask for explicit reasoning, not just the final answer — a numbered breakdown of steps makes it much faster to spot exactly where the logic went wrong when you need to fix it.
-
Bake validation criteria into the prompt itself — e.g. "don't consider this done until there's a test for the negative case," so quality-checking is part of the workflow, not a separate step someone has to remember to do.
4. Governance is the foundation, not friction
The more AI gets woven into daily workflow, the bigger the operational risk surface: code with subtle security holes, unverified dependencies pulled in because AI suggested them, and — in regulated environments like fintech — the real risk of sensitive code or data being sent to an external tool without anyone deciding that was acceptable. Some organizations restrict cloud-based AI assistants outright for exactly this reason.
Chasing adoption speed without governance produces more code, not necessarily more value — because review delays, newly introduced security gaps, and hidden rework quietly cancel out whatever speed you gained.
What this looks like in practice, from having gone through an ISO 27001 certification process with an engineering org:
- Set explicit rules for what code or data is allowed to go to an external AI tool at all — this needs to be a written policy decision, not an assumption.
- Run the same security scanning on AI-generated code that you'd run on human-written code. Don't grant it a pass because it "looks generated correctly."
- Prefer tools that understand your whole repository's structure over ones that only reason file-by-file — the file-by-file ones get noticeably worse on large, interconnected real-world codebases, which is exactly where the risk is highest.
5. Choose the tool that fits the job, not the loudest one
The AI coding assistant space is crowded — thousands of tools and extensions, most only a couple of years old. A few names consistently hold up in their respective lanes: Claude Code for agentic, terminal-based coding; Cursor for strong tab-completion; GitHub Copilot and Cline as mature, broadly adopted options across team sizes.
What matters more than brand recognition is two boring metrics: token efficiency (how often the tool needs a retry before it gets something right) and how well it understands your whole repository, not just the file open in front of it. Those two things predict real productivity far better than the subscription price does.
6. If your team uses Claude Code: use CLAUDE.md
For teams already on Claude Code, one of the highest-leverage habits is a CLAUDE.md file at the repo root. It's pulled in automatically as context at the start of every session, so it's the right place to document the things you'd otherwise explain to a new AI session (or a new hire) over and over:
- Common bash commands used in the project.
- Core files and important utility functions.
- The team's code style conventions.
- How to run the test suite.
- Repo etiquette — branch naming, merge vs. rebase preferences.
With that context persisted, the team stops re-explaining project structure every session — the AI starts each conversation with a consistent baseline understanding already in place.
Quick checklist
- Break large tasks into stages before asking AI to generate code.
- Always review and test AI-generated code before merging, especially around critical business logic.
- Start collecting the team's frequently used prompts somewhere version-controlled.
- Write down explicit rules for what data/code is allowed to go to external AI tools.
- If you use Claude Code, create and maintain a
CLAUDE.mdin every core repository. - Evaluate tools by repository understanding and token efficiency, not popularity.
Further reading: Anthropic Engineering Blog, Questera, Leanware, SD Times, Faros AI, Augment Code, PromptLayer, and Hexaware.