Code Mode不是按钮,而是面向可扩展软件的协作契约
2026/9/5 23:40:37 网站建设 项目流程

如果你看过程序员用 AI 对话框生成整个订单模块,再看一遍他后来如何为了支持多租户把模块推倒重做,大概会同意一件事:Code Mode 这个词,重点不在 Mode,而在“这模式是否面向可扩展软件”。Dex Horthy 发布 AI That Works 第 72 期时用了一个很长但准确的标题:面向可扩展软件的 Code Mode。它真正值得讨论的,不是让 AI 多写代码,而是让 AI 在软件系统里做一次可审计、可回滚、有边界的修改。

很多开发者在实际使用中早已走到这一步:不再问 AI“帮我写个订单模块”,而是告诉 AI“只改 service 层里的订单仓库接口,补一个分页查询方法,保持对外 API 不变”。这其实就是在实践面向可扩展软件的 Code Mode。但这不只是提示词的区别,也不只是某个工具界面的差异。背后是软件工程对变更管理的理解,是把 AI 从“生成器”变成“结对程序员”的关键一步。

1. “面向可扩展软件的 Code Mode”不是一句口号

1.1 对话模式生成的是“能跑的代码”,Code Mode 关心的是“能进仓库的变更”

用 AI 对话时,最典型的工作方式是“给我写一个函数”或“给这段代码加个功能”。它在几秒内输出完整代码,你粘贴到项目里,再手动修修改改。这个流程对脚本、算法验证、一次性工具非常有效。一旦目标是可扩展软件,问题就开始出现。

原因很直接:代码要能在一段时间内被反复修改,就必须有版本记录、评审记录和回滚能力。而对话模式生成的代码是“一次性文本”,它不属于任何文件、不产生 diff、不经过代码评审,也不自带测试。它只在聊天记录里存在。把它粘进代码库,等于直接绕过软件工程的一整套护栏。

Code Mode 的核心变化,是把 AI 的产出从“一段回答”变成“一个变更”。它让 AI 以代码文件、补丁、提交为单位来思考问题,并在生成代码时尽量遵循项目原本的结构和风格。这对可扩展软件来说才是关键:只有变更可以被定位、比较和撤销,系统才能持续演进,而不是反复重写。

1.2 Code Mode 不是按钮,而是你和 AI 之间的协作契约

在产品层面,很多工具都有叫“Agent”“Composer”“Code”之类的模式选项。但在工程实践里,真正决定成效的不是界面上的哪一个按钮,而是你是不是对 AI 提出了“按代码评审标准输出”的要求。

我把这种要求理解成一份协作契约,至少包含四点:

  • 明确本次改动的目标,最好对应一个可验收的行为变化。
  • 明确 AI 有权修改哪些文件,以及绝对不能碰哪些区域。
  • 给出验证方式,比如测试命令、检查清单或手工回归步骤。
  • 要求 AI 解释每个关键改动,而不是直接丢出新代码。

这四点不是形式主义。它们解决同一个问题:让 AI 的智能被约束在一个可理解的范围内。可扩展软件的复杂度,本来就不允许任何一个参与者——无论是人还是 AI——在边界之外自由发挥。

也许你会觉得这些要求太麻烦。但我们可以看一个反例:开发者对 AI 说“帮我把支付模块改得更稳定”,AI 可能给出的回答,会包括重构所有核心状态、调整数据库索引、把同步逻辑改成异步。每项听起来都合理,但合在一起就是一次高风险发布。可扩展软件真正想要的,不是“变强”,而是“在不破坏既有行为的前提下增强局部能力”。没有契约约束的 AI,只会放大你的模糊需求。

2. 可扩展软件真正考验 AI 的,是边界感而不是生成速度

2.1 可扩展性的本质是改动局部化、影响可预测

要讨论 AI 怎么写可扩展软件,先得说清楚什么是“可扩展”。很多团队把它理解成“功能多”或“性能高”,这其实是侧面。可扩展软件的关键特征是:当新需求进来时,你需要修改的地方是局部的,而不会像滚雪球一样越滚越大。

为什么这很重要?因为软件一旦进入真实业务,会积累很多“不能碰的前提”:旧客户的数据结构、第三方 API 的兼容、合同里承诺的响应格式。一个功能如果修起来必须同时改十几个模块,那么每次迭代都等于一次小型事故。

因此,可扩展软件对代码单元的要求,不只是“能跑”,还要“边界清楚”:模块知道哪些是自己的事,哪些该交给别的模块;对外暴露的接口尽量稳定;内部实现可以调整,但不影响使用者。任何人或 AI 在改代码时,只要越过这条边界,就会立刻破坏可预测性。

