edit | blame | history | raw

编码规范

创建人员:Codex
文件职责:定义通用编码注意事项、编码流程、验收方式、问题修复原则,适用于管理体系下的多个项目。
管理规范/模板:../../管理系统说明.md;../../全局规范.md;开发环境创建指南.md;开发审计规范.md;非临时文件应能追溯到事项、需求、方案、验收结果。
引用文件:../../管理系统说明.md;../../全局规范.md;开发环境创建指南.md;开发审计规范.md;编码方案范本.md;AI管理体系建议.md;旧项目开发规范已去项目化抽象。
记录方式:全局编码规范文档;编码流程、方案要求、测试验收或问题修复口径变化时更新。

统一依赖:本规范必须同时遵守 ../../全局规范.md../project-doc/项目规范.md;项目本地编码规范可补充流程,但不得违反全局规范、全局项目规范和本体系硬约束。

1. 目标

本规范用于约束 AI 或人工在项目中编写、修改、验收代码的全过程。

核心目标:

  1. 先明确目标和接口,再写代码。
  2. 代码变更必须可追踪、可复现、可验收。
  3. 多模块流程要避免散修、重复逻辑、隐式依赖和难以重跑。
  4. 数据校验要保护主流程,但不能层层加码到拖垮主流程。
  5. 发现问题时必须区分需求问题、代码问题、数据问题、流程问题。

2. 适用范围

适用于管理体系下所有项目的:

  1. 新模块开发。
  2. 多模块流程开发。
  3. 旧代码重构。
  4. Bug 修复。
  5. 数据处理脚本。
  6. 实验、回测、校验、审计辅助工具。

小脚本可以简化流程,但不能跳过输入输出说明、基本自检和结果记录。

2.1 开发体系绑定口径

开发体系默认随项目创建,但不单独承载业务目标,必须绑定目标体系或目标事项。

开发产物按目标体系分账:

  1. 代码放在 dev/<target>-dev/
  2. 测试放在 dev/<target>-dev/test/
  3. 目标相关代码文档、测试说明和重型编码方案附件放在 dev-doc/<target>-doc/
  4. 开发事项总纲、计划、执行日志和问题记录默认放在 dev-doc/ 根级账本,不在目标目录复制第二套。
  5. 审计报告入口按目标体系分账:需求开发、项目工具开发等独立开发事项写 dev-doc/开发审计报告.md;实验开发写 exp-doc/实验审计报告.md;案例分析开发写 ana-doc/案例审计报告.md

常见映射:

  1. 需求 / 需求开发:dev/pro-dev/dev/pro-dev/test/dev-doc/pro-doc/
  2. 实验开发:dev/exp-dev/dev/exp-dev/test/dev-doc/exp-doc/
  3. 案例分析开发:dev/ana-dev/dev/ana-dev/test/dev-doc/ana-doc/

不得把所有代码、测试或开发文档直接堆到 dev/dev-doc/ 根目录。

2.2 本地编码规范最低内容

每个项目的根级 dev-doc/编码规范.md 不能只写“引用 common 规范”。目标开发工作区 dev-doc/<target>-doc/ 不再创建第二份编码规范,只放目标代码文档和方案附件。

本地编码规范至少要包含:

  1. common 编码规范路径。
  2. 本地编码规范适用范围。
  3. 本地开发目录口径。
  4. 核心开发文档作用说明。
  5. 如有本地补充规则,说明不得削弱 common 硬约束。

核心开发文档作用说明至少覆盖:

