如果你最近关注 AI 编程工具,应该能明显感觉到一个趋势:AI 编程代理(Coding Agent)已经从"辅助补全"进化到了"自主执行"。Cursor、Claude Code、Codex、Trae、通义灵码,这类工具把"从需求到 PR"的链路压缩到了分钟级。但真正在一线带团队的人,最近普遍有一个困惑:代码产出量上去了,技术债也上去了。有些人交付速度快了一倍,另一些人则负责把代理写的"能跑的代码"重写一遍。
这不是模型能力的问题。很多团队把 AI 编程代理当成"自动写代码的机器",丢一个需求进去,等一个 PR 出来,然后发现里面全是复制粘贴变体、错误抽象、恒真断言和莫名其妙的依赖。从 Figma 这类长期做设计工程协作的团队视角看,这个问题真正的根源不是"AI 不够强",而是"上下文不够、约束不够、验证不够"。AI 代理本质上是一个能力极强、但对项目一无所知、而且极度擅长"看起来完成"的协作者。
这篇文章想分享的是:如何安全落地 AI 编程代理,而不是让它变成垃圾代码生成器。你会看到垃圾代码到底是怎么产生的;为什么上下文工程(包括 MCP、规范文件)比换一个更强的模型更关键;以及一套从任务描述、隔离环境、自动验证到人工审查的最小落地流程。适合正在团队里推动 AI 编程代理落地的工程师、技术 Leader,也包括打算把 Figma 设计稿交给代理去写代码的前端团队。
1. 为什么AI编程代理会写出"垃圾代码"
要解决垃圾代码问题,先得承认一个事实:在缺少约束的环境里,AI 编程代理产出垃圾代码几乎是必然的。这不是偶然失误,而是它的目标函数决定的。
代理的优化目标是什么?是"在当前上下文中,尽快让任务看起来完成"。注意,是"看起来完成",不是"真正完成"。因为代理没有长期记忆,看不到六个月后维护这段代码的你;它不会为代码的长期可维护性负责,只会为当前这个 prompt 负责。于是,它的最优策略就变成了下面这样:
- 复制一段相似代码改个变量名,而不是理解后重写;
- 用 any、@ts-ignore、except Exception 这类方式绕过类型和异常,而不是处理根本问题;
- 写一个只覆盖 happy path 的测试,让覆盖率数字好看;
- 为了实现一个小功能,引入三个不必要的依赖;
- 在你不注意的位置,顺手改动无关的文件。
每一件事单看都可以理解,放在一起就是一个逐渐腐烂的代码库。更隐蔽的一层问题是"幻觉上下文":代理会把从别的项目、别的框架里见过的模式嫁接到当前项目,看起来合理,实际上不符合你的目录结构、编码约定和接口设计。它不会主动问"你们的错误码约定是什么",因为它被训练成"尽量自己搞定一切"。
这引出一个在团队落地时非常实用的公式:
代理产出质量 ≈ 模型能力 × 上下文质量 × 验证强度模型能力是基数,大家用的模型差距没那么大;真正拉开差距的,是上下文质量和验证强度。你给代理的约束越清楚,事后验证越严格,垃圾代码就越难存活。反过来,如果上下文是一句模糊的需求,验证环节只有"能编译过",那不管换多强的模型,产出的都只是"更像样的垃圾"。
2. 核心认知:代理是协作者,不是替代者
很多人对 AI 编程代理的第一个误解,是把它的工作方式理解成增强版自动补全。实际上"代理(Agent)"和"补全(Copilot)"是两种完全不同的工作模式,搞清楚这一点,后面所有管理策略才有意义。
| 维度 | Copilot 补全 | Agent 代理 |
|---|---|---|
| 工作方式 | 你写一半,它帮你补下一段 | 你给任务,它自己读代码、改代码、跑命令 |
| 任务粒度 | 单点代码片段 | 一个功能、一次重构、一个 PR |
| 需要什么 | IDE 内即时上下文 | 项目规范、验收标准、运行环境 |
| 失败模式 | 补错了你马上能发现 | 可能改了一堆文件后才发现方向错了 |
正是因为工作方式变了,你对它的管理方式必须变。这里我常用一个类比:把 AI 编程代理当成一位"能力很强、效率很高、但刚入职、对公司业务一无所知、还特别不会拒绝需求的实习生"。这个类比能推导出几条非常具体的管理规则:
- 你给实习生的任务必须边界清楚:做什么、不做什么、验收标准是什么;
- 你必须让实习生理解项目的"常识":代码规范、目录结构、错误处理约定;
- 你必须审查实习生的产出:不是不信任,而是实习生确实不了解项目背景;
- 你必须让方向错了可以回滚:git 分支和基线,就是 AI 时代的后悔药。
这个类比能解释大部分失败案例:团队把代理当资深工程师用,给一句话需求,期待一个完美 PR,结果代理像实习生一样,热情但莽撞地把项目改成了一团乱麻。而团队如果把代理当成需要入职培训、需要师傅 review 的新人,反而更容易用好它。
这里有一个反直觉的结论:团队工程能力越强,AI 代理越安全。因为强团队有清晰的代码规范、测试文化和审查流程,代理的产出会被快速校正;而工程能力弱的团队,代理只会把原有的混乱加速放大。垃圾代码不是 AI 发明的,它只是在缺少约束的环境里"长"出来的。
所以"安全落地"的第一步,不是选模型、买额度、配服务器,而是先确认你的团队有没有一套哪怕最基本的代码标准、测试门禁和 review 习惯。没有这些东西之前,建议先把 AI 代理用在低风险、可丢弃的探索性任务上。
3. 从Figma的设计工程协作,看上下文为什么是水电煤
这一节我想从 Figma 这类公司最擅长的事情出发,解释"上下文"到底有多重要。设计工具公司每天面对什么问题?设计稿和代码之间的鸿沟。设计师在 Figma 里定好了颜色、间距、组件状态,标注写得很细;开发拿着设计稿手动翻译成代码,翻译过程中丢失信息,经常出现视觉偏差。前端团队对"figma 怎么看 UI 的位置标注""figma 怎样导出到蓝湖"这类问题的热情,本质上都是在解决同一个痛点:如何让设计信息更完整、更可靠地流到开发侧。
把这个逻辑放到 AI 编程代理上,结论是一样的:代理工作质量的生死线,在于它能不能拿到足够结构化的上下文。过去代理要"看图写码",只能从截图里猜尺寸、猜颜色、猜组件行为,猜错概率很高。现在有了 MCP(Model Context Protocol,模型上下文协议),AI 工具可以按标准方式去读取外部数据源的结构化信息:Figma 文件的图层结构、样式属性、设计 token、接口文档,甚至数据库 schema。这也是为什么近期"开源社区 figma mcp (community) 安装"这类搜索明显变多,Trae、Codex、CodeBuddy 这类编程工具也都在做 Figma 集成,因为设计稿是最典型的高价值上下文。
这里值得停下来解释一下 MCP,因为它很容易被误当成"又一个接口协议"。MCP 解决的问题是:AI 应用(比如你的编程代理)如何标准化地访问外部工具和数据。没有 MCP 之前,每个 AI 工具都要为每种数据源各自写一遍集成,Figma 一套、Jira 一套、数据库一套;有了 MCP 之后,数据源只需要实现一次 MCP 服务,任何支持 MCP 的客户端都能复用。对于前端团队来说,MCP 的价值在于:代理不再对着截图猜,而是直接读取设计稿里的结构化标注,像人看规范文档一样实现页面。
对比一下有上下文和没有上下文的差异,会看得更清楚:
| 没有设计上下文 | 有设计上下文(MCP/token) | |
|---|---|---|
| 颜色 | 猜一个接近的 hex | 直接取设计 token |
| 间距 | 目测 | 取 token 或标注 |
| 组件 | 重新造一个 | 复用组件库 |
| 响应式 | 猜 | 按设计稿约束实现 |
一句话:上下文不是锦上添花,是水电煤。没有它,代理就只能靠猜;而靠猜的代码,十有八九是要返工的。对于中文团队还有一个常被忽略的点:大家喜欢折腾"figma 汉化""figma 中文怎么设置",希望界面看得懂,这可以理解。但真正影响开发效率的,不是界面语言,而是设计信息能不能结构化地到达代理手里。语言设置解决的是"人看得懂",MCP 解决的是"代理读得懂",后者才是和工程质量直接相关的变量。
4. 前置条件:给代理一个干净、可控、可回滚的工作区
先看操作。落地 AI 编程代理之前,先把工作区准备好。我建议遵循三个原则:隔离、最小权限、可回滚。
隔离,是指不要让代理直接在你的主干分支或本地默认分支上工作,而是给它一个独立的特性分支,甚至一个独立的容器或沙箱。这样即使代理搞出破坏性改动,也不会污染主线。最小权限,是指代理使用的所有凭证都要按最小范围配置:API Key 只允许访问指定仓库,MCP 服务只授予读取所需数据的权限,云端环境凭证用临时凭证而不是长期密钥。记住,代理不是人,它不会因为"不好意思"而克制自己使用权限。可回滚,是指代理开始工作前必须记录基线:最轻量的做法是打一个 tag,更稳妥的做法是在沙箱环境里跑,不行就整个丢弃。
下面的脚本是一个最小示例,适合在本地或 CI runner 里执行:
# 1. 从最新主干创建隔离分支 git checkout main git pull origin main git checkout -b feat/ai-agent/$(date +%Y%m%d-%H%M%S) # 2. 记录基线,方便随时回滚 git tag ai-agent-baseline # 3. 运行代理执行任务,任务描述放在 docs/tasks/task-001.md # 注意:your-agent-cli 只是占位,请替换为你实际使用的代理工具的调用方式 npx your-agent-cli run --task docs/tasks/task-001.md # 4. 快速看一眼改动范围 git diff --stat # 5. 跑本地门禁 npm run lint npm run typecheck npm test每一步都有明确目的:第 1 步保证隔离,第 2 步保证可回滚,第 3 步是代理工作主体,第 4 步让你在合并前先人工确认改动范围,第 5 步是最低限度的自动验证。如果你用的工具链不是 npm,把第 5 步换成对应的构建和测试命令即可。真正重要的不是命令本身,而是这套顺序:先有隔离、再有基线、最后才让代理动手,这个顺序不能乱。
这里多说一句版本问题。AI 编程代理迭代非常快,工具版本、MCP 服务版本、模型版本都可能影响代理的行为。团队里建议把使用的工具版本记录下来,至少写进 README 或团队文档,避免出现"昨天能跑今天不能跑"的玄学问题。具体版本号请以你实际使用的为准,不要盲目追新,尤其是大型项目里,代理工具的升级往往需要跟着项目依赖一起评估,而不是单独升级。
5. 上下文工程实战:规范文件 + MCP 双通道
环境准备好之后,真正决定代理产出质量的是上下文。我把它分成两个通道:一个是"规范文件",告诉代理项目的常识;另一个是"MCP",让代理实时读取外部结构化数据。两条腿一起走,代理才不会瞎猜。
5.1 规范文件:把项目常识写下来
现在主流编程代理工具都支持在项目里放一个指令文件,比如 AGENTS.md、CLAUDE.md,不同工具叫法不太一样,但作用相同:在代理开始干活之前,先读一遍这个文件,获取项目的"入职培训"。一个合格的规范文件应该包含四类信息:技术栈、代码结构、硬性约束、完成定义。下面是一个可参考的示例:
# AGENTS.md ## 技术栈 - 前端:React + TypeScript + Vite - 样式:Tailwind CSS,禁止引入 styled-components - 状态管理:Zustand,禁止引入 Redux ## 目录结构 - src/components:UI 组件,一个组件一个文件夹 - src/services:API 封装,禁止在组件里直接发请求 - src/types:全局类型定义 ## 硬性约束 - 所有颜色、间距必须使用 design-tokens,禁止硬编码 - 新增对外接口必须补充 JSDoc - 不要修改与当前任务无关的文件 ## 测试要求 - 每个新增组件必须有至少一个测试 - 禁止只覆盖 happy path,必须覆盖空态和错误态 ## 完成定义(DoD) - 本地 lint 和类型检查全部通过 - 相关测试全量通过 - 变更集保持最小,与任务无关的改动视为失败这个文件看起来简单,但实际效果往往出人意料。它的本质是把散落在团队口头约定、代码 review 记录、群聊问答里的"常识",固化成代理每次开工前必读的指令。代理每完成一步,都会回头对照这些约束检查自己的改动,相当于有人一直在旁边提醒它"这个项目有规矩"。很多团队第一次写完 AGENTS.md 之后,会发现代理生成代码的风格明显更贴近团队已有代码,而此前他们花了很多时间在 review 里重复纠正同一个问题。
写这个文件时有一个非常容易踩的坑:内容写得太抽象。比如"代码要保持高质量"这种话,人看了点头,代理看了无从下手,因为它无法把"高质量"转换成具体的检查动作。正确的写法是像验收清单一样,给出能检查的、有边界的、最好能对应到具体命令的规则。比如"禁止硬编码颜色,必须引用 design-tokens",代理就能执行;而"注意代码风格",代理只能靠猜。说到底,质量不是一个感觉,而是一组可以被验证的规则。
5.2 MCP:让代理能"看见"设计稿和接口
规范文件解决的是"项目常识",MCP 解决的是"实时数据"。以 Figma 场景为例,如果你们的前端团队想让代理照着设计稿写页面,最理想的方式不是截图,而是让代理通过 Figma MCP 读取设计稿里的结构化信息。MCP 服务的接入方式通常是修改 AI 客户端的配置文件,下面是一个通用的 MCP 配置结构,具体 command 和 args 要替换成你实际使用的 MCP 服务:
{ "mcpServers": { "figma": { "command": "npx", "args": [ "-y", "your-figma-mcp-server", "--auth-token=在这里填入有读取权限的token" ], "env": {} } } }配置完成后,代理的工具列表里会出现"读取 Figma 文件"之类的能力。你在任务描述里告诉它"请读取 design 文件夹里 xxxx 文件,按照其中标注实现页面",代理就能直接拿到图层结构、样式属性、位置标注这些结构化信息,而不是对着截图目测尺寸、猜测颜色。这里的变化不仅仅是准确率提升,更重要的是代理可以一次性拿到完整的信息,不用反复追问,整个实现链路会顺畅很多。这也是为什么很多团队在接入 Figma MCP 之后,设计稿转页面的返工率明显下降。
需要单独提醒的是安全边界。MCP 的本质,是把外部数据源的能力开放给 AI 代理,权限开得越大,风险半径就越大。给 MCP 服务配置的 token 应该是只读的、作用域最小化的,不要图省事直接使用设计师或开发者的全量账号 token。尤其是当 MCP 后面接的是接口文档、数据库 schema、生产环境数据时,更要谨慎限制访问范围,遵循最小权限原则。这个原则在人工操作时代是常识,在 AI 代理时代反而容易被忽略,因为代理不会主动告诉你"我用了很高的权限"。
另外,社区里存在大量第三方 MCP 实现,质量和维护状况参差不齐。选择时优先看维护活跃度、是否开源、是否有安全审计记录,而不是看谁的功能列表最长。官方维护的 MCP 服务通常更稳妥;社区方案在接入前,建议先看 issue 区有没有大量未处理的安全相关问题,README 是否提供了明确的权限说明。这种谨慎不是对开源社区不信任,而是 MCP 服务一旦被缺陷或恶意代码影响,波及的是整个 AI 工具链。
5.3 把任务描述写成"需求卡片",而不是一句话
最后是任务描述本身。给代理的任务越模糊,它的自由发挥空间越大,垃圾代码的概率越高。我建议团队用固定的"需求卡片"模板,把背景、目标、约束、验收标准、禁止事项都写清楚:
## 任务背景 用户在下单页点击"提交订单"后,如果库存不足,需要给出明确提示。 ## 目标 实现前端库存校验,并在库存不足时展示错误状态。 范围仅限前端页面,不允许改动订单服务接口。 ## 约束 - 必须使用已有的 Alert 组件,禁止新造 - 错误文案从 i18n 资源文件读取,禁止硬编码 - 保持现有下单流程的交互不变 ## 验收标准 1. 库存不足时,页面出现 Alert 且文案正确 2. 库存充足时,不出现提示,流程照常 3. 新增测试覆盖"库存不足"和"库存充足"两种情况 4. 本地 lint、typecheck、test 全部通过 ## 禁止事项 - 不要修改订单服务接口 - 不要引入新的状态管理库写需求卡片的过程,本质上就是逼人去思考"这个任务到底要解决什么问题"。很多团队做完这一步发现,即使没有 AI,代码质量都提高了,因为过去一句话需求带来的理解偏差,在需求卡片阶段就被消灭了。而代理拿到这样一张卡片,几乎不需要猜测需求边界,产出的代码自然更可控。
6. 验证关卡:让"看起来完成"变成"真的完成"
上下文给足了,代理也可能犯错。所以在代理产出到合并之间,必须有一组验证关卡。我把它分成四层:静态检查、构建、自动化测试、人工审查。
第一层是静态检查。lint 和类型检查是最低门槛,它们能拦截大量低级问题:未使用变量、错误类型、违反代码风格。关键是这一层可以全自动,不应该占用人的时间。第二层是构建。代理改完一堆文件,最怕的是"单独看都能编译,合起来构建失败"。构建通过的优先级高于一切测试,因为它证明代码至少是一个自洽的整体。第三层是自动化测试。注意这里有个陷阱:代理写的测试,很可能只是为了让覆盖率数字好看。所以审查测试时,要看断言是否真实、是否覆盖边界和错误态,而不只是看行数。第四层是人工审查,这一层不可省略。哪怕你信任代理,也必须有人类工程师理解这次改动解决了什么问题、改了什么、影响范围是什么。
下面是一个最小 CI 配置示例,用来卡住前三层:
name: verify on: pull_request: types: [opened, synchronize] jobs: verify: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npm run lint - run: npm run typecheck - run: npm run build - run: npm test这个配置的作用是:任何人(包括代理)提交 PR,都会自动跑一遍检查,不通过就不允许合并。它把"代理写的代码质量"从靠自觉,变成靠制度。自动化检查通过之后,人工审查环节建议重点看四个东西:diff 是否最小,有没有无辜被改的文件;命名和抽象是否一致,代理经常生成和自己已有代码风格不一致的命名;测试是否真实,有没有全是恒真断言的假测试;以及有没有隐含假设,比如代理假设了不存在的接口、数据结构或权限。
审查完之后,再合并、灰度、观察。如果改的是核心链路,建议加特性开关,让变更可以在线上快速关闭。这四层关卡的意义在于,它把"代理说做完了"和"代码真的可用"之间拉开的那段距离,重新补了回来。
7. 最小落地流程:从任务描述到合并PR
把前面几节串起来,就是一个可以照抄的最小落地流程。假设你是前端团队,想让 AI 编程代理帮你实现一个基于 Figma 设计稿的页面,完整流程是这样的:
第一步,把设计稿准备好。确认设计文件对代理可见,MCP 配置完成,token 只有读取权限。第二步,写需求卡片。把上面的"需求卡片"模板填好,放在 docs/tasks/ 目录下,写成 markdown 文件。第三步,创建隔离分支并记录基线,用第 4 节的脚本,或直接在 CI runner 里执行。第四步,让代理执行任务,把任务卡片路径传给代理,让它读 AGENTS.md、读设计稿 MCP 数据、实现功能。第五步,自动验证,提交 PR 触发第 6 节的 CI 检查,lint、typecheck、build、test 全过。第六步,人工审查,按最小 diff、命名一致、测试真实、无隐含假设四个维度过一遍。第七步,合并、观察,合入主干后确认功能正常,必要时用特性开关回滚。
整个流程的核心思想是:把代理当成流水线上的一个工位,而不是一个不需要质检的黑盒。每个工位进出都有明确的质检标准,垃圾代码自然被挡在门外。很多团队刚接触这套流程时会觉得"流程太重了",但实际上,这些步骤大部分是一次性配置,真正每天要做的,只是写清楚需求卡片和最后的人工审查。相比代理随便写、人再花两天返工,这个成本低得多。
如果你想在团队里推广这套流程,建议不要一上来就全量铺开。先挑一个低风险、边界清晰、有现成验收标准的任务跑通,比如一个内部工具页面的重构。跑通了,再逐步扩大到中等复杂度的功能。这个渐进策略,远比"全员放开随便用"稳妥。每次完成一个任务,记录一下代理实际耗费的时间、人工审查的时间和返工次数,这些数据会成为你判断"什么任务适合交给代理"的重要依据。
8. 常见问题与排查思路
在实际落地过程中,以下问题出现频率最高,这里整理成一张排查表,建议收藏备用:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 代理改了与任务无关的文件 | 上下文里没有"最小变更"约束 | 检查任务描述和 AGENTS.md 约束 | 在指令文件里明确"禁止修改无关文件",审查时用 git diff 核对 |
| 代理生成的代码引入多余依赖 | 任务描述没有依赖约束 | 查看 package.json 的 diff | 需求卡片里写明"禁止引入新库,除非……" |
| 测试全是 happy path,覆盖率虚高 | 任务描述没有测试深度要求 | 阅读测试断言,不是只看覆盖率 | 在规范文件里明确"必须覆盖空态和错误态" |
| 代理读不到 Figma 设计稿数据 | MCP 配置错误或 token 权限不足 | 检查 MCP 客户端日志和配置 | 确认 mcpServers 配置正确、token 有对应文件访问权限 |
| 昨天能跑今天不能跑 | 工具或依赖版本变动 | 查版本记录和依赖锁文件 | 记录工具版本,提交 lockfile |
| 代理生成了不存在的接口调用 | 上下文缺少接口文档 | 检查错误堆栈和类型报错 | 通过 MCP 接入接口文档,或在任务卡片中提供接口示例 |
| 代理擅自改了公共组件的样式 | 缺少影响范围约束 | 审查 diff 中的公共组件改动 | 在需求卡片中声明禁止改动范围 |
第一个问题最典型:很多团队发现代理"很努力"地改了十几个文件,但真正需要的只有两个。这不是恶意,而是代理缺乏全局判断。唯一有效的办法是在指令里把边界写死,并在审查时严格执行"无关改动视为失败"。排查时有一个通用思路:先看是不是自动检查能发现的,再看是不是上下文能解决的,最后才考虑换模型或调参数。大多数问题出在上下文和验证这两层,而不是模型能力,这一点容易被忽略。
9. 最佳实践与后续学习方向
最后整理几条工程建议,都是可以直接落到团队里的。
第一,把"完成定义"前置。任何时候让代理动手,先写清楚验收标准。完成不是"代码能编译",而是"符合需求卡片、通过全部门禁、diff 最小、测试真实"。第二,坚持最小 diff。代理天然倾向大改,审查时对"无关文件改动"零容忍,长期下来,代理也会慢慢学会克制。第三,测试优先于功能。让代理先写测试,再实现功能,这个顺序能明显减少自说自话的假测试,也能让代理更早暴露理解偏差。第四,记录代理行为基线。每次迭代记录工具版本、模型版本、任务描述、审查结论,几周后你会得到一份宝贵的数据:什么样的任务适合交给代理,什么样的任务应该自己做。
第五,把安全边界当第一优先级。所有给代理的凭证按最小权限配置,MCP 服务只开放必要数据,生产环境和数据绝不能直接暴露给代理。这不是不信任 AI,而是工程常识:权限越宽,出事后的爆炸半径越大。第六,人的角色在升级。引入 AI 编程代理之后,工程师的核心能力不再是"写更多代码",而是"把问题定义得更清楚、审查得更准确"。这也是标题里 AI Engineer 这个词的真正含义:不是让 AI 替代工程师,而是让工程师学会和 AI 协作,成为能设计任务、能判断产出、能控制风险的人。
对于想继续深入的同学,我建议按这个顺序学习:先把上下文工程做扎实,包括规范文件、需求卡片和 MCP 接入;再研究验证体系,包括 CI 门禁、测试策略和审查清单;最后再关注模型和工具本身的迭代。工具更新很快,但上下文、验证、反馈这套工程方法论是穿越周期的。如果你所在的前端团队经常做"设计稿转页面"的工作,尤其值得把 Figma MCP 和设计 token 这条链路打通。当代理能直接读到设计稿里的结构化信息时,返工率会明显下降,这也是目前设计工程协作里性价比最高的一个改造点。