Andrej Karpathy 在社交媒体上的一次深刻反思,将当前大语言模型在编程任务中的系统性缺陷摆在了开发者面前。他指出模型会悄然做出错误假设而不进行检查,不管理自身的困惑,不寻求澄清,不暴露不一致性,不呈现权衡取舍,甚至在代码理解不足时仍会修改或删除注释与代码。这些问题并非偶发现象,而是有规律可循的系统性失误。基于这一洞察,社区开发者将其转化为一套可编程的 Claude Code 技能集 CLAUDE.md,为 AI 辅助编程提供了切实可行的工程化解决方案。
问题的本质:LLM 编程的四大顽疾
Karpathy 的观察揭示了 LLM 在编程场景中的四种典型行为模式。第一种是隐性假设与沉默推理,模型在面对模糊需求时倾向于自行选择一种解释然后闷头执行,从不主动询问确认。第二种是过度工程与抽象滥用,模型偏爱构建复杂的 API 和层级结构,常常用一千行代码实现只需一百行就能完成的功能。第三种是副作用驱动的修改,模型会 “顺手” 改进相邻代码、调整格式、甚至删除被认为无用的代码片段,即便这些操作与原始任务正交。第四种是目标模糊导致的迭代低效,当任务描述不够具体时,模型只能依赖频繁的澄清对话来推进进度。
这些问题在日常开发中造成的实际代价远超预期。不必要的代码变更增加了代码审查的负担,过度抽象使得后续维护成本飙升,未经请求的代码修改引入意外 bug,而缺乏明确成功标准的任务则导致反复修正。把这些教训转化为可强制执行的编程原则,正是 CLAUDE.md 技能集的核心价值。
原则一:编码前思考 —— 显性化推理过程
编码前思考原则要求模型将隐性的推理过程显性化。该原则包含四个关键行为:明确陈述假设、在存在歧义时呈现多种解释、在应有更简单方案时提出反对、以及在感到困惑时主动停止并请求澄清。
在工程实践中,这意味着任何代码生成的起点不应该是直接编写代码,而是首先识别需求中的不确定因素。例如当收到 “添加数据验证” 的任务时,模型应当首先明确验证哪些字段、接受什么格式、在何种条件下触发何种错误处理,而不是立即写出一套完整的验证逻辑。歧义处理同样重要,如果需求中涉及时间格式、编码方式或边界条件,模型应该在开始实现前列出所有可能的解释并请求确认。
这一原则的工程化实现可以通过 CLAUDE.md 中的显式指令来完成。技能集建议在每个任务开始时添加一个思考阶段,形式化输出对需求的理解、所做的假设以及识别出的不确定性。只有在这个阶段得到确认后,才进入实际编码环节。
原则二:简单性优先 —— 最小可行实现
简单性优先原则直指 LLM 过度工程化的顽疾。该原则要求模型只实现所请求的功能,不添加任何超出需求的特性,不为单次使用的代码创建抽象,不引入未经请求的 “灵活性” 或 “可配置性”,不为不可能发生的场景添加错误处理。如果两千行代码可以精简到五百行,就应该进行重写。
这个原则背后有一个简单但有效的检验标准:一位资深工程师是否会认为这个实现过度复杂?如果答案是肯定的,那就意味着需要简化。在实际操作中,这意味着模型应该抵制 “一次性写完整” 的冲动,采用增量式的方法,先实现核心功能并通过测试验证,再根据需要逐步扩展。
对于 Claude Code 而言,简单性原则可以在技能集中量化为具体的约束条件。例如禁止生成超过指定行数的单一函数、要求每个导出的函数都有对应的测试用例、禁止在首次实现中添加配置驱动逻辑等。这些约束不是限制能力,而是确保输出始终与实际需求保持对齐。
原则三:外科手术式修改 —— 精准的范围控制
外科手术式修改原则针对的是 LLM “顺手改进” 的冲动。该原则要求模型在修改现有代码时只触碰必须改动的部分,不 “改进” 相邻的代码、注释或格式匹配问题,不重构没有故障的部分,即使个人风格不同也要遵循现有代码规范,如果注意到不相关的死代码只能提及而不删除。当自己的修改产生了孤立的代码时,只清理自己引入的未使用导入、变量或函数。
这一原则的工程化意义在于将代码变更的影响范围最小化。每个被修改的代码行都应该能够直接追溯到用户的原始请求。在 CLAUDE.md 的实现中,这可以通过要求模型在提交变更前进行自检来完成:逐行确认每一处修改是否直接服务于任务目标,任何 “非必要” 的变更都应该被撤销或单独说明。
这种精确的范围控制对于大型代码库尤为重要。当模型试图在修复一个 bug 的同时 “优化” 周围的代码时,往往会引入新的问题。通过强制执行外科手术式修改的原则,可以将代码审查的关注点集中到真正重要的变更上。
原则四:目标驱动执行 —— 可验证的成功标准
目标驱动执行是四个原则中最具方法论价值的部分。Karpathy 指出 LLM 特别擅长在明确目标下进行循环迭代,因此关键不在于告诉模型具体做什么,而在于给它成功标准让它自主完成。
这个原则的核心转变是将指令性任务转换为声明性目标。“添加验证” 应该被转化为 “编写针对无效输入的测试,然后让测试通过”。“修复 bug” 应该被转化为 “编写一个能复现问题的测试,然后让它通过”。对于多步骤任务,应该先陈述简要计划,每个步骤后跟验证检查点。
在 CLAUDE.md 的实现中,这通常表现为一种结构化的任务描述格式。模型被要求在开始编码前先定义成功标准,这些标准应该是可观测、可测试的。弱成功标准如 “让它能工作” 会导致模型反复询问具体要求,而强成功标准如 “在给定三个无效输入时返回特定错误码” 则允许模型自主完成整个循环。
技能集的工程化部署
将上述原则转化为可编程技能集有两种主要方式。第一种是通过 Claude Code 的插件系统安装,命令为 /plugin install andrej-karpathy-skills@karpathy-skills,这会使技能在所有项目中生效。第二种方式是将 CLAUDE.md 文件放入特定项目,适合需要与项目特定规则结合的场景。
值得注意的是,这套技能集的设计偏向于谨慎而非速度。对于简单的 typo 修复或明显的一行代码修改,不必将完整流程全部走一遍。技能集的目标是在复杂任务上减少代价高昂的错误,而非拖慢简单任务的速度。
通过将 Karpathy 的洞察系统化地编码为 Claude Code 的执行原则,开发者可以有效地约束 LLM 的编程行为,使其输出更加可控、可预测且易于维护。这套技能的真正价值在于把来自一线实践的深刻观察,转化为每个项目中可重复执行的工程实践。
资料来源:本文核心原则与实践来自 GitHub 项目 forrestchang/andrej-karpathy-skills,该项目基于 Andrej Karpathy 关于 LLM 编程失误的原始推文整理而成。