文档 作用
目录导读.md 说明开发目录结构、代码入口、测试入口、当前事项和审计入口
编码规范.md 记录本地编码规范和 common 规范引用
开发审计规范.md 记录本地开发审计规范和 common 审计规范引用
开发事项总纲.md 记录开发事项背景、目标、边界、状态和结论
开发事项计划.md 记录开发计划、步骤、输入输出、验收方式和审计入口
开发方案/ 重型开发时按事项创建具体编码方案文件,例如 开发方案/<CODE-DESIGN-ID>.md;轻量开发不创建
开发执行日志.md 记录编码、测试、自检、中间结果、异常和偏离
开发审计报告.md 记录方案审核、实现审核、测试验收和复审结论
开发问题记录.md 记录非审计来源开发问题;审计问题只做跨轮索引

3. 总原则

3.1 需求先行

编码前必须先明确:

  1. 要解决什么问题。
  2. 输入是什么。
  3. 输出是什么。
  4. 成功标准是什么。
  5. 哪些行为不允许发生。

如果需求中的字段、接口、边界、验收标准不清楚,不应靠代码猜。应先记录为需求问题,再修需求或补说明。

3.2 编码方案先行

以下情况必须先写代码编写方案,再写代码:

  1. 新增整体系统模块。
  2. 改动超过一个模块。
  3. 涉及长流程、批处理、回测、发布、归档、审计。
  4. 涉及公共字段、公共表、公共工具函数。
  5. 涉及重跑、缓存、并发、断点续跑。
  6. 存在明确性能瓶颈或性能风险。

3.3 真问题优先

审查代码时要优先找会影响结果、阻断流程、污染数据、造成不可追踪的问题。

不应把命名小差异、文档措辞不优雅、非关键诊断项缺失,升级成主流程阻断问题。

3.4 公共能力复用

多个模块都需要的能力,应抽成公共函数、公共类或公共 helper。

典型公共能力包括:

  1. 路径解析。
  2. manifest 读写。
  3. receipt 读写。
  4. fingerprint 计算。
  5. schema 校验。
  6. gate 汇总。
  7. CSV/Parquet 分块读写。
  8. 错误码和状态码归一。

禁止在多个模块里复制粘贴同一套核心判断逻辑。

3.5 可追溯和可复现

重要运行必须能回答:

  1. 用了哪些输入。
  2. 用了哪个配置。
  3. 运行了哪个代码版本。
  4. 产出了哪些文件。
  5. 哪些检查通过,哪些检查失败。
  6. 如果失败,停在哪一步,为什么失败。

4. 编码前流程

编码前按以下顺序执行:

  1. 确认事项编号、任务目标、责任模块。
  2. 阅读相关需求文档、需求方案、架构文档、模块说明文档、核心流程文档、流程图、接口文档;没有的上游文档要说明“不适用”。
  3. 判断本次是需求问题、代码问题、数据问题,还是流程问题。
  4. 明确改动范围,列出会被影响的模块和产物。
  5. 如属于多模块或长流程改动,先写代码编写方案。
  6. 明确验收方式,包括最小样本、边界样本、失败样本、全量样本。
  7. 再开始编码。

如果本次是需求体系交付到开发的事项,还必须先读项目本地 pro-doc/需求规范.mdpro-doc/需求规范.md,以及需求文档引用的需求方案、架构文档、模块说明文档、核心流程文档。若这些上游需求文档缺失或互相冲突,应按需求问题退回,不得靠代码补口径。

如果本次是实验开发、案例分析开发或项目工具开发,也必须读取对应目标体系规范和事项账本;开发规范只约束怎么写代码,不替代目标体系的业务流程。

5. 三类编码流程

不同规模的代码任务按三类处理,不要把所有任务都套进重流程。

5.1 无需求文档的轻量实现

适用范围:

  1. 一次性辅助脚本。
  2. 小型数据检查脚本。
  3. 简单文件整理、格式转换、压缩、检索、统计。
  4. 不改核心业务流程、不产生正式主表、不影响长期接口的小改动。

这类任务通常不需要先写需求文档,也不需要写代码编写方案。

需求体系正式交付到开发的事项,默认不适用“无需求文档的轻量实现”。如果需求侧只给了口头要求或草案,应先回到需求流程形成可审计需求,再进入开发。

