首页
/ Ansible 仓库的 AI Agent 工作手册:CLAUDE.md 背后的 PR 审查流程与 CI 失败诊断体系

Ansible 仓库的 AI Agent 工作手册:CLAUDE.md 背后的 PR 审查流程与 CI 失败诊断体系

2026-09-04 22:12:49作者:曹令琨Iris

CLAUDE.md 是 Ansible(ansible-core)仓库中为 Claude Code 等 AI Agent 准备的入口文件,它通过引用机制指向仓库中真正的 Agent 工作指南,定义了 AI 助手在此仓库开展 PR 审查、CI 失败诊断、许可合规校验时的标准流程与红线规则。读完本文,你将掌握 Ansible 贡献流程中 Agent 视角的完整操作链路:从 gh 命令驱动的代码审查清单,到 hacking/azp/download.py 脚本背后的 Azure Pipelines 日志下载与失败分析机制,再到 changelog 片段、测试与许可证的硬性要求。

一、CLAUDE.md:一个三行的入口,一份完整的 Agent 规范

先看 CLAUDE.md 的全文内容,它只有三行:

- @AGENTS.md
- @~/.claude/ansible.md
- @CLAUDE.local.md

这是 Claude Code 的文件引用(@ 前缀)语法:Claude Code 启动时会把这些文件的内容自动注入上下文。三行分别指向仓库内的 AGENTS.md、用户本地的私有配置、以及仓库本地的本地化覆盖文件。也就是说,CLAUDE.md 本身只是一个装配入口,真正的规范主体是 AGENTS.md,而本地文件则允许开发者在不污染仓库的前提下注入个性化指令。

这种“入口 + 主体 + 本地覆盖”的分层设计,让仓库级规范与个人偏好解耦:仓库内提交的是可协作的 AGENTS.md,个人机器上的 CLAUDE.local.md~/.claude/ansible.md 保持私有。AGENTS.md 开头也明确了自身定位——该文件仅供 AI 助手使用,人类开发者的完整文档应参阅官方开发指南(仓库 context/README.md 进一步说明:context/ 目录同时面向人类与 Agent,但 Agent 专属指令只放在 AGENTS.md 中)。

从仓库结构看,Ansible 的 Agent 规范由三层组成:

