首页
/ Understand-Anything 大型 Monorepo 确定性基准测试:不跑 LLM 的可复现规模与性能证据

Understand-Anything 大型 Monorepo 确定性基准测试:不跑 LLM 的可复现规模与性能证据

2026-09-05 15:29:39作者:余洋婵Anita

Understand-Anything 内置了一个面向大型仓库的确定性基准测试(benchmark:large-repo),它只运行 /understand 工作流中的四个纯静态分析阶段——文件扫描、import 图提取、语义批次规划与 Tree-sitter 结构提取——并产出带版本化 JSON Schema 约束的机器可读报告与人类可读摘要。读完本文,你将掌握该基准测试的完整运行方式、报告契约(含 pairId、SHA-256 摘要、完整性检查与退出码语义)、可复现性协议,以及 TensorFlow 这类多语言大型 monorepo 的标准复现配方,从而为社区贡献可横向比较的规模与性能数据。

一、基准测试范围:只测确定性管道,明确排除 LLM

1.1 执行的四个阶段

基准测试的 runner 直接调用 /understand 技能所使用的真实确定性辅助脚本(定义见 scripts/lib/large-repo-benchmark.mjs),按固定顺序串行执行前三阶段,第四阶段按批次并发执行:

阶段 调用的真实脚本 作用
scan scan-project.mjs 文件扫描、分类、行数统计
imports extract-import-map.mjs 静态 import 图提取
batching compute-batches.mjs 语义批次规划
structure extract-structure.mjs 对每个批次做 Tree-sitter 结构提取

runner 对每段产物做形状校验(例如 validateScanArtifact 检查 scriptCompletedtotalFiles === files.lengthcontentDigest 为 64 位十六进制等,见 scripts/lib/large-repo-benchmark.mjs),校验不通过会把该阶段标记为 failed 而不是静默继续。

1.2 报告的指标集

runner 上报每阶段的 wall-clock 时间、(可用的)CPU 时间、峰值常驻内存、输出体积,以及仓库规模(文件数/行数/字节数、按类别与语言分布)、批处理统计(算法、批次数量、批大小分布)、结构覆盖率和确定性的 SHA-256 摘要。

内存指标的语义需要特别注意(原文档明确强调这一点):

  • 对 scan、imports、batching 这三个常规阶段,peakRssBytes 是该辅助进程自身的峰值 RSS;
  • 并发的 structure 阶段报告的是 maxWorkerPeakRssBytes——所有结构提取 worker 中单个 worker 的最大峰值 RSS,而不是各 worker 之和(聚合逻辑见 aggregateStructureResourcesscripts/lib/large-repo-benchmark.mjs);
  • structure 阶段的 userCpuTimeMicrossystemCpuTimeMicros 则是跨所有结构 worker 求和的。

1.3 硬性边界:不是端到端基准

报告模式被 Schema 固定为 "mode": "deterministic"。该 runner 调用 LLM、调用 API、统计 token、估算成本、生成知识图谱、渲染 dashboard。因此不得把这些结果当作端到端 /understand 基准来呈现。JSON 中的 estimatedAgentInputBytes 是确定性批次载荷(每个批次的 filesbatchImportDataneighborMap 序列化字节数之和,见 scripts/lib/large-repo-benchmark.mjs)的体积,不是 token 估算。

二、运行基准测试

2.1 安装与执行

在 Understand-Anything 的 checkout 中:

corepack pnpm install --frozen-lockfile
corepack pnpm --filter @understand-anything/core build
corepack pnpm benchmark:large-repo /absolute/path/to/repository --label public-repository-name --output /absolute/path/to/benchmark-results/public-repository-name.json

benchmark:large-repo 是根 package.json 中定义的脚本 node scripts/benchmark-large-repo.mjs,其 CLI 帮助文本同时给出等价的手动调用形式:

Usage:
  node scripts/benchmark-large-repo.mjs <repo-path> --output <path> [options]
  node scripts/benchmark-large-repo.mjs --repo <repo-path> --output <path> [options]

