news 2026/9/8 23:27:12

Metabase Fixbot 自动化修复工作流解析:从 Linear Issue 到代码修复、验证与提 PR 的完整链路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Metabase Fixbot 自动化修复工作流解析:从 Linear Issue 到代码修复、验证与提 PR 的完整链路

Metabase Fixbot 自动化修复工作流解析:从 Linear Issue 到代码修复、验证与提 PR 的完整链路

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

Fixbot 是 Metabase 仓库中为"修复 Linear issue"而设计的自动化 AI 工作流:它以/fixbot斜杠命令为编排入口,借助仓库内的 Claude Code 命令、dev/bot下的 Agent 提示模板,以及mage的 bot 系列 CLI 命令,完成问题上下文采集、Agent Prompt 生成、代码修复与自验、用户验收乃至 PR 提交流程。本文以 .claude/commands/fixbot.md 为主干,结合其下游文件与mage源码实现,说明这套工作流每一步做什么、为什么这样做,以及每个命令与产物的真实形态,供需要扩展或维护仓库开发工具链的读者参考。

一、工作流定位:在哪个环境下、修什么问题

先明确 fixbot 的边界。编排命令的开头就定义了它的运行方式与约束:

"You are the orchestrator for the fixbot workflow. Fixbot fixes a Linear issue, running directly in this project against the locally running server."

也就是说,fixbot 直接在当前仓库中运行,针对一台本地已经启动的 Metabase 服务进行排障和修复,而不是在隔离的临时环境中。如果希望把整个修复过程放进一个隔离的 git worktree(独立的后端 + 前端),则改用复合命令/autobot <branch> /fixbot <args>——autobot会先创建/复用 worktree、搭好开发环境,再在会话里以/fixbot作为内部命令执行(见 .claude/commands/autobot.md)。

在 Metabase 的机器人家族里,fixbot 与 qabot(QA 评审 PR)、reprobot(复现 bug 并产出失败测试)、uxbot(UX 评审)并列,分别对应修复、验收、复现与交互体验评估;dev/bot/下与之配套的 Agent 模板包括 dev/bot/fixbot-agent.md 等,公共操作手册则放在 dev/bot/common/(environment-discovery、test-strategy、reproduction-strategies、report-generation 等),fixbot 是这条自动化链路的"实施者"。

1. 直接运行与 worktree 运行的选择

运行方式触发命令运行环境适用场景
直接运行/fixbot [args]当前仓库 + 本地已运行服务快速修复,允许与开发中的工作区共享
隔离运行/autobot <branch> /fixbot <args>独立 worktree + 独立后端/前端需要干净分支、互不干扰的修复

