读懂 Selenium 仓库的 AGENTS.md:AI Agent 协作与 Bazel 单体仓库工程指南

📅 发布时间:2026/9/6 20:39:41
读懂 Selenium 仓库的 AGENTS.md:AI Agent 协作与 Bazel 单体仓库工程指南 读懂 Selenium 仓库的 AGENTS.mdAI Agent 协作与 Bazel 单体仓库工程指南【免费下载链接】seleniumA browser automation framework and ecosystem.项目地址: https://gitcode.com/GitHub_Trending/se/selenium在 Selenium 单体仓库monorepo中根目录的 AGENTS.md 是一份面向 AI Agent 的工程协作规范它约束了构建工具链Bazel/Bazelisk、执行模型、跨语言绑定的行为一致性、测试与日志习惯、废弃策略以及高风险变更的边界。读完本文你可以掌握在这类多语言、Bazel 构建的单体仓库中组织自动化任务的方法——包括如何用go/go.bat驱动 JRuby Rake 任务、如何用bazel query与--output_base安全地执行构建以及如何在改动后做跨绑定cross-binding核对与格式化校验。一、文档定位这是一个 Bazel 构建的 W3C WebDriver 单体仓库AGENTS.md 开篇给出的总览Overview说明了仓库性质Selenium is a Bazel-built monorepo implementing the W3C WebDriver (and related) protocols, shipping multiple language bindings plus Grid and Selenium Manager.即仓库实现 W3C WebDriver 及相关协议同时交付多种语言绑定、Grid 和 Selenium Manager 三部分产物。文档还特别提示README 面向贡献者最终用户文档存放在仓库之外这解释了为什么仓库内几乎找不到面向使用者的 API 手册。一个值得注意的细节根目录的 CLAUDE.md 内容只有一行AGENTS.md——这是 Claude Code 的引用语法意味着该文档被 AGENTS.md 完整代理。换言之AGENTS.md 是整个仓库唯一事实来源single source of truth的 Agent 指南其他 AI 工具入口都收敛到它。文档还定义了一个本地贡献者定制机制Local contributor customization.local/目录用于存放个人定制内容、生成产物、草稿与临时文件Git 忽略其中除.local/README.md之外的所有文件贡献者可以创建.local/AGENTS.md作为个人指令覆盖层local instruction overlay——规范要求 Agent 在开始任何任务前先检查该文件是否存在若存在则读取并将其作为个人偏好叠加overlay应用若存在.local/agent/skills/其中每个子目录的SKILL.md应被检查并视为用户自定义技能skills。这套机制的价值在于全局规范保持稳定而个人化的路径约定、测试偏好等可以无侵入地叠加且不会污染 Git 历史。二、两条不变量Invariants默认不破坏兼容不做全仓库重构文档Invariants一节列出了除非被明确要求、否则不得违反的硬约束默认维护 API/ABI 兼容性——用户的升级方式是只改版本号公开功能只能在下文所述的废弃策略Deprecation policy走完流程后才能移除避免仓库级重构/格式化——优先小而可逆reversible的 diff。这两条不变量贯穿了后文所有章节高风险变更清单、PR 审查优先级、改动后需声明影响面的流程本质上都是在执行这两条约束。三、工具链Bazelisk 密封工具集 JRuby Rake 任务3.1 一切经由 Bazel而非本地语言环境Toolchain一节的核心原则项目使用Bazelisk 配合 hermetic密封Bazel 工具集。因此不能假设某个语言Java/Python/Rust 等的本地开发环境已经配置好就去跑测试或执行 Selenium 代码Rakefile 任务通过打包的 JRuby 执行外层用go/go.bat封装CI 任务高频调用优先使用定向targetedBazel 命令在构建/测试前先用bazel query ...定位 label。3.2go脚本的真实实现一个 JRuby 包装器文档提到go封装了 JRuby仓库根目录的 go 脚本印证了这一点。其工作方式#!/usr/bin/env bash # we want jruby-complete to take care of all things ruby unset GEM_HOME unset GEM_PATH JAVA_OPTS-client -Xmx4096m ... --add-opens java.base/java.langALL-UNNAMED ... # This code supports both: # ./go namespace:task[--arg1,--arg2] --rake-flag # ./go namespace:task --arg1 --arg2 -- --rake-flag ... java $JAVA_OPTS -jar third_party/jruby/jruby-complete.jar -X-C -S rake $task ${rake_flags[]}关键点先unset GEM_HOME GEM_PATH把 Ruby 环境完全交给third_party/jruby/jruby-complete.jar见 third_party/jruby/ 中锁定的 JRuby 版本保证与本机系统 Ruby 无关支持两种参数风格./go namespace:task[--arg1,--arg2] --rake-flag或./go namespace:task --arg1 --arg2 -- --rake-flag。脚本会把--之前的参数拼成task[args]形式传给 Rake--之后的原样作为 rake flags默认 JVM 参数里包含-Xmx4096m以及若干--add-opens用于让 JRuby 在较新 JDK 的模块系统下正常工作。3.3 Rake 任务体系按语言命名空间组织Rakefile 展示了go背后的任务版图。每个语言加载一个 rake 文件到独立命名空间namespace(:java) { load rake_tasks/java.rake } namespace(:rb) { load rake_tasks/ruby.rake } namespace(:py) { load rake_tasks/python.rake } namespace(:node) { load rake_tasks/node.rake } namespace(:dotnet) { load rake_tasks/dotnet.rake } namespace(:rust) { load rake_tasks/rust.rake } namespace(:bazel) { load rake_tasks/bazel.rake }对应文件见 rake_tasks/如java.rake、python.rake、bazel.rb等。此外还有几个值得了解的通用任务默认任务是 Gridtask default: [:grid]且task grid: [:java:grid]——直接./go即构建 Selenium Grid 的 Java 产物更新类任务update_browsers更新固定的浏览器版本实际执行bazel run //scripts:pinned_browsers、update_manager、update_multitool、update_cddl从 w3c/webref 更新 CDDL 规范、update_cdp更新 Chrome DevTools 协议支持对应 scripts/update_cdp.py发布任务pre_release selenium-4.31.0形式的 tag 解析后按语言执行#{language}:version与#{language}:changelogs兜底规则任何长得像 Bazel label//...的任务名会被直接bazel buildrule(%r{//.*}) do |task| Bazel.execute(build, %w[], task.name) end也就是说./go //java/...会退化为bazel build //java/...任务系统对 Bazel 是透明的。3.4 依赖由 MODULE.bazel 统一固定文档将依赖更新 /MODULE.bazel/ repin 流程列为高风险项原因是 MODULE.bazel 中所有 Bazel 模块依赖都被显式钉住版本如rules_java 9.6.1、rules_python 1.9.0、rules_rust 0.0.96并用single_version_override强制关键库如protobuf 33.5与仓库内预编译产物保持一致# If you update this, also update the prebuilt version of protoc we use below bazel_dep(name protobuf, version 33.5) ... single_version_override( module_name protobuf, version 33.5, )这类文件是跨工具链的耦合点任何 Agent 修改它都可能同时影响 Java、Python、JS、Rust 等工具链故被要求修改前先请求验证。四、执行模型先 query后 build--output_base放在最前面Execution model一节给出了三条可直接照做的操作规程读文件之前先用bazel query探索构建图——在 monorepo 中通过构建图定位代码比全盘 grep 更快也更准优先直接执行 Bazel 命令。若因沙箱网络/工具链限制被阻止则把可复制粘贴的命令单独一行建议给用户而不是声称已执行当默认输出目录受限、或处于 git worktree 中时用--output_base隔离构建产物。文档特别强调了它的正确语法位置bazel --output_base$(git rev-parse --show-toplevel)/.local/output-base build //...它是startup flag必须放在build/test/query之前用git rev-parse --show-toplevel锚定到 worktree 根目录保证从任何子目录执行时路径都能解析到同一位置——这与第二节个人产出放.local/的约定正好呼应.local/output-base默认被 Git 忽略不会污染仓库。五、仓库布局五种绑定 共享高风险区Repo layout一节把仓库划分为两类区域并指明每个语言目录都有自己的 AGENTS.md 作为细则语言绑定Bindings绑定目录细则文档Java含 Gridjava/java/AGENTS.mdPythonpy/py/AGENTS.mdRubyrb/rb/AGENTS.mdJavaScriptjavascript/selenium-webdriver/javascript/selenium-webdriver/AGENTS.md.NETdotnet/dotnet/AGENTS.md共享/高风险区Shared/high-risk areasrust/——Selenium Manager 本体见 rust/AGENTS.mdcommon/——构建/测试接线build/test wiring影响多个区域common/src/——测试用 HTML fixtures见 common/src/web/ 下的click_tests/、modal_dialogs/等大量测试页面javascript/atoms/——共享 JS atoms爆炸半径大high blast radiusscripts/、rake_tasks/、.github/、Rakefile——工具链/构建自身third_party/——视为只读bazel-*/——视为生成的输出Bazel 符号链接产物不要手动改动。这个分层 AGENTS.md结构根文档管全局不变量子目录文档管语言细节是大型 monorepo 中管理 AI Agent 行为的有效模式全局规则少而稳定语言细节随语言演进互不干扰。六、跨绑定一致性改动用户可见行为前先对照其他绑定Cross-binding consistency checks一节的要求非常具体When changing user-visible behavior, compare with at least one other binding:rg term java/ py/ rb/ dotnet/ javascript/selenium-webdriver/即修改任何用户可见行为时至少用 ripgrep 在另一个绑定里搜索同一术语确认各语言实现是否同步。如果改的是共享/低层行为协议、序列化、remote/transport 传输层文档建议主动提出后续的 parity对齐工作或直接提 issue 记录。这一要求与 .github/pr_review.md 的审查优先级互相印证——Cross-binding parity被列为potentially blocking的潜在阻塞项之一一个绑定里的用户可见行为变化必须确认其他绑定已同步或有跟进记录。七、测试、日志与废弃策略7.1 测试偏好Testing一节的三条原则实现方案时优先先写测试test-first 偏好优先写小的单元测试而非浏览器测试理由是速度与可靠性避免 mock——mock 可能错误地表达 API 契约misrepresent API contracts。配套给出了三个常用 Bazel 测试 flagFlag作用--test_size_filterssmall只跑单元测试--test_outputall显示控制台输出--cache_test_resultsno强制重跑绕过缓存具体到某个语言的测试命令文档指回各语言 AGENTS.md如 java/AGENTS.md 指向java/TESTING.md。这与避免 mock的立场一致WebDriver 绑定天然面向真实浏览器语言级单测应聚焦序列化、capability 解析等纯逻辑而不是用 mock 假装驱动浏览器。7.2 日志与废弃语言细则里有可直接套用的模板根文档对日志在用户可能需要洞察的地方加日志和废弃策略本项目不遵循 semver移除公开功能前先标记为 deprecated 并附指向替代方案的消息只给原则落地模板在子目录文档中。例如 rust/AGENTS.md 给出// 日志分级 warn!(actionable: something needs attention); info!(useful: browser resolved successfully); debug!(diagnostic: request details for debugging); // 废弃标注 #[deprecated(since 0.1.0, note Use new_function instead)] pub fn old_function() { }java/AGENTS.md 则给出java.util.logging的对应写法LOG.warning/info/fine三级与Deprecated(forRemoval true)标注。注意这里的日志分级语义是统一约定的warning actionable需要处理、info useful有用、fine/debug diagnostic诊断细节各语言只是映射到各自的日志框架。7.3 非 semver 的现实意义not following semver意味着用户升级时不能依赖语义化版本号的 major 位判断破坏性变更这也反向解释了第二条不变量维护 API/ABI 兼容为何如此重要版本号的只改一个数字升级体验是以贡献者自觉做废弃流程为前提的。八、通用准则与格式化scripts/format.sh的三种模式General Guidelines一节包含若干 git 工作流层面的约定注释解释why而不是 what优先起好方法名PR 聚焦单一主题PR 会被squash 合入trunk分支——这解释了格式化脚本为何反复以 trunk 为基准移动文件时优先复制而不是删除重建以保留 git 历史避免运行bazel clean --expunge会清空所有密封缓存重建成本极高。格式化是 CI 上的常见失败点文档给出了 scripts/format.sh 的三种用法命令行为./scripts/format.sh无参检查相对 trunk 的全部变更含未提交内容类似./go format但带失败信息./scripts/format.sh --pre-commit只检查已暂存staged变更./scripts/format.sh --pre-push只检查相对 trunk 已提交的变更从 scripts/format.sh 源码可以看到它的实现细节自动识别当前分支若已在trunk上则对比origin/trunk否则对比本地trunk并用git merge-base找到公共祖先增量格式化只有当对应路径出现在变更集里才触发该语言格式器java/→ google-java-format、javascript/selenium-webdriver/→ prettier、rb/与Rakefile→ rubocop、rust/→ rustfmt、*.py→ ruff、dotnet/→ dotnet format而buildifier与update_copyright总是执行失败判定脚本先记录git status --porcelain基线格式化后若工作区状态与基线不同说明格式器改动了文件列出差异并exit 1——因此它既能自动修复也能作为 CI 的检查器文档补充的操作建议如果./scripts/format.sh已经挂在 pre-commit/pre-push hook 上就交给 hook 处理否则在 push 前运行或建议运行./scripts/format.sh --pre-push避免 CI 格式器失败。九、高风险变更清单与改动后自查9.1 哪些改动必须先请求验证High risk changes一节列出除非被明确指示修改前应请求验证上文标注为 high risk 的所有区域rust/、common/、common/src/、javascript/atoms/、scripts/、rake_tasks/、.github/、Rakefile、只读的third_party/WebDriver/BiDi 语义、capability 解析、wire 层协议线格式行为依赖更新 /MODULE.bazel/ repin 流程Grid 的 routing/distributor/queue 逻辑。这份清单与 .github/pr_review.md 的 Extra scrutiny 段落几乎逐字对应BiDi 语义、capability 解析、wire 层行为、Grid 路由/分发/队列、依赖更新与 repin、javascript/atoms说明仓库对人审和Agent 审使用的是同一套风险模型。该 PR 审查指南同时明确了不该评论的内容格式风格、CI 状态、只读的third_party/、面向用户的文档更新——因为用户文档不在本仓库以减少审查噪音。9.2 改动后的两个动作After making code changes一节要求 Agent/贡献者完成改动后主动指出触碰了哪些高风险区域注明跨绑定影响以及是否需要开跟进 issue。配合 Reviewing pull requests 一节指向 .github/pr_review.md整个协作闭环是全局不变量约束 → 语言细则落地 → 高风险区先验证 → 跨绑定核对 → 改动后声明影响面 → 按统一清单做 PR 审查。十、小结把 AGENTS.md 当成 monorepo 的运行手册AGENTS.md 本身很短但它定义了在这类仓库中工作的完整操作面入口与叠加根文档为唯一事实来源.local/AGENTS.md与.local/agent/skills/提供无侵入的个人化叠加构建面Bazelisk 密封工具集go包装 JRuby 驱动 Rake 任务bazel query先行、--output_base隔离 worktree 产物质量面test-first、小单测优先、少用 mock日志三级语义统一非 semver 下的显式废弃流程风险面BiDi 协议、capability 解析、MODULE.bazel、Grid 队列/路由、javascript/atoms等高风险区先验证后修改改动后声明影响与跨绑定跟进。对开发者或驱动开发者的 AI Agent而言遵循这份文档等价于同时满足仓库 CI 的检查格式化、构建、测试与人工审查的优先级清单.github/pr_review.md是贡献这类多语言 WebDriver 单体仓库时最直接可执行的工程约定。【免费下载链接】seleniumA browser automation framework and ecosystem.项目地址: https://gitcode.com/GitHub_Trending/se/selenium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考