执行流程:

  1. 明确用户要的结果、输入路径、输出路径。
  2. 说明关键假设,例如编码、文件格式、输出位置。
  3. 直接实现,代码保持小而清晰。
  4. 自测能运行,检查输出是否存在、行数或文件数是否合理。
  5. 如果脚本会复用,补最小使用说明。
  6. 如果执行中发现任务影响核心流程、正式产物、公共字段或多个模块,立即升级为“有需求文档的轻量实现”或“重型实现”。

最低交付:

  1. 代码文件。
  2. 运行方式。
  3. 输出位置。
  4. 简短自测结果。

5.2 有需求文档的轻量实现

适用范围:

  1. 已有需求文档。
  2. 改动边界清楚。
  3. 单模块或少量局部改动。
  4. 不涉及长链路调度。
  5. 不新增公共核心字段或公共基础设施。
  6. 不涉及复杂重跑、缓存、并发、发布流程。

这类任务可以不写代码编写方案。

执行流程:

  1. 先检查需求文档是否足够清楚,重点看目标、输入、输出、字段、边界、验收标准。
  2. 如果需求不清,先记录需求问题,不要靠代码猜。
  3. 需求没问题后再写代码。
  4. 写完后先做基础自测,例如语法、导入、最小样本、关键输出。
  5. 自检:逐条对比需求文档和代码实现,确认是否有字段缺失、口径偏差、流程绕过、产物不一致。
  6. 修掉自检发现的问题。
  7. 输出验收结论,说明跑了什么测试、结果是什么、还有什么限制。

最低交付:

  1. 代码变更说明。
  2. 对应需求文档。
  3. 自测命令和结果。
  4. 需求-代码自检结论。
  5. 未解决问题或限制。

5.3 有需求文档的重型实现

适用范围:

  1. 新增整体系统模块。
  2. 改动多个模块或多个阶段。
  3. 涉及核心主流程、正式数据链路、长流程调度。
  4. 涉及公共模块、公共字段、公共表、公共 gate、公共 helper。
  5. 涉及断点续跑、缓存、并发、子进程、全量批处理。
  6. 存在明确性能瓶颈或失败后代价较高。

这类任务必须在需求文档没有明显问题之后,先写代码编写方案,再写代码。

执行流程:

  1. 先审需求文档,确认目标、主链、接口、字段、产物、验收标准没有明显冲突。
  2. 写代码编写方案,说明模块边界、公共能力、验收、重跑、风险和协作方式。
  3. 代码编写方案必须交给审核员审核。
  4. 审核员确认方案没有明显流程、接口、职责、验收、重跑、公共模块问题后,才允许进入代码编写阶段。
  5. 如果审核员发现方案问题,必须先修方案,不能边写代码边补方案。
  6. 按审核通过的方案拆分实现,优先实现公共入口和关键主路径。
  7. 每个模块完成后做模块自测。
  8. 多模块串联后做链路 smoke。
  9. 自检:按需求文档和编码方案逐项对照代码、产物、日志、测试。
  10. 修复自检发现的真实问题。
  11. 生成最终验收结论,说明是否可以进入全量、发布或下一阶段。

最低交付:

  1. 需求文档。
  2. 代码编写方案。
  3. 代码变更说明。
  4. 模块自测结果。
  5. 链路自测结果。
  6. 需求-代码-方案一致性自检结论。
  7. 重跑或恢复说明。

6. 代码编写方案必须包含的内容

本节只适用于“有需求文档的重型实现”。轻量任务不强制写完整代码编写方案。

默认开发体系不创建空的 编码方案.md。重型开发发生时,按开发事项创建具体编码方案文件,例如 dev-doc/开发方案/<CODE-DESIGN-ID>.mddev-doc/<target>-doc/开发方案/<CODE-DESIGN-ID>.md。写方案时必须满足本节要求;如需要参考写法,可以看 编码方案范本.md,但不得把范本机械复制成无实际内容的方案。