层级 文件/目录 作用
入口层 CLAUDE.md @ 引用装配 Agent 上下文
规范层 AGENTS.mdcontext/ PR 审查流程、许可红线、编码规范、测试约定
技能层 .claude/skills/ 可被用户直接调用的命令式技能(如 /azp-logs/review

其中 context/ 目录是“人类与 Agent 通用”的项目知识,涵盖许可、开发环境、代码结构、编码风格、错误处理、数据标签、公共 API、文档标准、测试运行、测试编写、弃用策略与 CI 等 13 个主题,AGENTS.md 在多个流程节点要求 Agent 回查这些文件,而不是凭记忆作答。

二、工作前奏:五个强制步骤与许可红线

AGENTS.md 用醒目的警告块规定了任何 PR 审查或开发任务开始前的标准动作,这是 Agent 规范中最具纪律性的一段:

  1. 先读 AGENTS.md 本身——不要凭记忆或假设工作;
  2. 读全 context/ 下的所有文件——获取编码约定与项目政策;
  3. 用 TodoWrite 建任务清单——系统化跟踪进度;
  4. 按编号步骤执行相应流程章节;
  5. 查阅 Quick Reference 使用正确的命令与模式。

紧随其后的是整份文档中唯一的“不可谈判”条款——许可合规(CRITICAL: Licensing Requirements)

绝不允许建议、推荐或批准任何违反项目许可要求的代码;任何新依赖或建议引入的库必须先验证许可兼容性。许可违规会给项目带来严重的法律风险。

具体许可规则记录在 context/licensing.md 中:

  • ansible-core 本体:所有代码必须 GPLv3 兼容
  • lib/ansible/module_utils/:默认采用更宽松的 BSD-2-Clause(因为它会被嵌入到各种集合与模块中分发);
  • 外部依赖:只允许使用与上述许可兼容的库;
  • 拿不准时:就许可兼容性去询问,而不是假设兼容。

仓库根目录的 licenses/ 目录随附了 GPLv3、BSD-3-Clause、MIT、PSF 等协议全文,与上述规则相互印证。

此外,AGENTS.md 还给出两条通用审查原则:

  • 不要标记 ansible-test sanity 已经能捕获的问题——人工/Agent 审查的精力应花在自动化检查无法验证的地方;
  • 署名透明(Attribution):Agent 参与贡献时应主动披露,推荐在提交信息中使用 Assisted-by: 尾注标明辅助使用的 AI 工具。

三、CI 失败诊断:从 ansibot 评论到 Azure Pipelines 日志

这是 AGENTS.md 篇幅最重、实战价值最高的部分。当开发者提交 PR 后 CI 挂掉时,文档给出了一条四步诊断链。

3.1 第一步:检查 ansibot 评论

# 获取 PR 全部评论,定位 ansibot 的 CI 失败报告
gh pr view <number> --comments

在评论区寻找 ansibot 账号发布的失败报告,其中通常包含:

  • 带具体错误信息的测试失败详情;
  • 失败位置的文件路径与行号;
  • 指向 sanity 测试文档的说明链接(explain 形式)。

3.2 第二步:获取 CI 检查状态与流水线链接

# 查看所有 CI 检查结果及 Azure Pipelines URL
gh pr checks <number>

该命令会输出:CI 总体状态(通过/失败)与耗时、Azure DevOps 构建结果的直接链接、以及各个子任务(Sanity Test 1/2、Docker 测试、Units 等)的单独结果。

3.3 第三步:失败分析的标准工作流

AGENTS.md 把分析流程固化为五个环节:

  1. 先查 ansibot 评论,获取最直接的错误详情;
  2. gh pr checks <number> 拿到 Azure Pipelines URL 查看详细日志;
  3. 聚焦标记为 fail 的 job,检查其具体错误输出;
  4. 对 sanity 测试失败,错误信息通常直接指明了要修什么;
  5. 对功能测试失败,ansible-test 在本地跑同样的测试来复现和调试

第 5 步对应的本地命令约定记录在 context/running-tests.md 中,例如:

# 本地复现 sanity 失败(不需要 --docker)
ansible-test sanity -v --test pep8 --test pylint
# 针对具体文件跑 sanity
ansible-test sanity -v lib/ansible/modules/command.py
# 本地复现 unit 失败
ansible-test units -v --docker test/units/modules/test_command.py
# 本地复现 integration 失败(注意:集成测试要用发行版容器,如 ubuntu)
ansible-test integration -v --docker ubuntu ping

context/ci.md 则总结了 CI 失败的三类常见模式:sanity 失败通常有明确修法(行尾空白、import 错误等);集成测试失败可能需要平台专用容器或测试调整;单元测试失败往往指向真实的代码缺陷。

3.4 第四步:用 /azp-logs 下载完整流水线日志

当 ansibot 评论和网页 UI 的信息不足以定位问题时,使用仓库内置的 /azp-logs 技能:

# 用 PR 号下载日志(自动查找最新一次构建)
/azp-logs <pr_number>

# 或直接使用 gh pr checks 输出中的 build ID
/azp-logs <build_id>

# 或传入完整的 Azure Pipelines URL
/azp-logs https://dev.azure.com/ansible/ansible/_build/results?buildId=12345

这个技能的完整定义见 .claude/skills/azp-logs/SKILL.md。它声明了受控的工具白名单(gh pr viewgh pr checkslsReadGrep),并规定了一个重要的交互纪律:下载前必须先征得用户确认,因为一次完整 CI 运行的日志下载可能要 5-10 分钟、体积 10-50MB。

日志下载完成后的标准分析手法:

# 在按 build ID 命名的目录里 grep 常见失败模式
grep -r "FAILED\|ERROR\|Traceback" <build_id>/

# 定位 sanity 测试失败
grep -r "The test" <build_id>/ | grep -i "failed"

# 查看下载了哪些日志
ls -lh <build_id>/

日志文件按 job 层级命名(如 "Job Name Stage Name.log")。由于 Ansible 项目在 Azure DevOps 上公开可见,整个下载过程不需要任何认证

四、download.py 源码解析:技能背后的下载引擎

/azp-logs 技能并不自己实现下载,而是封装了 hacking/azp/download.py 脚本。阅读其源码可以弄清 AGENTS.md 中那些命令行参数的确切行为。

4.1 命令行参数全集

download.py 的 parse_args 函数 定义了脚本的完整接口:

参数 说明
RUN(位置参数) AZP 运行 ID 或构建 URL,二选一
-v, --verbose 显示正在下载的内容
-t, --test 演练模式:只显示将下载什么,不实际下载
-p, --pipeline-id 流水线 ID,默认值为 20
--artifacts 下载测试产物
--console-logs 下载控制台日志(CI 失败分析的推荐项)
--run-metadata 下载运行元数据 JSON
--all 下载以上全部
--match-artifact-name <regex> 只下载名称匹配该正则的产物,默认 .*
--match-job-name <regex> 只下载 job 名匹配该正则的产物,默认 .*

参数校验逻辑值得注意:--all 会展开为三个开关全开(源码第 105-108 行);如果三个下载开关一个都没开,脚本直接以 At least one download option is required. 报错退出(第 116-117 行)。这也解释了 AGENTS.md 中“Advanced usage”示例为什么总带着 --console-logs--all 之一:

# 只下载 job 名匹配 "Sanity.*" 的控制台日志
./hacking/azp/download.py <build_id> --console-logs --match-job-name "Sanity.*"

# 下载产物与元数据
./hacking/azp/download.py <build_id> --all

4.2 RUN 参数的双格式解析

run_id_arg 函数 用一个正则同时接受两种输入:纯数字 build ID,或完整的 Azure 构建 URL——URL 中的 buildId= 部分会被自动剥离并提取出数字 ID。这正是 /azp-logs 技能能够“直接接收 URL”的原因:

def run_id_arg(arg):
    m = re.fullmatch(r"(?:https:\/\/dev\.azure\.com\/ansible\/ansible\/_build\/results\?buildId=)?(\d+)", arg)
    if not m:
        raise ValueError("run does not seems to be a URI or an ID")
    return m.group(1)

4.3 时间线树与 job 过滤机制

download_run 函数 的实现分几步走:

  1. 输出目录固定为以 build ID 命名的目录output_dir = '%s' % args.run),这与技能文档“Logs will be saved to a directory named after the build ID”的说明完全对应;
  2. 若启用 --run-metadata,调用 pipelines/{pipeline_id}/runs/{run} REST API 拉取运行信息,写入 <build_id>/run.json
  3. 无论哪种下载模式,都会请求 build/builds/{run}/timeline 接口,把时间线记录解析成一棵父子树(roots / children_of / parent_of 三个结构);
  4. 遍历根节点下的每个 job,只有 "<parent job name> <child name>" 拼接后匹配 --match-job-name 正则的 job 子树才会被加入 allowed 白名单;
  5. --console-logs 模式下,遍历时间线记录,对每个在 allowed 集合内且有 log.url 的记录,把日志写入 <build_id>/ 目录——文件名由从根到叶的完整 job 层级名拼接而成源码第 201-215 行),路径分隔符被替换为 _,最终形如 Stage Name Job Name.log

