DoorDash 如何用多智能体清理 6 万个 Feature Flag

2026-09-18 26 预计阅读时间: 1 分钟
来源: infoq.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

Feature Flag 很容易创建,却很少有人愿意删除。随着实验结束、默认值固化和负责人变动,旧开关会逐渐变成散落在代码、配置和测试里的技术债。DoorDash 面对的是超过 60,000 个开关、横跨 623 个代码仓库的治理问题,单靠人工搜索和逐个提交 PR 很难持续推进。

DoorDash 为此构建了一套多智能体 LLM 工作流:通过 MCP 获取实时实验数据,让工程师确认清理决定,在隔离的 Git worktree 中并行修改代码,再执行自动验证。在 50 个开关的评估中,45 个生成了可用的 Pull Request,平均每次清理耗时 13.8 分钟,成本为 4.79 美元。

这里最值得关注的不是“让模型删除一个 if”,而是如何把证据、授权、代码修改和验证串成一条可审计的工程流水线。

删除开关之前,先证明它真的失效了

一个看起来长期为 true 的开关,不一定可以立即删除。它可能仍承担紧急回滚、地区隔离、旧客户端兼容或灰度放量的职责。只扫描代码无法回答这些问题,清理系统还需要实验平台中的实时状态与使用数据。

DoorDash 的工作流通过 MCP 引入实时实验数据。MCP 在这里的价值,是给智能体提供受控、结构化的上下文入口,而不是让模型根据变量名猜测开关状态。

一条可靠的清理决策至少应包含:

  • 开关当前是否仍有流量或活跃实验;
  • 最终应该保留哪个分支值;
  • 是否存在回滚窗口或最低保留期限;
  • 对应服务、代码仓库和负责人是谁;
  • 工程师是否明确批准删除;
  • 哪些测试、构建和静态检查必须通过。

因此,LLM 适合负责“找引用、理解分支、生成修改”,但不应该自行决定业务开关已经没有价值。实时数据和人工批准构成了真正的删除门禁。

多智能体的重点是隔离职责,而不是增加角色数量

根据已披露的工作流,可以把清理任务实践为几个相互约束的阶段:

  1. 证据收集:通过 MCP 查询实验状态、流量和元数据,生成候选清理清单。
  2. 人工审批:负责人确认最终值、影响范围和允许修改的仓库。
  3. 代码分析:智能体搜索直接引用、封装函数、配置文件、测试夹具和文档。
  4. 隔离执行:每个任务进入独立 Git worktree,避免并行智能体相互覆盖工作目录。
  5. 自动验证:运行格式化、类型检查、单元测试和仓库自定义检查。
  6. PR 生成:附上实验依据、修改摘要、验证结果和需要人工复核的风险点。

Git worktree 是这套方案中很务实的一环。多个智能体如果共享同一个 checkout,就可能互相切换分支、污染未提交文件,甚至把另一个任务的修改带入 PR。worktree 允许它们共享 Git 对象数据库,同时拥有彼此独立的工作目录和分支。

并行度也不应无限提高。实际系统通常要同时限制:

  • 每个仓库的并发任务数;
  • LLM API 和 MCP 数据源的速率;
  • 测试集群或 CI Runner 容量;
  • 同一代码所有者收到的 PR 数量;
  • 单次任务允许修改的文件和代码量。

一个可改造的 worktree 清理脚本

下面不是 DoorDash 的内部实现,而是根据上述架构整理的最小脚手架。它要求工程师先提供审批结果,再创建独立 worktree,调用已有的 Agent CLI,最后运行仓库验证命令。

将以下内容保存为 cleanup-flag.sh,然后执行 chmod +x cleanup-flag.sh。运行前需要把 AGENT_CMD 换成团队实际使用的 Agent CLI;该命令会由 bash -lc 执行,因此只能接受可信配置。

#!/usr/bin/env bash
set -euo pipefail

: "${REPO:?Set REPO to the local Git repository}"
: "${FLAG_NAME:?Set FLAG_NAME}"
: "${REMOVE_VALUE:?Set REMOVE_VALUE, for example true or false}"
: "${APPROVED:?Set APPROVED=yes after engineer approval}"
: "${AGENT_CMD:?Set AGENT_CMD to your trusted agent command}"
: "${VALIDATE_CMD:?Set VALIDATE_CMD, for example 'pytest -q'}"

