// PROMPT ENGINEERING GUIDE

AI Dev Prompting

Best practices to get production-quality code from AI assistants — especially Gemini. Built for Android/Kotlin developers.

#Gemini #Android #Kotlin #PromptEngineering
// 01 Role & Context
01

Assign a role before anything else

Start every prompt by telling the AI who it is. A well-defined role activates the right "mode" — a senior engineer produces different output than a generic assistant. Be specific: include seniority, stack, and project context.

✅ Example
You are a senior Android engineer with expertise in Kotlin, Jetpack Compose, Room, and Hilt DI. You are maintaining a production app called SafePlan. You write clean, minimal, well-structured code and never introduce regressions.
02

Provide full project context upfront

AI has no memory of previous sessions. At the start of any new conversation, paste your architecture summary, tech stack, file tree, and key constraints. This prevents the AI from suggesting incompatible patterns or libraries.

✅ Example
Project: SafePlan (Android, Kotlin, minSdk 28) Architecture: MVVM + Repository + Hilt + Room + Coroutines/Flow UI: Jetpack Compose + Material 3 + Navigation-Compose Key constraints: offline-first, no cloud sync, all strings localized (EN + FR)
// 02 Output Control
03

Always demand full file output

Never accept partial files or "here's the relevant section" snippets. Partial output forces you to manually merge code, which causes bugs. Explicitly require complete files every time.

✅ Template to include in every prompt
Always output the COMPLETE file content, from first line to last. Never truncate. Never use "// ... rest of file unchanged". Begin every file with: FILE: <relative/path/from/project/root>
✅ Do
Output full GoBagViewModel.kt from line 1 to end, no omissions.
❌ Don't
// ... existing code ...
// Only showing changed function
04

Use a consistent file header format

Require a standardized prefix on every file so you can copy-paste directly into your project without hunting for the path.

✅ Template
FILE: app/src/main/java/com/safeplan/ui/gobag/GoBagViewModel.kt // ── full file content below ──
// 03 Change Management
05

Require a "Files Changed" log after every reply

Ask the AI to always end its reply with a structured list of every file it modified and a one-line reason. This makes code review fast and helps you spot unintended changes immediately.

✅ Template to include in every prompt
At the end of every reply, print: ## Files Changed | File | Reason | |------|--------| | path/to/File.kt | One-line justification |
06

Number every request for easy follow-up

Long conversations cause the AI to lose track of which request it is addressing. Ask it to print a numbered request header at the start of every reply. This lets you reference previous requests precisely ("go back to Request #3") without ambiguity.

✅ Template
At the beginning of every reply, print: ## Request #[N] — [one-line summary of what was asked] Increment N for every new request in this conversation.
07

Ask for a Scope summary before any code

Require the AI to print what it understood and what it will NOT touch before writing a single line of code. This catches misunderstandings early and prevents the AI from "helping" by refactoring things you didn't ask for.

✅ Template
Before writing any code, print: ## Scope - What I will change: [list] - What I will NOT touch: [list] Wait for confirmation if the scope is ambiguous.
// 04 Safety & Quality
08

Enforce the minimal diff principle

AI models love to "improve" code beyond what was asked, introducing style changes, renames, and refactors that break things. Explicitly forbid this. Make it a standing rule in every prompt.

✅ Template
RULE — Minimal diff: Only modify code strictly necessary to implement the requested change. Never refactor, rename, reformat, or touch code outside the scope of this request. If you feel a refactor would help, mention it as a comment — do NOT apply it.
✅ Do
Fix only the broken DatePicker state hoisting in AddItemScreen.kt
❌ Don't
I also improved the ViewModel and moved the repository layer to be cleaner
09

Demand regression checks and simulated build

Ask the AI to mentally "compile" its output before presenting it: verify imports, check function signatures match their call sites, confirm navigation routes exist, and ensure no existing feature is broken.

✅ Template
Before outputting any file, perform a simulated build check: 1. Verify all Kotlin imports are correct and present 2. Confirm all string resources exist in both EN and FR 3. Confirm all navigation routes match the NavGraph 4. Confirm Room version is consistent (no missing migrations) 5. Confirm no existing feature is broken by this change If you find a regression risk, warn explicitly BEFORE the code.
// 05 Structure & Decomposition
10

Break large requests into numbered items

Never dump a wall of text. Structure your requests as a numbered list of independent tasks. This forces both you and the AI to think about each change atomically, and lets you skip or reorder items easily.

✅ Example
Implement the following changes: 1. HomeScreen: Add minimap to meeting point cards 2. Go-Bag: Fix broken category dropdown state 3. Settings: Add edit button to contact rows Process items 1 and 2 first. Wait for confirmation before item 3.
11

Process one group at a time

Large context windows are still limited. Asking for too much at once causes the AI to rush, truncate, or hallucinate. Ask it to process one logical group then pause — giving you control checkpoints.

