LLM Coding Best Practices
Principles and practices for improving the quality of LLM-generated code, particularly addressing common pitfalls identified by andrej-karpathy and formalized in projects like the karpathy-inspired-claude-code-guidelines.
Common LLM Coding Pitfalls
Assumption Problems
- Making wrong assumptions without verification
- Running with interpretations silently without checking
- Not managing confusion or seeking clarifications
- Failing to surface inconsistencies or present tradeoffs
Overcomplication Issues
- Creating bloated abstractions unnecessarily
- Implementing complex solutions when simple ones suffice
- Adding speculative features beyond requirements
- Building "flexible" or "configurable" systems not requested
Surgical Precision Problems
- Changing/removing code orthogonal to the task
- "Improving" adjacent code that wasn't broken
- Touching more than necessary for the requested change
- Not understanding the ripple effects of modifications
Best Practice Principles
1. Think Before Coding
- State assumptions explicitly - Don't guess, ask when uncertain
- Present multiple interpretations - Don't pick silently when ambiguous
- Push back constructively - Suggest simpler approaches when they exist
- Stop when confused - Name what's unclear and request clarification
2. Simplicity First
- Minimum viable solution - No features beyond what was asked
- No speculative abstractions - Avoid single-use abstractions
- Senior engineer test - Would they call this overcomplicated?
- Line count reality check - If 200 lines could be 50, rewrite
3. Surgical Changes
- Minimal scope - Touch only what you must change
- Style consistency - Match existing patterns even if different from preference
- Clean up responsibly - Only remove code orphaned by your changes
- Traceability - Every changed line should trace to the user's request
4. Goal-Driven Execution
- Define success criteria - Transform imperatives into verifiable goals
- Test-driven approach - Write tests first when applicable
- Verification loops - State plans with checkpoints
- Leverage LLM strengths - Use their ability to loop until goals are met
Implementation Strategies
Success Criteria Examples
Instead of: "Add validation" Transform to: "Write tests for invalid inputs, then make them pass"
Instead of: "Fix the bug"
Transform to: "Write a test that reproduces it, then make it pass"
Instead of: "Refactor X" Transform to: "Ensure tests pass before and after"
Multi-Step Planning
For complex tasks, state brief plans:
- [Step] → verify: [check]
- [Step] → verify: [check]
- [Step] → verify: [check]
Quality Indicators
You know these practices are working when you see:
- Fewer unnecessary changes in diffs
- Fewer rewrites due to overcomplication
- Clarifying questions before implementation (not after mistakes)
- Clean, minimal PRs without drive-by improvements
Key Insight
From andrej-karpathy: "LLMs are exceptionally good at looping until they meet specific goals... Don't tell it what to do, give it success criteria and watch it go."
This transforms the interaction model from imperative instructions to declarative goals with verification.
Trade-offs
These practices bias toward caution over speed. For trivial tasks (typo fixes, obvious one-liners), use judgment - not every change needs full rigor. The goal is reducing costly mistakes on non-trivial work.
See also
- karpathy-inspired-claude-code-guidelines
- andrej-karpathy
- Code Quality
- ai-assisted-development