if [[ "$APPROVED" != "yes" ]]; then
  echo "Cleanup rejected: explicit engineer approval is required." >&2
  exit 1
fi

REPO="$(cd "$REPO" && pwd)"
SAFE_FLAG="$(printf '%s' "$FLAG_NAME" | tr -cs 'A-Za-z0-9._-' '-')"
WORKTREE_ROOT="$(dirname "$REPO")/.flag-worktrees"
WORKTREE="$WORKTREE_ROOT/$(basename "$REPO")-$SAFE_FLAG-$$"
BRANCH="cleanup/$SAFE_FLAG-$(date +%s)"
PROMPT_FILE="$(mktemp)"

trap 'rm -f "$PROMPT_FILE"' EXIT
mkdir -p "$WORKTREE_ROOT"

if ! git -C "$REPO" diff --quiet || ! git -C "$REPO" diff --cached --quiet; then
  echo "Base repository has uncommitted changes; refusing to continue." >&2
  exit 1
fi

git -C "$REPO" worktree add -b "$BRANCH" "$WORKTREE" "${BASE_REF:-HEAD}"

cat >"$PROMPT_FILE" <<EOF
You are cleaning up an approved stale feature flag.

Flag: $FLAG_NAME
Replacement value: $REMOVE_VALUE
Repository: $WORKTREE

Requirements:
- Find direct and indirect references to the flag.
- Preserve only the behavior selected by the replacement value.
- Remove unreachable branches, obsolete tests, and stale configuration.
- Do not change unrelated behavior or public APIs.
- Do not commit, push, or open a pull request.
- Summarize uncertain references instead of guessing.
EOF

export FLAG_NAME REMOVE_VALUE WORKTREE
export FLAG_PROMPT="$PROMPT_FILE"

(
  cd "$WORKTREE"
  bash -lc "$AGENT_CMD"
  bash -lc "$VALIDATE_CMD"
)

echo
echo "Validation passed. Review the resulting diff:"
git -C "$WORKTREE" status --short
git -C "$WORKTREE" diff --stat
echo
echo "Worktree: $WORKTREE"
echo "Branch:   $BRANCH"
echo "Remove after review with:"
echo "git -C '$REPO' worktree remove '$WORKTREE'"

例如,某个 Python 仓库可以这样调用:

export REPO="$HOME/src/checkout-service"
export FLAG_NAME="checkout_v2"
export REMOVE_VALUE="true"
export APPROVED="yes"
export AGENT_CMD='your-agent-cli run --prompt-file "$FLAG_PROMPT"'
export VALIDATE_CMD='python -m compileall -q . && pytest -q'

./cleanup-flag.sh

生产版本还应把 MCP 查询结果、审批人、审批时间和实验链接写入机器可读的任务记录,并让 PR 机器人自动附加这些信息。不要只在 prompt 中声明“已批准”,否则任何调用者都能绕过治理流程。

如何判断这套系统是否值得推广

50 个开关中有 45 个产生可用 PR,说明这类任务很适合半自动化;但“可用 PR”不等于已经正确合并,更不等于线上风险为零。评估时应该继续跟踪:

  • PR 最终合并率以及人工修改比例;
  • 错删、漏删和回滚次数;
  • 从候选发现到合并完成的总周期;
  • 每个 PR 的模型、CI 和评审成本;
  • 动态字符串、生成代码和跨仓库引用的漏检率;
  • 清理后代码量、测试量和配置复杂度的实际下降。

采用时可以先从“状态明确、单仓库、测试完善”的开关开始,把自动化边界限制在创建草稿 PR。对于支付、权限、风控、旧客户端兼容和灾难回滚开关,应增加更严格的审批与观察期。

DoorDash 的案例说明,大规模代码维护并不只是一个更强模型的问题。真正让多智能体系统可落地的,是实时证据、明确授权、隔离执行、自动验证和可追溯审查。模型负责加速机械工作,工程控制负责限制它能犯多大的错。


相关推荐