Options:
  -o, --output <path>       JSON report path (required)
      --label <name>        Public label for the subject repository
      --concurrency <1-32>  Structural extraction workers (default: 5)
      --keep-artifacts      Preserve temporary deterministic outputs
  -h, --help                Show this help

参数解析与校验集中在 parseArgsscripts/lib/large-repo-benchmark.mjs):仓库路径必须存在且为目录;--output 必填且非空;--concurrency 必须是 1–32 的整数(默认 5,对应源码常量 DEFAULT_CONCURRENCY = 5);未提供的 --label 会回退为仓库目录名。

2.2 输出文件与 Schema 约束

命令写出两个文件:

  • public-repository-name.json——符合版本化 报告 Schema(JSON Schema draft 2020-12,additionalProperties: falseschemaVersion 固定为 1.0.0);
  • public-repository-name.md——与 JSON 同目录的人类可读摘要。

Schema 还内嵌了状态一致性规则,从 docs/benchmarks/large-repo-report-1.0.0.schema.jsonallOf 条件块可见:status: ok 要求四个阶段全部 okwarnings 为空且 integrity.filesSkipped 为 0;status: degraded 要求 warnings 至少 1 条或 filesSkipped ≥ 1status: failed 要求 error 为非空字符串。仓库测试在测试时编译该 Schema 并对 normal、empty、degraded、partial-failed 报告做验证(tests/benchmark/test_large_repo_benchmark.test.mjstests/benchmark/test_large_repo_report_schema.test.mjs),但 runner 本身不做运行时 Schema 校验——这是文档明确说明的分工。

仓库内附有一份真实示例报告,可用于对照字段含义:示例 JSON示例 Markdown。该示例状态为 degraded(459 个文件、127,155 行、约 8.9 MB 源码;structure 阶段 8070 ms,filesSkipped: 20),Markdown 摘要按 Run / Scale / Stages / Integrity and reproducibility / Environment / Warnings 分区展示。

2.3 报告对与并发锁

JSON 与 Markdown 共享一个生成的 pairId(UUID v4,Schema 中用正则约束)。同对的写入者通过排他锁串行化:deliverBenchmarkReportsopenSync(lockPath, 'wx') 创建 .ua-report-pair-<hash>.lock,先把旧文件备份为 .backup、临时文件以 wx 独占创建,再依次 rename 安装(scripts/lib/large-repo-benchmark.mjs);捕获到的同步投递失败会尝试恢复两个旧文件,恢复结果只以有界计数器形式上报,报告错误不暴露文件系统路径。

需要如实理解的局限:这不是崩溃原子的文件系统事务——进程被杀、断电或机器崩溃若发生在两次 rename 之间,仍可能留下缺失或不匹配的报告对。消费方应比较两个文件中的 pairId 并拒绝不匹配的对。

2.4 并发、临时产物与输出边界

  • 并发:默认 5 个 structure worker(mapWithConcurrency--concurrency 并发消费批次,scripts/lib/large-repo-benchmark.mjs)。可用 --concurrency 1--concurrency 32 覆盖;对比不同次运行时必须使用相同并发度
  • 临时产物:全部中间文件创建在操作系统临时目录(ua-large-bench-* 前缀的 mkdtempSync 目录)并在运行后删除;已有的 .ua/.understand-anything/ 分析数据通过 --exclude-analysis-data 参数排除在基准输入之外(见 scan-project.mjs 的参数说明)。唯一的持久化写入就是请求的 JSON 报告及其相邻的 Markdown 摘要。
  • 输出边界--output 必须解析到被分析仓库之外,CLI 通过 isPathInsideOrEqual + 物理路径规范化(realpathSync.native)强制该边界,包括经文件系统别名(符号链接等)的间接落点scripts/lib/large-repo-benchmark.mjs),Markdown 路径同样受检。
  • 诊断脱敏:所有写入报告的错误、stdout/stderr 片段都经过 redactPaths,把被分析仓库、工具仓库、产物根三类路径分别替换为 <subject><tool><artifacts>;每路流最多保留 128 KiB(STAGE_OUTPUT_MAX_BYTES),但仍会持续排空并检查子进程的全部输出。
  • 保留产物--keep-artifacts 保留中间文件并打印其位置。注意这些私有文件包含绝对路径与详细结构数据,发布前必须人工审查并脱敏

