Appearance
Part 4: 正确使用 AI 编程 (35-40 min)
核心思路:从心智模型到实操技巧,再到使用边界和团队采用
4.1 心智模型:模拟器而非实体
专家观点 — Andrej Karpathy
背景:前 Tesla AI 总监、OpenAI 联合创始人、斯坦福 CS231n 课程讲师 来源:2025 年 12 月 X 推文 [1]
「不要把 LLM 当作实体(Entity),要当作模拟器(Simulator)。」
这是什么意思?
text
┌─────────────────────────────────────────────────────────────────────┐
│ LLM 是模拟器,不是实体 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ❌ 把 LLM 当「实体」 │
│ │
│ 你: 「关于 XXX,你怎么看?」 │
│ │
│ 问题:根本不存在「你」。 │
│ │
│ LLM 会怎么做? │
│ → 采用一个「人格嵌入向量」(personality embedding vector) │
│ → 这个向量来自微调数据的统计规律 │
│ → 模拟一个「大众脸」来回答你 │
│ │
│ 结果:你得到的是一个「平均意见」,不是深思熟虑的观点 │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ✅ 把 LLM 当「模拟器」 │
│ │
│ 你: 「如果要探讨 XXX 这个话题,最合适的专家是谁?他们会怎么说?」 │
│ │
│ LLM 会怎么做? │
│ → 模拟特定领域专家的视角 │
│ → 调用训练数据中该领域的知识 │
│ → 给出更专业、更有针对性的回答 │
│ │
│ 结果:你得到的是「专家视角的模拟」,质量更高 │
│ │
└─────────────────────────────────────────────────────────────────────┘专家观点 — Andrej Karpathy [^65]
(2023 年 State of GPT 演讲)
「这些 Transformer 就是 token 模拟器。它们不知道自己不知道什么,只是尽力模拟下一个 token。」
这和 Context Engineering 有什么关系?
其实这也是一种「高信号 Context」—— 告诉模型要模拟谁。
| 提问方式 | 模型行为 | 结果质量 |
|---|---|---|
| 「你觉得这段代码怎么样?」 | 模拟「平均程序员」 | 泛泛而谈 |
| 「假设你是 Google 的 Staff Engineer,审查这段代码会关注什么?」 | 模拟「资深工程师」 | 更专业的审查意见 |
| 「这个架构设计有什么问题?」 | 模拟「平均意见」 | 可能漏掉关键点 |
| 「如果 Martin Fowler 看这个架构,他会怎么评价?」 | 模拟「架构大师视角」 | 更深入的分析 |
实操建议:
- 问观点性问题时,指定一个「角色」或「专家群体」
- 不是说「你是 XXX 专家」这种 roleplay,而是问「XXX 领域的专家会怎么看」
- 这样做的本质是:帮模型选择一个更高质量的「模拟目标」
4.2 Context Engineering 实操
Part 2 讲了 Context Engineering 是什么,这里讲怎么做。
text
┌─────────────────────────────────────────────────────────────────────┐
│ Context Engineering 的核心思维 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ❌ 错误思维:「我要把所有信息都告诉 AI」 │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 项目文档 + 所有代码 + 历史对话 + 各种规范 + ... │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ Context 爆炸 │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 准确率下降 (Context Rot) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ✅ 正确思维:「最小化高信号 Token」 │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 只给当前任务需要的信息 │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ System Prompt │ ← CLAUDE.md (精简) │ │
│ │ │ + 相关文件 │ ← 按需读取 │ │
│ │ │ + 当前任务描述 │ ← 具体、明确 │ │
│ │ └─────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 高质量输出 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘三条核心原则(来自 Anthropic 官方指南):
| 原则 | 说明 | 实操建议 |
|---|---|---|
| Context 是有限资源 | 准确率随 token 数增加而下降 | 定期 /clear,不要让对话无限累积 |
| 工具集要精简 | 每个工具占用 Context,功能重叠会让 AI 困惑 | MCP 不要装太多,保持功能不重叠 |
| 具体胜过模糊 | 「写测试」不如「为 foo.py 的登出边界情况写测试,不要用 mock」 | 花时间写好 prompt,比反复纠正划算 |
4.2.1 好 Context vs 坏 Context
这是同一个需求的两种写法,效果天差地别:
text
┌─────────────────────────────────────────────────────────────────────┐
│ ❌ 坏 Context │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 「帮我写一个时钟」 │
│ │
│ 问题: │
│ · 什么样的时钟?数字?模拟? │
│ · 什么技术栈?React?Vue?原生 JS? │
│ · 什么风格?简约?华丽? │
│ · 要什么功能?只显示时间?还是要闹钟? │
│ │
│ 结果:AI 自己猜,猜错了再改,浪费 Context │
│ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ ✅ 好 Context │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 「用原生 HTML/CSS/JS 写一个数字时钟: │
│ │
│ 功能要求: │
│ - 显示当前时间(时:分:秒) │
│ - 每秒自动更新 │
│ - 24 小时制 │
│ │
│ 样式要求: │
│ - 深色背景 (#1a1a2e) │
│ - 白色数字,使用等宽字体 │
│ - 居中显示,字号要大 │
│ │
│ 文件结构:单个 index.html 文件,CSS 和 JS 内联」 │
│ │
│ 结果:AI 一次性给出符合预期的代码 │
│ │
└─────────────────────────────────────────────────────────────────────┘写好 Context 的检查清单:
- [ ] 技术栈明确了吗?
- [ ] 功能边界清晰吗?
- [ ] 有没有可能被误解的地方?
- [ ] 输出格式/文件结构说清楚了吗?
4.2.2 Course Correct:早期纠偏
AI 走偏是正常的,关键是早发现、早纠正。
text
┌─────────────────────────────────────────────────────────────────────┐
│ Course Correct 时机 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ❌ 太晚纠正 │
│ │
│ 你: 写一个时钟 │
│ AI: [写了 500 行 React 代码] │
│ 你: 不对,我要原生 JS │
│ AI: [重写 500 行] │
│ │
│ → 浪费了大量 Context 和时间 │
│ │
│ ✅ 早期纠正 │
│ │
│ 你: 写一个时钟 │
│ AI: 我打算用 React 来实现,首先... │
│ 你: 停,用原生 JS,不要框架 │
│ AI: 好的,那我用原生 JS... │
│ │
│ → 在 AI 动手之前就纠正方向 │
│ │
└─────────────────────────────────────────────────────────────────────┘纠偏技巧:
| 场景 | 做法 |
|---|---|
| AI 选错技术栈 | 立刻打断:「停,用 XXX 而不是 YYY」 |
| AI 过度设计 | 「简化,不需要 XXX 功能」 |
| AI 理解错需求 | 「不是这个意思,我要的是...」 |
| 对话太长开始混乱 | /clear 清空上下文,重新开始 |
4.3 CLAUDE.md 与工具链
CLAUDE.md 是 Claude Code 的核心配置文件——AI 每次启动都会自动读取它。
text
┌─────────────────────────────────────────────────────────────────────┐
│ CLAUDE.md 的作用 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 没有 CLAUDE.md 有 CLAUDE.md │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Claude Code │ │ Claude Code │ │
│ │ │ │ │ │
│ │ 「这是什么项目? │ │ 「我知道: │ │
│ │ 用什么语言? │ │ - 这是 Python 项目│ │
│ │ 怎么跑测试? │ │ - 用 pytest 测试 │ │
│ │ 有什么规范?」 │ │ - 代码风格是... │ │
│ │ │ │ - 提交规范是...」│ │
│ └─────────────────┘ └─────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ 每次都要重新解释 直接开始工作,风格一致 │
│ │
└─────────────────────────────────────────────────────────────────────┘4.3.1 CLAUDE.md 写什么?
遵循 WHAT / WHY / HOW 结构(来自 HumanLayer 指南):
| 部分 | 内容 | 示例 |
|---|---|---|
| WHAT | 项目是什么、技术栈 | 「这是一个 Python 3.11 的 Home Assistant 集成」 |
| WHY | 项目目标、各模块作用 | 「用于接入公司物联网网关」 |
| HOW | 开发流程、测试方法、提交规范 | 「用 pytest 跑测试,commit 遵循 Conventional Commits」 |
关键原则:
| 原则 | 说明 |
|---|---|
| 保持精简 | 研究表明 LLM 可靠遵循 150-200 条指令,Claude Code 自带 ~50 条,留给你的不多 |
| 控制长度 | 300 行以内,理想情况 60 行以内 |
| 只写通用规则 | 不要写「某个具体功能怎么实现」,那是任务描述不是项目规范 |
| 不要当 Linter | 代码风格用 ESLint/Prettier/Ruff 等工具,不要写在 CLAUDE.md 里 |
| 手动编写 | 不要用 /init 自动生成,那个效果很差 |
4.3.2 OpenSpec:Spec-Driven 开发
作者实践
以下是我个人采用的工作流,不一定适合所有人。供参考。
我现在用的是 OpenSpec——一个 spec-driven 的开发流程。
text
┌─────────────────────────────────────────────────────────────────────┐
│ OpenSpec 目录结构 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ project/ │
│ ├── CLAUDE.md ← 项目入口,引用 OpenSpec │
│ └── openspec/ │
│ ├── AGENTS.md ← AI 的详细指南 │
│ ├── project.md ← 项目规范 │
│ ├── specs/ ← 当前状态(已实现的功能) │
│ │ └── [capability]/ │
│ │ └── spec.md │
│ └── changes/ ← 变更提案(待实现的功能) │
│ └── [change-name]/ │
│ ├── proposal.md │
│ ├── tasks.md │
│ └── specs/ │
│ │
└─────────────────────────────────────────────────────────────────────┘OpenSpec 的核心思想:
「Specs 是真相(已构建),Changes 是提案(待构建),保持它们同步。」
三阶段工作流:
| 阶段 | 触发条件 | 产出 |
|---|---|---|
| 1. 创建提案 | 新功能、Breaking Change、架构变更 | proposal.md + tasks.md + spec deltas |
| 2. 实现提案 | 提案被批准 | 代码实现,按 tasks.md 逐项完成 |
| 3. 归档提案 | 部署完成 | 移动到 archive/,更新 specs/ |
这样做的好处是:AI 在写代码之前,先帮你把需求和方案理清楚。避免了 Vibe Coding 那种「边写边想」的混乱。
4.3.3 工具链总结
text
┌─────────────────────────────────────────────────────────────────────┐
│ Claude Code 工具链全景 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ CLAUDE.md │ │
│ │ (项目入口配置) │ │
│ │ │ │
│ │ · WHAT: 项目是什么、技术栈 │ │
│ │ · WHY: 项目目标 │ │
│ │ · HOW: 开发流程、测试方法 │ │
│ └──────────────────────────┬──────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────┼─────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Skills │ │ MCP │ │ Slash │ │
│ │ │ │ Servers │ │ Commands │ │
│ │ 可复用 │ │ │ │ │ │
│ │ 能力包 │ │ 连接外部 │ │ 快捷命令 │ │
│ │ │ │ 服务 │ │ │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │writing- │ │ GitHub │ │/openspec │ │
│ │assistant │ │ Slack │ │:proposal │ │
│ │git- │ │ Database │ │/git- │ │
│ │workflow │ │ ... │ │workflow │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘| 工具 | 作用 | 我的使用场景 |
|---|---|---|
| CLAUDE.md | 项目配置入口 | 每个项目都有,定义基本规范 |
| OpenSpec | Spec-driven 开发流程 | 大功能开发前先写 proposal |
| Skills | 可复用的能力模块 | writing-assistant 写文章、git-workflow 提交代码 |
| MCP | 连接外部服务 | GitHub、文件系统 |
| Slash Commands | 快捷命令 | /openspec:proposal 创建提案 |
注意事项:
- MCP 不能装太多——每个 MCP Server 的工具定义都占用 Context
- Skills 按需加载——只有用到的时候才会消耗 Token
- 定期
/clear——不要让对话历史无限累积
4.4 现场演示:从零到部署
演示任务:用 Claude Code 从零开始,创建并部署一个时钟应用到 GitHub Pages
阶段一:好 Context vs 坏 Context
第一步:展示「坏 Context」的效果
text
┌─────────────────────────────────────────────────────────────────────┐
│ 演示 Prompt 1(坏 Context) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 你: 帮我写一个时钟 │
│ │
│ [等待 AI 响应,观察它会怎么理解这个模糊需求] │
│ │
│ 预期问题: │
│ - AI 可能选择你不想要的技术栈 │
│ - AI 可能添加你不需要的功能 │
│ - AI 可能问一堆澄清问题(浪费时间) │
│ │
└─────────────────────────────────────────────────────────────────────┘第二步:展示「好 Context」的效果
text
┌─────────────────────────────────────────────────────────────────────┐
│ 演示 Prompt 2(好 Context) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 你: 用原生 HTML/CSS/JS 写一个数字时钟。 │
│ │
│ 功能: │
│ - 显示当前时间(时:分:秒),24 小时制 │
│ - 每秒自动更新 │
│ │
│ 样式: │
│ - 深色背景,白色等宽字体 │
│ - 数字要大,居中显示 │
│ │
│ 输出:单个 index.html 文件,CSS/JS 内联 │
│ │
│ [观察 AI 直接给出符合预期的代码] │
│ │
└─────────────────────────────────────────────────────────────────────┘第三步:迭代添加功能
text
┌─────────────────────────────────────────────────────────────────────┐
│ 演示 Prompt 3(增量开发) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 你: 在数字时钟下方加一个模拟时钟(圆形表盘 + 时针分针秒针)。 │
│ 保持同样的配色风格。 │
│ │
│ [观察 AI 如何在现有代码基础上增量修改] │
│ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ 演示 Prompt 4(主题切换) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 你: 加一个主题切换按钮,可以在深色/浅色主题之间切换。 │
│ 记住用户的选择(用 localStorage)。 │
│ │
└─────────────────────────────────────────────────────────────────────┘阶段二:Course Correct 演示
text
┌─────────────────────────────────────────────────────────────────────┐
│ 演示 Prompt 5(故意制造纠偏场景) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 你: 加一个闹钟功能 │
│ │
│ AI: 好的,我来添加闹钟功能。我打算: │
│ 1. 添加一个设置闹钟时间的输入框 │
│ 2. 添加多个闹钟的支持... │
│ 3. 添加重复闹钟(每天/每周)... │
│ │
│ 你: 停。简化一下,只要: │
│ - 一个闹钟就够 │
│ - 用 prompt() 输入时间 │
│ - 到时间 alert 一下就行 │
│ │
│ [展示早期纠偏如何节省 Context] │
│ │
└─────────────────────────────────────────────────────────────────────┘阶段三:部署上线
text
┌─────────────────────────────────────────────────────────────────────┐
│ 演示 Prompt 6(GitHub 部署) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 你: 帮我把这个时钟部署到 GitHub Pages: │
│ │
│ 1. 用 gh 命令创建一个新的 public 仓库,名字叫 clock-demo │
│ 2. 初始化 git 并推送代码 │
│ 3. 配置 GitHub Actions 自动部署到 GitHub Pages │
│ 4. 告诉我最终的访问地址 │
│ │
│ [观察 AI 如何: │
│ - 调用 gh repo create │
│ - 创建 .github/workflows/deploy.yml │
│ - 执行 git 命令 │
│ - 一次性完成整个部署流程] │
│ │
└─────────────────────────────────────────────────────────────────────┘阶段四:Skill 实战
text
┌─────────────────────────────────────────────────────────────────────┐
│ 演示 Prompt 7(使用 Git Workflow Skill) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ [先对时钟做一个小修改,比如改个颜色] │
│ │
│ 你: /git-workflow 帮我提交这个修改 │
│ │
│ [Skill 自动加载,按照预定义的流程: │
│ - 检查 git status / git diff │
│ - 生成符合 Conventional Commits 格式的 message │
│ 格式: type(scope): concise summary │
│ 类型: feat / fix / refactor / docs / test / chore │
│ - 不带 AI 生成标记(无 🤖 签名) │
│ - 执行 commit 和 push] │
│ │
│ 示例输出: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ feat(ui): add theme toggle button │ │
│ │ │ │
│ │ - Support dark/light theme switching │ │
│ │ - Persist user preference in localStorage │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 对比:没有 Skill 时,你需要每次都告诉 AI: │
│ 「帮我 commit,用 Conventional Commits 格式,不要加 AI 签名...」 │
│ │
└─────────────────────────────────────────────────────────────────────┘Git Workflow Skill 的三个工作流(可独立或组合使用):
| 工作流 | 触发方式 | 作用 |
|---|---|---|
| Commit | /git-workflow 帮我提交 | 生成规范的 commit message |
| Pull Request | /git-workflow 帮我创建 PR | 创建分支 → commit → 开 PR |
| Release | /git-workflow 帮我发布 | 更新版本号 → 改 CHANGELOG → 打 tag → 发布 |
演示要点总结:
| 阶段 | 展示的概念 | 对应 Part 2 的知识点 |
|---|---|---|
| 阶段一 | Context 质量决定输出质量 | Context Engineering |
| 阶段二 | 早期纠偏节省 Context | Agent 的 ReAct 循环 |
| 阶段三 | AI 直接操作外部工具 | Function Call / Tool Use |
| 阶段四 | Skill 封装重复工作流 | Skills 渐进式加载 |
[!TODO] 演示准备
- [ ] 准备干净的演示环境(新文件夹、gh CLI 已登录)
- [ ] 测试完整流程(确保 GitHub Pages 能正常部署)
- [ ] 准备 Git Workflow Skill
- [ ] 录制备用视频(防止现场网络问题)
- [ ] 准备「坏 Context」的反面例子
4.5 使用边界
4.5.1 什么时候该用 / 不该用 AI
text
┌─────────────────────────────────────────────────────────────────────┐
│ AI 使用场景光谱 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 放心用 谨慎用 最好别用 │
│ ◄─────────────────────────────────────────────────────────────► │
│ │
│ · 拼写检查 · 业务逻辑实现 · 安全关键代码│
│ · 格式化 · 不熟悉的领域 · 架构决策 │
│ · 样板代码 · 性能优化 · 加密实现 │
│ · 文档草稿 · 并发代码 · 认证授权 │
│ · 单元测试 · 数据库设计 · 支付处理 │
│ · 代码解释 · API 设计 · 合规代码 │
│ · 重构建议 · 错误处理策略 · 你不打算 │
│ · 命名建议 · 第三方集成 理解的代码 │
│ │
│ 你完全理解 你需要仔细审查 你必须亲自写 │
│ AI 只是加速 AI 是参考意见 或深度审查 │
│ │
└─────────────────────────────────────────────────────────────────────┘引用 软件工程的「纯」与「不纯」:
text
┌─────────────────────────────────────────────────────────────────────┐
│ 纯粹工程 vs 不纯粹工程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 纯粹工程 不纯粹工程 │
│ (Pure Engineering) (Impure Engineering) │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ · 你非常了解的问题 │ │ · 你只有粗浅理解 │ │
│ │ · 社区不熟知 │ │ · 问题不新颖 │ │
│ │ (值得研究) │ │ 只是对你新 │ │
│ │ · 在专长极限边缘 │ │ · 很少处理透彻 │ │
│ │ · 有无限时间 │ │ 理解的问题 │ │
│ │ │ │ · 紧迫的截止日期 │ │
│ └──────────┬──────────┘ └──────────┬──────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ AI 帮不上忙 │ │ AI 可能比你更聪明 │ │
│ │ (需要深度思考) │ │ (快速出活) │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘作者观点
AI 最擅长的是「不纯粹工程」——那些你知道怎么做、但做起来很繁琐的事情。而「纯粹工程」——需要深度思考和创造性的部分——还是得靠你自己。
4.5.2 技能退化警示
三个需要警惕的征兆:
| 征兆 | 表现 | 后果 |
|---|---|---|
| 调试恐惧 | 看报错 → 复制给 AI → 不管它说什么都试 | 遇到 AI 搞不定的问题时完全不知道从哪下手 |
| 无脑复制 | 「代码能跑就行,不需要理解」 | 代码改动时不知道会影响什么 |
| 架构思维丧失 | 只会问「怎么写」不问「放在哪里」 | 系统越写越乱,最后只能推倒重来 |
一条判断标准:
专家观点 — Simon Willison [^55]
「我的黄金法则是:我不会提交任何我无法向别人解释的代码。」
4.5.3 成本意识
text
┌─────────────────────────────────────────────────────────────────────┐
│ 对话累积的成本问题 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 第 1 轮对话:输入成本 500 tokens │
│ 第 2 轮对话:输入成本 2000 tokens(包含第 1 轮历史) │
│ 第 3 轮对话:输入成本 4000 tokens(雪球越滚越大) │
│ ... │
│ 第 10 轮对话:输入成本可能已经是第 1 轮的 20 倍 │
│ │
│ 这就是为什么 Claude Code 有 /clear 命令 │
│ │
└─────────────────────────────────────────────────────────────────────┘Token 效率优化建议:
| 建议 | 说明 |
|---|---|
定期 /clear | 任务完成或对话偏离时,清空重新开始 |
| 精简 CLAUDE.md | 不要塞太多内容,60 行以内最佳 |
| MCP 不要装太多 | 每个 MCP Server 的工具定义都占 Context |
| 具体的 prompt | 一次说清楚,避免来回澄清 |
| 分任务处理 | 大任务拆成小任务,每个任务独立对话 |
4.6 团队采用
4.6.1 OCaml 13K PR 案例
2025 年 10 月,一位热情的外行用户给 OCaml 编译器项目提交了一个 13,000 行的 PR [3]。
这个 PR 是用 Claude 全程生成的,目的是实现 DWARF 调试支持。结果?被 maintainer 锁定并拒绝了。
text
┌─────────────────────────────────────────────────────────────────────┐
│ OCaml 13K PR 事件时间线 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 提交者: 一位热情的外行用户 │
│ 工具: Claude AI │
│ PR 规模: 13,000+ 行代码 │
│ │
│ 问题 1: 没有事先讨论就提交巨型 PR │
│ └─ 浪费了 volunteer maintainer 的时间 │
│ │
│ 问题 2: AI 生成的代码里有错误的版权声明 │
│ └─ 把代码归属给了 Mark Shinwell(一个真实的人) │
│ │
│ 问题 3: 被问到为什么有这个归属时,提交者说: │
│ 「Beats me. AI decided to do so and I didn't question it」 │
│ (我也不知道,AI 决定这么做的,我没质疑) │
│ │
│ 问题 4: 把大量 .md 文件加进了 .gitignore │
│ └─ 明显没有认真 review 过自己提交的代码 │
│ │
│ 结果: PR 被锁定,maintainer 非常耐心但明确地拒绝了 │
│ │
└─────────────────────────────────────────────────────────────────────┘教训:
「提交代码的工程师始终对代码质量、安全和功能负责,无论 AI 是否参与。」
4.6.2 分阶段采用策略
来自 Pete Hodgson 和 Jellyfish 的建议:
text
┌─────────────────────────────────────────────────────────────────────┐
│ 团队采用 AI 编程的三个阶段 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 阶段 1: 实验 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 目标: 理解能力和局限 │ │
│ │ 活动: │ │
│ │ · 小范围试用(1-2 人先跑起来) │ │
│ │ · 记录使用经验(踩了什么坑、学到什么) │ │
│ │ · 尝试不同场景(哪些适合 AI、哪些不适合) │ │
│ │ │ │
│ │ ← 我们团队目前在这里 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 阶段 2: 采用 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 目标: 成为日常工具 │ │
│ │ 活动: │ │
│ │ · 团队培训(今天这个分享算是开始) │ │
│ │ · 共享配置(CLAUDE.md、MCP 配置) │ │
│ │ · 建立 Code Review 规范 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 阶段 3: 影响 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 目标: 衡量实际效果 │ │
│ │ 活动: │ │
│ │ · 对比使用前后的效率指标 │ │
│ │ · 识别最佳实践,固化成规范 │ │
│ │ · 持续迭代改进 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘4.6.3 Oxide 五原则
企业实践 — Oxide 公司
背景:硬件+软件公司,由多位前 Sun/Joyent 资深工程师创办 来源:RFD 576: Using LLMs at Oxide [4]
| 原则 | 解释 | 我的理解 |
|---|---|---|
| 责任 | 人类判断始终在环内,对所有输出负责 | 不能说「AI 写的,我不知道」 |
| 严谨 | LLM 应该锐化思考而非替代思考 | 用 AI 加速,不是用 AI 偷懒 |
| 同理心 | 考虑内容创作者和消费者 | 想想 Reviewer 的时间,想想维护者的负担 |
| 团队合作 | 保持真诚的沟通 | 如果用了 AI,就说用了;不要假装是自己写的 |
| 紧迫感的平衡 | 不为速度牺牲质量 | 快不是目的,好才是 |
4.6.4 代码审查底线
对 AI 生成代码的审查,应该多问两个问题:
| 问题 | 为什么重要 |
|---|---|
| 「为什么选择这个方案?」 | 如果答不上来,说明你没理解代码 |
| 「考虑了哪些替代方案?」 | 如果没考虑,说明你只是接受了 AI 的第一个建议 |
4.7 Q&A 与资源
4.7.1 常见问题
| 问题 | 简短回答 |
|---|---|
| 「Claude Code 要钱吗?」 | 要,按 token 计费,公司应该会统一采购 |
| 「和 ChatGPT 比哪个好?」 | 写代码的话,Claude 目前更强;但选型要看具体场景 |
| 「会不会泄露公司代码?」 | Anthropic 声称不会用 API 数据训练模型,但敏感代码还是要注意 |
| 「我完全不懂 AI,能用吗?」 | 能,但建议先从简单任务开始,不要一上来就 Vibe Coding |
| 「AI 会取代程序员吗?」 | 短期不会,但会改变工作方式;不用 AI 的程序员可能会被用 AI 的程序员取代 |
| 「英文不好影响大吗?」 | 有影响但不大,Claude 中文支持不错;关键是学会组织 Context |
4.7.2 资源推荐
入门必读:
| 资源 | 说明 |
|---|---|
| Claude Code Best Practices | Anthropic 官方最佳实践 |
| Claude Code Docs | 官方文档,遇到问题先查这里 |
| 如何避免在 AI 时代技能退化 | 中文,技能退化警示 |
进阶阅读:
| 资源 | 说明 |
|---|---|
| Oxide RFD 576 | 企业级 LLM 使用策略 |
| 一个半月高强度 Claude Code 使用后感受 | 喵神的文章,实战经验 |
| Context Engineering Guide | 深入理解 Context Engineering |
4.7.3 最后一句话
用 AI 加速你已经理解的工作,而不是用它跳过你应该学习的过程。
这是我这几个月踩坑下来最深的体会。希望对大家有帮助。
参考资料
💬 L4 | Don't think of LLMs as entities but as simulators | Andrej Karpathy - 2025 年 12 月 7 日推文,提出「LLM 是模拟器而非实体」的心智模型,解释 personality embedding vector 概念。 ↩︎
📝 L3 | 如何避免在 AI 时代技能退化 | 宝玉的分享 - 中文译文,原文详述技能退化的四个征兆和七条实践建议。 ↩︎
💬 L4 | AI has a deep understanding of how this code works | Hacker News - 2025 年 10 月 OCaml 编译器 13K 行 AI 生成 PR 事件的社区讨论,展示了 AI 辅助编程的典型反面案例。 ↩︎
🔬 L1 | Oxide RFD 576: Using LLMs at Oxide - Oxide 公司关于企业级 LLM 使用的详细策略文档,强调责任、严谨、同理心等核心价值观。 ↩︎