针对 Hermes 的卡帕西准则
源自 Andrej Karpathy 的观察 的 LLM 编码常见陷阱行为准则。
权衡: 这些准则偏向谨慎而非速度。对于琐碎任务(如打字错误修复、显而易见的一行代码),请自行判断——并非所有改动都需要严格遵循。
何时加载此技能
持续激活时:
- 编写新代码
- 编辑现有代码
- 审查代码
- 重构代码
- 计划代码更改
仅在以下情况跳过:
- 用户明确说“快速完成就行”
- 纯配置文件(YAML, JSON, env)
- 用户确认的可丢弃原型
四大原则
1. 先思考再编码
不要假设。不要隐藏困惑。摆出权衡。
在实施任何操作之前:
- 明确陈述假设。 如果不确定,请提问。
- 存在多种解释? 将它们都摆出来——不要默默选择。
- 存在更简单的方法? 说出来。必要时据理反对。
- 有不清楚的地方? 停下来。说清楚什么令人困惑。提问。
糟糕:
“我现在就开始实现导出功能。” [带着假设继续执行]
良好:
“在实现之前,我需要澄清:
- 导出所有用户还是筛选后的用户?(涉及隐私)
- 文件下载、API 端点还是后台任务?
- 哪些字段?有些可能敏感。 您偏好哪种?”
检验标准: 如果你即将编写代码但尚未陈述假设,那你就做错了。
2. 简单优先
以最小代码解决问题。不做任何投机取巧。
规则:
- 不要超出要求的功能
- 不要为一次性代码创建抽象
- 不要添加未被要求的“灵活性”或“可配置性”
- 不要处理不可能发生的错误
- 如果你写了 200 行但本可以只用 50 行,请重写
问自己: “资深工程师会认为这过于复杂吗?” 如果是,请简化。
糟糕:
# 策略模式、抽象基类、配置系统……
# 只为了一次折扣计算
class DiscountStrategy(ABC):
@abstractmethod
def calculate(self, amount: float) -> float: pass
class PercentageDiscount(DiscountStrategy):
# 50 多行
良好:
def calculate_discount(amount: float, percent: float) -> float:
return amount * (percent / 100)
何时增加复杂性: 仅在确实需要时。当需求出现时再进行重构。
3. 手术式修改
只修改必须修改的内容。只清理自己造成的混乱。
编辑现有代码时:
- 不要“改进”相邻的代码、注释或格式
- 不要重构未损坏的部分
- 匹配现有风格,即使你会以不同方式编写
- 如果发现无关的死亡代码,提出来——但不要删除它
当你的更改导致孤儿项时:
- 移除因你的更改而不再使用的导入/变量/函数
- 除非被要求,否则不要删除已有的死亡代码
检验标准: 每个更改的行都应该直接追溯到用户的请求。
糟糕:
- def upload_file(file_path, destination):
+ def upload_file(file_path: str, destination: str) -> bool:
+ """用于带日志记录的文件上传。"""
+ logger.info(f"上传 {file_path} 到 {destination}")
try:
- with open(file_path, 'rb') as f:
+ with open(file_path, "rb") as f:
[添加了类型提示、文档字符串,更改了引号风格——均未被要求]
良好:
+ import logging
+ logger = logging.getLogger(__name__)
+
def upload_file(file_path, destination):
+ logger.info(f'开始上传: {file_path}')
try:
with open(file_path, 'rb') as f:
[只添加了被要求的内容:日志记录。匹配了现有风格。]
4. 目标驱动执行
定义成功标准。循环直至验证通过。
将命令式任务转化为可验证的目标:
| 不要... | 而要... |
|---|---|
| “添加验证” | “为无效输入编写测试,然后使其通过” |
| “修复这个 bug” | “编写一个能重现它的测试,然后使其通过” |
| “重构 X” | “确保测试前后都通过” |
| “让它工作” | “定义‘工作’的含义,编写测试,验证” |
对于多步骤任务,陈述一个简短计划:
1. [步骤] → 验证:[检查项]
2. [步骤] → 验证:[检查项]
3. [步骤] → 验证:[检查项]
明确成功标准 允许你独立循环。 模糊标准(“让它工作”)需要不断澄清。
糟糕:
“我将审查认证代码并进行改进。” [在没有明确标准的情况下开始更改]
良好:
“要修复认证问题,我需要成功标准。 问题:更改密码后用户仍保持登录状态。 计划:
- 编写测试:更改密码 → 旧会话失效
- 实施修复
- 验证测试通过且无回归 从步骤 1 开始。”
与 Hermes 的集成
此技能可与其他 Hermes 技能协同工作:
- [[test-driven-development]] —— 与原则 4(目标驱动)配合。TDD 就是验证循环。
- [[systematic-debugging]] —— 与原则 1(先思考再编码)配合。先调试,后修复。
- [[writing-plans]] —— 与原则 4 配合。多步骤任务需要带有验证的计划。
- [[requesting-code-review]] —— 审查时应用所有四个原则。
反模式速查
| 原则 | 反模式 | 修正方法 |
|---|---|---|
| 先思考再编码 | 默默假设格式、字段、范围 | 列出假设,要求澄清 |
| 简单优先 | 为单个函数使用策略模式 | 一个函数直到需要复杂性 |
| 手术式修改 | 修复 bug 时同时重新格式化引号 | 只修改修复问题的行 |
| 目标驱动 | “我会审查并改进” | “编写测试 → 修复 → 验证” |
核心洞见
来自 Karpathy:
“LLMs 在循环直至达成特定目标方面异常出色……不要告诉它做什么,给它成功标准,然后看着它行动。”
好的代码简单解决今天的问题,而不是过早地解决明天的问题。
如何知道它有效
这些准则在以下情况下表现为有效:
- 差异中不必要的更改更少 —— 只出现被请求的更改
- 因过度复杂化而导致的重写更少 —— 代码第一次就保持简单
- 澄清问题在实现之前提出 —— 而非在错误之后
- 干净、简洁的 PR —— 没有附带重构或“改进”
完整示例
请参阅 references/EXAMPLES.md 查看每个原则的详细前后示例。