代码编写方案至少包含以下内容。

代码编写方案必须经过审核员审核通过后,才能进入代码编写阶段。未审核、审核不通过、或审核意见未处理完成时,不得开始实现。

6.1 模块和接口

必须说明:

  1. 本次涉及哪些模块。
  2. 每个模块的职责是什么。
  3. 模块之间如何交互。
  4. 每个模块的输入表、输出表、关键字段、主键、枚举、错误码。
  5. 哪些字段是正式字段,哪些字段只是兼容 alias 或诊断字段。

6.2 公共模块和公共功能

必须识别多个模块共用的逻辑,并说明:

  1. 是否需要抽公共函数或公共类。
  2. 公共模块放在哪里。
  3. 哪些调用方必须使用这个公共入口。
  4. 哪些旧逻辑需要迁移或废弃。
  5. 如何防止调用方绕过公共入口。

6.3 性能风险和优化方案

性能优化不是代码编写方案的必选项。

如果本次改动存在明显性能风险,应提前识别:

  1. 大文件读写。
  2. 大表 join。
  3. 全量排序。
  4. 大 JSON 字段展开。
  5. 多进程或子进程。
  6. 重复计算。
  7. 可能长时间无日志的步骤。

如果存在明显性能风险,方案中要写明优化策略,例如分块、索引、缓存、流式写出、原子落盘、进度日志、断点续跑。

如果没有明显性能风险,可以只写“本次无明确性能瓶颈,暂不设计专项优化”,不要为了形式强行增加性能优化章节。

6.4 验收方案

必须写清:

  1. 单模块怎么验收。
  2. 多模块链路怎么验收。
  3. 需要哪些正例。
  4. 需要哪些反例。
  5. 哪些 gate 是主流程必过。
  6. 哪些检查只是外部诊断,不得阻断主流程。

6.5 扩展性设计

对可能频繁变化的部分,要明确扩展点:

  1. 规则配置。
  2. 枚举扩展。
  3. 字段扩展。
  4. 数据源扩展。
  5. 策略参数扩展。
  6. 输出格式扩展。

不得把频繁变化的业务规则散落在多个硬编码 if-else 中。

6.6 统一数据结构

贯穿全流程的字段、ID、状态、枚举应尽量统一。

如果必须保留旧字段 alias,必须明确:

  1. canonical 字段是什么。
  2. legacy alias 是什么。
  3. 二者是否必须逐行一致。
  4. 下游应读取哪个字段。
  5. 什么时候可以移除 alias。

6.7 重跑和恢复

长流程必须写清重跑原则:

  1. 什么时候从原始数据重跑。
  2. 什么时候可以从中间快照重跑。
  3. 哪些产物可以复用。
  4. 复用前必须校验哪些 fingerprint、schema、row_count、config。
  5. 失败产物如何标记,避免被误用。

不能只靠“文件存在”判断可复用。

6.8 高风险点

必须列出容易出错的关键点,例如:

  1. 未来函数。
  2. 主键不唯一。
  3. 多模块字段名不一致。
  4. 分组键和最终实体键不一致。
  5. 中间产物被误当正式产物。
  6. 诊断模块反向覆盖主流程结果。
  7. 半成品文件被当作完成文件。
  8. 同一逻辑在多个模块散修。

7. 编码规则

7.1 路径和配置

  1. 不得硬编码个人机器绝对路径。
  2. 路径应来自配置、参数或统一路径工具。
  3. 输出目录必须可配置。
  4. 重要运行要保存配置快照。
  5. 临时文件、正式文件、失败文件要有清晰命名。

7.2 输入处理

  1. 必需输入不存在时必须 fail-fast。
  2. 输入 schema 不匹配时必须报清楚缺失字段。
  3. 可选字段缺失时可以置空,但必须记录。
  4. 不得伪造缺失输入。
  5. 不得用测试数据冒充正式输入。

