news 2026/9/13 22:08:08

ADK-Python 文件组织规范实战指南:目录布局、文件头约定与测试镜像规则

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ADK-Python 文件组织规范实战指南:目录布局、文件头约定与测试镜像规则

ADK-Python 文件组织规范实战指南:目录布局、文件头约定与测试镜像规则

【免费下载链接】adk-pythonAn open-source, code-first Python toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control.项目地址: https://gitcode.com/GitHub_Trending/ad/adk-python

ADK(Agent Development Kit)Python 代码库在src/google/adk/下维护着数百个模块,为了让新增代码在"私人可见性、统一文件头、可预测的测试落点"三方面保持一致性,仓库通过.agents/skills/adk-style/这一风格技能沉淀了一套文件组织规范。本文以 file-organization.md 为骨架,结合workflow/tools/environment/的真实目录、scripts/compliance_checks.py的合规检查实现与.pre-commit-config.yaml的钩子配置,讲清楚在 ADK-Python 中新增一个.py文件时应遵循的布局规则、文件头要求,以及测试文件"镜像源码路径"的命名方法论,帮助你在提交代码前一次性通过全部机器检查。

一、两条核心布局原则

原文档将文件组织概括为两条铁律,任何新增代码都必须遵守:

  1. workflow/目录下"一文件一类"(One class per file):src/google/adk/workflow/中的每个模块文件只承载一个核心类,文件与类一一对应。
  2. src/google/adk/下新增模块默认私有(private by default):新文件必须以_下划线前缀命名,是否对外暴露由包的__init__.py与可见性规则决定。

从仓库实际目录看,这两条原则被严格执行。以src/google/adk/workflow/为例,目录下几乎全是_前缀文件,且每个文件对应一个独立类:

src/google/adk/workflow/ ├── __init__.py # 公开 API 的出口 ├── _base_node.py # BaseNode / START ├── _graph.py # Graph / Edge / DEFAULT_ROUTE ├── _node.py # Node / node 装饰器 ├── _join_node.py # JoinNode ├── _function_node.py # FunctionNode ├── _retry_config.py # RetryConfig ├── _errors.py # NodeTimeoutError ├── _workflow.py # Workflow └── _node_runner.py # 内部运行器(不出现在公开 API)

src/google/adk/workflow/__init__.py正是可见性规则的落点:它定义了__all__,只导出BaseNodeDEFAULT_ROUTEEdgeFunctionNodeJoinNodeNodeNodeTimeoutErrorRetryConfigSTARTWorkflownode这些公开符号,并通过_LAZY_MEMBERS字典将符号映射到各自的_私有模块做惰性导入,外部使用者从包顶层导入,永远不需要也不应该触及内部_模块。这与 visibility.md 中"文件私有、符号经__init__.py显式导出"的约定完全呼应——原文档在 file-organization 中只是点了一句"see the visibility reference",想要完整理解命名规则与公开符号暴露机制,应配合该参考文档阅读。

二、文件头三部曲:每个src/google/adk/模块的标准开头

规范要求src/google/adk/下的每个模块文件都从以下三部分开始,顺序固定:

  1. Apache 2.0 许可证头:由addlicense钩子自动补齐;
  2. from __future__ import annotations:延迟注解求值,配合类型检查与 Pydantic 模型定义使用;
  3. 导入语句:按"标准库 → 第三方 → 相对导入"三段排列。

from __future__ import annotations这一条并非口头约定,而是被scripts/compliance_checks.pycheck_future_annotations()函数机器化强制:任何不在豁免名单内的源码文件缺失该行,compliance-checks检查就会失败并阻断提交。豁免范围与文档描述完全一致——__init__.pyversion.pytests/目录以及contributing/samples/目录下的文件无需该语句。

src/google/adk/workflow/__init__.py的真实文件头为例,可以看到标准三段的实际形态:

# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # ...(Apache 2.0 许可证头全文) from __future__ import annotations from typing import TYPE_CHECKING from ..utils import _lazy

其中from __future__ import annotations位于许可证头之后、所有导入之前;标准库导入(typing)与相对导入(..utils)分属不同段落,符合"standard library → third party → relative"的顺序约定。想要了解这三段之间更多细节(如cli/包的导入方向限制、TYPE_CHECKING的循环导入规避),可继续阅读 imports.md 与 typing.md。

三、机器强制:这些约定由哪些钩子守护

原文档指出许可证头由addlicense钩子添加、from __future__ import annotationsscripts/compliance_checks.py检查。仓库根目录的.pre-commit-config.yaml完整揭示了这三道防线:

- id: addlicense # 自动为文件添加 "Google LLC" + Apache 2.0 许可证头 name: addlicense entry: bash -c '... addlicense -c "Google LLC" -l apache "$@" ...' - id: check-new-py-prefix # 强制新增 .py 文件必须以下划线前缀命名(私有默认) - id: compliance-checks # 调用 scripts/compliance_checks.py 做多项合规检查 entry: scripts/compliance_checks.py