✅ Template
Process one logical group at a time. After completing each group, stop and wait for my "continue" or "fix X" before proceeding. Do not attempt all items in one reply unless I explicitly say "do all".
12

Handle output limits gracefully

If the AI hits its output limit mid-file, it will truncate silently — producing corrupt code. Tell it exactly how to behave when it runs out of space.

✅ Template
If you reach your output limit before finishing: - Stop at the end of the last COMPLETE file (never mid-file) - Print exactly: "PAUSED — next file: [path/to/NextFile.kt]" - Wait for me to say "continue" before resuming
// 06 Gemini-Specific Tips
13

Use Gemini 2.0 Pro or 2.5 Pro for code generation

Gemini Flash is fast but cuts corners on code quality. For full Android project generation, always use Gemini 2.0 Pro or 2.5 Pro. The difference in code coherence across a multi-file project is significant.

✅ Gemini 2.5 Pro ✅ Gemini 2.0 Pro ⚠️ Flash (avoid for full projects)
14

Paste the file tree at the start of follow-up sessions

Gemini has no memory between sessions. At the start of a follow-up conversation, always paste the current file tree and a 5-line architecture summary. Without this, it will invent a different architecture and produce incompatible code.

✅ Template for follow-up sessions
Continuing work on SafePlan. Current file tree: app/src/main/java/com/safeplan/ ├── data/ │ ├── db/AppDatabase.kt │ ├── repository/GoBagRepository.kt ├── ui/ │ ├── home/HomeScreen.kt │ └── gobag/GoBagScreen.kt Do not change the architecture or package structure.
15

Specify exact library versions

Gemini will pick library versions it was trained on, which may be outdated or incompatible with your project. Always specify exact versions for critical dependencies in your prompt.

✅ Example
Use these exact versions (do not change them): - Room: 2.6.1 - Hilt: 2.51.1 - Compose BOM: 2024.09.00 - WorkManager: 2.9.1 - Coil: 2.7.0 - Maps Compose: 4.3.3
16

Ask for acceptance criteria, not just implementation

Instead of just saying "implement X," define what success looks like. This forces the AI to think about edge cases and produce more complete, testable code.

✅ Example
Implement vault password change. Acceptance criteria: - Dialog shows current password, new password, confirm fields - Wrong current password → show error, do not save - New password hashed with PBKDF2 + random salt → EncryptedSharedPreferences - On success: dialog closes, snackbar shows "Password updated" (localized) - On cancel: no changes to stored password
17

Never say "make it better" or "improve this"

Vague improvement requests are a regression machine. The AI will rewrite things you didn't want changed. Always describe exactly what the current problem is and exactly what the desired behavior should be.

✅ Do
The category DropdownMenu in AddItemScreen.kt does not respond to taps. Fix the state hoisting: move selected category into ViewModel StateFlow, not local remember.
❌ Don't
The Go-Bag screen needs improvement. Make it better and fix the bugs.
18

Include localization rules as a standing constraint

If your app is multilingual, add localization as a non-negotiable rule once and reference it in every follow-up. Without this, the AI will hardcode strings the moment you stop watching.

✅ Template
STANDING RULE — Localization: Every new user-facing string must be added to: - res/values/strings.xml (English) - res/values-fr/strings.xml (French) Zero hardcoded strings in Kotlin or Compose. Use plurals (<plurals>) where counts are involved.
// CHEATSHEET

Quick Reference Cheatsheet

Copy this block into every new Gemini session for instant best-practice enforcement.

🎭Start with a role: "You are a senior Android engineer…"
🗂️Paste file tree + stack at start of each session
📄Require full file output with FILE: prefix
📋Require Files Changed table at end of reply
🔢Number each request: Request #N at reply start
🔍Require Scope section before any code
✂️Enforce minimal diff: no unrequested changes
🛡️Require simulated build check before output
Handle output limits: stop cleanly, state next file
🏷️Specify exact library versions
Define acceptance criteria per feature
🌍Set localization as a standing rule
⚡ Master prompt header — copy into every session
You are a senior Android engineer maintaining [PROJECT NAME]. Stack: [your stack here] Architecture: [your architecture here] STANDING RULES (apply to every reply): 1. Minimal diff: only change code strictly needed. No unrequested refactors. 2. Full files: always output complete files with FILE: <path> header. 3. Files Changed: end every reply with a table of changed files + reason. 4. Request tracking: start every reply with "## Request #N — [summary]" 5. Scope first: before any code, print what you WILL and WON'T touch. 6. Simulated build: verify imports, routes, string resources, Room version. 7. No regressions: warn explicitly if a change risks breaking existing features. 8. Localization: all new strings in values/strings.xml AND values-fr/strings.xml. 9. Output limits: if you hit the limit, stop at end of complete file, print "PAUSED — next file: [path]" and wait for "continue".