npx skills add https://github.com/arist12/amd-skills --skill clean-code-style源自 Andrej Karpathy 对 LLM 编码常见问题的观察,旨在减少常见 LLM 编码错误的行为准则。
权衡取舍: 这些准则偏向谨慎而非速度。对于简单任务,请自行判断。
不要假设。不要隐藏困惑。明确权衡取舍。
在实现之前:
用户:"添加一个导出用户数据的功能"
糟糕——默默假设了范围、格式、字段和文件位置:
def export_users(format='json'):
users = User.query.all()
with open('users.json', 'w') as f:
json.dump([u.to_dict() for u in users], f)
良好——在编写代码前明确假设:
在实现之前,我需要澄清:
1. 范围:导出所有用户还是筛选后的子集?(隐私影响)
2. 格式:下载文件?后台任务?返回数据的 API 端点?
3. 字段:哪些用户字段?(有些可能敏感)
4. 数据量:通常有多少用户?(影响方法选择)
用最少的代码解决问题。不要添加推测性内容。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
问问自己:"资深工程师会说这过于复杂吗?" 如果是,就简化它。
用户:"添加一个计算折扣的函数"
糟糕——策略模式、配置数据类、50 多行代码只为一个计算:
class DiscountStrategy(ABC):
@abstractmethod
def calculate(self, amount: float) -> float: ...
class PercentageDiscount(DiscountStrategy): ...
class FixedDiscount(DiscountStrategy): ...
@dataclass
class DiscountConfig:
strategy: DiscountStrategy
min_purchase: float = 0.0
max_discount: float = float('inf')
良好——一个函数,完成:
def calculate_discount(amount: float, percent: float) -> float:
return amount * (percent / 100)
当你真正需要多种折扣类型时,再增加复杂性。
只修改必须修改的部分。只清理自己造成的混乱。
编辑现有代码时:
当你的修改产生孤立代码时:
检验标准:每一行被修改的代码都应直接追溯到用户的需求。
用户:"修复空电子邮件导致验证器崩溃的错误"
糟糕——添加文档字符串,改进电子邮件验证,添加没人要求的用户名验证:
def validate_user(user_data):
- # Check email format
- if not user_data.get('email'):
+ """Validate user data."""
+ email = user_data.get('email', '').strip()
+ if not email:
raise ValueError("Email required")
- if '@' not in user_data['email']:
+ if '@' not in email or '.' not in email.split('@')[1]:
raise ValueError("Invalid email")
+ username = user_data.get('username', '').strip()
+ if len(username) < 3:
+ raise ValueError("Username too short")
良好——只修复报告的 bug:
def validate_user(user_data):
# Check email format
- if not user_data.get('email'):
+ email = user_data.get('email', '')
+ if not email or not email.strip():
raise ValueError("Email required")
- if '@' not in user_data['email']:
+ if '@' not in email:
raise ValueError("Invalid email")
用户:"为上传函数添加日志记录"
糟糕——更改引号风格,添加类型提示,添加文档字符串,重新格式化空白:
- def upload_file(file_path, destination):
+ def upload_file(file_path: str, destination: str) -> bool:
+ """Upload file to destination with logging."""
良好——添加日志记录,匹配现有的单引号风格,不修改其他任何内容:
+ import logging
+ logger = logging.getLogger(__name__)
+
def upload_file(file_path, destination):
+ logger.info(f'Starting upload: {file_path}')
try:
定义成功标准。循环直到验证通过。
将任务转化为可验证的目标:
对于多步骤任务,陈述一个简要计划:
1. [步骤] -> 验证: [检查]
2. [步骤] -> 验证: [检查]
3. [步骤] -> 验证: [检查]
强有力的成功标准让你可以独立循环。弱标准("让它工作")需要不断澄清。
用户:"当存在重复分数时,排序会出错"
糟糕——立即更改排序逻辑,而没有确认 bug 是否存在。
良好——先复现,再修复:
# 1. 编写一个复现问题的测试
def test_sort_with_duplicate_scores():
scores = [
{'name': 'Alice', 'score': 100},
{'name': 'Bob', 'score': 100},
{'name': 'Charlie', 'score': 90},
]
result = sort_scores(scores)
assert result[0]['score'] == 100
assert result[1]['score'] == 100
assert result[2]['score'] == 90
# 验证:测试失败,排序不一致
# 2. 使用稳定排序进行修复
def sort_scores(scores):
return sorted(scores, key=lambda x: (-x['score'], x['name']))
# 验证:测试始终通过
| 原则 | 反模式 | 修复方法 |
|---|---|---|
| 先思考,后编码 | 默默假设格式、字段、范围 | 列出假设,请求澄清 |
| 简单优先 | 为单一计算使用策略模式 | 在需要复杂性之前,只用一个函数 |
| 精准修改 | 在修复 bug 时重新格式化引号、添加类型提示 | 只更改修复报告问题所需的代码行 |
| 目标驱动 | "我会审查并改进代码" | "为 bug X 编写测试 -> 使其通过 -> 验证没有回归" |
那些过于复杂的例子并非明显错误——它们遵循了设计模式和最佳实践。问题在于时机:它们在需要之前就增加了复杂性。
好的代码简单地解决今天的问题,而不是过早地解决明天的问题。
如果以下情况出现,则说明这些准则有效: 差异中不必要的更改减少,因过度复杂化而导致的返工减少,澄清问题在实现之前而非错误之后提出。
每周安装数
1
代码仓库
GitHub 星标数
1
首次出现
1 天前
安全审计
安装于
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
Behavioral guidelines to reduce common LLM coding mistakes, derived from Andrej Karpathy's observations on LLM coding pitfalls.
Tradeoff: These guidelines bias toward caution over speed. For trivial tasks, use judgment.
Don't assume. Don't hide confusion. Surface tradeoffs.
Before implementing:
User: "Add a feature to export user data"
Bad — silently assumes scope, format, fields, and file location:
def export_users(format='json'):
users = User.query.all()
with open('users.json', 'w') as f:
json.dump([u.to_dict() for u in users], f)
Good — surfaces assumptions before writing code:
Before implementing, I need to clarify:
1. Scope: Export all users or filtered subset? (privacy implications)
2. Format: Download file? Background job? API endpoint returning data?
3. Fields: Which user fields? (some might be sensitive)
4. Volume: How many users typically? (affects approach)
Minimum code that solves the problem. Nothing speculative.
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
User: "Add a function to calculate discount"
Bad — strategy pattern, config dataclass, 50+ lines for one calculation:
class DiscountStrategy(ABC):
@abstractmethod
def calculate(self, amount: float) -> float: ...
class PercentageDiscount(DiscountStrategy): ...
class FixedDiscount(DiscountStrategy): ...
@dataclass
class DiscountConfig:
strategy: DiscountStrategy
min_purchase: float = 0.0
max_discount: float = float('inf')
Good — one function, done:
def calculate_discount(amount: float, percent: float) -> float:
return amount * (percent / 100)
Add complexity later when you actually need multiple discount types.
Touch only what you must. Clean up only your own mess.
When editing existing code:
When your changes create orphans:
The test: every changed line should trace directly to the user's request.
User: "Fix the bug where empty emails crash the validator"
Bad — adds docstring, improves email validation, adds username validation nobody asked for:
def validate_user(user_data):
- # Check email format
- if not user_data.get('email'):
+ """Validate user data."""
+ email = user_data.get('email', '').strip()
+ if not email:
raise ValueError("Email required")
- if '@' not in user_data['email']:
+ if '@' not in email or '.' not in email.split('@')[1]:
raise ValueError("Invalid email")
+ username = user_data.get('username', '').strip()
+ if len(username) < 3:
+ raise ValueError("Username too short")
Good — only fixes the reported bug:
def validate_user(user_data):
# Check email format
- if not user_data.get('email'):
+ email = user_data.get('email', '')
+ if not email or not email.strip():
raise ValueError("Email required")
- if '@' not in user_data['email']:
+ if '@' not in email:
raise ValueError("Invalid email")
User: "Add logging to the upload function"
Bad — changes quote style, adds type hints, adds docstring, reformats whitespace:
- def upload_file(file_path, destination):
+ def upload_file(file_path: str, destination: str) -> bool:
+ """Upload file to destination with logging."""
Good — adds logging, matches existing single-quote style, touches nothing else:
+ import logging
+ logger = logging.getLogger(__name__)
+
def upload_file(file_path, destination):
+ logger.info(f'Starting upload: {file_path}')
try:
Define success criteria. Loop until verified.
Transform tasks into verifiable goals:
For multi-step tasks, state a brief plan:
1. [Step] -> verify: [check]
2. [Step] -> verify: [check]
3. [Step] -> verify: [check]
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
User: "The sorting breaks when there are duplicate scores"
Bad — immediately changes sort logic without confirming the bug exists.
Good — reproduce first, then fix:
# 1. Write a test that reproduces the issue
def test_sort_with_duplicate_scores():
scores = [
{'name': 'Alice', 'score': 100},
{'name': 'Bob', 'score': 100},
{'name': 'Charlie', 'score': 90},
]
result = sort_scores(scores)
assert result[0]['score'] == 100
assert result[1]['score'] == 100
assert result[2]['score'] == 90
# Verify: test fails with inconsistent ordering
# 2. Fix with stable sort
def sort_scores(scores):
return sorted(scores, key=lambda x: (-x['score'], x['name']))
# Verify: test passes consistently
| Principle | Anti-Pattern | Fix |
|---|---|---|
| Think Before Coding | Silently assumes format, fields, scope | List assumptions, ask for clarification |
| Simplicity First | Strategy pattern for one calculation | One function until complexity is needed |
| Surgical Changes | Reformats quotes, adds type hints during bug fix | Only change lines that fix the reported issue |
| Goal-Driven | "I'll review and improve the code" | "Write test for bug X -> make it pass -> verify no regressions" |
The overcomplicated examples aren't obviously wrong — they follow design patterns and best practices. The problem is timing : they add complexity before it's needed.
Good code solves today's problem simply, not tomorrow's problem prematurely.
These guidelines are working if: fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes.
Weekly Installs
1
Repository
GitHub Stars
1
First Seen
1 day ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
109,600 周安装