首页
/ Home Assistant Core 贡献指南解析:AGENTS.md 中的开发工作流、测试规范与 AI 协作边界

Home Assistant Core 贡献指南解析:AGENTS.md 中的开发工作流、测试规范与 AI 协作边界

2026-09-04 19:46:42作者:虞亚竹Luna

本文以 Home Assistant 核心仓库(homeassistant 包)根目录下的 AGENTS.md 为主体,系统讲解这份面向开发者(尤其是 GitHub Copilot 与 Claude Code 等 AI 编码代理)的仓库级指引:它规定了 Git 提交与 PR 操作准则、基于 uv + prek 的开发环境搭建命令、Python 3.14 的语法适配要点、测试编写规范与代码评审时的“好实践”标准,并划定了 AI 自主贡献的边界。读完后,你将能够按仓库官方要求完成环境初始化、运行测试、通过 pre-commit 检查,并理解每条规范背后的源码依据。

文档定位:一份写给 AI 代理与人类贡献者的开发规约

仓库自述(AGENTS.md 首段)指出:本仓库包含 Home Assistant 的核心,是一个基于 Python 3 的家庭自动化应用。AGENTS.md 标题为 “GitHub Copilot & Claude Code Instructions”,它是一份“仓库级指令文件”(repo-level instructions):当 AI 编码代理在此仓库中工作时,会读取该文件以了解提交规范、开发命令和评审偏好;同时它也等价于人类贡献者的工作手册。

几个可以从仓库结构确认的事实:

  • CLAUDE.md 是指向 AGENTS.md 的符号链接,因此 Claude Code 与通用 AGENTS 规范共用同一份内容,避免规则漂移;
  • pyproject.tomlrequires-python = ">=3.14.2".python-version 锁定 3.14.5,与文档中 “官方最低支持 Python 3.14” 的表述完全一致;
  • .pre-commit-config.yaml 中存在一个名为 gen_copilot_instructions 的本地 hook,会触发 python3 -m script.gen_copilot_instructions 重新生成 AI 指令相关内容,说明该文件处于项目的自动化维护链路中。

Git 提交与 Pull Request 操作准则

AGENTS.md 在提交与 PR 层面只给出两条硬规则,但对协作质量影响极大:

  1. PR 打开后,禁止对已推送到 PR 分支的提交执行 amend、squash 或 rebase。 理由是评审者需要能跟随提交历史、看清自上次评审以来发生了哪些变化。
  2. 开 PR 必须使用仓库模板,且不得删除模板中的任何内容,包括未勾选的复选框——保留未勾选项可以让评审者明确哪些选项没有被选择。

结合 .pre-commit-config.yaml 中的 no-commit-to-branch hook 可以看出,仓库还通过工具链禁止直接向 devmasterrc 分支提交,与上述 PR 流程形成闭环:所有变更都走 PR,历史可追溯。

开发命令:script/setup、uv 与 prek 的完整工作流

文档 “Development Commands” 一节定义了四条操作准则,下面逐条展开并给出仓库内的落地证据。

使用虚拟环境中的 python3

准则要求:运行代码时应在当前虚拟环境中执行 python3,以确保测试使用的是正确的 Python 版本。这一点在 script/setup 中可以直接验证:脚本会优先使用 uv venv .venv(未安装 uv 时回退到 python3 -m venv .venv)创建虚拟环境并激活它。

script/setup 初始化环境

准则要求:每次进入新的环境或 worktree 时,先运行 script/setup 完成虚拟环境与全部开发依赖(pylint、pre-commit hooks 等)的安装,这是提交前必需步骤。阅读脚本源码可以看到其完整步骤:

  1. .vscode/settings.json 不存在,从 .vscode/settings.default.jsonc 复制默认设置;
  2. mkdir -p config 并创建/激活虚拟环境;
  3. 调用 script/bootstrap 安装依赖;
  4. 执行 prek install 安装 pre-commit 钩子(prek 是 pre-commit 的 Rust 实现,与文档中 prek run 命令配套);
  5. 运行 hass --script ensure_config -c config 生成开发用配置,并追加 logger 配置(默认 infohomeassistant.components.clouddebug)。

该节还给出了一个明确的故障处理路径:如果 uv 报告“找不到所需 Python 版本的下包”,说明本机 uv 过旧,需升级 uv 后重新运行 script/setup

.vscode/tasks.json 中的开发命令集合

