最近我花了一整个上午跟一个代码智能体较劲。任务很简单——“给接口加个限流”它交回来一个进程内锁方案。单机运行一切正常部署到两台机器上之后立刻乱套限流统计各自为政请求瞬间把服务打穿。我一开始怪提示词太短后来复盘才意识到真正的问题不在模型不够聪明而在我一开头就没把需求说清楚。几乎在同一周我看到一位在AI领域摸爬滚打多年的工程前辈做了场访谈。访谈里有个判断在我们开发群里引发了一整天讨论未来的开发者人均会面对50个智能体“写需求”将取代“写代码”成为开发者最核心的技能。群友分成了两派。一派觉得50这个数字太魔幻完全是标题党另一派拍手叫好说这才是开发者的真正出路。我的看法是数字本身不用抬杠但“写需求取代写代码”这个方向值得所有天天跟代码智能体打交道的人认真拆解。下面这篇文字就是我结合自己最近的实战经验把这个“只见树木不见森林”的预言落到地里的过程。1. 先弄清楚“人均50个智能体”到底是在说什么场景1.1 50个不是50个聊天窗口而是50条职责线很多人听到“人均50个智能体”第一反应是一个人怎么同时开得了50个对话框我最初也这么想。后来换了个角度把这些智能体理解成“一条条自动化职责线”数字一下子就说得通了。你去看今天一个普通开发团队的工作流编码助手负责生成函数测试辅助负责补用例日志分析工具负责查异常安全扫描器负责盯依赖漏洞灰度发布脚本负责放量监控告警机器人负责通报还有代码评审助手、接口文档生成器、数据库索引建议器、需求拆分工具……每一样背后都是一个独立调度的智能体。以前它们是散落的几个小工具大家用完就关。可一旦这些能力被编排成一条完整的流水线角色就固定下来了A智能体专职拆需求B智能体专职写代码C智能体专职检查代码风格D智能体专职跑测试E智能体专职整理发布说明F智能体专职盯线上指标。你数数看一个后端项目从头到尾的职责线两位数几乎打不住。等到这些智能体既能调用外部接口、又能互相传递产出物的时候统计口径就完全变了。你不再是在“用几个AI聊天”而是在“管理一组各司其职的数字员工”。一个数字员工也未必只对应一个执行动作它可能需要一个主控智能体再加三个辅助智能体。这么一层层拆下去人均五十个并不是夸大的数字反而可能还有点保守。我得承认50更像一个数量级而不是精确的容量。但它指向了一个关键拐点当智能体的数量多到人眼无法逐个盯住结果时开发者的工作重心必然从“亲自动手做”转向“定义清楚、调度有序、验收到位”。1.2 “写需求”之所以成为核心技能本质上是因为责任转移顺着上面的思路往下走就会发现“写需求取代写代码”不是文字游戏而是一次责任迁移。过去开发者的产出物是源代码。函数怎么写、边界怎么处理、异常怎么抛都由你在代码里逐一落实。现在代码的生成动作被智能体接管了你的产出物变成了“一段能被智能体执行得很好的需求”。这段话包含什么它包含任务目标、输入输出格式、约束条件、边界情况、不允许做什么、以及验收标准。你不再直接操纵每一行代码而是在操纵一个“执行者”的行动边界。打个比方以前你是一个埋头画图纸的结构工程师现在更像一个现场导演。你得告诉灯光师要什么色调告诉摄影师怎么运镜告诉场务哪里需要清场。你不会亲自去扛摄影机但你对整个成片负责。如果一个镜头拍砸了你说“我也不知道怎么回事”是没人信的——因为定义任务的人就是你。这还没完。写需求的门槛实际上比写代码高。原因很简单代码里有语法检查、编译报错、单元测试兜底错误会被立刻暴露。而需求写错了智能体会很礼貌地照单执行把错误贯彻到三遍之后。我见过太多人跟智能体抱怨“怎么又错了”却很少反过头来审视自己给出的需求是否精确。“自动化放大模糊”这句话在我这里已经应验了好几回。2. 我实测出来的需求写法从模糊一句指令到高通过率需求卡2.1 一个“限流模块”案例暴露了模糊需求的真实成本开头提到的限流案例我现在拿出来反复当反面教材。当时我写的指令是“帮我写一个限流模块保护一下这个接口。”整个需求就这一句话。智能体给我返回了一个基于进程内锁的计数器。从代码角度看它并没有错——确实限制了请求而且写得很规整。但问题是业务场景要求限流必须在多实例之间共享状态否则每台机器各计各的数整体阈值形同虚设。智能体完全不知道这层背景因为它拿到的需求里没有“多实例部署”这几个字。我把当时的模糊需求跟后来我在同一个任务中写的清晰版本放在一起做过对比差别非常明显需求维度我原来一句话的写法后来结构化后的写法业务目标保护一下接口防止突发流量击垮HTTP接口连续超过阈值时返回503统计粒度未说明按用户维度做令牌桶每用户每秒放行3个请求共享状态未说明多实例部署必须用共享存储计数不能使用进程内变量被拒时的语义未说明返回HTTP 429并给出Retry-After响应头非目标未说明不做WAF级别的拦截不处理登录态校验同一个任务两种写法的耗时差距超过一上午。如果你让我总结这一上午的代价是什么我会说是“智能体在没有地图的情况下替我做了太多决定”。它决定用进程内锁它决定不处理响应头它决定把限流粒度做成全局计数。这些决定本该由需求发出者来做我却一个字没写。2.2 一张可直接复制使用的需求卡模板踩了这个坑之后我给自己定了一条规矩凡是交给智能体执行的任务必须至少写满“需求卡”上的七个字段。七个字段是我自己调出来的组合涵盖了生成类任务最容易忽略的信息点。【角色】 你是负责XX模块的工程师技术栈是XX。 【目标】 在XX场景下完成XX任务使XX达到XX效果。 【输入】 任务开始时可用的数据、文件、接口以及它们的格式说明。 【输出】 最终交付物是什么代码/文档/测试/数据放在哪个目录。 【约束】 必须遵守的技术限制、平台限制、时间限制、性能指标。 【禁止】 不要做什么。例如不要修改业务代码不要调用外部真实服务不要缓存敏感数据。 【验收标准】 什么样的结果可以算完成。要求可观测、可检查例如“测试覆盖率不低于80%”、“单测可在无网络环境运行”。有人听到“写需求”三个字以为就是把一句话说得长一点。不对。字段只是骨架真正的关键在“禁止”和“验收标准”这两栏。“禁止”栏负责划定边界。你告诉智能体“不要修改业务代码”它会主动规避对你业务逻辑的破坏你不写它就可能顺手给你重构一个不该动的方法。“验收标准”栏负责定义终点。你写清楚“覆盖率不低于80%”它就知道生成测试的深度不会拿三个示例用例糊弄你。没有终点的任务只会得到一份“看起来很努力”的结果。2.3 一张需求卡实战给“单元测试生成智能体”下达任务为了验证这套需求卡不是纸上谈兵我专门做了一次实验让同一个智能体执行同一份测试生成任务一次用一句话指令一次用完整需求卡。一句话指令是“给service.py生成测试。”智能体返回了5个用例覆盖了正常路径没处理异常分支和边界条件测试文件也没放到项目约定好的目录里。需求卡我是这么写的【角色】你是资深测试工程师熟悉pytest和项目的业务逻辑。 【目标】为service.py中的generate_token函数生成完整单元测试。 【输入】函数签名见service.py业务规则见docs/token_rules.md。 【输出】生成tests/unit/test_generate_token.py可被pytest直接运行。 【约束】不修改业务代码不依赖真实外部API环境变量用mock提供。 【禁止】不要编写需要联网的用例不要生成与实际逻辑无关的假断言。 【验收标准】核心函数行覆盖率不低于85%所有用例本地执行通过耗时不超过5秒。结果差异在哪智能体不仅把正常用例补齐了还主动覆盖了过期时间边界、空参数、非法输入这几类异常分支测试文件也放在了指定目录。整个过程没有来回拉扯一次通过。这套需求卡给了我一个很直接的结论智能体不是不会好好干活而是它只会在你给的地图范围内好好干活。地图画得越清楚它跑偏的概率就越小。3. 几十个智能体一同开工时最容易翻车的四个环节3.1 上下文污染A智能体的输出变成了B智能体的噪音当智能体数量还是个位数时上下文问题不太明显。你自己开两个窗口互相不干扰。可一旦数量上到几十个智能体之间开始互相传递产出物第一种翻车就来了上下文污染。我经历过一次典型的污染事故。A智能体负责重构一个数据解析模块顺手把接口返回字段从userName改成了nickname并且在它的产出文档里做了标注。B智能体负责生成调用方代码它读取的是仓库里的旧接口描述完全不知道A已经改了字段名。结果A那边测试全绿B那边编译报错两边都在坚持自己对了。人眼排查了半天才发现是两个智能体各自拿着不同版本的上下文在干活。解决办法不是靠模型变得更聪明而是先建立一条规矩给智能体之间传递信息时不要让它去“翻上一轮聊天记录”而是让它去读一个契约文件。接口定义、字段名、格式约定统一写进一个受版本控制的文件里。任何智能体要变更这个契约必须先改文件再重新触发下游流程。这一步本质上是把人与人协作时的“口头同步”转化成机器可读的显式协议。3.2 验证链缺位最终验收角色始终没有出现第二个容易翻车的环节是把所有智能体都设计成“生产者”却没安排“验收者”。代码生成智能体交代码测试生成智能体交测试文档智能体交文档每个人都在产出东西但没人对“这些产出拼在一起能不能用”负责。大多数人想当然地认为让写测试的智能体去验证写代码的智能体不就行了实际很尴尬测试智能体也是生成出来的它同样有可能把测试写错。如果在测试用例里把一个本不该存在的函数写成了“预期行为”下游全跟着错。我的经验是必须有一个独立的“验证智能体”专门拿验收标准逐条打勾。它的工作很枯燥检查代码是否通过构建、覆盖率是否达标、是否有网络请求、是否修改了指定目录之外的文件。它不是来创造新东西的它是来挑错的。你也可以把这件事理解成“设置一个最终负责的岗位”。多智能体协同最怕的就是责任稀释每人都做一点等于没人做最后那步确认。3.3 权限边界失控一个智能体被授权去做太多事十个人的团队里安排权限容易一个智能体系统里安排权限经常被忽略。很多人给智能体配置环境的时候图省事直接给它全部代码库可写权限、全部服务凭据可读权限。人手上还有自觉性智能体没有——它只会严格按指令执行哪怕这个指令会覆盖生产配置。我和一个朋友都犯过类似的错。他让智能体顺手跑一遍全量自动化测试智能体在执行过程中发现测试脚本里有个配置项过时了顺手就“帮忙”改掉了然后把责任范围之外的东西也提交了。单看改动无害但在审计场景里这种自动越权会带来非常大的信任成本。我现在给每个智能体都单独建立权限清单哪些目录可读、哪些目录可写、哪些服务可调、哪些接口禁调。这个清单不会花太多时间但好处极大。它相当于给每个数字员工发了一张出入证能做什么写清楚不能做什么也写清楚。权限这件事情宁可一开始收紧一点也不要等到出了问题再回滚。3.4 需求知识漂移聊天窗口会丢掉最关键的约束第四个翻车点我称之为“需求知识漂移”。许多人跟智能体协作久了会在同一个会话里不断加需求、改约束。今天说“不要缓存”明天说“缓存改成5分钟”后天说“还是别缓存了”。聊天记录长到几百条之后智能体对最新约束的记忆其实是模糊的。更麻烦的是这些约束只存在于某一次聊天里它没有变成团队可共享的知识。换一个人来维护同一个智能体不知道前面发生的所有调整只能从头猜一遍。时间一长智能体的行为逐渐偏离最初的目标就像代码里的逻辑债务一样变成一团看不见的黑洞。对付这个问题我把需求卡做成了项目里的一个requirements目录每个任务一张Markdown文件丢进Git管理。任何一次需求变更都去改这个文件而不是在对话里随口说。这样聊天的功能被弱化了文件成了唯一权威来源。虽然少了一点“随手聊”的痛快但换来的是需求的可追溯性。拉新成员接手的时候直接读文件不需要翻聊天记录。4. 现在就能开始练的三种“写需求”基本功4.1 练习一每天挑一件任务改写成需求卡不要等未来50个智能体铺到你面前才开始练。我建议从今天开始每天只挑一件你原本打算直接上手的工作先改写成一张完整的需求卡。比如你本来要写一个“把用户ID脱敏”的函数先不要打开编辑器先花三分钟把这些写清楚角色是什么、输入的用户ID格式是什么、输出要求什么格式、脱敏规则是保留前几位还是后几位、非法输入怎么做、验收标准是“单元测试通过且不泄漏原始ID”。一开始你会觉得很别扭因为“写代码”的直觉告诉你直接干更快。但坚持两周之后你会发现一个明显的变化你对任务边界的敏感度变高了。以前你觉得“先写着再说”现在你会下意识地先问一句“这个任务做到哪一步算完”。这个习惯迁移到任何智能体上都有效。4.2 练习二每个需求都必须写清“验收标准”和“非目标”如果只能选两个字段来练我一定只推“验收标准”和“非目标”。原因很简单这两栏是阻隔无效产出最有效的屏障。“验收标准”要求你把“完成”定义成可检查的句子。比如“不需要真实的数据库连接即可运行全部测试”这就是可检查的而“让程序更健壮”就完全不能检查。你写得越可检查智能体的执行就越容易收敛。“非目标”则是很多人根本不会写的一栏。工作中大量返工不是因为智能体做得不够多而是因为它做得太多。你让智能体优化一个接口性能它可能顺手把响应格式改了。你写清楚“本次不改动响应结构”它就会克制得多。这一栏的本质是在告诉智能体你的使命在这里画句号不要越界发挥。4.3 练习三画一张智能体协作图标出所有依赖和验证点等到你要管理的不止一个智能体时最关键的技能就变成了“看清全局”。我一直建议身边的朋友不要光堆智能体每加一个就要在白板上画一笔弄清楚它在整个流程里的位置。画图时只需要标三种关系输入来自哪里、输出给谁、谁负责验证它。你会发现很多“虚假调度”里一台智能体的输出没有人真正消费它只是被启动了而已。这些无意义节点会白白消耗时间和算力还会制造噪音上下文。我自己的做法是把这张图写成一个纯文本文档每次加新智能体都更新一遍。不需要画得多精美重点是让依赖关系和验证点显式存在。当某个环节出了问题你能一眼看出是哪条链路上的产物出了问题而不是在一堆日志里捞针。4.4 一个心态上的提醒最后还想说点跟技术无关的。许多一线开发者在听到“写需求取代写代码”时第一反应是抵触觉得这是资本拿来裁员的说法。我理解这种焦虑但我觉得真正值得关注的不是“写代码”这个动作本身消失而是“理解系统”和“定义边界”的能力变得更值钱了。代码会越来越像一种内部实现细节就像今天很少有人会自己写服务器压测脚本——那是性能工程师的事。但需求定义能力恰恰是每个人都要跟智能体协作时绕不开的底牌。它会决定你提的需求是被智能体正确地执行还是被智能体“礼貌地误解”。最后分享一个我最近养成的习惯每次让智能体干活之前先自己在心里用一句话说一遍“这一单的目标是什么绝对不做哪些事”。如果一句话说不清楚说明需求还没到位那就停下来把需求写到能说清楚为止。这个习惯是我踩了无数个坑之后留下的成本很低收益却非常直接。未来那50个智能体迟早会来而在它们到来之前早把“写需求”练成本能的人一定是最先从这场变化里受益的那批人。