2.5 警告与结构诊断的有界性

  • 警告摘要有界:每个条目记录阶段、总警告 count、最多 5 条(WARNING_SAMPLE_LIMIT = 5)脱敏后的 messages,以及报告被省略或截断细节的 truncated 标志。
  • 结构诊断全局有界:诊断在整个运行范围内有界,而不是每批次一份。报告保留确定性样本与成功/失败/跳过的聚合计数,但在摘要形成后丢弃各 worker 的原始 stdout/stderr。
  • 覆盖率语义structureCoverage 统计成功的结构分析;没有注册结构解析器的文件计入 filesSkipped,并使报告变为 degraded;可选 call-graph 能力缺失同样计为跳过。但若某解析器已声明能力,随后抛出异常或产出无效结果,则保持为完整性失败,而不是被当作跳过的工作。

三、测量原理:worker 如何拿到真实 CPU 与 RSS 数字

理解报告的指标为何可信,值得看一段实现。runner 并不直接 spawn 各辅助脚本,而是启动统一 worker scripts/lib/benchmark-stage-worker.mjs:它先重建辅助脚本期望的 process.argv 形态、临时替换 process.exit,然后在同一进程内 import 目标脚本,从而让 process.resourceUsage() 测到真实阶段的资源消耗。结束后把度量以 __UA_BENCHMARK_METRICS__ 前缀的 JSON 行写到 stderr(peakRssBytesmaxRSS * 1024 换算,user/sys CPU 用前后差值),父进程的 createStderrInspector 按行探测该标记、解析度量,同时把 Warning: 行计入警告统计。

确定性方面,inputDigest 直接取扫描产物的 contentDigestoutputDigestbuildOutputDigest 对 import 图摘要、批次计划摘要与每批次结构输出摘要做规范化 JSON(键排序)SHA-256 得出(scripts/lib/large-repo-benchmark.mjs),不依赖字段顺序。完整性检查 buildBenchmarkIntegrity 则交叉验证:扫描到的文件是否全部恰好被分入一个批次、import 目标是否都可解析、结构输出路径与批次清单是否一一对应(缺失/重复/意外路径均会被计数)。

四、可复现性协议

要让另一位贡献者能复现你的结果,原文档给出六条协议,结合源码可以看得更具体:

  1. 固定两个不可变 commit:为 Understand-Anything 与被分析仓库各记录一个 commit。报告会在两个目录都是 Git 工作树时自动捕获两者的 commit(gitMetadatarev-parse HEAD + status --porcelain 探测,且禁用可选锁,scripts/lib/large-repo-benchmark.mjs)。
  2. 尽量使用干净工作树:存在已跟踪或未跟踪变更时报告记录 dirty: true,Markdown 报告在工具或被测工作树任一为 dirty 时会显示醒目的警告(renderMarkdownReport 中生成)。
  3. 控制变量:操作系统、Node.js 版本、机器、并发度、.understandignore 规则在对比运行之间保持一致。
  4. 至少运行三次并保留所有报告:第一次运行应视为可能的冷缓存结果,不要静默丢弃。
  5. 时机与内存只在同机比较:跨机报告是有价值的规模证据,但不构成公平的性能回归对比。
  6. 先核对摘要再比性能:在对比" supposedly 相同输入"的性能前,确认 inputDigestoutputDigest 一致。

分享时同时提交 JSON 与 Markdown 两个文件。报告有意省略 Git 远程 URL、主机名以及绝对的被测/工具/产物路径;但包含公开 label、commit 哈希、OS release、CPU 模型、内存大小与项目统计——因此发布前请审阅两个文件。

五、TensorFlow 复现配方

TensorFlow 是一个合适的"人工"被测对象:大型、多语言 monorepo。文档特意强调:基准测试并不专属于 TensorFlow,CI 也不会克隆或基准测试 TensorFlow;下面命令是复现配方,而不是"我们对 TensorFlow 跑过基准"的声明。