准则提到 .vscode/tasks.json 包含常用开发命令。该文件实际定义了一组 VS Code 任务,覆盖了日常开发的全部高频操作:

任务 命令 用途
Run Home Assistant Core python -m homeassistant -c ./config 本地运行核心(依赖先编译英文翻译)
Pytest python -m pytest --timeout=10 tests 全量测试
Pytest (changed tests only) python -m pytest --timeout=10 --picked 只跑有变更的测试
Ruff / Prek prek run ruff-check --all-filesprek run --show-diff-on-failure 检查与格式化
Code Coverage pytest --cov=homeassistant.components.<name> ... 针对单个集成生成覆盖率
Update syrupy snapshots pytest ... --snapshot-update 更新快照
Compile English translations python -m script.translations develop --all 编译翻译字符串
Create new integration python -m script.scaffold integration 脚手架创建新集成

会话收尾的 lint 检查

准则要求:每次代码会话结束后运行 uv run --no-sync prek run --all-files,检查 lint 与格式问题。--no-sync 表示不重新同步依赖,直接复用当前环境执行;--all-files 则对全部文件而非仅暂存文件执行钩子,适合在会话末尾做全量自查。

Python 3.14 语法适配要点

这是文档中对 AI 代理最具操作价值的一节:因为 Home Assistant 的最低 Python 版本就是 3.14,代理不应把 3.14 的新语法当作品味问题上报。文档列出三条具体规则:

  1. 不要把依赖 Python 3.14 的语法或特性标记为问题,也不要建议旧版本兼容写法。 这一点由 pyproject.tomlrequires-python = ">=3.14.2"AGENTS.md 的声明共同背书。
  2. except TypeA, TypeB:(无括号多异常)在 3.14 中显式合法,不要标记为问题。
  3. PEP 649 惰性求值注解:注解在 3.14 中惰性求值,前向引用无需加引号,也无需 from __future__ import annotations——注解可以直接引用模块中后定义的名字。

从工程角度看,这三条规则的实质是防止 AI 代理把“正确的新语法”误判为缺陷并发起无谓的回退修改,保证代码库能够稳定演进到最新语言特性。

测试规范:从命令编写到快照策略

文档 “Testing” 一节的七条规则可以归纳为三层。

运行与翻译再生成

  • 统一使用 uv run --no-sync pytest 运行测试;
  • 修改某个集成的 strings.json 后,必须先运行 python3 -m script.translations develop --integration <integration_name> 重新生成英文翻译文件再跑测试——因为测试加载的是生成产物 translations/en.json,而不是直接读 strings.json.vscode/tasks.json 中对应的 “Compile English translations” 任务(--all 全量版)印证了这一流程在项目中的常态化地位。

测试代码风格

  • 所有测试函数参数必须带类型注解;
  • 优先使用具体类型(如 HomeAssistantMockConfigEntry)而非 Any
  • 参数不会被使用到函数体中时,优先 @pytest.mark.usefixtures 而非形参注入;
  • 避免在测试中写条件分支——应拆分测试或调整参数化,让每个用例路径都被直接覆盖;
  • 多个共享大部分代码的测试,应合并为一个 pytest.mark.parametrize 参数化测试,并用带 idpytest.param 为每个用例命名;
  • 硬编码的 entity_id 在测试中是允许的;同一 ID 重复出现时提取为常量。

快照测试

仓库使用 Syrupy 做快照测试,要求利用 .ambr 快照文件代替在 Python 代码里重复、穷举式地生成测试数据。tests 目录下存在大量 .ambr 快照(如 tests/snapshots),.vscode/tasks.json 也提供了 --snapshot-update 的专用任务,构成“生成 → 比对 → 更新”的完整闭环。

代码“好实践”:评审视角下的四条硬标准

AGENTS.md 的 “Good practices” 一节实质上揭示了维护者的评审标准,以下逐条说明并给出源码佐证。

参考 Platinum/Gold 质量等级的集成

文档指出:在 Integration Quality Scale 中达到 Platinum 或 Gold 等级的集成代表高标准的代码质量与可维护性,是寻找代码范例时的首选起点;等级记录在每个集成的 manifest.json 中。例如 homeassistant/components/deconz/manifest.json 这类集成的 manifest 中即可看到质量等级字段。

信任服务 Schema 的校验,不做防御性冗余

在评审实体动作(entity actions)时,不要建议对已被 Home Assistant 服务/动作 schema 及实体选择过滤器校验过的输入字段追加防御性检查;只有当数据绕过了这些校验器、或被转换成更不安全的形式时才建议额外保护。这条规则的本质是把校验责任收敛到框架层,避免集成代码中散落重复 guard。

