
最近一个做技术管理的老朋友跟我聊起一件事他们团队三个月前开始重度使用 AI 编程智能体开发内部系统新功能出得极快负责人一度非常满意。但等到第二个月做迭代时维护成本开始失控——AI 生成的代码风格不一致模块之间耦合严重很多地方没有测试加一个小字段需要改三处调用每次改完总有一两个隐藏问题。更尴尬的是已经没有人能说清某段逻辑当初为什么要这样写。这个故事并不是孤例。现在很多团队对 AI 编程智能体的评价非常两极在小 demo 和原型项目里它几乎无所不能进入真实业务系统的长期维护阶段却很容易变成“代码噪声制造机”。所以“AI编程智能体能否构建可维护软件”这个问题值得认真回答。我的判断是AI 编程智能体已经能构建“能运行的软件”但“可维护的软件”是另一件事。前者是生成问题后者是边界问题。标题里的 Boundary 这个词恰好点出了真正的关键——我们需要认真讨论的不是 AI 能不能写代码而是我们有没有为它划清任务、质量、上下文和责任的边界。1. 先别急着回答“能”先搞清楚“可维护软件”到底难在哪1.1 “跑通”和“可维护”是两种完全不同的判断标准一个程序能跑通只能说明在某个输入范围内行为符合预期。而可维护软件意味着在未来的 12 个月、24 个月里它能持续以可接受成本被修改、扩展、迁移和删除。这两者的评价标准完全不同。AI 编程智能体天然擅长给人类提供“跑通”这个反馈运行一次成功了测试通过了界面能操作了这些反馈都是即时、可感知的。因此人很容易被当下的正反馈误导得出“AI 已经能构建可维护软件”的结论。但维护成本是一个延迟反馈。它往往要等几周、几个月后才出现在某次需求变更中表现为一个原本应该半小时完成的改动花了整整一天才理清关联关系。等到团队意识到问题时AI 生成的代码已经融入系统处理成本比当初阻止它更贵。所以我的第一个建议是评估 AI 编程智能体时不要用 demo 的完成速度做判断标准而要用“三个月后改需求需要多久”来衡量。这才是可维护软件的真正定义。1.2 可维护性不是一种风格而是一组约束系统很多管理者把可维护性理解为“代码整洁”这是一种过于狭窄的理解。整洁只是表面真正决定可维护性的是一组约束系统。维度含义AI 生成代码的常见薄弱点可读性接手者能否快速理解意图变量命名随意关键逻辑缺少注释可测性是否能低成本编写有效测试逻辑与副作用耦合难以 mock可扩展性加需求时能否局部修改缺少接口抽象到处打补丁可删除性废弃功能能否被安全移除引用关系混乱删除后残留一致性是否符合项目既有约定风格跳变架构层级混乱这些约束不是静态规则而是项目在长期演进中形成的“集体记忆”。AI 编程智能体如果只看到当前任务片段不知道项目的全局约定生成结果自然容易破坏一致性。举个例子一个项目规定所有外部调用必须走 repository 层数据库错误统一封装成领域异常。但 AI 智能体在只看到服务类代码时很可能会直接在一个新方法里写 sql 查询或抛出底层异常。单看代码不算错放进整个系统架构里就是一次维护债务。可维护性永远是“系统视角”的评价不是“单文件视角”的评价。1.3 为什么 AI 生成的代码经常“第一眼很漂亮第二眼很头痛”AI 编程智能体在生成代码时优化目标通常是“概率上最像人类代码”而不是“在这个项目中长期最可维护”。它没有经历过维护这种代码的痛苦也不会为三个月后的需求变更提前做设计预留。它能模仿优秀代码的表层合理的命名、漂亮的格式、常见的结构。但这些表层背后有一整套决策逻辑为什么这里用策略模式而不是 if-else为什么这个函数不暴露给外部为什么这里选择快速失败而不是兜底这些决策往往来自对业务需求、团队能力和长期演进成本的综合判断不是单个代码片段能体现的。所以评估 AI 智能体的能力时不能只看它生成了什么样的代码还要看它是否理解这些代码在系统里的位置以及将来会如何被修改。否则我们只是在用“代码看起来整洁”替代“代码真正可控”。2. AI 编程智能体真正强的不是“写代码”而是“把一次性操作变成可复用流程”2.1 能力变化从“补全一个函数”到“完成一次小任务”现在的 AI 编程智能体已经远不止“代码补全”这么简单。它可以理解自然语言任务可以读取多个文件可以修改多处代码可以运行测试并根据报错信息继续修复。在合适的条件下它已经像一个“能执行任务的初级工程师”。这种能力带来的真正价值是把开发者从“手动实现已知方案”中解放出来。比如生成 CRUD 接口、写单元测试、批量修改某个函数签名、整理配置文件模板这些重复性工作交给 AI 后人的时间可以更多用于设计、评审、排查和运维。但要注意一个前提这种能力之所以有效是因为任务已经被人类拆解成了相对明确、可验证、局部的小步骤。一旦任务模糊、方案争议、跨模块影响未知AI 的表现会迅速下降甚至会信心满满地给出一个“看起来合理但实际会破坏架构”的改动。2.2 擅长清单和不擅长清单我们需要对 AI 编程智能体的能力范围有一个清醒的认识。以下是我在工程实践中的归纳AI 编程智能体相对擅长的场景AI 编程智能体需要强约束的场景有明确规格的接口/CRUD/数据转换从含糊的产品描述直接设计架构根据类型定义生成实现在遗留代码中判断正确的抽象层级为已有函数补测试在多个技术方案间做长期取舍批量格式化、命名统一、API 迁移处理“这里为什么存在”的隐性知识生成脚手架、样板代码、配置保持跨团队一致的编码风格这个区分非常关键。因为很多人失败的原因是把 AI 从“擅长清单”直接扔进“强约束场景”。比如让 AI 根据一句话需求设计一个订单系统的模块边界这就相当于让一个执行力很强但没有业务背景的人去做架构决策结果可想而知。2.3 它更像“非常快的执行者”而不是“负责任的设计者”我的核心判断是AI 编程智能体是极其快速的执行者但不是一个负责任的设计者。它不会为自己的代码负责。它不会在一年后回来处理自己留下的技术债也不会因为模块可扩展性差而被扣绩效。它只负责“在当下把任务做完”而不负责“让系统在长期保持健康”。所以我们必须把“维护责任”这条边界设清楚。AI 可以快速执行人也必须快速审核AI 可以生成方案人也必须对方案去向做判断。真正决定可维护性的不是 AI 的能力而是人的把关质量。如果把软件开发比作一次长期项目AI 更像是效率极高的“外包执行团队”而内部的主架构师和开发负责人仍然需要对边界、结构、技术债和长期趋势负责。这个认知能帮我们避免很多不切实际的期望。3. 想让 AI 智能体产出可维护代码先给这五条边界画清楚3.1 任务边界把任务缩小到“一次评审能看懂”的粒度不要一次让 AI 从零构建整个模块。给它的任务应该像一个小而清晰的任务单包含目标、输入、输出、涉及文件、禁止修改文件和完成标准。任务越清晰生成结果越可控也越容易维护。下面是一个常见写法它可以作为团队模板的基础目标在 order service 中新增批量查询接口 输入OrderId[]返回 OrderSummary[] 涉及文件src/order/query.ts, src/order/query.test.ts 禁止修改src/payment、src/legacy 完成标准 - tsc 类型检查通过 - 新增测试覆盖空列表和异常输入 - 不改动已有接口行为这份任务单看起来简单但它定义了四条至关重要的边界做什么、改哪里、不碰哪里、什么叫完成。AI 智能体在这样的边界内工作产出的代码会稳定很多。3.2 数据边界限制它可读、可写的文件范围真实项目里如果 AI 智能体被授予整个仓库的读写权限它很容易跨层修改。比如为了“顺手优化”把底层工具函数也改了导致与本次需求完全无关的模块发生行为变化。更稳妥的做法是限制上下文和文件读写范围。能在配置层限制就限制不能限制时至少要在 diff 审查阶段建立“无关修改不得合并”的规则。不要因为 AI 能力强就默认它拥有全仓权限。权限越大风险扩散越难控制。3.3 上下文边界给它足够但不越界的上下文给 AI 编程智能体的上下文不是越多越好。代码太多反而会淹没关键信息让它在无关的模式里寻找“灵感”最后生成一个四不像。更合理的做法是围绕任务本身提供上下文接口定义、数据模型、当前函数、调用方示例、项目规范片段。这些是生成可维护代码的必要条件。如果你真的需要它理解更广的模块可以先用一段话总结模块职责再把相关文件路径给它而不是直接把整个仓库的代码塞进上下文。保持“聚焦”本身就是一种可维护性的保障。因为当上下文越聚焦AI 的变更范围就越可预期评审时的认知负担也越小。3.4 验收边界定义“什么叫完成”AI 的默认完成标准是“代码看起来能用”。但如果由它自己判断几乎所有的生成结果都算“完成”。这是最大的风险点。人必须替它定义验收标准。比如类型检查和 lint 通过单元测试覆盖关键输入和边界条件对已有行为不产生非预期变化代码评审人看得懂并愿意签字确认。尤其是修改已有代码时“行为不变量”应当成为默认验收项。让 AI 自己跑一个新写的测试证明不了它没有破坏其他东西。必须靠全量测试和人工评审来确认。验收边界划定得越早返工越少。3.5 所有权边界写代码的人可以换维护责任不能换团队可以大量使用 AI 编程智能体生成代码但每个模块必须有一个“维护责任人”。责任人负责评审 AI 生成的变更、解释关键决策、维护模块文档并在未来需求变更时承担改动成本。没有责任人的 AI 生成代码最终会成为“孤儿代码”。它们看起来还在运行但没有人敢动没有人知道为什么这样写也没有人愿意为它补充测试。这是比代码风格混乱更可怕的长期风险因为可维护性本质上依赖“有人愿意承担责任”。一个实用的边界清单可以贴在团队文档里边界类型核心问题落地动作任务边界这次要做什么写任务单明确目标和范围数据边界可以读哪些文件、改哪些文件配置读写权限或要求 reviewer 严格把关上下文边界给 AI 多少信息才足够提供接口、模型、规范而不是全仓代码验收边界什么叫完成定义类型检查、测试、行为不变、评审通过所有权边界出了问题谁负责指定模块维护责任人一条重要的实操经验先给 AI 一个很小的任务比如“给这个工具函数补测试并保持行为不变”跑通后你再逐步放开范围。不要第一次就让它重构整个服务。4. 在工程实践里AI 生成的代码离“可维护”还差哪几块拼图4.1 缺的从来不是代码量而是系统性的“架构看护”代码规模小的时候AI 生成看起来没问题。但项目一长大模块边界被破坏、依赖关系变乱、抽象层次混乱问题就会出现。AI 编程智能体没有“长期架构记忆”。它不知道模块设计的初衷不知道有些地方为什么不能互相依赖也不清楚未来业务会在哪个方向演进。它只会按照当下任务和现有代码模式做局部优化而这种局部优化很容易与全局架构相冲突。因此团队需要补上“架构看护”的角色。可以人工也可以用工具固化包依赖规则、分层约束、模块准入标准。比如“controller 层不能直接访问 repository 层”“基础设施代码不能污染领域层”这些约定应该变成机器可检查的规则而不是靠每个人自觉。只有当架构边界被持续看护时AI 生成的代码才有机会顺着正确的结构生长。4.2 可测试性是最容易牺牲的工程属性AI 生成的代码往往喜欢把逻辑直接写在组件或服务方法里缺少依赖注入缺少纯函数导致测试只能 mock 很重的外围依赖。这种情况下写测试的成本极高开发者就会选择不写可维护性随之下降。解决思路是在任务单中明确要求“业务逻辑与副作用分离”。比如让 SQL、网络请求、文件 IO 等副作用封装在独立层让核心计算逻辑写成不依赖外部状态的纯函数让 AI 为纯函数先写单测再补外层集成。同时要警惕 AI 生成“为了过测试而过的测试”。它可能把断言写得极其宽松或者只覆盖正常路径对边界和异常不闻不问。测试的价值不在于数量而在于语义是否准确。这仍然需要人来审查。4.3 缺少“变更影响面”意识当我们让 AI 修改一个函数时它有时会顺手修改相邻代码理由是“这里看起来有 bug”或“这样更合理”。这种无关修改是最危险的维护风险当前任务的验证往往不会覆盖这些无关区域于是新问题被悄悄带入系统。在 Review AI 变更时必须只接受最小变更。具体来说看 diff 中是否包含任务描述之外的文件看每一处改动是否都对应本次需求发现“顺手优化”要求撤销或单独发 PR。这不是限制 AI 的能力而是让每一次改动都可追溯、可解释。可维护性要求系统每个部分的变化原因都是清晰的而不是“反正它顺手改了”。4.4 命名、抽象和一致性需要项目“宪法”可维护软件背后往往有一组隐性约定错误如何抛出、目录如何命名、组件如何分层、函数如何返回结果。AI 编程智能体不会自动遵守这些约定除非你在任务中明确输入。更好的做法是建立一份“项目宪法”写得足够具体可以放进智能体的系统提示词或规范文件。例如错误处理所有业务错误统一抛出领域异常不直接返回 null命名repository 方法用动词短语service 方法以业务流程命名分层controller 只做参数校验和响应转换测试每个公共函数必须有至少一个正常路径和异常路径测试。同时用 lint、架构守护工具把这些约定变成可自动化检查的规则。否则约定只是愿望不能持久。4.5 维护是一个负熵过程AI 既是加速器也可能是加速失控器软件在没有人为治理的情况下一定会变得越来越乱。变量命名从清晰到随意模块从低耦合变成蜘蛛网注释从解释原因变成陈述表象。AI 编程智能体也存在同样的加速效应。它会参考现有代码模式生成新代码。如果现有代码整洁它大概率生成整洁代码如果现有代码混乱它会沿用混乱的模式甚至把混乱复制得到处都是。也就是说AI 不会自动校正代码库的演进方向它只会放大当前基线的状态。所以只有先治理好代码基线再大规模使用 AI才可能获得正向收益。如果你现在的代码库已经技术债缠身最不应该做的事就是让 AI 直接在债务上继续加码。5. 真要在项目里引入 AI 编程智能体我建议先走一条灰度路径5.1 五个阶段的能力演进很多团队一上来就让 AI 承担完整功能的开发结果往往高开低走。更稳妥的路径是从小任务、低权限开始逐步建立信任。阶段人机协作模式AI 可承担任务可以升级的前提一人类主导AI 补全单函数生成、变量重命名、注释diff 稳定评审通过二AI 执行小任务补单测、生成样板代码、修指定 bug测试通过变更范围可控三AI 承担明确功能有规格的小功能多文件修改质量门禁全绿代码可解释四AI 负责局部模块迭代受保护模块内重构、API 迁移行为 diff 验证回滚方案明确五受约束的自主开发在边界清晰的子系统内自主迭代有监控、审计、责任人和快速回滚每个阶段都需要验证上一阶段的结果。不要因为一次成功就跳过阶段也不要因为一次失败就彻底否定。灰度升级的核心是AI 的自主权必须匹配可控性。5.2 每个阶段都要保住的底线不管 AI 走到哪个阶段有几条底线不能突破所有 AI 变更必须经过代码评审所有行为变更必须有测试证明不能只看 AI 自己报“通过”所有“为什么这样做”的设计判断最终要由人回答不在没有测试覆盖、没有回滚计划的模块上让 AI 自主操作。这些底线看起来很低但在实际推进中经常被忽略。团队一旦适应了 AI 的高效输出就会下意识减少评审投入这正是风险累积的开始。5.3 哪些场景不要用 AI 智能体自主做灰度路径不仅指“逐步开放”也意味着“有些地方永远不开放”。以下几种场景我不建议让 AI 智能体自主决策需要大量隐性领域知识的遗留系统变更可能导致数据损坏或资金风险的生产系统安全、合规、审计敏感的功能没有测试覆盖、没有回滚计划的模块架构方向尚未明确的探索性代码。在这些场景里AI 更适合扮演“被明确指令驱动的助手”而不是“自主开发者”。边界不是限制 AI 发挥而是保护代码库让 AI 的产出可控、可承接。一个常见做法是让 AI 在隔离的分支或 feature flag 后面生成变更通过测试和线上观察后再合并到主干这比直接信任生成结果稳妥得多。6. 一个更现实的判断别问“能不能”要问“如何维护”6.1 可维护软件依然是软件工程问题不是提示词问题很多人以为只要 prompt 写得足够精巧AI 就能写出可维护的软件。但这个假设过于乐观。可维护性是由评审制度、测试策略、架构治理、团队规范共同保证的工程属性而不是提示词技巧能够直接输出结果。提示词只是给 AI 下达指令它决定的是“AI 按什么方向生成”但无法替代“系统长期健康”所需要的工程制度。真正可维护的软件背后往往是一个可维护的组织有清晰的责任人、有质量红线、有人愿意为长期成本做决策。因此讨论 AI 编程智能体时我们不能只问模型能力还要问组织能力。如果我们没有准备好引入变更评审、测试门禁和模块边界那么 AI 生成的代码越高效系统熵增越快。6.2 AI 真正改变的是“维护什么”和“怎么维护”AI 把写代码的边际成本大幅降低后一个更有意思的变化出现了很多以前不愿做的“脏活”现在可以交给 AI 做人把时间花在更重要的判断上。比如批量修改函数签名、迁移旧 API、补充单元测试、清理重复代码。这些工作过去成本很高容易被推迟现在可以快速完成。这意味着我们能够更频繁地进行小步重构代码库可以保持更健康的状态。但这也意味着开发者的核心能力从“写代码”变成了“定义需求、审查设计、评估风险”。我们不再需要和 AI 比拼打字速度而是需要比 AI 更清楚“什么值得做”“做到什么程度算好”“哪些边界不能越过”。可维护性的上限仍然由人的设计判断决定。6.3 人机协作的“维护性合约”每一次让 AI 执行任务之前都相当于签一份合约你AI提供最小可行变更我人提供清晰的验收标准和边界如果变更破坏可维护性我可以拒绝合并。这个合约不一定要写成正式文档但它必须成为团队工作流的默认动作。在一次 AI 变更进来后至少要有三个问题这个变更有没有超出任务范围我是否理解它为什么这样写三个月后我还能安全地修改这段代码吗如果三个问题的答案都是肯定的这个变更就值得合并。如果有一项存疑就不要因为 AI 速度快而放松标准。可维护性是一种选择而不是自动发生的属性。6.4 下一步最该做的一件事不要急着让 AI 去构建一个全新系统。找一个已经存在、测试覆盖还不够、但规模很小的模块手动给它写一份任务单包括目标、涉及文件、禁止修改文件、验收标准然后让 AI 做一次很小的改动。接着认真看 diff跑全量测试问自己“三个月后我还能看懂并修改这段代码吗”。如果答案是肯定的你就找到了一种适合自己团队的 AI 协作方式如果答案是否定的说明边界还不够清晰继续调整任务单。把这次经验作为团队引入 AI 编程智能体的基线。先跑通一条最小闭环再逐步扩大权限。可维护软件不是一次生成出来的而是在长期迭代中一次次保护下来的。AI 能做得越多人的边界意识越要清楚。不是限制 AI而是当我们知道边界在哪里AI 才能在安全范围里最大程度地发挥。