Home Assistant Core 贡献指南解析:AGENTS.md 中的开发工作流、测试规范与 AI 协作边界
【免费下载链接】core:house_with_garden: Open source home automation that puts local control and privacy first.项目地址: https://gitcode.com/GitHub_Trending/co/core
本文以 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.toml 中
requires-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 层面只给出两条硬规则,但对协作质量影响极大:
- PR 打开后,禁止对已推送到 PR 分支的提交执行 amend、squash 或 rebase。理由是评审者需要能跟随提交历史、看清自上次评审以来发生了哪些变化。
- 开 PR 必须使用仓库模板,且不得删除模板中的任何内容,包括未勾选的复选框——保留未勾选项可以让评审者明确哪些选项没有被选择。
结合 .pre-commit-config.yaml 中的no-commit-to-branchhook 可以看出,仓库还通过工具链禁止直接向dev、master、rc分支提交,与上述 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 等)的安装,这是提交前必需步骤。阅读脚本源码可以看到其完整步骤:
- 若
.vscode/settings.json不存在,从.vscode/settings.default.jsonc复制默认设置; mkdir -p config并创建/激活虚拟环境;- 调用
script/bootstrap安装依赖; - 执行
prek install安装 pre-commit 钩子(prek是 pre-commit 的 Rust 实现,与文档中prek run命令配套); - 运行
hass --script ensure_config -c config生成开发用配置,并追加logger配置(默认info,homeassistant.components.cloud为debug)。
该节还给出了一个明确的故障处理路径:如果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-files、prek 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 的新语法当作品味问题上报。文档列出三条具体规则:
- 不要把依赖 Python 3.14 的语法或特性标记为问题,也不要建议旧版本兼容写法。这一点由 pyproject.toml 的
requires-python = ">=3.14.2"和 AGENTS.md 的声明共同背书。 except TypeA, TypeB:(无括号多异常)在 3.14 中显式合法,不要标记为问题。- 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全量版)印证了这一流程在项目中的常态化地位。
测试代码风格
- 所有测试函数参数必须带类型注解;
- 优先使用具体类型(如
HomeAssistant、MockConfigEntry)而非Any; - 参数不会被使用到函数体中时,优先
@pytest.mark.usefixtures而非形参注入; - 避免在测试中写条件分支——应拆分测试或调整参数化,让每个用例路径都被直接覆盖;
- 多个共享大部分代码的测试,应合并为一个
pytest.mark.parametrize参数化测试,并用带id的pytest.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 中现成的任务(编译翻译、快照更新、集成脚手架),贡献者即可在完全符合仓库规范的前提下完成从环境搭建到提交自检的全部环节。
【免费下载链接】core:house_with_garden: Open source home automation that puts local control and privacy first.项目地址: https://gitcode.com/GitHub_Trending/co/core
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考