Vibe Coding 的 70% 之后

摘要从一个会话复盘工具的诞生与失控,讲清提示词、代码接管、生产安全、后台 Agent,以及开发者如何守住最后的工程责任。

文章目录9 节
  1. 第一个晚上,页面已经能跑了
  2. 提示词是一份会继续生长的任务合同
  3. 第一个真实用户撞上了最后 30%
  4. 代码进仓库,责任也随之进来
  5. 从原型到生产,要开始设计失败
  6. 还要追问代码从哪里来、数据去了哪里
  7. 后台 Agent 把一次对话变成一次委派
  8. 人的价值开始体现在判断质量
  9. 资料

Addy Osmani 的《Beyond Vibe Coding》共有 11 章、254 页。全书从 Vibe Coding 和提示词起步,经过原型、Web 开发与代码审查,最后进入安全、伦理、后台 Agent 和职业变化。

它讨论的核心问题很朴素:模型已经可以在几分钟里搭出一套像样的软件,接下来谁来理解它、验证它、维护它,并在出事时承担责任?

为了让这件事具体一点,我们用一个虚构的小项目贯穿全文:做一款会话复盘工具。用户上传 Agent 的执行日志,系统在后台生成摘要、失败原因和改进建议,最后得到一条可以分享的报告链接。功能听起来只需四步:登录、上传、分析、分享。它也恰好会撞上 AI 编程里最常见的墙。

第一个晚上,页面已经能跑了

把需求交给编码模型:

做一个 Agent 会话复盘工具。
用户可以上传 JSON 日志,查看分析进度,完成后得到一份报告。
使用 React、Go 和 SQLite,界面简洁,支持登录和分享。

模型会很快创建前端路由、上传表单、数据库表和几个 API。启动服务,页面有 loading,有成功提示,甚至连空状态都做了。上传一份样例日志,几秒后报告出现在屏幕上。这个夜晚很容易让人产生一种感觉:产品已经完成大半,剩下的只是润色。

这种速度确实有价值。过去需要先搭脚手架、查组件文档、写重复的 CRUD;现在可以直接看到交互,用真实页面检验想法。对一次性脚本、内部实验和周末原型,这种工作方式已经足够好。

书中把 AI 编程放在一条连续光谱上:

工作方式人的主要动作合适的终点
探索式 Vibe Coding描述效果、运行结果、继续调整想法得到验证
AI 辅助工程定义约束、检查实现、补齐证据系统可以维护和上线

两种方式可以出现在同一个项目里。做第一张页面时放松一些,接触用户数据时马上收紧。风险决定工程投入,不能用同一套流程处理落地页配色和权限模型。

提示词是一份会继续生长的任务合同

第一条提示词适合启动原型,留给模型的猜测空间也很大。它不知道日志能有多大,不知道报告默认私有,不知道分析服务可能超时,也不知道分享链接需要随时撤销。

更完整的一轮任务可以这样写:

目标:登录用户上传一次 Agent 会话,异步生成复盘报告。

现状:Go HTTP 服务已有 session cookie;SQLite 迁移由 migrations/ 管理;
前端请求统一经过 api.ts;后台任务目前只有进程内队列。

边界:日志最大 20 MB;报告默认仅 owner 可见;分享链接随机生成、可撤销;
同一日志重复提交只创建一个分析任务;分析超过 90 秒进入 failed。

验收:覆盖越权读取、重复提交、超时重试和撤销分享;
上传期间其他请求仍能响应;不得把原始会话写入应用日志。

交付:先说明数据流和风险,再修改代码;给出测试结果、未解决问题和回滚方法。

这里没有咒语。目标、现状、边界、验收和交付把一次聊天变成了可以核对的任务。模型少猜一步,评审者就少追一次事故。

复杂任务还需要分轮推进。第一轮只读仓库并画出数据流;第二轮确定表结构和状态机;第三轮实现一个可验证切片;后续根据测试、日志和 diff 收敛。一次生成几十个文件看起来省时,评审时却很难判断错误从哪里进入。

提示词也不该独自承担全部上下文。长期有效的事实要落进仓库:类型表达数据边界,测试表达历史行为,项目文档表达禁区,lint 和 CI 表达最低质量线。会话会结束,这些文件会继续约束下一位开发者和下一轮 Agent。

第一个真实用户撞上了最后 30%