2.2 AI 没有“系统全局地图”,边界必须由人明确提供

很多人在使用 AI 时会有一种错觉:它读过整个代码库,所以应该全局理解系统。但现实是,工程级 AI 工具的上下文往往只覆盖你选中的文件、目录或文档,并不是真正的“全库心智”。即便工具引入了更大上下文,也依然存在被遗漏的隐式依赖、约定和历史原因。

正是在这种“AI 系统视野有限”的背景下,边界感变得尤其关键。你需要主动告诉 AI:

  • 这个模块对外承诺的接口文件在哪。
  • 哪些文件属于内部实现,AI 可以自由调整。
  • 哪些模块属于历史兼容红线,绝不能动。
  • 新修改应该落在哪一层,是 service、repository 还是 controller。

这些信息不是代码注释的替代品,而是 AI 执行任务时的“观察窗口”。窗口给多大,AI 就能多精确地理解任务;窗口给得太宽,AI 反而容易被无关代码干扰。

2.3 有限上下文不是缺陷,它反而倒逼小步提交

在一些编码模型评测或受限执行环境里,常会看到类似evaluation mode running with code size limit: 2k的提示。这通常意味着当前运行环境限制的代码规模在 2k 量级,不能一次生成一个大模块。

这类限制容易被认为是能力短板。但从可扩展软件的角度看,它反而是一种保护:如果你只能在一个 2k 规模的差异里完成修改,你就必须把任务拆小,必须先把小改动验证好再继续。复杂系统里多数严重事故,都不是单点小修改造成的,而是多个范围模糊的大修改叠加出来的。

我并不是说所有工具都应该限制在 2k,工程上当然有批量重构、跨文件迁移的需求。真正重要的不是数字本身,而是你要理解 AI 的“有效工作半径”是有限的。一旦你试图绕过这个半径,让它一次性处理过大改动,它就会开始在无关代码里“发挥”,边界也随之消失。

3. Code Mode 落地流程:从任务卡片到合并,每一步都要可审计

3.1 第一步:写一张任务卡片,把“不做”写清楚

Code Mode 最基础的落点,是先把你想达成的行为变化写成一个短小的“任务卡片”。卡片不一定写在文件里,也可以作为第一条提示词传给 AI。它不会让你的提示词变长很多,但会明显提高 AI 输出的稳定度。

任务卡片建议至少包含五块内容:目标、改动范围、禁止改动、验收标准、回滚预案。下面是一个常见写法:

任务:为订单服务增加“按用户ID查询订单列表”接口 目标: - 新增 list_orders_by_user_id(user_id, page, size) - 复用已有的分页结构,不改变现有响应语义 改动范围: - src/order/repository.py - src/order/service.py - tests/order/test_service.py 禁止改动: - 不改数据库表结构 - 不修改订单状态机的任何取值 - 不添加新的全局缓存 验收标准: - pytest tests/order -q 通过 - 无用户或参数越界时,沿用现有异常类型 - 已有订单相关用例全部通过 回滚预案: - 若合并后发现异常,git revert <commit>,不回退数据表

看起来像需求单,但真正用过之后就会知道,它对 AI 的约束力很直接。只要是按这个结构给出的任务,AI 就不容易把“新增接口”做成了“顺手重构订单模块”。

3.2 第二步:让 AI 先给改动方案,再给代码

很多工程师一上来就让 AI 直接生成代码,结果生成完发现它改了预期之外的文件。更稳的顺序是“先要方案,再要 diff”。

你可以把上面那张任务卡片继续发给 AI,并加一句:“先不要写代码,只告诉我你会改动哪些文件、哪些函数,风险点是什么。确认后我再让你输出补丁。”这样做的价值,是把 AI 从“追求即时输出”的逻辑中拽出来,让它先建立问题模型。

方案确认后,下一步也不是让它生成完整文件。更可审计的方式,是要求 AI 输出一个统一格式的 diff,或者至少逐段给出“文件路径 -> 当前代码 -> 新代码 -> 改动原因”。这样你在评审时,不是在几千行代码里猜它为什么要改,而是在每个 diff 片段上做决定。

3.3 第三步:用最小验证替代“看起来没问题”

AI 生成的代码第一版大概率能跑,但能跑不代表没破坏边界。所以验证动作必须落在至少两个层面:

第一层,自动化测试。哪怕项目当前测试不多,也要把 AI 改动涉及到的模块跑一遍。第二层,diff review。重点看新增代码有没有触碰禁止改动的区域、有没有把私有方法改成公共方法、有没有偷偷引入新的第三方依赖。

常见命令可以这样用:

git diff --stat git diff src/order/ tests/

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询