其中compliance-checks的实际逻辑位于 scripts/compliance_checks.py,与文件组织规范直接相关的检查点包括:

  • check_future_annotations(content, filename):校验from __future__ import annotations是否存在,豁免条件精确实现为filename.endswith('__init__.py')filename.endswith('version.py')、路径含'tests/'、路径含'contributing/samples/'四类;
  • 同一脚本还顺带检查 logger 命名(必须是google_adk.前缀)、禁止cli/包外反向导入、mTLS 端点、内部短链与 FastAPI 路由装饰器顺序等,任一失败都会sys.exit(1)阻断流程。

因此,在 ADK-Python 中"文件放哪里、叫什么名字、文件头长什么样"不再是评审意见,而是 PR 之前就必须通过的机器门槛。相关钩子的完整清单与各自检查内容,可以对照 SKILL.md 末尾的 "A check failed — where to look" 速查表逐项定位。

四、测试文件放哪里:镜像源码路径

规范对测试落点的要求只有一句话:tests/unittests/下镜像源码的目录结构。文档给出的第一组示例在仓库中真实存在:

src/google/adk/tools/environment/_edit_file_tool.py tests/unittests/tools/environment/test_edit_file_tool.py

对应到仓库:源码位于 src/google/adk/tools/environment/_edit_file_tool.py,测试位于 tests/unittests/tools/environment/test_edit_file_tool.py。同一目录下还有配套的_read_file_tool.pytest_read_file_tool.py_write_file_tool.py_execute_tool.py等,镜像关系一一对应、目录层级完全一致。

这条规则的工程价值在于可推导性:看到任意一个src/google/adk/下的源码文件,任何人都能零成本推算出它的测试文件路径;反过来,测试失败时也能沿镜像路径立即定位到被测实现。注意镜像时只保留源码文件名的"去下划线、去扩展名"部分——_edit_file_tool.py对应test_edit_file_tool.py,前缀统一为test_,而不是test__edit_file_tool

五、一对多测试:以源码文件名作为共享前缀

当一个源文件需要拆分成多个测试文件时,规范给出的命名技巧是:使用源码文件名(去掉前导下划线与扩展名)作为共享前缀,后缀表达测试关注的不同维度。文档示例在workflow/目录下同样真实存在:

src/google/adk/workflow/_workflow.py tests/unittests/workflow/test_workflow.py tests/unittests/workflow/test_workflow_hitl.py tests/unittests/workflow/test_workflow_nested.py

对照仓库 tests/unittests/workflow/ 目录,这套命名体系被大规模执行:围绕_workflow.py一个源文件,测试族扩展到了test_workflow.py(基础行为)、test_workflow_hitl.py(人工介入场景)、test_workflow_nested.py(嵌套工作流)、test_workflow_concurrency.py(并发)、test_workflow_dynamic_nodes.py(动态节点)、test_workflow_failures.py(失败路径)、test_workflow_parallel_worker.py(并行执行)、test_workflow_routes.py(路由)等十余个文件;而_base_node.py_graph.py_join_node.py等同样各自拥有test_base_node.pytest_graph.pytest_join_node.py一一对应的测试。

这种"前缀 + 维度后缀"模式的好处是:用test_workflow_*一个 glob 就能搜出某个类的全部测试场景,源码变更时按前缀即可定位所有需要同步更新的测试文件,也方便 CI 按模块粒度并行分发测试任务。

六、实操自查清单

在 ADK-Python 中新增或移动一个.py文件前,对照以下清单逐项确认:

检查项要求强制方式
文件位置功能模块放入src/google/adk/<子包>/对应目录人工 + 评审
文件命名新文件默认私有,必须以_前缀开头(如_workflow.pycheck-new-py-prefix钩子
workflow/内聚性一个文件只放一个核心类人工 + 评审
许可证头文件头包含 Apache 2.0 许可证("Google LLC")addlicense钩子自动补齐
延迟注解非豁免文件必须含from __future__ import annotationscompliance-checks(compliance_checks.py)
导入顺序标准库 → 第三方 → 相对导入isort/ruff钩子
公开符号暴露仅在包__init__.py中导入并写入__all__,配合 visibility.md人工 + 评审
测试镜像测试置于tests/unittests/<同构路径>/test_<源码名>.py人工 + 评审
一对多测试多测试文件共享test_<源码名>_前缀,后缀表达场景维度人工 + 评审

需要说明的是:__init__.pyversion.pytests/contributing/samples/四类文件享有豁免——它们无需from __future__ import annotations,但其余规则(如测试镜像)依然适用。若新增文件需要对外提供公开 API,请务必先阅读可见性参考文档,理解"文件私有、符号公开"的完整暴露链路,再动手提交。

【免费下载链接】adk-pythonAn open-source, code-first Python toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control.项目地址: https://gitcode.com/GitHub_Trending/ad/adk-python

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

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

IMU+GPS融合实战:Matlab实现稳定EKF姿态解算

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 21:56:51

C语言流程控制:从基础到高级应用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 21:56:20

I²C与SPI本质区别:物理层、时序与PCB设计实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 21:48:35

YOLO网格本质:不是画布而是坐标调度系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华