核心原则

为 Claude 写优化协议,本质上是在划定边界:哪些判断由文档给出,哪些判断留给 Claude

写文档之前先问自己:这件事 Claude 读代码和数据之后能自己推导出来吗?如果能,就不要写。文档只负责两件事:

  1. 问题是什么(需要解决的目标)
  2. 好坏怎么判断(可量化的验收标准)

其余的——根因分析、方案设计、实现路径、执行顺序——全部留给 Claude。


什么该写

性能目标和验收标准

用可量化的指标定义"什么叫成功"。Claude 需要知道往哪个方向优化,以及优化到什么程度算完成。

好的写法

验收标准:SCX 与 CFS 组平均利用率差距 ≤ 5%,总分 ≥ CFS × 90%。


优先级顺序

告诉 Claude 先解决什么、后解决什么,以及优先级之间的前置依赖关系。但不要规定优先级内部的执行顺序——那应该由诊断数据决定。

好的写法

优先级:P0 → P1 → P2。P0 内部优先级由诊断数据决定。P1 前置条件:P0 验收通过。


诊断流程的数据采集方法

告诉 Claude 采集哪些原始数据、怎么计算关键指标、判断阈值是多少。这是过程规范,不是分析指导。

好的写法

  • CFS 组平均利用率 = sum(各分配 CPU 利用率) / CPU 数
  • 差距 = CFS 组平均 - SCX 组平均
  • 差距 > 5% → 进入根因分析

工程接口约定

脚本之间的数据交换格式、目录结构、文件命名。这类内容不会因代码变更而过期,是稳定的工程契约。

迭代流程规范

编译命令、测试命令、提交条件、多轮验证要求。这些是固定流程,不是分析判断。


什么不该写

代码现状描述

调度机制表、参数值表、架构图、调用流程图——所有描述"代码现在长什么样"的内容都不该写在优化协议里。

原因:代码会随每次提交变化,文档会迅速过期。更危险的是,Claude 读到文档描述后会优先相信文档而不是去读代码,导致基于过时信息做判断。

反面例子

机制 位置 说明
Pre-sticky 快速路径 SCX_enqueue() rotate+scan 之前判断 sticky阈值
动态 sticky 阈值 SCX_pick_idle_cpu() 正常 65%,CPU 过载时升至 85%

为什么有害:假设上一轮优化已经把 Pre-sticky 快速路径移除了,但这张表还在。Claude 读到"Pre-sticky 快速路径:rotate+scan 之前判断 sticky",会认为这个路径仍然存在,分析问题时围绕它展开,而不是去读代码确认实际情况。文档描述和代码现实的偏差,会让 Claude 的整个分析建立在错误的前提上。


根因假设列表

把过去分析出的根因列成清单,标上 H1/H2/H3 供 Claude 参考——这是最常见的陷阱。

原因:Claude 读到假设列表后会倾向于逐一验证这些已知假设,而不是从数据出发发现真正的问题。代码改变后旧假设可能已经不成立。而这些假设本来就是从代码逻辑推导出来的,Claude 直接读代码能得到同样甚至更准确的结论。

反面例子

H1:Pre-sticky 快速路径过度触发

SCX_aware_enqueue() 在 rotate+scan 之前先做 sticky 判断,高负载任务几乎永远满足条件,跳过负载均衡。

验证方法:统计 pre-sticky 命中率 > 50% 则说明大部分调度决策跳过了负载均衡。

为什么有害:这个假设是通过读代码推导出来的,Claude 自己读代码也能得出同样结论。写在文档里只会让 Claude 优先验证 H1,而不是先看数据再判断问题出在哪。如果上一轮优化已经修掉了这个路径,H1 就不再成立,但 Claude 仍会把时间花在验证一个已经不存在的问题上。


现象到数据的映射表

“观察到现象 X,应该去采集数据 Y”——这类映射表看起来像诊断指南,实际上是在替 Claude 做分析推理。

原因:Claude 读完代码后完全可以自己判断"这个现象说明哪个机制可能有问题,需要采集什么数据"。把推理过程写死在文档里,等于剥夺了 Claude 根据实际代码结构灵活推断的能力。

反面例子

观察到的现象 需要进一步采集的数据
部分 CPU 持续 idle enqueue 各路径命中分布;pick_idle_cpu 返回值分布
部分 CPU 持续高负载 sticky 判定阻止率;迁移尝试次数 vs 成功次数

实现方案和伪代码

方案 A/B/C 的对比、推荐方案、伪代码示例——这些是实现层面的内容,不属于优化协议。

原因:Claude 会倾向于直接采用文档里标注"推荐"的方案,而不是根据当前代码结构判断哪种实现更合适。伪代码尤其危险,Claude 可能直接照抄而跳过设计思考。

反面例子

方案 A(推荐):移除 pre-sticky 快速路径,每次都走 rotate + scan。

方案 B:保留快速路径但增加额外条件——只有当 CPU 整体负载 < 40% 时才跳过。


固定的执行顺序

在优先级内部规定"必须按 P0-1 → P0-2 → P0-3 → P0-4 顺序执行"。

原因:执行顺序应由诊断数据决定。如果数据显示问题根因是 P0-3 对应的机制缺失,就应该先做 P0-3。把顺序写死会导致 Claude 按文档执行而不是解决问题。

反面例子

优先级:P0 → P1 → P2,P0 内部按 P0-1 → P0-2 → P0-3 → P0-4 顺序


会迅速过期的状态信息

“当前状态:已连通”、“已改造”、“新增”——任何描述当前实现状态的标注。

原因:这类信息在下一次提交后就可能不准确,维护成本高且容易误导。

反面例子

指标 生产者 存储路径 当前状态
性能分数 auto-test.sh scores.csv 已连通
per-CPU 利用率 diag-cpu.sh diag/cpu_util/ 已集成

文档结构模板

一份好的优化协议只需要以下几节:

  1. 优化目标和验收标准:整体性能目标(量化)、核心诊断原则
  2. 诊断流程:度量框架(用什么指标、怎么计算、阈值是多少)、进入根因分析的判断标准
  3. 优化方向:每个方向只写"问题是什么 + 验收标准",不写根因、不写方案、不写实现
  4. 迭代流程:验收判定规则、多轮验证要求
  5. 记录模板:每次迭代填写的结构化记录

一句话总结

优化协议告诉 Claude 要解决什么问题,不告诉 Claude 怎么解决。凡是 Claude 读代码和数据之后能自己推导出来的,一律不写。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