演示时使用的是一份 30 KB 样例。真实用户上传了 18 MB 日志,整个服务开始卡顿。另一个用户连续点击两次提交,后台跑出两份昂贵的分析任务。有人把分享链接里的 ID 改了一位,意外读到了别人的报告。分析供应商超时后,页面永远停在“处理中”。排查日志时,运维人员又发现用户对话被完整打印到了控制台。

页面仍然漂亮,每个主流程也都“能用”。系统已经同时出现性能、幂等、鉴权、状态恢复和隐私问题。

书里的“70% 问题”描述的正是这种落差。70% 是体验上的比喻,无需当成精确统计。模型擅长高频结构:表单怎么写、路由怎么接、ORM 怎么查。项目最费时间的部分往往藏在局部事实和失败路径里。

演示时看到的功能上线后出现的事实需要补上的工程约束
文件上传成功大文件占满内存,请求相互阻塞流式读取、大小上限、并发控制
报告可以打开顺序 ID 可以被猜测owner 校验、随机令牌、撤销机制
点击后开始分析重复点击创建重复任务幂等键、唯一约束、状态机
页面显示处理中进程重启后任务丢失持久化 Job、租约、超时与重试
错误会写入日志日志包含用户原始会话脱敏、访问控制、保留周期

继续发一句“帮我修好”通常会进入补丁循环。模型给上传接口加了大小判断,却仍在判断前把整个文件读进内存;给报告接口补了登录校验,却忘了核对报告 owner;给失败任务加重试,又让两个 Worker 同时领取同一个 Job。

最后 30% 要求开发者离开对话框,回到系统本身:复现问题、读调用链、确定不变量、缩小改动、运行检查。AI 依旧可以参与,只是每一步都要由证据牵引。

代码进仓库,责任也随之进来

生成代码经常呈现一种迷惑性:命名完整,注释流畅,结构眼熟,读起来像团队里某位靠谱同事写的。熟悉感只能证明它接近常见答案,无法证明它符合当前系统。

例如模型可能从请求体读取 user_id,再据此查询报告。这样的写法在 CRUD 示例里很常见,在真实鉴权中却把身份决定权交给了客户端。它也可能使用内存 Map 保存任务状态,单进程演示完全正常,一次重启就会让所有处理中任务失踪。

接管生成代码时,可以沿着一次请求走完四遍:

  1. 意图遍:逐条对照需求,确认遗漏和误解;
  2. 数据遍:数据从哪里进入,经过哪些转换,最终写到哪里;
  3. 失败遍:网络断开、进程重启、重复请求和部分成功会留下什么;
  4. 权限遍:谁可以读、写、删除和分享,每一层依据什么身份。

然后再看抽象、命名与重复代码。很多评审一上来就讨论函数长度,最危险的越权访问反而藏在整洁的 helper 后面。

测试要固定行为,也要替未来保存上下文。会话复盘工具至少需要几类证据:

  • 单元测试验证状态转换和分享令牌;
  • 集成测试连接真实数据库,覆盖唯一约束和事务回滚;
  • 并发测试同时提交相同日志,确认只产生一个 Job;
  • 端到端测试用两个用户尝试互相读取报告;
  • 故障测试在任务执行中杀掉 Worker,确认租约过期后可以恢复。

当这些测试进入仓库,下一轮 Agent 无需完整听完项目历史。它只要破坏旧约束,CI 就会立刻发声。测试、类型、lint、代码审查和部署门禁共同组成了可执行的项目记忆。

从原型到生产,要开始设计失败

原型验证“顺利时能否走通”,生产系统还要回答另一组问题:用户会不会越权,依赖会不会失联,进程会不会在写到一半时退出,值班的人能不能看懂现场。

先看安全。上传内容属于不可信输入,文件名不能直接拼路径,JSON 解析需要尺寸和深度限制,数据库查询要使用参数,报告读取必须在服务端校验 owner。密钥只能从受控配置进入进程,错误日志不能顺手带出请求头和用户正文。新增依赖还要确认来源、维护状态和许可证。

再看任务状态。只有 processingdone 两个值时,系统很难处理现实。更可用的状态机会包含 queuedrunningsucceededfailedcancelled,并记录尝试次数、租约到期时间和最后一次错误。Worker 领取任务需要原子 claim;执行结果要核对 owner 或 fencing token;超时任务要能恢复,失败重试要有上限。