7.3 输出处理

  1. 重要输出必须写 manifest。
  2. 大文件或关键文件应先写临时文件,完成后原子 rename。
  3. 中途失败不得留下看似完成的正式文件。
  4. 输出 row_count、key_count、schema 应可审计。
  5. 输出应尽量可重复生成。

7.4 数据安全和时间安全

  1. 涉及时间序列、时序决策、预测、回测时,必须明确 as-of 时间。
  2. 不能用未来数据生成过去时点的信号。
  3. 若实验阶段刻意允许使用未来信息,必须在实验说明中明确标注,不能和实盘口径混用。
  4. 买卖、判断、持仓、退出等操作必须能追溯到当时可见的信息。

7.5 错误处理

  1. 合同错误必须显式失败。
  2. 不得 silent pass。
  3. 不得用 fallback 掩盖主路径错误。
  4. 自动重试只能用于明确的临时 I/O 或网络问题。
  5. 失败原因要能定位到模块、输入、字段、规则。

7.6 代码组织

  1. 函数应短小,职责单一。
  2. 复杂规则应抽成命名函数。
  3. 公共判断应集中到公共模块。
  4. 魔法数字必须有常量名或配置名。
  5. 代码命名遵循项目语言惯例。
  6. Python 默认使用 snake_case 函数和变量、PascalCase 类名、UPPER_SNAKE_CASE 常量。

8. 日志和证据链

重要流程建议输出:

  1. run_meta.yamlrun_meta.json
  2. config_snapshot.yamlconfig_snapshot.json
  3. runtime.log
  4. output_manifest.csv
  5. selfcheck.md
  6. evidence_chain.md
  7. 关键中间产物

日志至少包含:

  1. run_id
  2. matter_id
  3. step_id
  4. module
  5. stage
  6. input_path
  7. output_path
  8. input_row_count
  9. output_row_count
  10. elapsed_seconds
  11. status
  12. error_code
  13. error_message

长流程必须有进度日志,不得长时间无输出导致无法判断是正常运行还是卡死。

9. 数据校验原则

9.1 主流程只保留轻量核心校验

主流程中的校验只应覆盖核心合同:

  1. 必需输入存在。
  2. 必需字段存在。
  3. 主键或关键键合法。
  4. 行数明显合理。
  5. 上下游 handoff 可读。
  6. 核心状态不违反硬合同。

主流程不应被过重的外围诊断项卡死。

9.2 重型数据校验放到只读 helper

复杂数据校验应做成外部只读 helper,而不是塞进主流程。

helper 只允许:

  1. 读取已落盘产物。
  2. 输出 summary/report/readout。
  3. 标记诊断问题。
  4. 给人工或后续修复提供证据。

helper 不允许:

  1. 改写业务主表。
  2. 改写 stage output。
  3. 改写 root manifest。
  4. 改写 final manifest。
  5. 改写 fingerprint receipt。
  6. 反向覆盖主流程成功或失败状态。

9.3 不做一堆 gate 压垮模块

不要为了“看起来严谨”无限增加 gate。

只有会影响主流程正确性、数据安全、结果可信度的检查,才应成为主流程硬 gate。

发布级、审计级、归档级、诊断级检查,应放在对应层级,不得混进样本、smoke、10k、50k 的核心执行链。

10. 测试和验收

10.1 分层测试

推荐分层:

  1. L0:语法、导入、静态检查。
  2. L1:单模块最小样本。
  3. L2:多模块 smoke 链路。
  4. L3:边界样本和回归样本。
  5. L4:全量或准全量验收。

不得直接用全量跑批替代前置验证。

10.2 验收样本

验收至少考虑:

  1. 正常样本。
  2. 边界样本。
  3. 缺字段样本。
  4. 空结果样本。
  5. 多候选或多状态样本。
  6. 历史上出过 bug 的回归样本。

