Gemini 2.5 Prompting Guide for Coding Tasks
Reference document for writing effective prompts when delegating to Gemini 2.5 Pro or Flash. Covers model selection, thinking mode, context window use, structured output, tool use, and antipatterns.
Model Selection
Choose based on task complexity and cost tolerance:
| Model | Use when | Context | Thinking |
|---|---|---|---|
gemini-2.5-pro | Complex architecture, cross-file refactors, SWE-bench-style tasks, novel algorithm design | 1M tokens | Always on (128–32,768 tokens, default dynamic) |
gemini-2.5-flash | Production tasks with good cost/quality balance: reviews, summaries, data extraction, chat | 1M tokens | Dynamic by default (0–24,576 tokens, can disable) |
gemini-2.5-flash-lite | High-volume, low-cost: classification, routing, simple translation, triage | 1M tokens | Off by default (512–24,576 tokens) |
Decision rule: Default to Flash for most coding assistance. Switch to Pro only when Flash produces shallow or incorrect reasoning on complex multi-step problems. Use Flash-Lite only when cost is the primary constraint and quality requirements are low.
SWE-bench data point: Gemini 2.5 Pro scores ~63.8% on SWE-bench Verified with a custom agent setup — comparable to frontier models for real-world GitHub issue resolution.
Thinking Mode (Budget Tokens)
Gemini 2.5 models have an internal reasoning phase ("thinking") before responding. You control how many tokens it can spend reasoning.
How to configure (Gemini API)
# Python SDK
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Refactor this authentication module...",
config=types.GenerateContentConfig(
thinking_config=types.ThinkingConfig(
thinking_budget=8192 # or -1 for dynamic, or 0 to disable
)
)
)
Token budget ranges
| Model | Min | Max | Default |
|---|---|---|---|
| gemini-2.5-pro | 128 | 32,768 | Dynamic (cannot disable) |
| gemini-2.5-flash | 0 | 24,576 | Dynamic (-1) |
| gemini-2.5-flash-lite | 512 | 24,576 | 0 (disabled) |
When to use each level
Disable (budget=0) or minimal:
- Simple lookups: "What does this function return?"
- Mechanical transforms: format conversion, renaming, boilerplate
- Single-file edits with clear instructions
- When latency is critical
Medium (512–4096 tokens):
- Standard code review requests
- "Explain why this is slow"
- Bug diagnosis with provided stack trace
- Multi-file but clearly scoped changes
High (8192–32,768 tokens) or dynamic (-1):
- Complex algorithm design or optimization
- Architectural planning across a full codebase
- Debugging non-obvious failures with multiple possible causes
- Code migration or refactoring with implicit constraints
- Writing Python web apps with auth ("verified code generation")
Cost warning: High thinking budgets cost significantly more. One practitioner reported auto-mode costing ~37x more than flash-only mode for identical workloads ($6k vs $163/month at scale). Match thinking budget to actual task complexity.
Prompt Structure for Coding Tasks
The canonical structure
[Role/persona — optional but effective]
[Context: what exists, what matters]
[Task: specific, scoped, explicit]
[Constraints: what NOT to do, style rules]
[Output format: how to structure the response]
Role setting works well with Gemini
Gemini responds well to role framing. Set it in the system prompt or at the start:
You are a senior Go engineer specializing in performance-critical systems.
You follow idiomatic Go, prefer composition over inheritance, and always
handle errors explicitly rather than panicking.
Task decomposition
Break large tasks into sequential prompts. Do not cram multi-phase work into one prompt.
Bad:
Refactor the authentication module, add rate limiting, write tests,
and update the API documentation.
Good (4 separate prompts):
- "Refactor the auth module. Preserve the existing interface exactly."
- "Add rate limiting middleware. Wire it after the auth middleware."
- "Write unit tests for the rate limiter. Cover the burst and sustained rate cases."
- "Update the API docs for the two new rate-limiting headers."
Explicit negation — critical for Gemini
Gemini's most common failure mode: "I Know Better" syndrome — it fixes unrelated code you didn't ask it to touch. Always state what NOT to do:
Bad:
Refactor this function to be more efficient.
Good:
Refactor this function for efficiency.
DO NOT change the function signature.
DO NOT modify the input validation logic.
DO NOT add or remove comments.
DO NOT change error return types.
Architecture-first, then implementation
For complex features, establish the design before writing code:
Before writing any code, describe the architecture for adding webhook
support to this service. Cover: data model changes, handler design,
retry strategy, and failure modes. I'll confirm the approach before
you implement.
Incremental generation for large features
For anything generating hundreds of lines, do it in stages:
Generate the HTML structure for the dashboard component first.
Stop after the HTML. I'll review it before we proceed to CSS and JS.
Context Window Strategy (1M tokens)
What to include
- All files directly relevant to the task (source, not compiled output)
- Configuration files that affect behavior (tsconfig, pyproject, etc.)
- Interface/type definitions that the code must satisfy
- Existing tests that encode the expected behavior
- The specific error message, stack trace, or failing test output
What to exclude
Aggressively filter before passing a repo:
| Exclude | Reason |
|---|---|
*.csv, *.json data files | No semantic value for code tasks |
*.svg, *.png, static assets | Not code |
*_test.py, test_*.py | Unless understanding tests is the goal |
*.lock, *.sum files | Noise |
node_modules/, .venv/, dist/ | Never include |
| Comments + whitespace | Compress with tools like yek or repomix |
Filtering workflow for large repos:
- Assess token count:
repomix --output-show-line-numbers - Remove irrelevant file types via ignore patterns
- Target subdirectory relevant to the task
- Exclude test directories if not needed
- Strip comments as final step
Practical reality: 1M tokens = ~30,000 lines of code. Most real projects that need full context fit within this after filtering. For repos that genuinely exceed 1M tokens even after filtering, use RAG or chunk by subdirectory.
Query placement in long-context prompts
Always put your question/task AFTER the context, not before.
[All code/documents here]
---
Given the above codebase, identify all places where database connections
are not properly closed on error paths.
Google's official guidance: "the model's performance will be better if you put your query at the end of the prompt."
Multiple-needle limitation
Gemini handles single-query retrieval well (up to 99% accuracy) but performance degrades when searching for multiple independent facts simultaneously. For multi-part questions, ask them sequentially rather than in one prompt.
Context caching (API)
For repeated queries over the same large context (e.g., a full codebase you're asking multiple questions about), use context caching to avoid re-sending the same tokens:
# Cache the codebase context, then query multiple times
cached_content = client.caches.create(
model="gemini-2.5-pro",
contents=[large_codebase_content],
ttl="3600s"
)
# Subsequent queries reuse the cache, costing much less
Context degradation warning
Despite the 1M token window, reliability drops after ~200K tokens in practice. If you notice Gemini forgetting earlier instructions, r