1. 当“写代码”不再是核心动作,程序员的价值锚点正在漂移
过去十几年,我们评价一个开发者的能力,习惯看他写得多快、写得多好、对语言特性掌握得多深。键盘敲击速度、代码行数、调试经验,这些构成了“码农”这个身份的基本盘。但最近一两年,尤其是智能体编程工具密集落地之后,我身边不少一线开发者都经历了一种微妙的心理落差:你花半小时手写的一段业务逻辑,智能体可能几十秒就生成完毕,而且风格统一、边界处理甚至比你更周全。这不是危言耸听,而是正在发生的日常。
这个项目标题里提到的“99%代码交给智能体,你只需做这三件事”,本质上是在描述一种角色迁移:从亲手实现每一个函数的人,变成定义目标、约束边界、验收结果的人。我把这个新角色叫做“指挥官”。指挥官不亲自扣扳机,但他决定打哪里、什么时候打、打到什么程度算赢。对应到AI编程场景,这三件事就是:把需求翻译成智能体能理解的精确指令、为智能体搭建可运行可验证的工程环境、对智能体的产出做质量裁决与迭代反馈。
这篇文章适合三类人看。第一类是一线开发者,正在焦虑自己的编码技能会不会被稀释;第二类是技术管理者,想知道团队引入智能体后工作流该怎么改;第三类是对AI编程感兴趣但还没真正上手的人,想搞清楚“智能体编程”和“用AI补全代码”到底差在哪里。我会把这三件事拆开揉碎,配上我实际踩过的坑和验证过的操作细节,让你看完就能在自己的项目里试起来。
2. 智能体编程和代码补全,差的不是一点半点
2.1 从“你写它猜”到“你说它做”的范式切换
很多人第一次接触AI编程,用的是代码补全工具。你敲一个函数名,它帮你补全参数和返回值;你写一段注释,它给你生成几行实现。这种模式的核心还是“你在写”,AI只是加速器。但智能体编程完全不同。你给它的不是一个函数签名,而是一个任务描述,比如“帮我把用户模块的注册流程改成支持手机号加验证码,同时保留原有邮箱注册路径,数据库迁移脚本也要一并生成”。它会自己拆解任务、规划步骤、读写多个文件、运行测试、根据报错自我修正,最后交给你一个可运行的变更集。
这个差异带来的直接后果是:你的输入质量决定了它的输出上限。代码补全时代,你写错了它顶多补错一行;智能体时代,你需求描述里有一个歧义,它可能给你生成一整套偏离方向的代码,而且因为它“太能干”,你如果不仔细验收,很容易把错误一路带到生产环境。
2.2 智能体工程的核心能力栈长什么样
我把智能体编程涉及的能力分成四层。最底层是上下文管理,智能体需要知道当前项目的目录结构、依赖关系、代码规范、已有接口定义,这些信息给不全,它就会凭空捏造。往上一层是任务规划,它要把一个大需求拆成可执行的小步骤,并且知道哪些步骤可以并行、哪些必须串行。再往上是工具调用,读写文件、执行命令、跑测试、查文档,这些动作它得能自主发起。最顶层是自我验证,它要能判断自己生成的代码是否满足需求,不满足就回退重试。
这四层里,最容易被低估的是上下文管理。我见过太多人直接把智能体往一个老项目里一扔,说“帮我加个功能”,结果它生成的代码引用了根本不存在的工具类,或者把新逻辑写到了错误的模块里。不是智能体不行,是你没给它足够的“地图”。
2.3 为什么说“99%代码交给智能体”不是夸张
有人会觉得99%这个数字太激进。我一开始也这么想,直到我统计了自己最近三个月在一个中型项目里的实际工作。这个项目大约四万行代码,我亲手敲的代码占比不到百分之五,而且主要集中在两类:一类是智能体反复改不对的边界条件处理,另一类是涉及内部加密协议的敏感逻辑,我出于安全考虑不放心让它碰。剩下的业务逻辑、接口定义、单元测试、数据库迁移脚本、甚至部分前端组件,都是智能体生成后我审查修改的。
但这里有个关键前提:那99%的代码不是“一键生成”出来的,而是经过多轮对话、约束、修正才达到可合并状态的。智能体第一版产出通常能覆盖百分之六七十的正确逻辑,剩下的百分之三四十需要你通过反馈把它拉回来。所以“指挥官”的工作量并不小,只是工作性质变了——从体力活变成了判断活。
3. 第一件事:把模糊需求翻译成智能体能执行的精确指令
3.1 需求描述的颗粒度决定返工次数
我做过一个对比实验。同一个需求“给订单列表加一个按状态筛选的功能”,我用两种方式给智能体下指令。第一种是口语化描述:“订单列表需要支持按状态筛选,状态包括待付款、已付款、已发货、已完成。”第二种是结构化描述:“在订单列表页顶部添加筛选栏,筛选栏包含一个下拉选择器,选项值为 pending、paid、shipped、completed,默认选中全部。选择后触发列表刷新,刷新时调用 GET /api/orders?status=xxx 接口,接口返回结构不变。筛选栏样式复用现有 FilterBar 组件。”
第一种方式,智能体生成了筛选逻辑,但状态值用了中文枚举,接口参数名用了 state 而不是 status,前端组件也是自己新写了一个,没有复用已有的 FilterBar。我花了将近二十分钟跟它来回修正。第二种方式,它一次就生成到位,我只改了一个样式间距。颗粒度差一个层级,返工时间差一个数量级。
3.2 我常用的指令模板长什么样
经过反复打磨,我现在给智能体下指令基本遵循一个固定结构,你可以直接拿去用:
任务目标:一句话说清楚要做什么。 涉及范围:列出需要改动的文件或模块,如果不知道具体文件,描述功能边界。 输入输出:接口的请求参数、响应结构、数据格式,越具体越好。 约束条件:代码规范、依赖限制、性能要求、兼容性要求。 验收标准:怎么判断做完了,最好能对应到可运行的测试或可观察的行为。这个模板看起来啰嗦,但它能逼你把脑子里那些“默认成立”的假设显式写出来。智能体不会读心术,你省掉的每一句话,它都会用一次错误的生成来提醒你。
3.3 一个真实案例:从三次返工到一次通过
上个月我要给一个后台管理系统加“批量导出选中用户”的功能。第一次我给的指令是:“加一个批量导出用户的功能,导出格式用 Excel。”智能体生成了一个导出按钮,点击后调用了后端接口,但接口是它自己编的,前端也没有处理选中状态。第二次我补充了“基于表格的选中行导出”,它改对了前端逻辑,但后端接口返回的是 CSV 格式,不是 Excel。第三次我把接口定义、文件命名规则、导出字段列表全部写清楚,它才一次生成到位。
后来我复盘,如果第一次就把“选中行 ID 列表通过 POST 请求体传给 /api/users/export,后端用 openpyxl 生成 xlsx 文件,文件名格式为 users_export_YYYYMMDD_HHmmss.xlsx,导出字段包括用户名、邮箱、注册时间、最后登录时间”这些信息写进去,根本不需要三次。智能体的“笨”,很多时候是你指令的“模糊”映射出来的。
4. 第二件事:给智能体搭一个能跑、能测、能回滚的工程环境
4.1 为什么环境准备比写指令还重要
指令决定智能体“想做什么”,环境决定它“能做什么”。我见过一个团队,智能体生成的代码逻辑完全正确,但因为项目里没有配置测试框架,智能体无法自我验证,只能靠人工跑一遍才知道对不对。结果每次生成完都要手动启动服务、点页面、看日志,效率反而比手写还低。后来他们花半天时间把单元测试和接口测试跑通,智能体的自我修正能力立刻上了一个台阶——它能在生成代码后自己跑测试,根据报错调整实现,直到测试通过才交出来。
所以我在任何项目里引入智能体之前,都会先做三件事:确保项目能一键启动、确保有可运行的测试用例、确保代码变更可以快速回滚。这三件事不做,智能体就是个只会写代码不会验证的“盲人”。
4.2 最小可运行环境的搭建清单
以我最近在用的一个 Python 后端项目为例,我给智能体准备的环境包括:
- 依赖管理:用
uv或poetry锁定依赖版本,避免智能体安装不兼容的包。我试过让它自己pip install,结果它装了一个和现有框架冲突的版本,排查了半天。 - 测试框架:
pytest加pytest-cov,每个核心模块至少有冒烟测试。智能体改完代码后会自动跑pytest tests/ -x,遇到失败就停下来修。 - 代码规范工具:
ruff做 lint 和格式化,mypy做类型检查。智能体生成完代码会先跑一遍ruff check和mypy,把低级错误挡在提交之前。 - 版本控制:每次智能体任务开始前自动创建一个分支,任务完成后我审查 diff 再决定是否合并。这样即使它改崩了,我直接删分支就行,不影响主幹。
- 日志与可观测:本地开发环境打开详细日志,智能体可以通过日志判断接口是否被正确调用。
这套环境搭下来大概需要一两个小时,但之后每次智能体任务的效率提升是数量级的。磨刀不误砍柴工,在智能体编程里体现得淋漓尽致。
4.3 让智能体自己跑测试的配置细节
智能体跑测试不是简单执行一条命令就行,你需要告诉它测试的范围和预期。我通常会在项目根目录放一个AGENT.md文件,里面写清楚:
## 测试命令 - 全量测试:pytest tests/ -x --tb=short - 单模块测试:pytest tests/test_<module>.py -x - 类型检查:mypy src/ - 代码规范:ruff check src/ ## 测试通过标准 - 所有测试用例通过 - 无 mypy 类型错误 - 无 ruff 严重级别告警 ## 失败处理 - 如果测试失败,先阅读报错信息,定位到具体文件和行号 - 修改代码后重新运行相关测试,直到通过 - 如果连续三次修改仍失败,停止并输出失败原因这个文件相当于给智能体的一份“操作手册”。有了它,智能体在自我验证环节的表现会稳定很多,不会出现“测试失败了但它假装没看见继续往下走”的情况。
5. 第三件事:做质量裁决,而不是做代码搬运工
5.1 审查智能体产出的三个层次
智能体交给你代码之后,你的审查不能只看“能不能跑”。我一般分三层看。第一层是功能正确性,跑测试、点页面、看接口返回,确认需求被满足。第二层是代码一致性,看它有没有遵循项目已有的命名习惯、目录结构、错误处理方式。智能体很容易“自作主张”引入新的模式,比如项目里统一用自定义异常,它却抛了内置的ValueError,这种不一致短期没事,长期会变成维护噩梦。第三层是安全与边界,看它有没有处理空值、越界、并发冲突、权限校验这些容易被忽略的情况。
第三层是最容易出问题的。智能体生成“正常路径”的代码很擅长,但异常路径经常一笔带过。我现在的习惯是,每次审查时专门问自己一句:“如果用户传了空值、如果接口超时、如果两个请求同时改同一条数据,这段代码会怎样?”很多时候这一问就能发现智能体漏掉的边界处理。
5.2 反馈智能体的正确姿势
发现智能体产出有问题时,反馈方式直接决定它下一次能不能改对。我总结了一个原则:指出具体位置、描述预期行为、给出修改方向,但不要直接告诉它怎么写。比如它生成的查询接口没有分页,你不要说“加个 limit 和 offset”,而是说“这个接口在数据量大的时候会返回全部结果,需要在数据库层面做分页,每页默认二十条,页码从请求参数获取”。前者它只会机械地加两个参数,后者它会去理解分页的完整逻辑,包括参数校验、默认值、边界处理。
另外,反馈要一次给全。我试过挤牙膏式反馈,改完一个点再说下一个,结果智能体每次都在局部修改,最后代码结构变得很别扭。后来我改成一次性列出所有问题,它反而能整体规划,改出来的代码更干净。
5.3 什么情况下必须人工接管
虽然标题说99%交给智能体,但有些场景我坚决自己写。一是涉及资金计算、权限判定、加密解密的逻辑,这些地方错一个符号就是事故,我不放心让智能体独立完成。二是性能极度敏感的代码,比如高频交易路径上的循环,智能体生成的实现往往“正确但不够快”,需要人工做算法层面的优化。三是和外部系统对接的协议适配层,因为外部系统的文档经常和实际行为不一致,智能体只能按文档写,踩坑还得人来填。
指挥官的价值不在于什么都不做,而在于知道什么时候该亲自出手。把智能体当成一个能力很强但经验不足的初级工程师,你的角色就是那个兜底的技术负责人。
6. 从码农到指挥官,我踩过的五个坑
6.1 坑一:把智能体当搜索引擎用
刚开始用的时候,我习惯问它“这个功能怎么实现”,然后把它给的代码复制到项目里。结果发现它给的代码经常和项目现有结构不匹配,改起来比自己写还费劲。后来我改成把项目上下文一起给它,让它基于现有代码生成变更,情况才好转。智能体不是问答机器人,它是需要上下文的执行者。
6.2 坑二:一次给太大的任务
我试过让智能体“把整个用户模块从 Session 认证改成 JWT 认证”,涉及十几个文件。它确实生成了大量代码,但改到一半就乱了,有些文件改了有些没改,测试也跑不过。后来我把大任务拆成“先加 JWT 工具类”“再改登录接口”“再改鉴权中间件”“最后清理 Session 相关代码”四个子任务,每个子任务单独验证,才顺利完成。智能体的工作记忆有限,任务粒度控制在它能一次理清的范围内。
6.3 坑三:忽略智能体的“幻觉依赖”
智能体有时候会引用一些不存在的库或函数。比如它生成了一段用requests发请求的代码,但项目里实际用的是httpx。这种“幻觉依赖”在它不熟悉项目时特别常见。我的应对方法是,在AGENT.md里明确列出项目允许使用的依赖清单,并且在审查时专门检查 import 语句。
6.4 坑四:没有版本控制就让它改代码
早期我图省事,直接让智能体在当前分支上改,结果有一次它把一个核心文件改坏了,我又没提交,只能凭记忆手动恢复。从那以后,我养成了铁律:智能体任务开始前必须创建新分支或至少提交当前变更。这个习惯救了我好几次。
6.5 坑五:过度信任测试通过的结果
测试通过不代表代码没问题。我遇到过智能体生成的代码测试全绿,但实际运行时因为并发问题导致数据不一致。原因是测试用例没有覆盖并发场景。所以我现在除了看测试结果,还会针对关键路径做一次人工的“异常场景推演”,尤其是涉及状态变更和共享资源的逻辑。
7. 这套工作流适合什么样的项目和团队
7.1 项目特征:有测试、有规范、模块边界清晰
智能体编程在结构良好的项目里如鱼得水,在“祖传代码”里寸步难行。如果你的项目有完善的测试覆盖、统一的代码规范、清晰的模块划分,智能体能发挥出极大价值。反过来,如果项目里到处都是隐式依赖、没有测试、命名混乱,智能体生成的代码只会让混乱加剧。所以引入智能体之前,先花时间把项目的基础设施补齐,这个投入是值得的。
7.2 团队角色:需要有人对最终质量负责
智能体不会为代码负责,人才会。所以团队里必须明确谁是指挥官,谁对智能体产出的代码做最终裁决。这个角色不一定是技术最强的,但一定是最了解业务需求和系统边界的。我见过有的团队让每个人都各自指挥智能体,结果代码风格五花八门,合并时冲突不断。后来他们指定了一个人统一审查智能体产出,情况才改善。
7.3 不适合的场景:探索性原型和一次性脚本
如果你只是写一个一次性脚本,或者做一个还没想清楚的原型,手写可能比指挥智能体更快。因为智能体需要你先把需求想清楚、把环境搭好,这个前期成本在短平快场景里不划算。指挥官模式适合的是有长期维护需求、有明确验收标准的工程任务。
8. 我目前的工作流长什么样
早上到工位,我先花十分钟把今天要做的任务拆成智能体能执行的粒度,写清楚每个任务的指令和环境要求。然后启动智能体,让它在一个独立分支上跑第一个任务。它跑的时候我去处理邮件和评审。它跑完通知我,我审查 diff、跑一遍关键测试、确认没问题就合并。然后启动下一个任务。一天下来,我能推进的任务数量大概是纯手写时代的两到三倍,而且因为每个任务都有测试兜底,出错的概率反而更低。
当然也有不顺的时候。有时候智能体在一个问题上反复卡住,我会直接接管,手写那部分逻辑,然后让它继续处理剩下的。指挥官不是甩手掌柜,而是知道什么时候该自己上的那个人。这个边界感,是我用了大半年智能体编程之后,觉得最难也最值得修炼的能力。