10.3 通过标准

通过标准必须明确:

  1. 哪些文件必须存在。
  2. 哪些行数必须一致。
  3. 哪些 key 必须唯一。
  4. 哪些字段允许为空。
  5. 哪些状态允许出现。
  6. 哪些错误必须 fail-fast。

11. Bug 修复规则

11.1 先分类

发现问题后先分类:

  1. 需求问题:需求模糊、冲突、缺字段、边界不清。
  2. 代码问题:实现与需求不符。
  3. 数据问题:输入数据缺失、错乱、污染。
  4. 流程问题:顺序、重跑、验收、归档不合理。
  5. 性能问题:结果正确但运行不可接受。

需求问题不能只改代码绕过去,必须先修需求或补合同。

11.2 修主路径

反复出现的问题,优先修公共入口和主路径,不要只修报错点。

如果多个模块都有同类问题,应:

  1. 抽公共函数。
  2. 统一调用方。
  3. 补公共测试。
  4. 删除或废弃散落逻辑。
  5. 用回归样本验证全链路。

11.3 关闭问题标准

问题关闭前必须满足:

  1. 能复现原问题,或能解释为什么无法复现。
  2. 有对应修复。
  3. 有最小验证。
  4. 有回归验证。
  5. 相关问题文档已更新。
  6. 若是需求问题,已标注为需求问题并同步给需求负责人。

12. 多 AI 协作规则

多 AI 并行时必须遵守:

  1. 先冻结接口,再并行实现。
  2. 每个 AI 明确负责文件和模块。
  3. 不同 AI 不应同时修改同一核心文件,除非有明确合并人。
  4. 公共字段和公共工具只能由一个 owner 统一修改。
  5. 每个 AI 都要记录修改内容、验证结果、未解决问题。
  6. 审核 AI 只记录真问题,不把边角料升级成阻断。

13. 性能规范

性能优化要遵循:

  1. 先定位瓶颈,再优化。
  2. 优先减少重复 I/O、重复解析、重复 join、重复全量排序。
  3. 大表优先考虑分块、索引、缓存、投影列、sidecar 分账。
  4. 长流程必须可观察进度。
  5. 不为了性能破坏数据合同。
  6. 性能优化必须证明结果不漂移,或明确说明允许漂移的范围和原因。

14. 重跑和断点续跑

长流程必须设计重跑策略:

  1. 原始数据重跑。
  2. 中间快照重跑。
  3. 指定阶段续跑。
  4. 失败阶段重跑。
  5. 只读审计重跑。

复用中间产物时必须校验:

  1. 输入 fingerprint。
  2. 配置 fingerprint。
  3. 代码版本或规则版本。
  4. schema。
  5. row_count。
  6. key_count。
  7. completion marker。

半成品、失败包、空壳文件不得被当作可复用产物。

15. 禁止事项

禁止:

  1. 没有需求或目标就直接写代码。
  2. 需求不清时用代码猜。
  3. 用假数据、默认值、空字符串掩盖缺失输入。
  4. 用未来数据生成历史信号。
  5. 把诊断 helper 变成主流程阻断器。
  6. 重复复制公共逻辑到多个模块。
  7. 只修局部报错,不修公共入口。
  8. 只看父进程不看子进程就判断卡死。
  9. 只靠文件存在判断流程完成。
  10. 不记录验证结果就关闭问题。

16. 最低交付清单

正式交付代码至少应包含:

  1. 代码变更说明。
  2. 影响范围说明。
  3. 运行命令或入口。
  4. 输入输出说明。
  5. 验证命令和结果。
  6. 已知限制。
  7. 是否涉及需求问题。
  8. 是否涉及性能风险。
  9. 是否需要后续重跑。

一句话原则:先把目标、接口、数据、验收、重跑讲清楚,再写代码;代码要解决真问题,不要用过重校验拖垮主流程。