PyPTO-Gym 多智能体编排行为原则详解:Simplicity First、Surgical Changes 与 Goal-Driven Execution
【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址: https://gitcode.com/cann/pypto-gym
导读
principles.md是 pypto-orchestration-manual 技能库中的基础行为纲领,定义了本仓库所有 skill 执行时共同遵守的三条核心原则:Simplicity First(简洁优先)、Surgical Changes(外科手术式修改)、Goal-Driven Execution(目标驱动执行)。该文档是 pypto-op-orchestrator 在每次会话首次调度子代理前必须加载的入门参考(SKILL.md 明确要求 "Always load before the first dispatch of any session")。本文将逐条解析这三条原则的判定标准、在 PyPTO 算子开发流水线中的具体落点,并结合仓库中的强制规则(rules.md)、子代理调度契约(agents.md)、lint 门禁(lint-gate-rules.md)与验证工具源码(detailed_tensor_compare.py)做纵深印证,帮助读者理解多智能体协作下"少写、少改、可验证"的开发纪律。
一、原则总览:为什么编排者需要一份"行为宪法"
在 PyPTO-Gym 仓库中,算子开发不是单个 Agent 的独立行为,而是由pypto-op-orchestrator 驱动的 8 智能体团队(planner、mathematician、architect、coder、verifier、debugger、optimizer)在 Stage 1–7 流水线上接力完成的过程(见 agents.md)。流水线中,一份 kernel 代码会经过设计、golden 冻结、分模块实现、逐模块验证、E2E 验证、性能调优等多次交接,任何"过度设计""顺手重构""无验证目标的乱改"都会被放大为后续阶段的返工成本。
因此 principles.md 定义了适用于每个 skill、每个子代理的三条基础行为原则,而 rules.md 在此之上叠加 PyPTO 专属的强制条款(zero-tolerance 规则、三大架构禁令、停止条件等)。二者关系正如原文档开篇所声明:
These principles apply to every skill. rules.md adds PyPTO-specific enforcement on top.
换言之:principles 是"怎么做事的风格",rules 是"什么事绝对不能做"。原则部分负责减少不必要的改动、降低返工率;规则部分负责保证产物硬性合规。编排者在每次会话开始时按 AGENTS.md 的强制启动顺序加载:先读 SKILL.md,再读 principles.md → agents.md(agents.md 携带了全部子代理的输入/交付件/门禁/交接信息,足够完成派发;rules.md 属于按需加载的执行细节)。
原则是否生效的验收信号
原文档在结尾给出了判断这套原则是否真正起效的四个信号,可作为团队自检标准:
- diff 中不必要的改动减少(Surgical Changes 的直接效果);
- 因过度复杂化而导致的返工重写减少(Simplicity First 的直接效果);
- 澄清性问题发生在实现之前而非犯错之后(Goal-Driven Execution 的直接效果);
- 每个模块以更少的尝试次数通过验证(三条原则综合作用的结果)。
二、原则一:Simplicity First(简洁优先)
2.1 原则定义与判定测试
"Minimum code that solves the problem. Nothing speculative."—— 用解决问题所需的最少代码,不写任何投机性内容。原文档给出了明确的禁止清单:
- 不实现超出需求范围的功能;
- 不为一次性使用的代码引入抽象;
- 不添加未被要求的"灵活性"或"可配置性";
- 不为不可能发生的场景编写错误处理;
- 如果写了 200 行而 50 行就能完成,就重写。
判定测试:如果一位资深工程师认为这段代码过于复杂,那就简化它。
这条原则在仓库的 lint 规则中得到了制度化。例如 lint-gate-rules.md 中的OL56(S0):Stage 6 之前pypto.loop的unroll_list只能包含单一值(默认[1]),含 2 个及以上值会触发编译路径爆炸、拖慢编译并使开发流程超时——多值展开调优仅允许在 Stage 7 进行。这正是"不做投机性优化"的工程化表达:在正确性未锁定前,任何为性能预铺的复杂路径都被直接拦截。
2.2 PyPTO 应用场景:最小可行实现 + detailed_tensor_compare
原文档明确给出了原则在 PyPTO 算子开发中的落点:
Every module should be the minimum viable implementation that passes
detailed_tensor_compare. Do not add speculative optimization, extra loop unrolling, or unused tile configurations.
即:每个模块只做到能通过detailed_tensor_compare的最小可行实现,不添加投机性优化、多余的循环展开或未被使用的 tile 配置。
这里提到的detailed_tensor_compare是仓库的核心精度比对工具,源码位于 cannbot-skills/ops/pypto-op-verify/scripts/detailed_tensor_compare.py。其核心逻辑是:
- 将两个张量
.cpu().float()归一化后逐元素比对; - 容差判定采用
atol + rtol * |expected|标准(默认rtol=1e-3、atol=1e-3,见 TensorCompareOptions); - 返回包含
all_close、out_of_tolerance_count、out_of_tolerance_ratio、max_diff、mean_diff、std_diff等字段的详细统计字典; - 对 tuple/list/dict 等嵌套输出结构递归展开到每个张量叶子逐一比对(tensor_leaf_pairs),输出结构不匹配(类型、数量、键不一致)会直接抛
AssertionError; - 对非有限值(NaN/Inf)有专门处理:仅当两侧同时为同符号 Inf 时才视为容忍,否则计为超差(源码 _build_result)。
在测试实践中,仓库测试目录大量使用该工具。例如 tests/ops/qwen3_5/gdr_bwd/test_gdr_bwd.py 通过 import 该 helper 对 golden 与 PyPTO 输出做全叶子精度比对;tests/ops/ling_3_0_flash/chunk_kda/test_chunk_kda.py 同样如此。规则 rules.md 将其固化为强制项:禁止省略detailed_tensor_compare或只比对单个输出——每个 stage 的每个叶子输出都必须比对,测试文件test_<op>.py同样如此。
2.3 简洁原则与"分层模板"的平衡
需要强调的是,"简洁优先"不等于"可以随意组织代码"。仓库通过 impl_template.py.tmpl 强制 kernel 实现采用Layer G–K 分层结构(Layer G 缓存桥接、Layer H PyPTO 子内核、Layer I kernel 实现、Layer J@pypto.frontend.jit入口、Layer K host wrapper),并由规则 rules.md 规定每个交付物(<op>_module1.py…<op>_module1…N.py及集成 kernel)都必须以此为骨架。
这两者并不矛盾:模板解决的是"代码该长在哪一层"的结构问题,简洁原则解决的是"每一层内部该写多少逻辑"的数量问题。例如 Layer K(host wrapper)被严格限定为三个职责——搬张量到设备、分配输出 buffer、恰好调用一次 JIT 入口(impl_template.py.tmpl);任何在 wrapper 里用 Pythonfor ... in range(...)驱动 kernel 分块的行为都会被OL45(S0)拦截,因为分块迭代必须放进 Layer I 的pypto.loop中。这就是"简洁"与"结构合规"的协同:把逻辑放在它该在的位置,并且每个位置只做最少的事。
三、原则二:Surgical Changes(外科手术式修改)
3.1 原则定义与判定测试
"Touch only what you must. Clean up only your own mess."—— 只触碰必须改的部分,只清理自己造成的混乱。当编辑既有代码时:
- 不"顺手改进"相邻代码、注释或格式;
- 不重构没有坏的东西;
- 即使你会有不同的写法,也要匹配既有风格;
- 如果发现无关的死代码,提出来但不要删除。
而当自己的改动制造了孤儿引用(orphans)时:移除由你的改动导致不再使用的 import/变量/函数;但不删除改动前就存在的死代码(除非被明确要求)。
判定测试:每一行改动都必须能直接追溯到当前任务。
这条原则的深层动机在于多智能体流水线的特殊性:一份 kernel 文件会被多个 Agent 依次读写(coder 写、verifier 判、debugger 查、optimizer 调),任何"顺手重构"都可能破坏其他 Agent 对代码的预期,制造无法定位的回归。
3.2 PyPTO 应用场景:冻结模块、golden 代码与失败边界
原文档给出了三个非常具体的 PyPTO 落点:
- 不要"改进"已冻结的模块(frozen modules)。在 rules.md 中,golden 文件在 Stage 2 冻结后不得无证据修改,任何变更都要记录在
<op>_golden.py头部注释中,Stage 5+ 的变更还要额外记入custom/<op>/MEMORY.md。这保证了 golden 作为所有阶段精度基线的稳定性。 - 不要重构已经工作的 golden 代码。golden 是纯 torch 规范化实现(lint-gate-rules.md 的OL15要求 golden 禁止
import pypto、禁止.T/.t(),必须用torch.transpose),它是验证 PyPTO 内核正确性的基准,动它等于移动标尺。 - 当下游模块失败时,不要编辑上游 staged 文件——先检查失败的边界。这对应 rules.md 的模块边界检查纪律:每个模块的 golden vs PyPTO 边界验证通过后才能进入下一个模块,边界失败应定位到具体模块,而非盲目回改上游。
3.3 与 lint 门禁的协同:OL 规则的"定位"作用
Surgical Changes 与 lint-gate-rules.md 中的 OL 规则体系形成了精密的协同。lint 在文件写入(post-edit hook)与阶段/Phase 门禁(submit_for_verify/complete_phase/complete_stage)时自动运行,其作用正是把"哪里违反了哪条纪律"精确指认出来,让 Agent 只修改被点名的位置而非大面积返工:
| OL 规则 | 级别 | 语义要点 | 与 Surgical Changes 的关系 |
|---|---|---|---|
| OL45 | S0 | Layer K wrapper 禁止for ... in range(...)驱动 kernel | 精确锁定违规行,无需重写整个 wrapper |
| OL57 | S0 | JIT 图内只允许pypto.loop/loop_unroll/for...in range | 限定修改范围为 JIT 图内部 |
| OL48 | S0 | tile 参数必须是编译期字面量 | 防止为修 bug 而引入动态 tile 的"大改" |
| OL62 | S0 | impl 内 torch 仅限 layout/alloc/cast/reshape,数值计算必须在 JIT 图内 | 杜绝 dummy-JIT 全谱作弊 |
| OL50 | S1 | Layer K wrapper 显式参数必须与module_interfaces.yaml的 primary_inputs 顺序一致 | 锁定接口契约,禁止随意增删参数 |
规则 rules.md 明确要求:任何 lint 规则处于 FAIL 时不得宣称完成。这意味着"外科手术式修改"有了可自动执行的兜底——每次 edit 后 lint 立刻反馈哪一行违反了什么,Agent 只需针对被拦截的OLxx规则做最小修补,然后重新submit_for_verify。
3.4 "只清理自己的混乱"在流水线中的体现
当 verifier 报告 FAIL 时,编排者遵循verifier(裁判)→ debugger(调查)→ coder(应用补丁)→ verifier(再次裁判)的固定链路(agents.md)。其中 debugger 被明确禁止直接写生产 kernel 代码,只能向 MEMORY.template.md 的Development & debug log提交补丁方案(含文件+行范围、当前片段、建议片段、对失败验证的预期效果);生产代码的写入只有 coder 有权限。这种职责分离正是 Surgical Changes 在组织层面的延伸:谁造成的混乱(失败的实现)由谁负责清理(coder 应用补丁),调查者只提供证据、不动刀。
四、原则三:Goal-Driven Execution(目标驱动执行)
4.1 原则定义:把任务转化为可验证的目标
"Define success criteria. Loop until verified."—— 定义成功标准,循环直至验证通过。这是三条原则中最具操作性的:它要求把模糊的任务描述转化为可机械验证的成功标准,从而让 Agent 能够独立循环(loop)而不必频繁打扰人类澄清。
原文档给出的转化示例表:
| 原始说法 | 转化后的可验证目标 |
|---|---|
| "Implement Phase M1" | "M1 passesdetailed_tensor_comparewithall_close: trueon all outputs" |
| "Fix precision" | "Identify diverging checkpoint via bisection, apply fix, re-run compare" |
| "Optimize performance" | "Reduce kernel time by N% while layout check exits 0 and all outputs pass compare" |
4.2 多步骤任务的计划格式
对多步骤任务,原文档要求先陈述简短计划,每一步都挂一个验证动作:
1. [Step] → verify: [check] 2. [Step] → verify: [check] 3. [Step] → verify: [check]强成功标准让你能独立循环;弱标准(如"make it work")会导致无休止的澄清。这在多智能体场景下尤为关键:编排者派发子代理后,无法(也不应)逐行盯守,靠的正是每个阶段/Phase 明确的 gate 判据。
4.3 Goal-Driven 在仓库中的制度化
这条原则在仓库中不是口号,而是被完整制度化的状态机与门禁体系:
(1) Stage/Phase 状态机(state_transition)
AGENTS.md 定义了 Phase 状态机:
pending --start_phase--> in_progress in_progress / in_debug --submit_for_verify (lint PASS)--> awaiting_verify in_progress / in_debug / awaiting_verify --complete_phase (lint PASS)--> verified 任一态 --fail_phase--> in_debug (达到 max_cycles 时为 blocked)每个 transition 都对应一个明确的"验证动作":submit_for_verify跑 Phase 范围 lint(FAIL 则抛错且状态不变);complete_phase再跑一遍 lint 兜底;complete_stage(5)仅在所有已启动 phase 均为 verified时放行。
(2) 每阶段的 verifier 检查清单
AGENTS.md 列出了每个 Stage 的验证内容,可视为"成功标准清单"的权威版本:
| Stage | 成功标准(verifier 检查内容) |
|---|---|
| 1 | API map 干净(零unsupported行或每行有文档化 workaround) |
| 2 | goldenallclose通过、零.T、shape 注释齐全 |
| 4 | 模块拆解/契约/module_interfaces.yaml齐备;L1 路径还需对抗 harness 存在且--self-test通过 |
| 5 Phase M_k | 模块单测通过 + layout check 退出码 0 +--up-to-module k处 prefix-eval 报status: "PASS" |
| 6(最终 E2E) | detailed_tensor_compare全输出all_close: true+ layout check 退出码 0 + 完整 impl 的 prefix-eval PASS |
| 7(调优收尾) | debug_options已还原 + 调优报告已生成 + verifier 回归确认无精度/结构回归 |
(3) MEMORY.md 的机器可读字段
MEMORY.template.md 顶部即要求维护一组机器可读字段作为目标的持续追踪:
phase: 0|1|2|3|4|5|6 decomposition_level: L0|L1 # from DESIGN.md;L0 = single module, L1 = multi-module module_count: 1 # 1 for L0, ≥2 for L1 active_module: M1 # for L1 only;L0 sets active_module: M1 (single) current_staged_file: custom/<operator_name>/<operator_name>_module1.py modules_pypto_verified: - id: M1 evidence: "<command or pointer to Per-module verification log row>" detailed_tensor_compare_ok: true # false until boundary passes next_mandatory_step: "<one concrete step>" correctness: not_started | golden_ok | sim_ok | npu_ok optimization: not_started | … | complete | skipped_user_request blockers: []其中next_mandatory_step字段正是 Goal-Driven 原则的即时体现——每一轮结束后都明确写出"下一个必须步骤",确保任意时刻接手流水线的 Agent 都知道当前目标是什么。
4.4 目标驱动在精度问题排查中的应用
原文档示例中"Fix precision"被转化为"通过 bisection 定位发散 checkpoint,应用修复,重跑 compare"。仓库为此提供了配套工具链:
- detailed_tensor_compare.py 返回的字典包含
out_of_tolerance_ratio、max_diff、outlier_indices(超差元素索引)、outlier_values1/2等字段,可精确定位"哪个坐标点发散、偏离多少"; - snapshot_bisect.py(pypto-op-verify 技能)用于对中间快照做二分定位;
- 规则 rules.md 的Golden function inventory要求:把 golden 中每个数学操作逐行列清单,与 PyPTO 实现交叉核对(✅ 带 pypto 调用+行号 / ❌ 缺失),存在任何 ❌ 时不得运行测试或推进模块——因为精度错误最常见的原因就是"某个操作根本没实现"。
这套机制让"修精度"从玄学变成可定位、可验证的工程问题。
五、三条原则的协同与流水线落地全景
5.1 原则之间的依赖关系
三条原则不是孤立的,而是层层支撑的闭环:
- Simplicity First 控制写入端:产出最小可行实现,减少后续需要维护和排查的代码量;
- Surgical Changes 控制修改端:后续迭代只动必须动的地方,保护已冻结的 golden 与已验证模块;
- Goal-Driven Execution 控制验证端:为每一步定义机械可查的成功标准,让"少写、少改"的成果能快速被确认或否定。
三者共同服务于一个目标:让每个模块以更少的尝试次数通过验证(原文档的验收信号第 4 条)。
5.2 在 Stage 5 分模块循环中的完整示例
以 L1 路径(module_count ≥ 2)的 Stage 5 为例,三条原则如何在循环中同时起作用(流程见 AGENTS.md):
start_phase(M_k),在 MEMORY.md 设置active_module: M_k——Goal-Driven:明确当前目标模块;- 派发 coder 产出
<op>_module<suffix_k>_impl.py,按 Layer A–L 模板实现最小可行版本(Simplicity First,不预写下一模块的逻辑,规则 rules.md 要求后续阶段先 stub); submit_for_verify(M_k)跑 Phase lint,FAIL 则 coder 只修补被拦截的OLxx行(Surgical Changes);- verifier 以 Phase scaffolding 模式验证——比对每个叶子输出(Goal-Driven 的"all outputs"标准),PASS 才
complete_phase; - FAIL 则携带
failure_category+ 失败文件派发 debugger 调查、coder 应用补丁(Surgical Changes 的职责分离),循环上限 10 次后 phase 进入blocked,编排者须上报用户或rollback_to_stage(Goal-Driven 的失败出口)。
L0 路径(module_count == 1)则直接跳过 staged 链:coder 一次产出<op>_impl.py,verifier 跑单次 E2Edetailed_tensor_compare,PASS 即complete_stage(5)(AGENTS.md)。
5.3 性能调优阶段的"目标"形态
进入 Stage 7 后,Goal-Driven 原则体现为可量化的性能目标:AGENTS.md 要求编排者 INIT 时计算perf_target_us(若 initial prompt 已注入平台性能基线,则必须原样采用),并把target_met = 实际us ≤ perf_target_us作为 S4 调优循环(S4_FRONTEND → [S4_SWIMLANE → S4_INCORE] × ≤3 轮 → S5)的退出判据;同时要求perf_baseline_us/perf_target_us必须是真实数值(非pending)才能派发下一轮。这完全对应原文档示例表中的第三条转化:"Reduce kernel time by N% while layout check exits 0 and all outputs pass compare"——优化轮次的最终验收仍然要由 verifier 以 Stage 7 regression mode 重跑 E2Edetailed_tensor_compare+ layout check 兜底(agents.md),确保性能目标达成不以精度/结构回归为代价。
六、实践建议:如何在算子开发中应用这三条原则
基于原文档与仓库机制,可将三条原则转化为可直接执行的开发纪律:
- 动手前先定义成功标准:对每个模块,把目标写成"
detailed_tensor_compare全输出all_close: true"(rtol/atol 默认1e-3,可经TensorCompareOptions调整)而非"实现这个功能";多步骤任务按[Step] → verify: [check]格式列计划。 - 写最少但合规的代码:遵循 impl_template.py.tmpl 的 Layer G–K 分层;不预写未验证模块的逻辑(先 stub 并注释
# STUB: until M2 verified; golden-fed tensor,见 rules.md);不添加投机性优化(Stage 6 前unroll_list只用单值)。 - 改代码只动必动处:被 lint 拦截时只修报出的
OLxx行;不重构未坏代码;不修改已冻结的 golden;下游失败先查失败边界,不回改上游 staged 文件。 - 让验证说话,不用口头"应该能过":规则 rules.md 明令禁止用"should pass"/"aligned"之类表述替代真实运行——必须运行命令并把证据粘贴进日志或 stage 交付物(Stage 5+ 同时写入
custom/<op>/MEMORY.md)。 - 遇到晦涩错误不轻言放弃:
FFFFF、UNKNOWN、0x3FFFF等Errcode: F…!不是停止理由(rules.md);仅当参考代码缺失、golden 无法等价归一、框架根本性阻塞集成形式、缺少必要运行时日志或继续推进等于盲猜时,才允许暂停(Stop Conditions,rules.md)。
结语
principles.md 虽然篇幅精炼,却是整个 PyPTO 多智能体开发流水线的行为基石。Simplicity First 控制写入的量,Surgical Changes 控制修改的面,Goal-Driven Execution 控制验证的锚——三条原则与 rules.md 的强制规则、lint-gate-rules.md 的 OL 门禁、agents.md 的派发契约共同构成了"少写、少改、可验证"的完整工程闭环。理解这三条原则,也就理解了 pypto-op-orchestrator 团队何以能够以可重复、可审计的方式把自然语言算子需求逐步推进为通过全输出精度验证的 PyPTO kernel 交付物。
【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址: https://gitcode.com/cann/pypto-gym
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考