校验保证键存在时,用直接下标访问

当校验已保证 dict 中某个键存在时,优先写 data["key"] 而不是 data.get("key")——这样契约违背会立即显形,而不是被静默吞掉。这与“不掩盖问题”的评审哲学一致。

注释纪律:只解释 why,不解释 what

文档对注释的规定相当具体,值得逐条对照执行:

  • 注释保持简短:要么一行说明非显而易见的约束,要么干脆不写;
  • 禁止复述下一行代码的注释(如 if self.initialized: 上方的 # Check if initialized);注释只解释 why(非显而易见的约束、令人意外的行为、workaround),从不解释 what;引用“代码以前长什么样”来为本次修改辩护的注释一律不加;
  • 禁止在函数内外添加分区/分隔注释(如 # --- XYZ Triggers ---),这类注释极易过时并误导;
  • 测试中解释“为何发起某次调用/断言”的注释是允许的例外。

异常捕获的最小化 try 原则

捕获异常时 try 块应尽量小:不要用 try 包裹大段代码,也不要捕获那些本不应抛异常的函数的异常。从源码结构看,这与 Home Assistant 大量使用 async with 上下文管理器和窄作用域任务(如 homeassistant/helpers/service.py 中服务处理被包装为独立 HassJob)的异步风格是配套的。

敏感服务必须走 admin 校验

文档要求:可能修改配置或有安全影响的敏感服务动作,应要求管理员用户,并使用 async_register_admin_service 服务助手注册,由它代为完成校验。该助手位于 homeassistant/helpers/service.py

@callback
def async_register_admin_service(
    hass: HomeAssistant,
    domain: str,
    service: str,
    service_func: Callable[[ServiceCall], ...],
    schema: VolSchemaType = vol.Schema({}, extra=vol.PREVENT_EXTRA),
    supports_response: SupportsResponse = SupportsResponse.NONE,
    *,
    description_placeholders: Mapping[str, str] | None = None,
) -> None:
    """Register a service that requires admin access."""
    hass.services.async_register(
        domain, service,
        partial(_async_admin_handler, hass,
                HassJob(service_func, f"admin service {domain}.{service}")),
        schema, supports_response,
        description_placeholders=description_placeholders,
    )

其包装的 _async_admin_handler(同文件 L982-L993)在真正执行服务前会取出调用上下文中的用户并检查 user.is_admin:用户不存在时抛 UnknownUser,非管理员抛 Unauthorized。也就是说,“admin 校验”不是文档口号,而是框架内置且可测试的调用链。注意 schema 默认 extra=vol.PREVENT_EXTRA,进一步印证了“在框架层严格校验、集成层不做冗余防御”的设计取向。

AI 政策边界:允许工具,禁止自主

AGENTS.md 最后一条把前述所有规则置于 Open Home Foundation AI Policy 的框架下:

  • 遵循 AI_POLICY.md不接受自主贡献:每一处变更在提交前必须经过人类的评审、理解并能被人类解释;
  • 不得自主开 issue 或 PR,也不得在未经用户评审的情况下以用户名义发表评论。

AI_POLICY.md 进一步细化了边界:AI 生成但贡献者未亲自评审理解的内容不会被接受;疑似自主生成的 PR/issue 会被直接关闭;允许用 AI 润色语法与表达,但不允许用 AI 代答维护者的提问;引用 AI 交互上下文必须用引用块并明确标注。这条政策与文档中“PR 必须用模板、不得自主操作”的规则互相呼应,共同构成人类在环(human-in-the-loop)的完整闭环。

速查:按 AGENTS.md 要求的最小开发循环

综合全文,一条可复制的日常工作流如下:

# 1. 新环境/新 worktree:初始化(创建 venv、安装开发依赖与 prek hooks)
script/setup

# 2. 确认使用的是虚拟环境内的解释器
python3 --version

# 3. 修改集成 strings.json 后(如有),先重新生成英文翻译
python3 -m script.translations develop --integration <integration_name>

# 4. 运行测试
uv run --no-sync pytest

# 5. 会话收尾:全量 lint 与格式检查
uv run --no-sync prek run --all-files

配合 .vscode/tasks.json 中现成的任务(编译翻译、快照更新、集成脚手架),贡献者即可在完全符合仓库规范的前提下完成从环境搭建到提交自检的全部环节。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

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