最后看可观测性。一次分析应有贯穿上传、Job 和报告的 request ID;指标需要展示队列长度、等待时间、成功率和各类失败;日志只保留定位问题所需的字段。上线采用小流量或可回滚发布,数据库迁移提前验证向前与向后兼容。

这些工作很少出现在漂亮的首屏截图里,却决定了团队凌晨两点面对的是一条清楚的告警,还是一片无法解释的用户投诉。

还要追问代码从哪里来、数据去了哪里

书中专门用一章讨论知识产权、透明度、公平和责任。编码模型可能生成一段高度熟悉的实现,也可能建议一个许可证不兼容的依赖。看到异常完整的注释、特定项目名或大段风格突变时,应停下来检查来源,必要时重写。团队也需要记录哪些关键模块由 AI 深度参与,保留对应的人工审查证据。

输入端同样有边界。客户代码、生产日志、密钥和个人信息能否交给外部模型,要看工具的数据政策与组织授权。把敏感日志粘进聊天窗口是一个不可逆动作,之后再删除本地会话无法收回已经发送的数据。

面向用户的生成结果还需要考虑偏差和伤害。假如复盘工具开始给开发者评分,模型可能把代码风格、语言表达和工作时长混成一个看似客观的数字。更稳妥的做法是展示可核对的事件:哪次工具调用失败、哪段测试缺少证据、任务在哪个状态停留。结论应当允许申诉,评价规则应当公开。

后台 Agent 把一次对话变成一次委派

IDE 里的助手通常伴随开发者逐步工作。后台 Agent 接到目标后,会在隔离环境里读取仓库、修改文件、运行测试,数十分钟后带回一个 diff 或 Pull Request。人可以同时派出多个任务,工作节奏从持续对话变成派发、等待和集中审查。

想象晚上十点,开发者把三个任务交出去:A 修复重复 Job,B 给上传接口改成流式读取,C 补报告越权测试。第二天一看,A 和 C 都修改了同一套测试夹具,B 为方便测试重写了上传模块,三个分支单独通过,合在一起却冲突不断。

并行能力会放大已有的任务质量。边界清楚时吞吐上升,任务含糊时会更快地产生一堆互相冲突的解释。后台 Agent 需要一套明确的执行链:

任务合同
  → 独立工作区与最小权限
  → 计划、实现和自测
  → 测试、lint、安全扫描
  → 提交 diff、证据和剩余风险
  → 人工审查与合并门禁

适合委派的任务通常有稳定复现、明确边界和确定性验收,例如补测试、升级依赖、机械迁移和修复局部缺陷。跨系统架构、生产事故、模糊产品决策仍需要人持续参与。

Agent 也需要运行边界:独立 worktree 防止互相覆盖;凭证按任务最小化;网络、时间和资源设上限;危险命令经过 hook 拦截;成功时只返回摘要,失败时把关键错误送回循环。任务完成的定义应包含测试结果、变更范围和未解决风险,不能只看“Agent 已结束”。

人的价值开始体现在判断质量

代码生成成本下降后,开发者的工作重心会移动。高级工程师要花更多时间定义架构边界、识别长期成本、制定团队标准;中级工程师要补强系统集成、性能、运维和跨模块调试;初级工程师仍需亲手理解数据结构、网络、数据库和并发,才能分辨一个答案是在解决问题,还是在制造更隐蔽的问题。

团队评价方式也要变化。生成了多少行代码、一天合并多少 PR,越来越难代表有效产出。更值得观察的是:从需求到可验证结果花了多久,线上逃逸了多少缺陷,评审发现了哪些系统风险,失败能否快速回滚,同类错误有没有沉淀成新的测试和规则。

未来的开发环境会继续吸收测试生成、调试、重构、设计和项目管理。自然语言会成为重要入口,代码依然承担精确执行和团队协作。开发者逐渐从逐字符生产代码,走向管理意图、上下文、证据与风险。

回到那款会话复盘工具。首个晚上完成的页面没有失去价值,它让想法迅速显形。后续的权限测试、持久化 Job、脱敏日志和发布门禁也没有拖慢创新,它们让这个想法获得了被真实用户使用的资格。

这本书留下的工程规则可以压成一句话:模型负责扩大实现吞吐,系统负责提供验证证据,人负责决定什么可以交付。

资料

本文根据官方目录与公开预览进行中文浓缩解读,贯穿案例为便于说明而设计。