hacking/azp/ 目录下还有三个姊妹脚本,说明在 hacking/azp/README.md 中:get_recent_coverage_runs.py(查询最近覆盖率运行的 CI URL)、incidental.py(基于 CI 数据做“顺带覆盖”分析报告)、run.py(触发新的 CI 运行)。其中 download.py 的典型用法示例——下载一次覆盖率运行的产物与元数据——正与本文 3.4 节失败分析的流程同源。

五、PR 审查:七步清单与 review 技能

AGENTS.md 的“PR Review Guidelines”一节给出了适用于每一次 PR 审查的清单:

□ 为审查步骤创建 TodoWrite 清单
□ 第 1 步:gh pr view <number> 获取 PR 详情
□ 第 2 步:gh pr diff <number> 获取全部变更
□ 第 3 步:检查必备组件(changelog、测试)
□ 第 4 步:gh pr checkout <number> 检出 PR 分支
□ 第 5 步:gh pr view <number> --comments 查看既有反馈
□ 第 6 步:确认所有问题都已处理
□ 第 7 步:点名尚未解决的反馈
□ 每完成一步就把对应 TodoWrite 项标记为完成

七个步骤按序展开是:

  1. Get PR detailsgh pr view <number> 理解 PR 范围与描述;
  2. Get PR diffgh pr diff <number> 查看全部改动;
  3. 优先检查必备组件——changelog 片段是否存在、测试是否配套(分别对应 context/documentation-standards.md 的 changelog 要求与 context/writing-tests.md 的测试期望);
  4. Checkout PR 分支gh pr checkout <number>,让改动应用后从整体上审视代码,而不是盯着孤立的 diff;
  5. Review existing feedbackgh pr view <number> --comments 查看全部评论与历史审查意见;
  6. Verify all issues addressed:确认 bot 失败、审查者要求、讨论点都已解决;
  7. Call out unresolved feedback:对仍未处理的意见显式点名。