该配方把 TensorFlow v2.19.0 钉在 commit e36baa302922ea3c7131b302c2996bd2051ee5c4

Bash

git clone --depth 1 --branch v2.19.0 https://github.com/tensorflow/tensorflow.git ../tensorflow-v2.19.0
if [ "$(git -C ../tensorflow-v2.19.0 rev-parse HEAD)" != "e36baa302922ea3c7131b302c2996bd2051ee5c4" ]; then echo "TensorFlow v2.19.0 did not resolve to the pinned commit" >&2; exit 1; fi
corepack pnpm benchmark:large-repo ../tensorflow-v2.19.0 --label tensorflow-v2.19.0 --output ../benchmark-results/tensorflow-v2.19.0.json

PowerShell

git clone --depth 1 --branch v2.19.0 https://github.com/tensorflow/tensorflow.git ..\tensorflow-v2.19.0
if ((git -C ..\tensorflow-v2.19.0 rev-parse HEAD).Trim() -ne 'e36baa302922ea3c7131b302c2996bd2051ee5c4') { throw 'TensorFlow v2.19.0 did not resolve to the pinned commit' }
corepack pnpm benchmark:large-repo ..\tensorflow-v2.19.0 --label tensorflow-v2.19.0 --output ..\benchmark-results\tensorflow-v2.19.0.json

两个配方都在基准执行前断言不可变 commit,并把报告输出保持在 TensorFlow checkout 之外(这恰好满足 --output 必须位于被测仓库外的 CLI 约束)。社区测试者分享两个报告文件即可;报告中的 environment 区块(OS release、CPU 模型、逻辑核数、内存)让硬件与运行时差异显式可见。

六、社区规模计划

原文档给出的推进路线(值得作为贡献者的行动清单):

  1. 先落地可复现的确定性 harness 及其经测试验证的报告契约;
  2. 为 TensorFlow 与其他社区 monorepo 各收集至少三份输入/输出摘要一致的报告;
  3. 只跨同机运行比较时机与内存;
  4. 用这些证据决定下一个要优化的瓶颈;
  5. 把 LLM、token 与成本基准测试保留为独立的未来层次,而不是从这个确定性 harness 推断端到端性能。

七、状态与退出码

退出码 含义 报告行为
0 完成,状态为 okdegraded 写出 JSON 与 Markdown
1 某个确定性阶段、完整性检查或临时产物清理失败 输出位置可写时写出部分报告;清理失败出现在 secondaryErrors 中,不取代主阶段错误
2 无效的 CLI 用法 不写任何报告

degraded 的含义是:确定性管道完成了,但报告了警告或跳过了文件。在把该次运行纳入对比之前,先检查 warningsintegrity 与 Markdown 摘要。

从源码看,状态判定与退出码由三段逻辑产生(scripts/lib/large-repo-benchmark.mjs 与入口 scripts/benchmark-large-repo.mjs):

  • 任一完整性检查失败(hasFailedIntegrity:批次缺失/重复、import 目标不可解析、structureCoverage !== 1、结构或 call-graph 失败、批次失败、结构路径缺失/重复/意外、畸形批次等)→ status: failed,退出码 1;
  • 有警告或 filesSkipped > 0status: degraded,退出码 0;
  • 否则 → status: ok,退出码 0。
  • 若非 --keep-artifacts 模式下临时产物删除失败,secondaryErrors 追加 stage: cleanup 条目且不覆盖已有的主错误信息,状态转为 failed、退出码 1;CLI 用法错误在解析期抛出 CliUsageError,由入口脚本打印帮助并以退出码 2 结束;报告写入失败则抛出 BenchmarkReportWriteError(stdout 保持为空、错误信息不含文件系统路径),退出码 1。

八、进一步深入的路径

适用前提小结:该基准面向"大到超出常规 CI 夹具"的仓库,用于本地与社区运行;它产出的是确定性静态分析层的规模与性能证据,任何关于 LLM 阶段、token 成本或端到端 /understand 体验的结论,都不应基于这套报告得出。

登录后查看全文
热门项目推荐
相关项目推荐