



Prompt Engineering · Python · AI Code Generation
I’ve run roughly 400 code-generation sessions across Claude, GPT-4o, and Gemini 2.5 over the past 14 months. What separates a prompt that produces working Python immediately from one that needs six back-and-forths isn’t creativity — it’s structure. This guide shows exactly what that structure looks like.
TL;DR — What You Need to Know in 2 Minutes
- The real problem: Vague prompts generate vague Python. “Write a web scraper” produces unusable boilerplate; a structured prompt specifying stack, error handling, and output format produces near-production code.
- Key finding: The CRTSE framework (Context → Role → Task → Standards → Examples) consistently outperforms unstructured prompting in both correctness and security — supported by a 2025 FORGE benchmark study on 1,080 GPT-4o samples.
- Best technique for security-sensitive code: Recursive Critiques Improvement (RCI). Ask the model to generate, then self-critique, then regenerate.
- Honest expectation: Even well-prompted AI generates Python with security issues about 30% of the time in complex scenarios. Human review is not optional.
- Next step: Start with the six prompt templates in §4. Adapt one to your actual task before reading further.
Most developers who are frustrated with AI-generated Python are blaming the wrong thing. The model isn’t the problem — the instruction is. Established
Think about what happens when a junior developer gets an ambiguous ticket. They produce something that technically runs but misses the actual requirement by a mile. AI behaves identically. Augment Code’s enterprise prompt guide (Jan 2026) puts it this way: think of the model as a very fast junior developer who knows syntax but doesn’t understand context. You wouldn’t hand a junior a two-word task description and expect production code.
The productivity gains above are real, but they depend heavily on prompt quality. My own experience matches: the sessions where I spent 90 seconds writing a careful prompt produced working code ~78% of the time on the first response. When I rushed with a one-liner, that dropped to roughly 30–35% — meaning I spent more total time iterating than if I’d just written the code myself.
Published on DEV Community in March 2026, CRTSE has become the de facto structure for developer prompts. It stands for Context, Role, Task, Standards, Examples. The sequence matters — role before task shifts the model toward higher-quality output patterns without being roleplay fluff.
Fig 1 — CRTSE Prompt Architecture
Recursive Critiques Improvement is slower but materially better for sensitive code. A 2025 FORGE study benchmarking prompt techniques across 1,080 GPT-4o-generated code samples found RCI outperformed zero-shot and few-shot approaches specifically for reducing Common Weakness Enumeration (CWE) vulnerabilities in Python. The method: generate → critique → regenerate. You can wire this into a single prompt or as a two-step chain.
The difference between a prompt that works and one that wastes 20 minutes is almost always one of six missing components. Here’s what every serious Python prompt needs, with notes on what happens when you skip each one.
| Component | Example | What breaks without it |
|---|---|---|
| Python version + runtime | Python 3.12, runs on AWS Lambda | Gets deprecated syntax, wrong async patterns |
| Exact library stack | httpx 0.27, pydantic v2, boto3 | Mixes incompatible APIs, uses wrong method signatures |
| Input/output contract | Takes a list of URLs, returns {url: status_code} | Produces code with wrong return shape |
| Error handling scope | Catch network timeouts, raise custom exceptions | Silently swallows errors or crashes on edge cases |
| Negative constraints | No global state, no print() for logging | Gets the most common “bad” pattern for the task |
| Output format | Single module, no classes, type-annotated | Delivers an over-engineered class hierarchy nobody asked for |
Negative constraints deserve extra attention. Telling the model what not to do consistently produces better output than only describing what you want. This feels counterintuitive, but it maps to how the model samples: without constraints, it defaults to the most statistically common pattern for the task, which is often a textbook example that doesn’t match production requirements.
These are real templates from my workflow, edited for clarity. Placeholders shown in [brackets]. They’re not magic — you still need to adapt them to your stack and requirements.
Act as a senior Python data engineer. Context: I have a [CSV / Parquet / JSON] file at [path/S3 URI] with the schema [describe columns and types]. Task: Write a function that reads this file, filters rows where [condition], transforms [column] by [operation], and writes the result to [output destination]. Standards: - Python 3.12, pandas 2.x or polars if faster - All IO wrapped in try/except with specific exception types - Logging via structlog, not print() - Type annotations on all function signatures - No global variables Constraints: Do NOT use pd.read_csv with default dtypes — specify dtype explicitly. Output: A single .py module, no class, just functions. Include a __main__ block for CLI testing.
You are a backend engineer who cares about security and performance.
Context: I'm adding a [POST/GET] /[route] endpoint to an existing FastAPI app. Auth is handled by a middleware already in place (Bearer JWT). Database is PostgreSQL via asyncpg.
Task: Write the endpoint that:
1. Validates incoming JSON against [describe shape or paste Pydantic model]
2. Queries [describe query]
3. Returns [describe response shape]
4. Returns HTTP 422 on validation failure, 404 if record missing, 500 with generic message on DB error (don't leak internals)
Standards:
- Async throughout
- Pydantic v2 models, no dict access
- SQL queries parameterized — never f-strings in queries
- No hardcoded credentials anywhere
Output: The route file only. Assume app = FastAPI() exists. No boilerplate setup.
Act as a Python scraping specialist. Context: I need to extract [describe data] from [URL pattern]. The site uses [static HTML / JavaScript rendering — specify]. I'm running this on a server, not a local machine. Task: Write a scraper that: - Fetches [N] pages - Parses [specific fields] using CSS selectors or XPath - Respects robots.txt - Implements retry with exponential backoff (max 3 attempts) - Writes output to [CSV / SQLite / JSONL] Standards: - Use httpx + BeautifulSoup for static, or playwright for JS rendering - Randomize user-agent and add 1–3s delay between requests - Python 3.12 Constraints: No Scrapy unless I ask. No selenium. Output: Runnable script, commented, with a .env template for any config values.
I have a Python function that's failing. Here it is: [paste function] The error is: [paste full traceback] Expected behavior: [describe what it should do] Actual behavior: [describe what's happening] Do not rewrite the function from scratch. Identify the root cause, explain it in one sentence, then show the minimal diff needed to fix it. If there are related bugs I should know about, list them separately after the fix.
Unit tests
Write pytest tests for this function: [paste function] Requirements: - Cover: happy path, empty input, None input, boundary values, and at least one edge case you identify that I haven't mentioned - Use pytest.mark.parametrize for related cases - Mock any external calls with pytest-mock - No test should take >200ms (add @pytest.mark.timeout if needed) - Do NOT test implementation details — only observable behavior Return just the test file. No explanation unless a test choice is non-obvious.
Code review / refactor
Act as a senior Python engineer doing a code review. Be critical but specific. Here's the function to review: [paste code] Review for: 1. Correctness (bugs, edge cases) 2. Performance (obvious inefficiencies) 3. Readability (naming, structure) 4. Security (if this function handles user input or external data) Format: For each issue, write [SEVERITY: critical/major/minor], [location: line X], [problem], [fix]. After the list, show the refactored version. Limit: flag the 5 most important issues only. I don't need nitpicks.
5. Chain Prompting for Complex Codebases
Single-prompt code generation works well for isolated functions. Once you’re touching multiple files — say, adding a feature that requires a DB migration, a new API route, and a frontend component — single prompts start breaking down. The model loses the plot around message 8–10 in a complex context. Probable
The pattern that’s working for teams in 2026: describe one entire feature, get a plan, approve the plan, then execute file by file. Skillify’s 2026 AI Python tool roundup notes that tools like Claude Code and Windsurf allow prompts like “Create a new API endpoint in routes.py, define the Pydantic model in schemas.py, and generate a migration script” — turning the AI into an execution partner rather than a suggestion engine.
Fig 2 — Chain Prompting for Multi-File Tasks
The critical step people skip is step 2. Don’t let the model jump straight to writing code from a feature description. Ask it to output a plan — which files it will create, what each function signature looks like, what the data flow is. Reviewing that costs 3 minutes and catches 80% of architectural mistakes before any code exists.
6. Security: The Inconvenient Reality
I want to be direct about something that gets glossed over in most AI coding guides. Established
A 2025 study benchmarking prompt engineering techniques for secure code generation (FORGE/IEEE) found that roughly 32.8% of Python code snippets generated by Copilot and marked as AI-generated in GitHub projects contained security issues. A separate analysis by Pearce et al. found around 40% of Copilot completions in their CWE-scenario benchmark were vulnerable.
Those numbers aren’t a reason to stop using AI for Python. They’re a reason to review. The same FORGE study found that RCI prompting meaningfully reduced vulnerability rates — but didn’t eliminate them. The practical implication: AI code generation and human security review aren’t alternatives. They’re complementary.
7. What Could Be Wrong
- Library version drift. Prompts that specify library versions will produce correct code today and broken code in 18 months when APIs change. The model’s training data skews toward older library versions — always check against current docs.
- The more complex the prompt, the more the model hallucinates. I’ve seen well-structured 12-component prompts produce code that invents nonexistent library methods. Length isn’t the same as quality.
- RCI doesn’t work reliably on all models. It performs well on Claude 3.5+ and GPT-4o. On smaller or older models, the self-critique step often produces a re-explanation of the problem rather than an actual fix.
- This guide is based on ~400 sessions, mostly backend Python. I haven’t systematically tested ML/data science workflows, embedded Python, or CPython C extension code. Those are different animals.
- Prompting well is not a substitute for understanding the code. If you can’t read the output critically, you can’t trust it. AI raises the floor for people who understand Python; it doesn’t substitute for understanding.
8. Benchmarks in Context
SWE-bench Verified has become the standard for measuring AI code generation capability. Established
| Model / Tool | SWE-bench Verified | Date | Source |
|---|---|---|---|
| Claude Opus 4.6 (Claude Code) | 80.8% | Q1 2026 | Tech-Insider |
| Claude Code (standalone, 2025) | 72.5% | 2025 | Codegen.com |
| GPT-4 baseline (2024) | ~20% | 2024 | CodeToDeploy |
One caution here: SWE-bench tests multi-file edits against real GitHub issues. It’s a good benchmark for agentic tools. For single-function generation — which is how most developers actually use AI — the relevant metric is closer to HumanEval pass@1. GPT-4o and Claude 3.5/4 are both above 85% on HumanEval for straightforward Python functions. SWE-bench and HumanEval are measuring different things; treat them as complementary, not competing. Probable
FAQ
Which AI model is best for Python code generation in 2026?
For agentic, multi-file tasks: Claude Code (Opus 4.6, 80.8% on SWE-bench). For inline autocomplete and boilerplate: GitHub Copilot remains faster at ~28 seconds to working code for routine tasks vs ~41 seconds for Claude Code. For free or low-cost: GPT-4o mini or Gemini 2.0 Flash perform well on self-contained functions. The honest answer is it depends on the task — no single model wins everywhere.
Does the CRTSE framework work with all LLMs?
Yes, but results vary. On reasoning-capable models (Claude 3.5+, GPT-4o, Gemini 2.5 Pro) it produces a clear step-up in output quality. On smaller models it helps structure the response but the underlying capability ceiling still applies. Don’t expect CRTSE to turn a 7B model into Claude Opus.
How long should a Python prompt be?
Long enough to cover the six components in §3, short enough to stay focused. In practice, 100–300 words is the sweet spot for a single function. Longer than that and you risk context dilution — the model starts weighting earlier instructions less. For complex multi-file tasks, use chain prompting instead of a single mega-prompt.
Is AI-generated Python safe to deploy directly?
No, not for anything security-sensitive. The FORGE 2025 benchmark found meaningful vulnerability rates even with well-structured prompts. RCI helps but doesn’t eliminate the risk. Treat AI-generated code like code from an external contributor: it must pass your code review and CI/CD security checks before production.
What’s the fastest way to go from a vague idea to working Python?
Use the ETL or API template from §4, substitute your specifics, and add one RCI instruction at the end. If the output needs more than two follow-up prompts to get right, stop and rewrite the original prompt with more specificity. Iteration feels productive but is usually slower than a better initial prompt.
Can AI handle Python version migrations (e.g., 3.9 → 3.12)?
Reasonably well for syntax changes (walrus operator, match statements, structural pattern matching). Less reliably for library API changes where the model’s training data is mixed. I’ve run ~30 such migrations — the model catches obvious deprecations but misses subtle behavioral changes in stdlib modules. Always run your test suite after AI-assisted version migration. Probable
Do these techniques work in IDEs (VS Code, PyCharm) or only in chat interfaces?
The CRTSE framework and template approach work in chat interfaces (Claude.ai, ChatGPT) and in AI-native IDEs (Cursor, Windsurf, Claude Code terminal). In inline autocomplete tools like standard Copilot, you’re limited to shorter context — focus on the negative constraints and output format components, which have the highest per-word impact on output quality.
Verdict
The gap between a developer who prompts well and one who doesn’t is measurable in minutes per task — and it compounds across a week, a sprint, a year. None of this is especially complicated. The CRTSE structure, six prompt components, the RCI self-review instruction: that’s a morning’s worth of practice and you’ll have internalized it. What takes longer is developing the judgment to review AI output critically.
AI doesn’t replace Python knowledge. It amplifies it. The developers I see getting the most out of these tools are the ones who read the generated code before running it — not because they distrust AI, but because they’re curious enough to learn from it.
More from BestPrompt.art
- The Complete Prompt Engineering Guide — Frameworks, Techniques, Examples
- ChatGPT Prompts for Developers: 60+ Templates by Stack
- Claude Prompts That Work: Tested Patterns for Technical Writing
- AI Code Review Prompts — Find Bugs Before They Find You
- HR AI Prompts: Recruiting, Screening, and Onboarding Templates
- Write for BestPrompt.art — Guest Contributor Guidelines
How to Generate Code With AI Prompts — Beginner to Pro
Mastering AI Code Generation: Expert Prompt Engineering Strategies for 2025
The Prompt Engineering Stack —The Mistake Costing You Results Every Single Month
The Secret Prompt Structure That Gets the Best Result (2025)
How to Write Prompts for ChatGPT Like a Pro




