【免费下载链接】jevgrep
Find code by asking what it does. A CLI for coding agents that uses Jev to discover relevant files and source context.
导读
audit-performance是 jevgrep 仓库内置的 Agent 技能之一,它定义了一套可执行的性能审计流程:先找到"没有有用边界地增长、或重复却毫无进展"的工作,产出证据支持的台账或报告,再选择"能保留恢复能力的最小修复"。本文以该技能文档(.agents/skills/audit-performance/SKILL.md)为骨架,结合 jevgrep 检索管线(packages/core/src/retrieve.ts、packages/core/src/evaluator.ts、packages/core/src/cache.ts、packages/core/src/filesystem.ts)的真实实现,讲解六步工作流、优先级策略、护栏与完成定义,并给出"有界工作 + 持续恢复"在真实代码中的落地形态。读完本文,你将掌握一套可直接用于任何代码库的性能审计 SOP,以及验证"修复确实有界且仍可恢复"的红/绿证明方法。
一、这个技能要解决什么问题
技能开篇就给出了核心判断标准:
Find work that grows without a useful bound or repeats without progress.
即审计的目标不是"发现慢的代码",而是找到两类病态工作:
- 无界增长(grows without a useful bound):工作量随历史、租户、路径数或故障时长线性/超线性增长,却没有与之匹配的上限;
- 无进展重复(repeats without progress):轮询、重试、批次扫描在"没有任何状态必须改变"的情况下反复执行,可能永远循环或饿死。
同时要求产出"evidence-backed ledger or report"(有证据支撑的台账或报告),并"prefer the smallest fix that preserves recovery"(优先选择保留恢复能力的最小修复)。这两点分别对应技能末尾的 Guardrails 与 Done 定义,是整份文档的方法论闭环。
二、六步工作流:从热路径追踪到红/绿证明
第一步:Trace hot paths(追踪热路径)
Find recurring syncs, polls, streams, retries, queues, scheduled jobs, filesystem walks, and request-time reads. Follow each through its production caller; ignore test-only paths.
需要关注的工作形态包括:周期性同步、轮询、流、重试、队列、定时任务、文件系统遍历、请求时读取。关键纪律是"Follow each through its production caller"——必须沿生产调用链追踪,忽略测试专用路径。
以 jevgrep 为例,检索管线中的"热路径"清晰可循:
- 文件系统遍历:
discover()从根目录逐层列出目录与文件,见 packages/core/src/retrieve.ts; - 请求时读取:每个候选文件经
unchanged()重新读取并比对内容哈希后才允许上传,见 packages/core/src/retrieve.ts; - 重试/队列:导航打分失败的批次被二分拆分后重新追加到同一队列,见 packages/core/src/retrieve.ts。
第二步:Compute the amplification(计算放大倍数)
State the trigger and worst-case work in concrete units: rows, queries, pages, entries, bytes, jobs, retries, or full-file rewrites. Distinguish a bounded large constant from work that grows with history, tenants, paths, or outage duration.
放大倍数必须用具体单位描述:行、查询、页、条目、字节、任务、重试次数或整文件重写。更重要的是区分两种性质完全不同的工作量:
- 有界大常量(bounded large constant):最坏情况固定,可以接受;
- 随历史/租户/路径数/故障时长增长的工作:真正的风险。
jevgrep 中的放大计算有明确数字可查:
| 边界 | 默认值 | 位置 |
|---|---|---|
| 遍历条目总数 | 100_000(超出即记录resource_limit) | retrieve.ts |
| 导航请求批大小 | 128 项 或 38_000 字节,二者先到先拆 | retrieve.ts |
| 目录预览 | 64 条目 或 4_096 字节后截断 | retrieve.ts |
| 单文件读取上限 | 16 MiB(maxFileBytes) | filesystem.ts |
| 单源文件上传上限 | 1_000_000 字节(超出记录resource_limit/source_inspection_limit) | retrieve.ts |
| 忽略规则文件上限 | 1 MiB(maxIgnoreBytes) | filesystem.ts |
这些数字把"最坏情况工作量"固定成了常量,而不是随仓库规模无限放大——这正是第二步要求"区分有界大常量与随路径数增长的工作"的实践。
第三步:Check forward progress(检查前向进展)
For every retry, fixed-prefix batch, cutoff, or transitional poll, identify what changes before the next attempt. If nothing must change, it can loop or starve forever. Check that partial fixes do not merely delay the same work.
对每一个重试、固定前缀批次、截断或过渡性轮询,都必须回答:下一次尝试前,什么必须发生变化?如果"什么都不必改变",它就可能永远循环或饿死。同时要警惕:部分修复不能只是把同样的工作推迟到以后。
jevgrep 的源码处处体现这个原则:
- 批打分失败后的二分拆分:一组导航项打分失败时,代码把组从中间拆成两半重新入队,而不是整组无限重试。只有当叶子组仍失败或发生终端失败时才记录 issue——恢复成功的父组不算"不完整"("A recovered parent is not incomplete"),见 retrieve.ts。这就是"重试前有状态必须改变"(组变小)的典型实现。
- 目录遍历的游标分页:
listPage()返回nextCursor,消费完一页才继续下一页,见 filesystem.ts。即使中途放弃(closeCursor),也不会重新从头扫描同一前缀。 - 429 冷却是有进展的等待:遇到 429 时解析
retry-after头,把cooldownUntil向后推,等待期间可被取消信号中断,见 evaluator.ts。等待本身不产生新请求,但"时间推进"使得下一次尝试有实际意义。 - 内容哈希保鲜校验:任何一次上传前都通过
unchanged()复核源文件哈希,源已变化则丢弃缓存证据,防止"把过期源传给模型后拿回无效结论"。
第四步:Falsify severity(证伪严重性)
Inspect existing caps, indexes, backoff, deadlines, healing owners, and caller frequency. Dismiss findings already bounded cheaply enough or continuously healing.
找到疑似问题后,先检查已有的上限、索引、退避、截止时间、自愈 owner 和调用频率——已经"足够便宜地被限制住"或"在持续自愈"的发现应当直接驳回,而不是强行"修复"。
jevgrep 中有大量这类"已证伪"的机制:
- 并发与请求上限:
stageWorkers = 32限制每个阶段并发(retrieve.ts);createEvaluator默认并发 32、请求总数上限 50_000(evaluator.ts、evaluator.ts); - 超时截止:每次模型调用包裹
AbortSignal.timeout(options.timeoutMs ?? 15_000),默认 15 秒(evaluator.ts); - 认证失败全局自愈:401/403 触发独立的
authenticationFailureAbortController,一次性中止所有等待中的请求,避免逐请求空转(evaluator.ts、evaluator.ts); - 调用频率:CLI 提供
--concurrency,帮助文档明确建议慢网络下用 1–4(apps/cli/src/args.ts)。
如果一个发现对应的路径已经具备上述任一机制,且成本足够低,就应记录驳回理由而不是进入修复队列——这能显著压缩性能台账中的噪音。
第五步:Record before fixing(先记录再修复)
If the project keeps a performance ledger, append every supported finding and important dismissal using its existing convention. Otherwise return a compact report. Include priority, trigger, impact, current owner, acceptance seam, and evidence.
无论项目是否有正式的性能台账,纪律都是一样的:动手修复之前,先把发现落成记录。记录必须包含六个要素:
- priority(优先级,依据下文策略)
- trigger(生产触发条件)
- impact(影响)
- current owner(当前 owner)
- acceptance seam(验收接缝:在哪个最外层接缝上证明红/绿)
- evidence(证据)
第六步:用策略排序,并完成红/绿证明
If implementation is authorized, invoke the project's test-writing workflow and prove the old behavior red at the outermost practical seam. Fix, review, and update the ledger or report with verification evidence.
实施被授权后:调用项目的测试编写流程,在最外层可行的接缝处把旧行为证明为"红",然后修复、评审,最后用验证证据更新台账或报告。这里的"红/绿证明"不是普通的单元测试,而是要在 Done 节中强调的双重证明:修复后既要有界(bounded work),又要持续恢复(continued recovery)。
三、优先级策略:什么该修,什么不该修
最高优先级:会造成可见损害或"毒项"
技能文档给出的最高优先级条件是,问题可能造成:
- 用户可见的冻结或错误(user-visible freeze or error)
- 内存/磁盘增长(memory/disk growth)
- 请求处理被阻塞(blocked request processing)
- 数据丢失(data loss)
- 舰队级放大(fleet-wide amplification)
- 毒项(poison item):一个坏数据/坏任务堵塞在队列头,阻止后续所有工作
低风险修复偏好
Prefer low-risk fixes that bound existing work: stream pagewise, honor backpressure, coalesce schedules, move poison rows aside, skip proven no-ops, or make one exhaustive search end in a terminal verdict.
偏好"给已有工作加上界"的低风险修复,具体手法包括:
- stream pagewise(按页流式处理)——对应 jevgrep 的游标分页;
- honor backpressure(尊重背压)——对应
stageWorkers有界并发与acquire()等待队列(evaluator.ts); - coalesce schedules(合并调度);
- move poison rows aside(把毒行挪到一边);
- skip proven no-ops(跳过已被证明的无效操作)——对应缓存命中直接返回(evaluator.ts);
- make one exhaustive search end in a terminal verdict(让一次穷尽搜索以终局裁决收尾)。
safety cap 的定位
A safety cap is a pathology guard, not a normal product limit: set it above legitimate large workloads, emit actionable telemetry when reached, and define what happens next.
安全上限是病理守卫,不是正常产品限额:要设在合法大工作量之上,达到时发出可操作的遥测,并定义接下来发生什么。jevgrep 对此的执行非常典型——100_000条目上限达到时记录resource_limitissue,最终结果状态变为incomplete(CLI 退出码 2),而不是静默返回残缺结果(retrieve.ts、apps/cli/src/index.ts)。
不要按吓人的计数排序
技能文档明确警告三条"看起来吓人但不必修"的情况:
- 轮询可以无限继续:只要被轮询的状态有真实的恢复 owner、最终可能变化,就修"永远不会愈合的状态",而不是修"只是活得很久的计时器";
- 廉价的有界数据库工作:没有生产证据就不要为了减少一个适度的固定查询数去建投影、缓存、游标状态机或替代读模型;
- 不要优化掉即将有用的信息:如果数据可能很快支撑产品 UI 或行为,就不要提前裁剪。
这三条本质上是在对抗"看到 count 就动手"的本能,与第四步的"证伪严重性"互为表里。
四、护栏(Guardrails):修复不得破坏恢复能力
技能文档给出六条护栏,每一条都能在 jevgrep 源码中找到对应实现或对应测试。
护栏 1:保留 healing(Preserve healing)
A cache or no-op shortcut must retain cheap recovery signals and fall back to ordinary reconciliation on drift, uncertainty, restart, or prior failure.
缓存或"no-op 捷径"必须保留廉价的恢复信号,并在漂移、不确定、重启或先前失败时回退到普通对账。
jevgrep 的缓存设计完全符合:缓存条目以sha256(JSON.stringify([schema, namespace, request]))为键,只存答案不存请求原文;每次读取校验 schema、时间戳、答案类型与 TTL(默认 7 天),任何不符都按未命中处理(packages/core/src/cache.ts)。更重要的是,缓存命中前仍会执行policy.beforeAttempt的源哈希复核(evaluator.ts),即"命中缓存也要确认源没变"——这就是"保留廉价恢复信号、漂移时回退对账"的字面实现。测试 test/retrieval-freshness.test.ts 专门验证"排队的导航请求永不把随后被排除的源上传出去"。
护栏 2:恢复扫描必须完成或持久化进展
A recovery scan must either finish or persist forward progress. For a local, prunable namespace, prefer one complete pass with a ceiling high enough to indicate pathology rather than an ordinary large project. For a legitimately huge namespace, persist a cursor and resume after it.
恢复扫描要么完成,要么持久化前向进展:
- 对本地可修剪的命名空间,倾向一次完整扫描,上限设到"足以标示病理"而不是"普通大项目"的量级;
- 对真正巨大的命名空间,持久化游标并在其后恢复;
- 找到目标即更新身份;穷尽未命中或异常上限产生该领域的终局裁决;
- 绝不要永远重启同一个部分前缀。
jevgrep 的listPage游标就是"持久化前向进展"的实现——每次调用返回nextCursor,调用方决定继续、暂停或closeCursor主动放弃(filesystem.ts),从结构上杜绝"同一前缀从头重扫"。
护栏 3:分离可重试失败与终局失败
Separate retryable failures from terminal ones. A permanent rejection must not sit at a queue head or fixed prefix forever.
可重试失败与终局失败必须分离,永久拒绝绝不能一直堵在队列头或固定前缀。
jevgrep 的evaluator是教科书级实现:
- 401/403 → 立即触发全局认证中止,不可重试(evaluator.ts);
- 408/429/5xx/
TimeoutError/可重试网络错误 → 判定为 transient,才允许重试(evaluator.ts); - 导航类多问题请求默认只尝试 1 次(
attemptLimit = navigation && multiple ? 1 : 2),429 时才放宽到 2 次(evaluator.ts、evaluator.ts)。
护栏 4:双向绑定传输与队列
Bound both sides of a transport and every durable/in-memory queue. State the overflow behavior; never silently drop accepted durable data.
传输的两端和每个持久/内存队列都要有界,必须说明溢出行为,绝不静默丢弃已接受的持久数据。
jevgrep 的双向绑定非常具体:上行请求有38_000字节批上限与request-sizeissue;下行答案单条maxEntryBytes(min(maxBytes, 1 MiB))超限即cache_limit(cache.ts、cache.ts);内存中排队请求在认证失败/取消时被显式 reject 而非悬挂(evaluator.ts)。溢出行为都以 issue 形式记录在结果中,最终可见于 CLI 的incomplete状态。
护栏 5:匹配产品生命周期
Match compatibility work to the product lifecycle. In prelaunch code, prefer direct changes and add no legacy branches or migrations unless real persisted data requires them.
兼容性工作要匹配产品生命周期:prelaunch 代码中偏好直接修改,除非真实持久数据需要,否则不添加遗留分支或迁移。
这一点在 jevgrep 中体现为缓存 schema 的版本化设计:缓存键和载荷都携带schema(当前为 1)与policyVersion、parserVersion、promptVersion、protocol等命名空间字段(cache.ts、evaluator.ts)——语义变化时旧条目自然失效,而不是为旧格式写兼容分支。
护栏 6:每个限制必须有可观测信号
Every limit introduced or changed must have an observable log or metric with the limit kind, configured bound, affected owner, and overload outcome.
每个引入或改动的限制都必须有可观测的日志或指标,包含:限制类型、配置的边界、受影响的 owner、过载结果。
jevgrep 的 issue 机制就是统一的可观测出口:issue(kind, count, message)把resource_limit、request-limit、cache_corrupt、cache_unavailable、cache_limit、source-invalid、changed、interrupted、authentication等全部聚合进result.issues,并附带命中/未命中统计(retrieve.ts、cache.ts)。CLI 层把这些转成退出码:0 完成、1 失败、2 不完整、130 中断(apps/cli/src/args.ts、apps/cli/src/index.ts),下游 Agent 可以据此判断"缺了哪些上下文"。
五、完成定义(Done):什么才算真正做完
技能文档用两句话定义完成,缺一不可:
The audit is complete only when every finding has a production trigger, quantified amplification, priority rationale, acceptance seam, and recorded disposition; every dismissed candidate says which bound or healing mechanism makes it acceptable.
审计完成的标准:每个发现都有——生产触发、量化放大、优先级理由、验收接缝、已记录处置;每个被驳回的候选都必须说明"是哪个边界或愈合机制使它可接受"。也就是说,"驳回"不是简单忽略,而是要给出一条可追溯的理由。
An implementation is complete only when its red/green proof shows bounded workandcontinued recovery.
实施完成的标准:红/绿证明必须同时展示有界工作与持续恢复。这解释了为什么 jevgrep 的每次修复都要带上像unchanged()哈希复核、429 冷却、游标续扫这样的"恢复机制"——只证明"工作量变小了"是不够的,还必须证明"系统在异常后仍能自己站起来"。
六、把方法论落进真实仓库:jevgrep 检索管线复盘
如果你要在自己的仓库执行这套审计,jevgrep 本身就是一份"标准答案式的样例"。把六步工作流套在它的检索管线上:
- Trace:从
retrieve()入口(packages/core/src/retrieve.ts)沿discover → score → select → assessFiles → selectTestBodies走一遍生产调用链; - Amplification:把遍历条目(100_000)、导航批(128/38_000 字节)、源大小(1 MiB)、文件读取(16 MiB)换算成最坏情况字节与请求数,确认全部是有界常量;
- Forward progress:核对每个重试(批二分、429 冷却、哈希复核)都有"下次尝试前必须改变的变量";
- Falsify:把已经被
stageWorkers=32、requestLimit=50_000、timeoutMs=15_000、认证中止、缓存 TTL 覆盖的发现直接驳回并记录理由; - Record:所有未被驳回的发现进入台账,标注 priority/trigger/impact/owner/acceptance seam/evidence;
- Prioritize + prove:对最高优先级项在最外层接缝写红/绿测试——仓库的 test/retrieval-freshness.test.ts 与 test/evaluator.test.ts 就是这样验证"源变更后缓存与摘要被正确失效"的。
结语
audit-performance的完整方法论可以浓缩为一句话:找到无界增长或无进展重复的工作,量化它,证伪它,记录它,然后用保留恢复能力的最小修复收口它。技能文档给出的六步工作流负责"发现问题",优先级策略负责"决定修什么",六条护栏负责"确保修复不引入新病理",Done 定义负责"验收到底做没做完"。当你在自己的代码库里追踪轮询、重试、队列与扫描时,不妨逐条对照 jevgrep 的实现——每一个"看起来的边界"背后,都应当同时站着"上限数字"和"自愈机制"这两样东西。
【免费下载链接】jevgrep
Find code by asking what it does. A CLI for coding agents that uses Jev to discover relevant files and source context.
相关推荐
cloudflare-security-audit 技能实战:AI/LLM/Agent 攻击面安全审计方法论
cloudflare security audit 技能实战:AI/LLM/Agent 攻击面安全审计方法论 导读 本文以 AAS 仓库中 cloudflare
AI 技能AI 插件OpenFang security-audit 技能详解:基于 OWASP 与 STRIDE 的 Agent 安全审计方法论
OpenFang security audit 技能详解:基于 OWASP 与 STRIDE 的 Agent 安全审计方法论 导读 security audit
人工智能大模型AI Agent自主智能体Agent 编排MCP Clients知识图谱GitLens a11y-audit 技能全解:基于 WCAG 2.1 AA 的代码可访问性静态审计方法论
GitLens a11y audit 技能全解:基于 WCAG 2.1 AA 的代码可访问性静态审计方法论 导读 GitLens(vscode gitlens)
开发工具版本控制
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考