autobot 文档还支持 PR 预览环境(形如https://pr<NUMBER>.coredev.metabase.com)的远程模式,此时本机不启动服务,bot 直接对接已部署的预览环境。

二、Step 1:生成每次运行的隔离目录(Per-run Directory)

工作流的第一步是为本次运行分配独立的产物目录,这是整套设计的地基:

  • 生成时间戳,格式固定为YYYYMMDD-HHMMSS(如20260907-070155);
  • 若无法确定当前墙钟时间,运行./bin/mage -bot-timestamp获取——明确禁止直接用date命令
  • 定义两个变量并据此建目录:
TIMESTAMP=<YYYYMMDD-HHMMSS> OUTPUT_DIR=.bot/fixbot/<TIMESTAMP>

紧接着执行mkdir -p <OUTPUT_DIR>,保证后续所有cp/Write写入都能成功。设计要点有三条,直接体现了多任务并发的可靠性考量:

  1. 本次运行产生的所有文件(包括 discover 阶段工件)都只能落在<OUTPUT_DIR>/,不允许出现跨运行共享的路径;
  2. 因为目录名带秒级时间戳,同一仓库内多次/fixbot调用不会互相冲突;
  3. 严禁从上次运行的目录复制旧工件(例如linear-context.txt),上下文必须让 discover 重新生成,避免把过期内容带进本次修复。

这样的"一运行一目录 + 全局唯一产物路径"约定,配合 mage/src/mage/bot/prompt.clj 中写入文件前自动mkdirs父目录的实现,让每个阶段的文件操作都无须担心路径竞争。

三、Step 2:上下文收集——discover 阶段与 config.env

<OUTPUT_DIR>/config.env不存在时,先执行 discover:

/fixbot-discover $ARGUMENTS --output-dir <OUTPUT_DIR>

Discover 把工件直接写入<OUTPUT_DIR>/,从不写共享位置。随后编排者读取两份关键输入:

文件从中提取的内容
<OUTPUT_DIR>/config.envISSUE_IDBRANCH_NAMEAPP_DB
<OUTPUT_DIR>/linear-context.txt完整 Linear issue 内容(注入 Agent 模板的LINEAR_CONTEXT

3.1 fixbot-discover 的职责拆解

.claude/commands/fixbot-discover.md 把上下文发现拆成六个子步骤:

① 解析 Issue ID。位置参数支持三种输入格式,需归一化为 Linear issue ID:

  • Linear issue ID(如MB-12345UXW-3155)——直接使用;
  • GitHub issue 编号(如12345)——先解析为 Linear;
  • GitHub issue URL——先抽取编号再解析为 Linear。

GitHub 输入的解析路径是:用gh issue view <NUMBER> --repo metabase/metabase --json body,comments,title拉取 issue,在正文与评论里搜索 Linear 链接(https://linear.app/metabase/issue/[A-Z]+-[0-9]+模式)并抽取 ID;找不到 Linear 链接时,改用./bin/mage -bot-fetch-issue以 GitHub issue 标题派生搜索词直接搜索 Linear;仍无匹配则明确告知用户并停止。ID 最终必须通过[A-Z]+-[0-9]+校验。

② 解析运行目录。$ARGUMENTS中提取--output-dir <PATH>(缺失即停止并提示),TIMESTAMP取路径尾部的时间戳段。

③ 从 Linear 拉取 issue。执行./bin/mage -bot-fetch-issue <ISSUE_ID>,读取输出中的 issue 详情与分支名,并把完整输出写入<OUTPUT_DIR>/linear-context.txt

该命令的底层实现见 mage/src/mage/bot/linear.clj:通过 GraphQL(endpoint 为https://api.linear.app/graphql)按 identifier 查询,返回identifier / title / description / url / branchName / state / comments等字段;API Key 通过 mage/src/mage/bot/env.clj 的共享解析函数获取。值得注意的是 linear.clj 内部把该命令记为-fixbot-fetch-issue(usage 提示即./bin/mage -fixbot-fetch-issue MB-12345),说明这套 bot CLI 在迭代中调整过命名,新增命令时需以当前mage任务表为准。

④ 确定分支名。优先取 Linear issue 输出中声明的分支;若未指定,则用 issue ID 小写化作为分支名(例如MB-12345mb-12345)。

⑤ 推断应用数据库。依据 issue 描述/评论内容,从三个候选中选择一个:

  • 提到MySQL问题、MySQL 专有 SQL 语法或错误信息 →mysql
  • 明确提到MariaDBmariadb
  • 其他一律 →postgres(默认)。

这一点之所以重要,是因为 Metabase 支持 Postgres/MySQL/MariaDB 等不同应用数据库,某些 bug 只在特定方言下复现,bot 需要按正确数据库启动测试环境。

⑥ 写结果。用结构化格式把五元组写入<OUTPUT_DIR>/config.env

APP_DB=<postgres|mysql|mariadb> BRANCH_NAME=<branch-name> ISSUE_ID=<ISSUE_ID> TIMESTAMP=<TIMESTAMP> OUTPUT_DIR=<OUTPUT_DIR>

autobot 的编排逻辑里还有一层兜底:读完 config.env 后若APP_DB缺失,默认按postgres处理。这套"配置文件即契约"的约定,让 discover 阶段与后续的 Agent 阶段通过文件解耦,任何一方都能独立测试。

四、Step 3:用 mage 生成 Agent Prompt

上下文齐备后,编排者用mage的模板引擎从 Agent 提示模板渲染出本次运行专属的 prompt:

./bin/mage -bot-generate-prompt \ --template dev/bot/fixbot-agent.md \ --output <OUTPUT_DIR>/prompt.md \ --set "ISSUE_ID=<ISSUE_ID>" \ --set "BRANCH_NAME=<branch-name>" \ --set "APP_DB=<postgres|mysql|mariadb>" \ --set "OUTPUT_DIR=<OUTPUT_DIR>" \ --set-from-file "LINEAR_CONTEXT=<OUTPUT_DIR>/linear-context.txt"

参数语义:

参数作用说明
--template指定 Agent 提示模板指向 dev/bot/fixbot-agent.md,必填且要求文件存在
--output渲染产物路径写入<OUTPUT_DIR>/prompt.md,必填
--set KEY=VALUE内联变量例如 ISSUE_ID、BRANCH_NAME、APP_DB、OUTPUT_DIR
--set-from-file KEY=path从文件读入多行值LINEAR_CONTEXT内容通常很长且含换行,直接内联需要繁琐的 shell 转义,故用此方式按路径读取

4.1 模板引擎源码级原理

mage/src/mage/bot/prompt.clj 的generate-prompt!展示了渲染的实际行为:

  • 必填参数校验:--template/--output缺失即报错退出;模板文件不存在同样退出;
  • 先执行resolve-file-includes,把{{FILE:path}}占位符替换为仓库根目录下对应文件的内容——只做一遍,被包含的内容不会被再次扫描,路径相对仓库根目录,文件缺失时替换为<!-- FILE NOT FOUND: path -->并给出警告;
  • 再用--set--set-from-file合并出的替换表,把{{KEY}}占位符逐一替换(源码中是逐 key 执行str/replace,因此替换后的值不会参与其他 key 的展开);
  • parse-set-args对缺少=--set项给出黄色警告并忽略;parse-set-from-file-args对不存在的文件也仅警告并将值置为空串;
  • 写入前.mkdirs自动创建父目录,然后spit输出并打印Wrote prompt:

这样,fixbot-agent.md 模板里的两类占位符——{{ISSUE_ID}}{{BRANCH_NAME}}{{APP_DB}}{{LINEAR_CONTEXT}}这类变量占位符,以及{{FILE:dev/bot/common/environment-discovery.md}}{{FILE:dev/bot/common/test-strategy.md}}这类文件包含占位符——会在渲染时被统一替换,最终产出一个自包含、可直接作为 Agent 系统提示的 prompt.md。这种"模板 + 文件包含 + 运行时变量"的结构,让 agent 手册可以复用公共章节,避免在多份模板间复制粘贴漂移。

五、Step 4:执行阶段——Agent 的任务模型与自主边界

编排者随后读取渲染好的<OUTPUT_DIR>/prompt.md,按其中的 Phase 1–4 顺序执行,且要求所有阶段在同一个 turn 内完成,除非触发 STOP 条件——不能在阶段之间停下来等用户。真正定义 Agent 行为的是提示模板 dev/bot/fixbot-agent.md,其任务模型包含约束、阶段与安全边界三层。

5.1 两条硬性约束

20 分钟时间上限。Agent 若在 20 分钟内未能完成"理解—修复—自检"(Phases 1–3),必须立刻停下,把已有的诊断、部分修复和阻塞点呈现给用户并请求指引——"能说明自己卡在哪里的 fixbot,远比一个默默绕圈烧时间的 fixbot 有价值"。

Know Your Limits。fixbot 只处理能自主完成的简单明确 bug 与功能请求,遇到以下情况必须 STOP 并说明原因:

  • 修复涉及复杂架构决策、存在工程师难以一致认同的取舍;
  • 改动以难以察觉的方式影响既有功能(如其他功能依赖的行为);
  • 功能请求本身该不该做需要产品讨论;
  • issue 存在歧义,不同解读会导向差异很大的方案;
  • 修复横跨多个子系统、爆炸半径过大;
  • 需要靠猜而不是靠把握来确定预期行为。

模板还给出了一个沟通技巧:任何需要用户输入、提问、停下决策、或必须让用户注意的节点,都要用醒目的横幅框住(示例为用╔═╗绘制的 "FIXBOT NEEDS YOUR INPUT" 风格 banner),避免用户错过关键信息。

5.2 六个执行阶段

阶段目标关键动作
Phase 1 Understand理解问题通读已注入的 LINEAR_CONTEXT(不再重复 fetch);充分搜索代码库理解 bug 周边架构;涉及 UI 时用 Playwright MCP 复现;产品行为歧义才问用户
Phase 2 Fix修复严格 red/green TDD;后端先写失败 Clojure 测试(./bin/test-agent),前端先写 Jest 单测或 Cypress E2E;补上 issue 编号命名规范
Phase 3 Self-Review自检改过的 Clojure 文件跑/clojure-review、TS/JS 文件跑/typescript-review;逐个解决发现的问题;有重大改动则复审,直到干净
Phase 4 Verify验证UI 修复先由 Agent 用 Playwright MCP 自查;再把精确的验收步骤交给用户:URL 一律用http://localhost:$MB_JETTY_PORT/...(后端端口而非前端 dev server),并提醒登录凭据来自./bin/mage -bot-server-info
Phase 5 Open PR提交用户确认后提交:绝不提交.claude/.bot/fixbot/mage/下的改动;逐个git add path/to/file.clj(禁用git add ./-A);commit 与 PR 中严禁出现 Linear URL 或 issue ID(内部信息不外泄);PR body 用固定模板(Description / How to verify / Checklist)且不加 label
Phase 6 Monitor PR跟进提 PR 后用/cibot监控 CI 结果并处理失败,直到通过

值得注意的是模板环境章节特别说明:开发环境始终是 Enterprise Edition(EE),即使 issue 说的是 OSS 版本也要在 EE 下开发测试;若修复确实必须在 OSS 版验证(例如 OSS-only 行为差异),要停下告知用户,而不是强行尝试 OSS-only 修复。同时关于"用户画像"的设定也约束了交互方式:用户不是开发者,不要向 TA 要实现建议或技术决策,但 TA 是资深的 Metabase 产品用户,可用于澄清预期行为与做 UI 验收。

5.3 复现机器人(reprobot)协同

模板还提供了与 reprobot 的协作路径:若 issue 评论里包含 reprobot 的排查结论(Linear 评论中的 patch 或测试代码),可取来作为 TDD "red" 步骤的起点;但模板同时告诫——reprobot 的分析与根因假设不总是正确,必须对照真实代码自行验证。这与dev/bot/中 reprobot/qabot/fixbot 分角色协同的设计互为印证。

六、支撑 Agent 运行的公共手册与 mage 基建

{{FILE:...}}注入到提示模板中的公共手册,承载了 agent 实际操作的底层能力:

6.1 environment-discovery:环境发现与免硬编码

dev/bot/common/environment-discovery.md 规定了一套"先发现、后使用"的原则,核心是./bin/mage -bot-server-info——它会一次性输出 Jetty 后端端口、前端 dev server 端口、nREPL/socket REPL 端口、数据库端口、配置文件路径与内容、环境变量与 edition/token/连接 URI。严禁硬编码端口、凭据与 API key,一律从-bot-server-info动态获取。配套的 mage 实现包括:

  • -bot-repl-eval '<clojure-form>'——统一 REPL 入口,自动在 nREPL 与 socket REPL 间回退(见 mage/src/mage/bot/repl_eval.clj);
  • -bot-api-call /api/<path> [--method ...] [--api-key ...] [--body ...]——API 调用封装(见 mage/src/mage/bot/api_call.clj);
  • -bot-preflight-health——轮询健康检查最长 5 分钟的后端就绪探测(见 mage/src/mage/bot/preflight.clj);
  • 环境变量解析优先级:mise.local.toml > .env > .lein-env > 系统环境变量(见 mage/src/mage/bot/env.clj)。

该手册同时强调数据库操作应通过 REPL + Clojure JDBC(Toucan2)进行(如./bin/mage -bot-repl-eval '(do (require (quote [toucan2.core :as t2])) (t2/select :model/Card :id 1))'),而不是在 shell 里直接跑psql/mysql;日志访问可通过metabase.logger.core(logger/messages)(最近 250 条)与set-ns-log-level!动态调整级别;此外还有 Playwright MCP 工具装载、fail-fast 策略、远程 PR 环境模式(Tailscale 依赖、通过 API 而非本地库访问数据、破坏性测试先快照再回滚)等约束。

6.2 test-strategy:测试类型选型与命令

dev/bot/common/test-strategy.md 提供测试选型矩阵:后端逻辑/查询处理器/API 用 Clojure 单测(test/metabase/...);前端 UI 行为用 Jest 组件测试(co-located*.unit.spec.tsx);端到端用户流程用 Cypress(e2e/test/scenarios/...);混合改动则两者都写。文件命名有固定规律:src/metabase/foo/bar.cljtest/metabase/foo/bar_test.clj。运行命令示例:

./bin/test-agent :only '[metabase.foo-test/issue-12345-test]' bun run test-unit-keep-cljs path/to/file.unit.spec.ts npx cypress run --spec e2e/test/scenarios/category/file.cy.spec.ts

测试命名还要求带上 issue 号(如(deftest issue-12345-test ...)),让自动化修复的测试可以追溯到原始工单。

6.3 状态与结果汇报

为了让用户在长任务中保持知情,agent 要维护两个文件:.bot/autobot/llm-status.txt(1–3 行的状态栏,如 "Reproducing issue"/"Writing tests"/"Blocked: ..."),以及<OUTPUT_DIR>/result.md——后者由/autobot-result <branch> <bot>读取展示,格式为"已完成 / 当前状态"两段式摘要加一份不断追加的绝对路径产物清单(diff 分析、截图、API 响应、日志抓取等)。

七、完整命令速查

下面是整套 fixbot 工作流涉及的触发命令与 CLI,便于对照使用:

位置命令用途
编排入口/fixbot <issue>直接在当前仓库修复 Linear issue
隔离运行/autobot <branch> [from <base>] /fixbot <issue>worktree 内修复
上下文发现/fixbot-discover <issue> --output-dir <dir>解析 issue、推断 APP_DB、写 config.env
时间戳./bin/mage -bot-timestamp生成YYYYMMDD-HHMMSS(禁止用date
拉取 issue./bin/mage -bot-fetch-issue <ISSUE_ID>Linear GraphQL 拉取 issue 详情
渲染 prompt./bin/mage -bot-generate-prompt --template dev/bot/fixbot-agent.md --output ... --set ... --set-from-file ...生成自包含 Agent 提示
环境发现./bin/mage -bot-server-info端口/凭据/API key/环境变量一站式输出
REPL./bin/mage -bot-repl-eval '<form>'nREPL/socket 自动回退求值
API./bin/mage -bot-api-call /api/...免手工鉴权的 HTTP 调用
健康检查./bin/mage -bot-preflight-health后端就绪轮询(最长 5 分钟)
测试./bin/test-agent/ Jest / Cypress后端/前端/E2E 测试

八、小结:这套编排设计的可取之处

从仓库实现回看 fixbot 工作流,可以提炼出四个值得借鉴的设计点:

  1. 文件即接口、目录即隔离:discover 与执行阶段通过config.env和 per-runOUTPUT_DIR解耦,秒级时间戳保证并发安全,"禁止复制旧工件"杜绝了上下文过期问题;
  2. 模板 + 文件包含 + 变量mage -bot-generate-prompt{{FILE:path}}机制让 agent 公共手册可以在多份 bot 模板间复用,单一事实来源,避免各 bot 行为漂移;
  3. 明确的时间预算与决策边界:20 分钟硬上限、"Know Your Limits" 的 STOP 清单,把自主执行限定在低风险修复内,把架构取舍与产品歧义交还人类;
  4. 安全与卫生红线:不提交.claude/.bot/mage/等生成/拷贝目录,逐文件 stage,PR 与 commit 零 Linear 内部信息,敏感信息不落公开历史。

对希望基于 .claude/commands/fixbot.md 理解或扩展这套"机器人修复 issue"基础设施的读者,建议按 .claude/commands/fixbot-discover.md → dev/bot/fixbot-agent.md → dev/bot/common/environment-discovery.md 的顺序阅读,并结合 mage/src/mage/bot/prompt.clj 与 mage/src/mage/bot/linear.clj 等实现逐行对照,即可获得从"编排命令"到"底层 CLI"的完整视角。

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 23:25:22

Ryujinx Switch 模拟器上手指南:从安装到调优的完整流程

Ryujinx Switch 模拟器上手指南&#xff1a;从安装到调优的完整流程 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx 你手上有一份 .nsp 游戏文件&#xff0c;想不插主机就玩起来。Ryuj…

作者头像 李华
网站建设 2026/9/8 23:24:54

HIL测试本质:信号→协议→硬件→模型→验证的全链路解构

1. 为什么HIL测试不是“会CANoe就上岗”&#xff0c;而是汽车电子验证的终极守门人 刚入行那会儿&#xff0c;我带过三个应届生&#xff0c;清一色自动化/车辆工程专业&#xff0c;简历上都写着“熟练使用CANoe”“了解CAN总线”。结果第一次让他们搭一个VCU的HIL测试环境——没…

作者头像 李华