辅助工具清单同样明确:gh 系列命令之外,用 Read 工具细读具体变更文件,用 Grep(底层是 ripgrep)检索相关代码模式与测试覆盖。

这套清单在仓库中还有一个可直接调用的实现:.claude/skills/review/SKILL.md 定义了 /review <pr_number> 命令,其 front-matter 声明了工具白名单(TodoWritegh pr view/diff/checkout/checksReadGrepGlobSearch),把 AGENTS.md 的七步流程代码化。该技能还补充了两条清单之外的硬标准:

  • 测试范围:测试必须真实覆盖被改动的代码路径,而不是随机增加覆盖行;单元测试应为 pytest 风格、功能性优先、不与 mock 深度耦合;几乎所有插件改动都需要集成测试;
  • Changelog 校验:片段结构必须符合 changelogs/config.yaml 定义的章节;
  • 审查节奏:单轮审查的反馈项不应超过 20 条。

5.1 Changelog 片段的章节约束

AGENTS.md 要求“每个 PR 都要有 changelog fragment”,而片段能用哪些章节由 changelogs/config.yaml 严格定义:

sections:
- ['major_changes', 'Major Changes']
- ['minor_changes', 'Minor Changes']
- ['breaking_changes', 'Breaking Changes / Porting Guide']
- ['deprecated_features', 'Deprecated Features']
- ['removed_features', 'Removed Features (previously deprecated)']
- ['security_fixes', 'Security Fixes']
- ['bugfixes', 'Bugfixes']
- ['known_issues', 'Known Issues']

此外该配置还声明 notesdir: fragments(片段放在 changelogs/fragments/)、changes_file: changelog.yamlrelease_tag_re: '(v(?:[\d.ab\-]|rc)+)' 等。仓库当前累积的片段文件(如 changelogs/fragments/86656-fix-step-in-free-strat.yml 一类,以 issue 编号命名)就是这条流程的实物样本——每个待发布变更都以一个独立 YAML 片段记录在案,发布时由 ansible-test 生态中的 changelog 工具汇总进 changelog.yaml

六、把整套规范串起来:一次典型的 Agent 审查会话

综合 CLAUDE.md → AGENTS.md → context/ → skills 四层信息,一次标准的 Agent 介入流程是:

  1. Claude Code 启动,CLAUDE.md 通过 @ 引用把 AGENTS.md 注入上下文;
  2. Agent 按“Always Start Here”要求通读 context/ 全部 13 个主题文件;
  3. 用 TodoWrite 建立审查清单,依次执行 gh pr viewgh pr diff → 核对 changelogs/fragments/ 中的片段与 changelogs/config.yaml 章节、核对测试覆盖 → gh pr checkout → 复查评论;
  4. 若 CI 失败:gh pr view --comments 找 ansibot 报告 → gh pr checks 拿流水线链接 → 需要深挖时经用户确认后 /azp-logs <build_id>,由 hacking/azp/download.py 把控制台日志落盘到 <build_id>/ 目录 → grep FAILED/ERROR/Traceback 定位 → 按 context/running-tests.md 的命令在本地用 ansible-test 复现;
  5. 全程任何新增依赖先过 context/licensing.md 的 GPLv3/BSD-2-Clause 兼容性校验;提交信息带 Assisted-by: 尾注。

这套设计的工程价值在于:把原本依赖资深维护者经验的“看哪里、查什么、用什么命令”全部沉淀为仓库内可版本化的文本,AI Agent 与新人开发者读的是同一套规范,而 .claude/skills/ 中的技能文件又把这些流程收敛为一键命令——规范文档、执行技能与底层脚本(hacking/azp/)三者一一对应、互为印证。

七、适用边界与说明

  • 本文所有命令与流程均基于当前仓库内容(AGENTS.md.claude/skills/hacking/azp/download.pycontext/),适用于 Ansible 上游开发流程,与最终用户编写 playbook 的使用场景无关;
  • CI 基础设施为 Azure Pipelines,-p/--pipeline-id 默认值 20 与 API 域名(dev.azure.com/ansible/ansible)均硬编码在 download.py 中,指向 Ansible 上游公开流水线;
  • CLAUDE.md 引用的 ~/.claude/ansible.mdCLAUDE.local.md 属于本地文件,不在仓库内,本文不对其内容作推断;
  • 文中未涉及仓库未公开说明的内部实现细节;对行为差异(如日志命名规则)均以 download.py 源码 为准。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384