瓶颈透镜 (Bottleneck Lens)
找到瓶颈。证明改进。
保持收集本地化;默认不上传源代码、跟踪信息或报告。可移植的指令和捆绑的脚本不依赖于特定的代理供应商。捆绑路径相对于此 SKILL.md 解析。CLI 需要 Python 3.10+;目标适配器支持 Python 3.10+ 和 Node.js 22+。Node 支持基准测试/CPU 模式;Python 还支持分配分析。
发现并商定工作负载
阅读项目说明、清单、锁定文件、入口点以及现有的性能/正确性测试,无需导入项目模块或执行设置钩子。识别语言、框架、解释器、依赖项以及实际缓慢的操作。选择 Python 或 Node 适配器以及现有的项目运行时。对于其他语言,解释收集器的边界并建议合适的分析器,而不是假装捆绑的适配器支持它。
选择一个有代表性、有界的工作负载,并带有稳定的数据集、种子、并发性、缓存策略和预期输出。优先选择可信的现有基准测试或一个经过审查的小型驱动程序,该驱动程序能验证结果。测试收集和应用程序导入也会执行代码。如果没有可运行的工作负载,请提供假设和收集计划;切勿编造测量结果。
在执行不熟悉的仓库之前,显示确切的解释器、工作目录、命令和参数、调用次数、超时时间、输出路径以及可能的数据库/网络/文件影响。如果对话中尚未涵盖,请获得对该具体工作负载的授权。检查或分析的权限不是修改应用程序代码的权限。除非用户已授权优化,否则在更改前请询问。对于未更改且已获批的范围,请勿再次询问。安装依赖项、附加到进程以及访问生产环境需要各自的相应授权。
收集器以用户的权限运行代码:子进程分离和超时不是安全沙箱。必要时使用固定装置或测试数据库。切勿在工作负载 ID 或命令行参数中传递凭据;参数和路径会在本地记录。报告可能泄露内部路径。不要仅仅为了发现未知命令的作用而运行它们。
收集证据
阅读 references/measurement.md 了解命令、指标定义、统计决策和退出代码。共享的版本 2 格式定义在 references/measurement.schema.json 中。仅为授权的工作负载执行捆绑的收集器。重新收集旧的或临时的工件,而不是猜测其缺失的指标边界。
- 首先收集一个无仪器基准测试。保存所有样本、环境元数据、工作负载标识和代码修订版本。每个样本使用一个新进程。一个被丢弃的热身运行也是一个新进程;它不会加热后续进程中的应用程序状态。
- 在单独的调用中收集 CPU 分析信息,以及针对 Python 的分配分析信息。它们的时序是诊断性的,不能替代基准测试的时序。Node CPU 模式保留 V8 分析信息和事件循环诊断信息;样本命中次数不是调用次数,并且 V8 分析信息包含收集器启动时间。默认的基准测试和分配收集每次执行工作负载八次(一次热身,七次记录运行);CPU 分析信息增加一次调用,无需热身。在获批的计划中包含这些计数。
- 在编辑之前保留基线。使用新的输出名称:脚本拒绝覆盖工件。选择一个持久的结果目录,并将每个 JSON 文件与其相邻的工件目录放在一起。记录数据集标识、
--input文件哈希、种子、修订版本、相关的--source文件以及缓存策略。记录的种子不会为应用程序代码播种;自动元数据无法确定实际的缓存状态或未指定的输入。 - 在有意义的情况下,使用
--expected-stdout配合独立审查过的已知答案。每次调用,包括热身,都会被检查。没有这个预言机,自动比较就无法评估正确性;请单独运行并报告项目测试。狭窄的输出相等性并不涵盖所有应用程序不变量。 - 优先为 Python API 或工作进程使用有限驱动程序。捆绑的工具不是 HTTP 负载生成器、实时进程采样器、线程级 CPU 分析器或进程树监视器。它不直接测量 I/O 字节数、查询次数、请求百分位数或吞吐量。需要时,与用户一起选择额外的仪器,并记录其范围/开销。
诊断并提出建议
对于每个发现,引用工件、函数/文件/行、调用次数或分配大小,以及相关的自身/累积时间。区分观察到的事实、假设和拟议的更改。累积时间在调用树中重叠;切勿将它们相加为总时间的百分比。高累积时间标识了昂贵的路径,但不一定是需要重写的函数。
低于挂钟时间的 CPU 时间可能暗示等待,但不能证明磁盘、数据库或网络因果关系。重复的函数调用不能证明 N+1 次查询:获取查询计数/跨度并检查循环。分配快照描述了快照时的存活分配情况,而不是所有瞬时分配或泄漏。通过重复的工作负载和保留证据来确认可疑的泄漏。明确说明未知状态。
根据测量的贡献、可能的收益、实现成本、正确性风险和资源权衡来确定更改的优先级。在适用的情况下描述缓存失效、排序、事务、并发性和内存影响。在测量之前不要承诺百分比的改进。
在授权范围内优化和验证
进行最小授权的更改,并保留无关的工作。运行相关的正确性测试,并在相同的测试夹具上比较输出/不变量。仅成功退出进程不是正确性验证。
使用相同的环境、工作负载、种子、缓存策略、运行次数和超时时间重复相同的基准测试和受影响的分析。rerun 使用记录的请求执行当前代码并检查输入哈希;它不会恢复历史修订版本。将无仪器时序与无仪器时序进行比较,并将同类内存指标进行比较。通用的 JSON 不会使不同的进程/线程范围或运行时计时间隔可互换。如果依赖项/解释器/工作负载发生变化,将其报告为单独的实验,而不是绕过兼容性检查。
使用捆绑的比较命令来区分描述性的中位数/均值变化、配置的实践阈值以及关于均值差异的独立样本置换证据(跨比较指标进行 Holm 校正)。在查看结果之前选择阈值;默认的 5% 并非普遍有意义。范围重叠不是显著性检验。该检验假设独立的、可交换的样本;当漂移可能使该假设无效时,检查变异性并重复或交错 A/B 测量。不确定的结果不能证明等价性。
自动化的 verified_improvement 状态仅限于测量的工作负载和匹配的通过输出预言机,需要支持的实际主要指标改进,并且如果其他比较指标中存在支持的实际回退,则会阻止该状态。失败的输出检查会退出代码 3 并阻止验证,即使执行速度更快。--fail-on-regression 使支持的实际回退退出代码 1;针对不确定比较的零退出不代表认证改进。不要在叙述中宣传未经评估或失败的结果。如果存在相邻的代表性工作负载且已获授权,请运行它们。仅对测试过的场景声称回退覆盖。当达成一致的问题得到回答、运行失败、达到授权边界或无法获得可比较的测量结果时,停止扩展实验。
交付结果
使用用户的语言。每次收集/比较都会生成一个 Markdown 报告和 JSON 文件;用用户的语言添加代理解释,同时保留原始证据。首先说明发现了什么、其证据以及下一个实验,然后包括:
- 范围、命令、环境/修订版本、输入、重复次数和测量边界。
- 包含证据和置信度的发现;将未测量的建议分开。
- 已进行或拟议的更改、权衡以及带有命令/结果的正确性检查。
- 对于每个可比指标,前后的中位数和均值、最小值/最大值、样本数量以及变化百分比。测试和实际决策使用均值;中位数变化是描述性的。包括单位以及进程/线程/启动边界。正值变化表示值更高;负值表示更低。将零基线标记为未定义。
- 状态:测量的基线、不确定、观察到的改进/回退或已验证的改进。为可比重复测量加上通过的正确性检查保留“已验证的改进”。速度提升伴随内存增加是一种权衡,而不是无条件的胜利。
- 未测试的路径、不可用的指标、噪音、下一步操作以及具体的记录重播命令。明确标记捆绑的
scripts/demo.py已知答案演示,切勿将其数字重用作应用程序结果。
Markdown/JSON 文件是可移植的基线;代理可以使用其可用的展示工具添加图表。不要依赖托管仪表板、外部 AI 端点、专有连接器或可选图表工具来完成此工作流。