Uber 最近公布的一个数据在工程圈传得很快:AI Agent 已经接管了约 70% 的代码 PR 相关工作,而同期 AI 账单并没有跟着涨。也就是说,业务体量变大、Agent 干活变多,但成本被压住了。
这背后不是“买更多模型额度”堆出来的,而是一套工程化打法。今天这篇文章就把这件事拆开看,重点分析三个问题:
- Uber 这套 Agent 接管代码 PR 的链路到底由哪些环节组成;
- 我们自己要在团队里落地类似方案,环境、工具链、批量任务和 API 怎么设计;
- 如何在不增加模型预算的前提下,把 Agent 使用量做大,也就是“AI 账单零增长”的成本控制思路。
如果你是平台工程、DevOps、AI 应用开发或者技术管理方向的读者,这篇文章值得收藏。尤其是那些正在评估“AI Agent 到底能在软件研发流程里承担多少工作”的团队,看完之后基本能判断该从哪个环节先下手。
1. 核心事实速览
先把这段标题信息中能确认真实性的内容列出来,后面分析都基于这些事实展开。
| 项目事实 | 说明 |
|---|---|
| 事件主体 | Uber 工程团队 |
| 核心成果 | AI Agent 接管约 70% 的代码 PR 相关工作 |
| 成本特征 | AI 账单零增长,即在 Agent 任务量大幅增加的情况下,总成本未同比例上升 |
| 主要场景 | 代码审查、PR 管理、研发流程自动化 |
| Agent 类型 | 面向软件研发流程的代码智能体,非单纯聊天机器人 |
| 关注重点 | 规模化落地能力、成本控制手段、工程化集成方式 |
| 对团队参考价值 | 中大型研发团队可借鉴其“先小范围试点、再逐步扩大接管比例”的路径 |
| 信息边界 | 输入材料仅给出标题级事实,内部具体模型、框架、部署细节未披露 |
从材料能确认的只有上面这些公开信息。下面文章内容会在“基于这些事实做合理分析”和“给出可复用的通用方案”之间明确区分,不会虚构 Uber 内部未公开的技术细节。
2. 代码 Agent 接管 PR:到底接管了什么
2.1 PR 生命周期里有哪些环节可以被 Agent 接管
一个标准的代码 PR 从创建到合并,大致经历这几个阶段:
- 代码提交与 PR 创建
- 变更描述生成
- 代码评审
- 冲突检测与处理
- 自动化测试
- 合入审批
- 合并后的清理
传统团队里,这些环节大部分靠人工。开发人员写代码,维护者看代码,CI 跑测试,最后手动点击合入。70% 的接管率意味着,Agent 把其中大量重复性、规则明确的工作拿走了。
从行业普遍实践来看,Agent 最容易接管的 PR 环节包括:
- 根据代码 diff 自动生成 PR 描述;
- 自动检查代码风格、基础静态缺陷;
- 自动补充单元测试或修复简单测试失败;
- 检测分支冲突并给出合并建议;
- 对重复性变更做批量评审;
- 根据模板自动更新文档和 changelog。
这些环节有一个共同点:规则相对清晰、人工成本高、出错后可回退。Agent 在这里干活,风险可控,收益却很大。
2.2 为什么 Uber 要先拿 PR 场景做 Agent 规模化
PR 和代码评审是所有研发团队的刚需,每天都有大量重复工作。它是 Agent 落地的“高价值场景”。
第一,数据充分。代码仓库里的历史 PR、评审意见、合并记录都是高质量训练和评估材料。
第二,反馈闭环快。Agent 给出的评审意见能立刻被真实代码和维护者验证,做得好不好一目了然。
第三,容错空间大。Agent 接管的只是评审和流程环节,最终合入权限仍然掌握在人工手里,出错不会直接破坏生产环境。
从标题里“70%”这个数字来看,Uber 选择的是一个可以批量复制的工作场景,而不是单点炫技。这也是 Agent 工程化和普通 AI 功能体验的本质区别。
3. 适用场景与使用边界
3.1 适合什么团队接入
代码 PR Agent 最适合的团队有几类:
- 代码仓库数量多、PR 流量大的中大型研发团队;
- 已经有成熟 CI/CD 流程,但评审人力吃紧的团队;
- 有统一代码平台(GitHub、GitLab 或自建 Gerrit)的团队;
- 老板已经愿意为 AI 工具付费,但要求所有功能都要算清楚 ROI 的公司。
对这类团队来说,Agent 接管 PR 的比例可以从 20% 到 30% 起步,跑通后再逐步向 70% 靠近。
3.2 哪些场景不适合
以下几类场景不建议急着上 Agent:
- 核心安全模块、支付、权限系统的 PR,必须走严格人工评审;
- 代码风格极度混乱、没有统一规范的老仓库,Agent 会把问题放大;
- 没有测试覆盖的仓库,Agent 提出的“优化建议”无法被自动验证;
- 合规要求极高、每次变更都必须有人工签字的行业。
3.3 合规和边界提醒
代码 PR 是公司核心资产的一部分。接入 Agent 时要注意:
- 代码不得未经授权发送到外部第三方模型服务;
- 涉及用户数据、密钥、内部逻辑的代码必须走私有化部署或本地过滤;
- Agent 的评审意见可以自动生成,但合入权限必须保留给人类工程师;
- 定期抽检 Agent 的接管结果,确保没有错误流转到主干分支。
这里有个原则:Agent 接管的是重复劳动,不是决策权。这个边界守住,70% 的接管率才有实际意义。
4. 从 0 到 1 落地代码 PR Agent 的环境准备
不是每个团队都叫 Uber,但“用 Agent 接管 PR 比例逐步提升”这件事,任何一个研发团队都可以按下面这套思路去搭。
4.1 基础设施清单
做一套代码 PR Agent,需要的不是 GPU,而是 API 网关、代码平台权限、CI 执行环境和任务队列。通用清单如下:
| 组件 | 作用 | 说明 |
|---|---|---|
| 代码仓库平台 | 获取 PR、diff、评审上下文 | GitHub Teams 或 GitLab CE 均可 |
| 模型服务 | 提供代码理解、生成和评审能力 | 支持 OpenAI、Claude、国产模型或本地模型 |
| 事件接收器 | 监听 webhook,感知 PR 创建和更新 | 用 FastAPI 写一个简单的 webhook 服务即可 |
| 任务队列 | 处理异步批量评审任务 | Redis + Celery 或直接用消息队列 |
| 结果存储 | 保存评审记录和 agent 决策日志 | PostgreSQL、MySQL 都可以 |
| 监控面板 | 观察 token 消耗、任务成功率 | Grafana + Prometheus 或云提供商监控 |
如果只是个人或小团队先做验证,不需要完整架构。一个 Python 脚本加上 GitHub Actions 就能跑通最小闭环。
4.2 代码平台接入准备
以 GitHub 为例,你需要申请一个 GitHub App 或 Personal Access Token,权限范围只需Pull requests: read/write和Checks: read/write。
# 生成 PAT 后放到环境变量中,注意不要提交到代码仓库 export GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxx" export GITHUB_API_URL="https://api.github.com"GitLab 类似,需要api权限的 Personal Access Token。如果公司自建 GitLab,还需要确认网络策略是否允许内部服务调用模型 API。
4.3 模型服务选择
根据团队数据合规要求选择:
- 代码允许出网:直接调用 OpenAI GPT-4o 等云端模型,接入最快;
- 代码不能出网:部署本地模型,需要准备 GPU 服务器;
- 既要能力又要合规:使用云端私有化 API,不走公开通道。
从成本控制角度,生产环境建议同时配置两个档位的模型:
- 强模型:负责复杂评审、冲突分析和重构建议;
- 轻模型:负责 PR 描述生成、模板填充、格式检查。
这也是“AI 账单零增长”的常用手法:让简单任务走低成本通道,复杂任务才用强模型。
5. 最小可运行方案:一个 Agent 自动评审 PR
下面给出一个真实可跑的最小方案。这里用 Python 请求 GitHub API 获取 PR diff,然后调用模型服务生成评审意见。大家可以把它作为自己团队方案的起点。
5.1 获取 PR 的 diff 内容
import os import requests GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN") REPO = "your-org/your-repo" PR_NUMBER = 123 headers = { "Authorization": f"token {GITHUB_TOKEN}", "Accept": "application/vnd.github.v3.diff", } url = f"https://api.github.com/repos/{REPO}/pulls/{PR_NUMBER}" response = requests.get(url, headers=headers, timeout=30) diff = response.text print(f"diff 长度:{len(diff)} 字符")这个接口返回的是标准 unified diff 文本,也就是我们平时在 GitHub 网页上看到的那种+、-格式。模型理解这种格式没有难度。
5.2 调用模型生成评审意见
import os from openai import OpenAI client = OpenAI( api_key=os.environ.get("LLM_API_KEY"), base_url=os.environ.get("LLM_BASE_URL"), ) prompt = f"""你是一名资深代码评审工程师。请对下面这个 PR 的 diff 进行评审。 要求: 1. 找出可能的 bug、性能问题和安全问题; 2. 指出代码风格和可维护性问题; 3. 只输出最重要的 5 条意见; 4. 每条意见必须给出对应的代码位置和修改建议。 diff 内容: {diff} """ response = client.chat.completions.create( model="your-strong-model", messages=[ {"role": "system", "content": "你是资深代码评审助手。"}, {"role": "user", "content": prompt}, ], temperature=0.2, max_tokens=2000, ) review_comment = response.choices[0].message.content print(review_comment)这里需要注意diff变量需要从上一步传入,实际写代码时建议把获取 diff 和调用模型封装成两个函数。
5.3 通过 GitHub Review API 回写评审意见
headers = { "Authorization": f"token {GITHUB_TOKEN}", "Accept": "application/vnd.github+json", } review_url = f"https://api.github.com/repos/{REPO}/pulls/{PR_NUMBER}/reviews" payload = { "commit_id": "latest-commit-sha", # 需要从 PR 接口获取 "event": "COMMENT", "body": "以下为 AI Agent 自动生成的评审意见,请人工工程师复核后处理。\n\n" + review_comment, } resp = requests.post(review_url, headers=headers, json=payload, timeout=30) print(resp.status_code)到这一步,Agent 已经完成了从“获取代码”到“输出评审意见”再到“写回 PR”的完整闭环。
5.4 测试流程表
把上面三步串起来后,按下面的测试矩阵验证:
| 测试项 | 输入 | 预期结果 | 判定标准 |
|---|---|---|---|
| diff 获取 | 指定仓库和 PR 号 | 返回非空字符串 | diff 包含新增和删除行 |
| 评审生成 | 把 diff 发给模型 | 返回结构化意见 | 意见包含文件路径和行号 |
| 意见回写 | POST 到 Review API | 状态码 201 | PR 页面出现 Agent 评论 |
| 错误处理 | 无效 PR 号 | 返回 404 | 程序能捕获异常并打印错误 |
首次跑通后,再考虑接 webhook 自动化。
6. 自动化与批量任务:从 20% 到 70% 的工程路径
6.1 用 Webhook 代替手动触发
手动调用脚本跑一两个 PR 没问题,但要提高接管比例,必须自动化。最简单的方式是用 webhook 监听 PR 事件。
from fastapi import FastAPI, Request app = FastAPI() @app.post("/webhook/pr") async def handle_pr_webhook(request: Request): payload = await request.json() action = payload.get("action", "") pr_number = payload.get("number") repo_name = payload.get("repository", {}).get("full_name") if action in ["opened", "synchronize", "reopened"]: # 加入任务队列,避免阻塞 webhook 响应 print(f"收到 PR 事件: {repo_name}#{pr_number}") return {"status": "ok"}这里的关键是:webhook 只负责接收事件,真正的评审工作必须放到异步任务队列里。否则 PR 一多,webhook 服务就会超时。
6.2 用 Celery 做批量评审队列
# tasks.py from celery import Celery celery_app = Celery( "pr_review_agent", broker="redis://localhost:6379/0", backend="redis://localhost:6379/1", ) @celery_app.task def review_pr_task(repo_name: str, pr_number: int): # 1. 获取 diff # 2. 调用模型生成评审意见 # 3. 回写 GitHub return {"repo": repo_name, "pr": pr_number, "status": "completed"}调用方式:
review_pr_task.delay("your-org/your-repo", 123)任务队列带来的好处是:
- PR 数量爆发时,任务自动排队,不会压垮 API 服务;
- 可以对任务设置超时和重试;
- 可以按优先级处理:比如先评审紧急 PR;
- 失败任务不会丢失,Celery 会记录失败状态。
批量处理的压力测试思路是这样的:先从单个仓库接入,观察 100 个 PR 的评审成功率。成功率稳定在 90% 以上,再往更多仓库扩散。每扩一个仓库,记录 token 消耗、API 延迟、人工干预比例。这就是“从 20% 接管率向 70% 稳步推进”的工程路径。
6.3 批量处理的节流设计
模型 API 通常有速率限制。批量任务必须做节流。
import time import random def throttled_call(func, max_per_minute=30): interval = 60.0 / max_per_minute time.sleep(interval + random.uniform(0, 0.5)) return func()实际业务接入时,更推荐的做法是每个 PR 的评审任务做二次确认。如果是大规模变更(比如超过 3000 行 diff),可以拆分成多个子任务,每个子任务只评审一部分文件。这样既能提高单个文件的评审深度,也能避免模型因为上下文过长而丢失关键信息。
7. 成本控制:AI 账单零增长的几条硬手段
这是“AI 账单零增长”最容易让人好奇的部分。虽然不知道 Uber 内部具体怎么优化,但从行业通用的成本工程手段来看,可以做到这几点:
7.1 请求分层与模型路由
不是所有 PR 都需要最强的模型。最简单有效的规则:
- diff 少于 50 行:用轻量模型;
- diff 在 50 到 500 行之间:用中等模型;
- diff 超过 500 行、核心模块变更:用强模型;
- 需要重构建议、语义理解:直接用强模型。
这套路由逻辑写成一个配置即可:
model_routing: light: max_diff_lines: 50 model: "cheap-fast-model" medium: max_diff_lines: 500 model: "balanced-model" strong: min_diff_lines: 501 model: "powerful-model" requires_human_review: true按这个策略,100 个 PR 里 70% 可以走轻量模型,剩下 30% 走强模型,总成本接近原来的 30% 到 40%。
7.2 缓存历史评审结果
很多 PR 的变更高度相似,尤其是文档、配置、依赖升级类。可以缓存以下内容:
- 仓库路径 + diff 哈希 → 评审结果;
- 重复出现的高频代码问题 → 直接命中库,不调用模型;
- 相同依赖升级 PR → 复用上一次评审意见。
CACHE_TTL_SECONDS = 86400 def get_cached_review(diff_hash: str): # 伪代码:从 Redis 取缓存 return redis_client.get(f"review:{diff_hash}") def cache_review(diff_hash: str, review: str): redis_client.setex(f"review:{diff_hash}", CACHE_TTL_SECONDS, review)缓存命中率到 20% 到 30% 是很正常的事,这部分流量直接零成本。
7.3 输出长度与 Prompt 压缩
模型按 token 计费时,输出长度是成本大头。控制输出的办法:
- 要求模型只输出“必须修改的问题”,不要列一大堆可改可不改的建议;
- 设置合理的
max_tokens; - 对超大 diff 先做 AST 或正则压缩,去掉无关改动;
- 让模型用结构化 JSON 输出,避免多余解释。
{ "review": { "critical_issues": [], "suggestions": [], "approved": true } }把输出格式限定成 JSON 后,token 消耗通常能下降一半以上。
7.4 建立成本水位线
“零增长”不是凭空来的,是要管出来的。团队需要有预算水位线:
- 每 PR 评审成本上限,超过告警;
- 每月 token 消耗趋势,按月环比;
- 每模型调用成本排行,找出“高消耗低价值”的调用直接砍掉。
这里建议用一套简单的统计存储:
CREATE TABLE agent_cost_log ( id BIGINT PRIMARY KEY AUTO_INCREMENT, repo VARCHAR(255), pr_number INT, model VARCHAR(100), prompt_tokens INT, completion_tokens INT, cost DECIMAL(10,6), created_at DATETIME DEFAULT CURRENT_TIMESTAMP );每周跑一次 SQL,就能看出成本都花在哪了。哪里超过水位线,就针对哪个需求调整路由或缓存策略。
8. 效果验证:怎么评估“接管率”是实打实的
“70% 接管率”不能只看自动生成的评论数量。要验证接管率,需要从四个维度看:
8.1 任务完成率
统计 Agent 处理成功的 PR 数占所有 PR 数的比例。重点看失败原因:
- API 超时;
- diff 格式解析失败;
- 模型输出不符合格式要求;
- 权限不足无法回写评论。
任务完成率达到 90% 以上,才具备“接管”的资格。另外还需要区分“Agent 参与”和“Agent 接管”。
8.2 人工介入率
这是最容易虚标的指标。一个 PR 如果 Agent 跑了一遍,但最终所有有价值的意见都是人工评审员自己写出来的,那这个 PR 不算真正被接管。
正确的统计口径是:被合入到最终合并版本的 Agent 评审意见或 Agent 自动修改,占整体有意义的变更比例。
8.3 返工率
这个被很多团队忽略。加入 Agent 评审后,PR 因为 “Agent 提了一堆无效意见导致人工工程师沟通成本增加” 而修改的轮次是否增加?
如果 Agent 评审后,PR 的平均修改轮次从 1.5 轮涨到 2.5 轮,那就是负收益。这时候需要降低 Agent 的输出频率,只让它标记高危问题。
8.4 成本 ROI 模型
先记录一个 PR 之前人工评审的平均时长。假设 30 分钟,折算人力成本是 C。使用 Agent 后,该 PR 的人工评审时长降到 10 分钟,Agent 调用成本是 D。
节省成本 = (30 - 10) / 60 × 人力时薪 - D只有算出来为正,Agent 接管才有商业意义。
用一个表格来汇总跟踪指标:
| 指标 | 计算方式 | 目标区间 | 含义 |
|---|---|---|---|
| 任务完成率 | Agent 成功任务 / 全部任务 | >90% | Agent 流程稳定性 |
| 意见采纳率 | 被人工采纳的意见 / Agent 总意见 | >40% | 评审质量 |
| 平均修改轮次 | 总修改轮次 / PR 数 | 不高于原基线 | 流程效率 |
| 单 PR 成本 | 总 AI 成本 / PR 数 | 低于人工成本 | 经济性 |
| 月成本环比 | 本月成本 / 上月成本 | <=1.0 | 成本零增长 |
这五组指标,才是判断“Agent 接管 70% PR 且 AI 账单零增长”是否健康的标准。
9. 常见问题与排查方法
代码 PR Agent 在落地时大概率会遇到下面这些问题:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| webhook 收不到 PR 事件 | 回调地址不通或 Secret 不一致 | 查看代码平台 webhook 投递记录 | 检查内网穿透、回调 URL 和 secret |
| 拿到 diff 为空 | PR 已合并或 Token 权限不足 | 直接 curl 测试 API | 确认 Token 有 pull requests 读权限 |
| 模型评审意见太泛 | Prompt 没有给出格式要求 | 查看原始提示词 | 强制指定输出格式和代码位置 |
| 模型总是漏掉安全漏洞 | 强模型能力不足或上下文被截断 | 检查 diff 截断长度 | 大 diff 拆分评审,或换更强模型 |
| 批量任务堆积 | 任务队列消费速度跟不上 | 查看队列积压数 | 增加 worker 数或加节流 |
| AI 成本突增 | 大量大 diff 走了强模型 | 查看模型路由日志 | 调低强模型触发阈值 |
| Agent 评论触发 PR 通知轰炸 | 每次 commit 都触发评审 | 检查 webhook 事件过滤 | 只在 opened 和 review_requested 时触发 |
| 评审意见被开发者忽略 | 意见无上下文,可信度低 | 统计意见采纳率 | 增加 diff 上下文和文件行号链接 |
排查优先级建议:先看日志,再看 API 返回码,最后看模型输出。日志里一定要记录 PR 号、模型调用耗时、token 数量和返回状态码“四个基本信息”。没有这四样,任何问题排查都会变成盲找。
10. 最佳实践与使用建议
在把 Agent 引入代码 PR 流程时,下面是一套经过验证的推进路径。
10.1 三个阶段推进接管率
第一阶段,只读模式。Agent 只生成评审意见,不自动修改任何代码。这个阶段持续两周,统计意见采纳率和误报率。
第二阶段,建议模式。Agent 在评审意见基础上生成“建议修改”的代码块,由人工开发者选择是否一键接受。这个阶段关注修改后测试通过率。
第三阶段,接管模式。Agent 对低风险 PR 自动生成修改并提交到新分支,保留人工合入权限。这个阶段才可以说是“接管”。
从行业普遍实践看,绝大多数团队推进到第二阶段就比较合理了,第三阶段需要非常强的工程兜底。
10.2 数据与安全合规
代码 PR 中经常包含敏感信息,比如数据库地址、内部业务逻辑、密钥。接入模型服务前要过一遍:
- 做代码脱敏正则,过滤可能的密钥和 IP;
- 限制 Agent 只能访问指定仓库的分支;
- 所有 prompt 和返回结果保存到公司内部存储,方便审计;
- 不能让 Agent 的 API key 具备写主干分支的权限。
这里特别强调:Agent 的 Token 权限必须做到最小化。它不需要管理员权限,不需要删分支权限,甚至不需要写主干分支权限。给一个只读代码 + 只写评论的 Token 就够了。
10.3 保留一条人工兜底链路
即使 Agent 已经稳定处理 70% 的 PR,也要保留一条 100% 人工评审的通道:
- 安全敏感模块的 PR 强制人工;
- 首次提交的新贡献者 PR 强制人工;
- Agent 评审后出现 3 次以上误报的 PR 类型,强制人工复查;
- 回滚率超过阈值的模块,暂停 Agent 接管。
这个兜底通道是 Agent 工程化能够持续扩大接管范围的前提。没有了兜底,一次重大误判就可能让整个 Agent 项目被叫停。
11. 总结与下一步
Uber 这个案例最有价值的点不是“70%”这个数字,而是它验证了一件事:AI Agent 在软件研发流程里不是演示品,是可以规模化、可以算账、可以在预算不涨的情况下长期运行的工程模块。
如果你所在团队准备跟进,建议下一步按顺序做三件事:
第一,挑一个仓库,用文中第 5 节的脚本跑通“Agent 自动评审 PR”的最小闭环。不需要完整架构,能出评审意见就算第一步成功。
第二,把 webhook 加上,设置好任务队列和日志。这个阶段开始收集前四类数据:任务完成率、意见采纳率、平均修改轮次、单 PR 成本。
第三,根据数据决定模型路由策略和缓存策略。争取在业务量增长的情况下,把 AI 成本涨幅控制在预算以内。到这一步,你就触摸到“AI 账单零增长”的现实路径了。
最值得最先验证的功能,永远是“Agent 输出的评审意见到底有没有用”。先解决质量问题,再谈成本优化。最容易踩的坑,则是模型 token 消耗没有被监控,等月底账单一看,成本翻了几倍还说不清楚钱花在哪里。
建议收藏备用。后续等有更多公开信息,再结合具体模型选型另写一篇代码评审 Agent 的模型效果对比。