自用AI代码质量规范
我已经受不了AI发挥了, 说好的把AI当人一样用呢? 但它做的根本就不是人做的
为了能许愿式编程(我是老板, AI你自己揣摩吧), 需要用 Hook 去限制它
本笔记用于给ai生成skill的人类编写的大纲
一、总览
skill 定位: 一个全能的、一次性的代码质量红线安装与完善工具, 发挥ai具体情况具体分析的能力, 为项目定制、补充符合我需求的代码质量检查工具. 必须由用户主动触发
包括:
- 代码质量
- 编码规范
- 架构推荐
- 格式化
- lint
- 自定义规则
- 注释
- 第三方库推荐
- 文档规范
- 项目AI上下文
- github特有: 工作流CI
- github特有: 协作规范
- 编码规范
- 测试
- 仅后端API的测试 (区分使用假数据 和 真数据)
- 仅前端请求后端API的测试
- 仅前端UI的测试 (使用假数据)
- e2e的测试
- 性能测试
- 构建测试 & 历史兼容性测试
- 元门禁 (对于这些门禁的代码质量检查)
特别的, 本地开发仅会对当前工作区的diff内容进行代码质量检查和测试. 另外禁止一边开发一边测试. 必须一次性开发完成后再跑一轮对应测试 (否则效率太低了)
评级:
-
警告: 表述需要注意, 静态工具无法断定的. 比如 内容的关联变更. 这是需要 review 的 (需要汇总为一个待review文件, md + json文件, 方便人与机器阅读), 这部分仅警告. 不会拦截.
-
错误: 明确被工具扫描到的问题, 如果不修改则会: (Agent运行时: 任务未完成, 需要返工)、禁止push、CI拦截. 同理会产出md/json
Tip
如果下文没有明确提及, 则默认都是 错误 评级!
二、代码质量
2.1 编码规范
技术选型, 后端推荐 py + FastApi (协程) (必须使用uv包管理), 前端只能使用 React + Ts (必须使用pnpm包管理), 禁止任何的 mjs/js 出现 (除非是框架工具等)
2.1.1 架构推荐
对于快速开发, 应优先复用已有代码, 复用顺序为:
本项目已有代码 > 标准库 > 已使用的第三方库 > 新增第三方库
引入新的第三方库需要人工决策, 记为 Warning.
2.1.1.1 接口与实现
业务模块对外只暴露稳定的公共接口, 调用方不应依赖具体实现.
优先使用简单的函数式接口, 将校验、业务流程与具体实现分离:
async def get_user_data(user_id: int) -> UserData:
if not _validate_user_id(user_id):
return UserData.IdErr
return await _find_user_by_id(user_id)
调用方只依赖 get_user_data, 不关心 _find_user_by_id 的具体实现.
实现细节应放入 impl/ 或其他明确的内部目录:
user/
├── init.py # 公共接口
└── impl/
├── database.py # 数据库实现
└── mock.py # 假数据实现
其中:
- 公共代码只能依赖公共接口
- 禁止跨模块直接依赖其他模块的
impl/ impl/内部可以依赖本模块其他实现- 需要替换实现时, 应尽量只修改模块内部代码
2.1.1.2 API 与数据来源分离
需要明确区分:
API
├── 纯数据 / 假数据实现
└── 真实依赖实现
业务逻辑不应直接绑定数据库、远程服务等具体依赖, 以便分别进行无真实依赖测试和真实依赖测试.
2.1.1.3 依赖方向
项目整体优先保持 有向无环 依赖:
上层业务
↓
公共模块
↓
底层实现
禁止无明确边界的循环依赖和网状依赖.
跨模块导入时, 默认只允许依赖目标模块的公共接口.
以下情况可以直接导入:
- 工具库
- 常量库
- 类型定义库
- 明确声明为公共基础模块的代码
禁止直接导入其他业务模块的内部实现.
例如:
aLib/
├── init.py
└── impl/
├── a.py
└── ai.py
bLib/
├── init.py
└── impl/
└── b.py
允许:
aLib/init.py → aLib/impl/a.py
aLib/impl/ai.py → aLib/impl/a.py
bLib/impl/b.py → aLib/init.py
禁止:
bLib/impl/b.py → aLib/impl/a.py
bLib/impl/b.py → aLib/impl/ai.py
2.1.1.4 目录规模
单个目录建议不超过 6 个文件.
超过 6 个文件时:
- 默认
Warning - 若目录职责已经混杂, 则为
Error - 若确有合理原因, 可以申请豁免
豁免必须记录:
{
"path": "src/user",
"reason": "该目录承担同一职责, 拆分后反而增加依赖复杂度",
"expires_on_change": true
}
豁免信息纳入 Git, 并在该目录再次发生变更时重新检查.
2.1.1.5 前后端接口对应
前端请求层与后端路由层应保持清晰的一一对应关系.
例如:
frontend/api/user.ts
↕
backend/router/user.py
同一业务模块的前端请求接口, 应能在对应的后端路由中找到.
若一个模块无法建立明确对应关系, 应进行架构检查.
部分情况下可以配置白名单 (比如通用权限检查等接口)
2.1.2 格式化
项目应该需要成熟的第三方格式化工具.
强制要求, 大括号和换行规范如下:
int main() { // 这种 `{` 的写法; 禁止 `\n{`
if (true) // 禁止缩行, 如 if (...) todo
print("Good");
else
print("Bad");
}
行长度 120 字符. 缩进只能使用4空格, 注释: 空格一格 (连续2行单行注释, 使用右对齐)
逻辑代码 (如后端、ts), 单文件限制 300 行 (格式化后)
前端/UI代码, 单文件限制 500 行 (格式化后)
Note
调用层归一为脚本. 在 AI 执行完写入/Bash工具后调用 Hook
在 commit 前也会对 diff 的文件执行一次
Tip
可以提供一个默认排查git提交的脚本目录, 如 scripts/.hx_code_quality, 存放当前工作区的格式化过的文件的md5, 到时候直接看 md5 是否正确就知道哪些是已经格式化的, 哪些是没有覆盖的. 这样可以加快速度 (其他任务同理, 不再提及)
当commit了后, 就把对应的文件在 .hx_code_quality 的缓存中删除
2.1.3 lint
使用现代的 lint 检查工具, 附上常见的现代检查规则即可. 必须要有类型检查.
2.1.4 自定义规则
Python:
- 禁止在局部导入任何内容. 所有的导入只能在文件头部
- 普通文件禁止定义任何常量. 常量必须集中存放在常量文件夹
通用AST:
- 函数注释, 必须和参数、返回值对应, 如:
/**
* @brief 加法
*
* @param a
* @param b
* @return int
*/
int add(int a, int b);
如果函数内有diff, 那么它的注释可能需要变化(已经是双方都要同步变化). 需要警告
2.1.5 注释
在日常代码编写中, 就要确保代码如注释的风格. 此处更多的是约束 函数签名等大范围的注释 (但是依旧全局适用)
-
文件开头 禁止 大于 10 行的注释
-
注释只说明代码本身无法表达的 意图、原因、约束和特殊情况, 不要重复代码行为
-
优先解释 Why 而非 What; 简单、直观的代码无需注释
-
注释必须简洁、准确并与代码同步, 避免无意义或过时的注释
-
对于用户的决策, 应该引用其
note, 而不是长篇大论来龙去脉; (参考 skill:hx-agent-notes)
2.1.6 第三方库推荐
具体情况具体分析, 引入第三方库必须要用户决策 (包管理的包出现diff, 是警告. 需人工评审)
2.2 文档规范
Tip
所有的地方 (包括注释), 禁止 emoji 和中文标点, 统一使用 ASCII 标点
核心规则:
- 一篇文档只讲一个主题, 不要写成百科全书
- 当前事实和历史原因分开: 现在是什么放
reference/, 为什么这么做放decisions/ - 不要重复写: 已有文档能更新就直接更新, 不要创建 xxx-v2.md
- 上层讲整体, 下层讲细节; 不要跨文档重复维护同一知识
- 文档写"规则、约束、行为、契约", 不要写大量思考过程和废话
- 失效文档移到
archive/, 不要和当前文档混在一起
docs/
├── tutorials/ # 怎么做
├── reference/ # 现在是什么、怎么用
├── reference/api # 契约, 里面存放如: user.yaml/user.md 的文件, 其中 yaml 是API契约, 会被门禁检验
├── architecture/ # 整体怎么设计
├── decisions/ # 为什么这么设计
└── archive/ # 废弃文档, 如何判断废弃? 它描述的东西现在还成立
文档行数需要在 1500 行内
2.3 项目AI上下文
上下文定义:
参考 dsh, 我们要求 AGENTS.md 小于 150 行, 大小小于 16KB
另外, 我们要求每一个存在 README.md 的地方, 必须编写一个 AGENTS.md (反之同理)
AGENTS.md 按照披露式加载, 仅有该目录用到的上下文才需要写入 AGENTS 中
因此有质量检查红线:
- 所有文件的dfs路径上,
2.4 工作流CI
Tip
Github工作流CI, 在触发过程中, 还可以使用机器人账号, 进行评论指定代码位置, 然后把总结写到 PR/commit 的评论上.
2.4.1 Push 触发
用户提交触发, 分为3个工作流:
他们都是扫描 diff级别, 并且不会短路, 一次性扫描所有的问题.
代码质量工作流:
- 格式化检查
- lint检查
- 自定义规则检查
- 注释检查
- @todo AI CR: 警告级别的内容, 筛选出真问题
- @todo AI CR: 基于 diff 上下文 和 commit 语义的代码评审
文档规范工作流:
- 无 emoji 和中文标点
- 文档行数检查
- 文档命名检查
- AI 上下文检查: AGENTS.md 与 README
- AI 上下文检查: sum(AGENTS.md) + skill引导注入
- AI 上下文检查: notes 双链 (参考对应skill)
- @todo AI CR 文档 review (暂时没有)
构建测试:
- 对应项目需要进行构建, 确保编译能提供. 然后基于此产物走 [测试工作流] (与下面步骤并行)
- 兼容性测试 (如有 docker 更新后, 是否能正确启动? 不会和历史版本冲突)
测试工作流:
- 后端 无真实数据 的测试
- 后端 连接测试数据库 的测试 (ci 可能不好实现)
- 前端 API 对接假后端数据 的测试 (UI 测试)
- 前端 API 对接真后端数据 的测试 (前端接口测试)
- 前后端联调 E2E 测试
2.4.2 PR 触发
对于测试工作流, 会触发全量测试, 其他和 Push 触发一致
2.5 协作规范
需要定义:
.github/
├── ISSUE_TEMPLATE/ # Issue 模板 (必须提供: Bug 反馈、功能建议)
├── PULL_REQUEST_TEMPLATE.md # PR 模板
└── CODEOWNERS # 自动分配 Review
CONTRIBUTING.md # 协作说明
三、测试
测试必须按照 被测试的业务模块 组织, 并在模块内部区分不同测试层级.
3.1 测试层级
不同测试只验证自己的职责, 不应重复承担其他层级的测试职责:
unit: 测试独立业务逻辑, 不依赖真实外部资源api/mock: 测试后端 API, 使用假数据和假依赖api/real: 测试后端 API, 使用测试环境中的真实依赖frontend/api: 测试前端 API 调用、参数处理和异常处理frontend/ui: 使用假数据测试页面展示和交互e2e: 验证完整用户流程以及前后端协同
API 契约应作为前后端接口的统一规范来源. 契约发生变化时, 必须触发对应的契约测试以及相关模块测试.
3.2 测试入口
统一提供测试入口:
具体实现可以根据项目技术栈选择不同测试工具, 但测试入口和触发规则应保持统一.
3.3 Diff 影响测试
测试默认按照本次 Diff 选择受影响的测试, 不应每次都执行全量测试.
架构时必须建立:
代码 → 业务模块 → 测试
例如:
backend/user/service.py
↓
user
↓
┌──────┼────────┐
↓ ↓ ↓
unit API E2E
↓
frontend/api
test:affected 应优先使用依赖关系分析确定影响范围, 路径规则作为兜底.
测试选择遵循:
依赖关系分析
↓
业务模块关系
↓
API / 契约关系
↓
路径规则兜底
↓
无法安全判断
↓
全量测试
修改公共工具、公共类型、基础设施、构建配置等无法可靠判断影响范围时, 必须执行全量测试.
3.4 测试触发
本地开发阶段, 禁止反复执行完整测试集.
AI 完成当前任务后, 根据最终 Diff 一次性选择并执行对应测试:
完成修改
↓
获取 Diff
↓
分析受影响模块
↓
选择测试
↓
统一执行
Push 时执行本次 Diff 影响的测试; PR 时执行完整测试集, 作为合并前最终检查.
四、元门禁
skill 提供 (本身需要遵从代码质量规范)
每个规则设计时候必须:
- 可单独测试
- 有正例
- 有反例
- 输出稳定
- 有唯一规则 ID
- 有明确等级
方便结构化存储和PR中评论.
五、细节
-
Diff 级别 ≠ 只看 Diff 那几行:
检查范围以 Diff 为入口, 但允许读取被修改文件 / 函数 / 类型 / 依赖关系的上下文
-
Baseline:
对于新项目我们可以使用这个规则, 对于一个旧项目, 直接引入规则会导致大量问题. 如果目前无法快速重构. 那边就需要区分
历史问题与新增问题
本文没有引用站内其它文档。



