baekchangjoon/kn-estimator
GitHub: baekchangjoon/kn-estimator
在调用 LLM 为 Spring 后端生成测试前,通过静态扫描预估成本并输出将二次方开销转化为线性成本的接口分块方案。
Stars: 0 | Forks: 0
# kn-estimator
**在使用 LLM 为 Spring 后端生成黑盒 API 测试之前**,该工具会对目标项目进行
静态扫描(不调用 LLM,耗时数秒),以计算**预期成本、时间以及成本最优的生成分组(chunk
plan)**。它针对具体项目计算得出,如何将原本在单个会话中呈二次方(N²)增长的成本,通过分块转化为线性(一次方)增长——即确定每次将多少个、以及哪些 endpoint 组合在一起。
```
단일 세션: cost(N) = a + b·N + c·N² ← 컨텍스트 누적(δ·τ)이 만드는 2차 항
청크 실행: cost(N) ≈ N × g(K), g(K) = a/K + b + c·K ← K를 벽 안에 가두면 1차
K*_cost = √(a/c) K*_wall = (W_soft − S0 − δ_env) / δ_ep
```
## 安装
无需预装 Python —— 推荐路径是使用 [uv](https://docs.astral.sh/uv/)
(uv 会自动下载并管理所需的 CPython):
```
curl -LsSf https://astral.sh/uv/install.sh | sh # uv 1회 설치
uvx --from git+https://github.com/baekchangjoon/kn-estimator kn-estimate --groups
```
**Homebrew** (macOS/Linux):
```
brew install baekchangjoon/tap/kn-estimator
```
**Docker** (GHCR —— 将目标项目作为卷挂载):
```
docker run --rm -v "$PWD:/w" ghcr.io/baekchangjoon/kn-estimator /w --groups
```
**pip** (如果已有 Python 3.9+):
```
pip install git+https://github.com/baekchangjoon/kn-estimator
```
仅使用标准库,因此没有额外的依赖项。开发模式安装请使用:
```
git clone https://github.com/baekchangjoon/kn-estimator && cd kn-estimator
python3 -m venv .venv && .venv/bin/pip install -e '.[test]'
```
## 快速开始
```
kn-estimate --groups
```
执行示例(实测输出):
```
N=18 chunks=3 k_avg=6.0 est=$21.18
[spring-petclinic] 비용 최적 생성 묶음 (template×sonnet):
그룹1(POST /api/reservations, GET /api/reservations/{id}, …) — $6.93, peak 295,105
그룹2(GET /api/pets/types, GET /api/pets/{petId}, …) — $7.08, peak 301,767
그룹3(GET /api/owners, GET /api/owners/{ownerId}, …) — $7.17, peak 305,431
위 3개 그룹을 각각 **새 독립 세션**으로 돌리세요 — 세션을 이어가면 비용이 2차로
돌아갑니다. 예상 총 $21.18, 예측구간 $15~$28.
ℹ 이 프로젝트의 자체 캘리브레이션이 없습니다 — 동봉(tainted-spring-auth-user) 계수로 추정했습니다 …
```
将每个分组作为一个新的独立会话来运行,开销就会随 endpoint 数量 N 呈线性增长。
同时生成的产物:
| 产物 | 内容 |
|---|---|
| `/.kn/kn-report.md` | 面向人类的报告 —— N·w 分布、推荐方案、预测区间、成本曲线(a,b,c)、K\*、模式×模型矩阵、以 Controller 为单位的表格、免责声明 |
| `/.kn/kn-plan.json` | 面向机器的方案 —— 各 chunk 的 endpoint、预期成本、峰值上下文,`cost_curve`, `controllers` |
## 核心思想
在单个 LLM 会话中按顺序处理 endpoint 时,有两项指标会同时增长 ——
轮数(∝N)和每轮读取的上下文(累积残留,∝N)。总读取成本是两者的乘积,因此与 N²
成正比。如果将 endpoint 每次分为 K 个批次交由独立会话处理,每个会话就只会消耗二次曲线中
“成本依然较低的初始部分”,从而使得总成本与 N 呈线性关系;并且这条直线的斜率 g(K)
会呈现出一条 U 型曲线,由此便可推导出最优的 K 值。
kn-estimator 会在启动前:
1. **静态扫描**目标项目,计算 N(JSON endpoint 数量)以及每个 endpoint 的工作量
w_i(handler span + 依赖切片 + MyBatis XML/JPA entity),
2. 根据实测的校准系数(S0/τ/δ/out,按 模式×模型 区分),对 chunk 进行**以轮为单位的
模拟**,
3. 结合成本最优与上下文上限两者中率先触及的约束条件,输出**对 Controller 友好的 bin-packing
chunk 方案**。
```
cost = P_cache_read·Σ(τ_i·C) + P_cache_write·(S0 + Σδ_i) + P_out·Σout_i
```
因为 w_i 并不是绝对的 token 数量,而是仅仅作为 δ·out·τ 的乘法协变量(ŵ^α)使用,所以绝对的
成本水平完全取决于校准系数(即使对 w 统一乘以一个倍数,结果也不会改变)。
公式推导与实测依据:[docs/cost-model-explained.md](docs/cost-model-explained.md)。
## CLI 选项
```
kn-estimate [옵션]
```
| 选项 | 默认值 | 含义 |
|---|---|---|
| `--mode flat\|template` | template | 生成模式 |
| `--model opus\|sonnet\|haiku` | sonnet | 目标模型(未校准的单元格标记为 `insufficient_calibration`) |
| `--groups` | off | 以 “groupN(EP, …)” 执行指令的形式输出成本最优的生成分组 |
| `--calibration ` | 内置版本 | 使用自定义的校准文件 |
| `--w-soft ` | 330000 | 质量策略界限(超出时触发惩罚+警告,并被有效 W_hard 封顶) |
| `--w-hard ` | 900000 | 模型上限界限(按各模型 window×0.9 自动封顶 —— haiku 为 180K) |
| `--conservative` | off | W_soft=250K 保守预设 |
| `--parallel` | off | 假设 chunk 并行执行(wall-clock=max,cache_write 额外附加 5%) |
| `--out-dir ` | `.kn` | 产物目录名称 |
## 校准
通过内置的校准数据(基于 tainted-spring-auth-user 的 17 次实测,覆盖 3 个单元格 —— opus 未实测),即使没有外部数据也能直接运行;此外还内置了 petclinic 和 tainted-spring-community 的校准数据,可通过名称进行选择(`--calibration petclinic`, `--calibration community`)。但请注意,内置系数基于单一项目的实测,因此**不保证绝对 USD 的准确性** ——
在多项目实测(54 次运行)中,直接沿用内置系数的误差为 −23~−34%,而在进行试点重新校准后误差控制在了 ±10%。如果在运行时不指定 `--calibration`,CLI 会提示这一情况以及试点流程:
```
# 1) 使用相同 mode×model 实测 2 个或以上大小不同的 group(例如:1 个 EP + 最小 group)
# 2) 使用实测原始数据重新计算自身系数
kn-calibrate --ledger run_ledger.jsonl --runs runs/ --out my-cal.json
# 3) 根据通过 gate 的 session 的 context 分布重新计算 --w-soft 后重新运行
kn-estimate --calibration my-cal.json --w-soft <재산정값>
```
记录 schema 及详细流程:[docs/GUIDE.md](docs/GUIDE.md) §4.4.
## 构建
```
src/kn_estimator/
endpoints.py # 엔드포인트 인벤토리 (N) — @RestController/@ResponseBody 스캔
scan.py # 엔드포인트별 작업량 슬라이스 (w_i) — DI 그래프 BFS, MyBatis/JPA 조인
model.py # 청크 비용 시뮬레이션 (턴 단위, 캐시 read/write/out 분해)
plan.py # 컨트롤러 친화 FFD 파티션, 이층 벽(W_soft/W_hard), K*, 비용 곡선
calibrate.py # 실측 원장 → 셀별 계수 (kn-calibrate)
cli.py # kn-estimate — 보고서·플랜·매트릭스·그룹 출력
data/calibration*.json # 동봉 캘리브레이션 (캠페인 실측 — 기본 auth-user + petclinic/community)
docs/ # 가이드·수식 유도·설계·실측 캠페인·연구 노트
results/ # 캘리브레이션 원장·트랜스크립트 (재현용 원자료)
research/ # 검정 스크립트 (w 공변량, 단위별 계수 분화)
tests/ # pytest — SUT 없이 45건, SUT 있으면 +13건
```
## 测试
```
.venv/bin/python -m pytest tests/
```
如果指定路径不存在,涉及 SUT(petclinic fork)·外部示例依赖的测试将会被跳过
(可通过 `KN_SUT`, `KN_EXTERNAL_SAMPLE`, `KN_LEDGER`/`KN_RUNS` 环境变量进行指定)。
其余 45 个测试用例不依赖具体环境,并且 CI(GitHub Actions)会在每次 push·PR 时执行。
## 文档
| 文档 | 内容 |
|---|---|
| [docs/GUIDE.md](docs/GUIDE.md) | 工作原理·流水线·CLI·试点校准工作流 |
| [docs/cost-model-explained.md](docs/cost-model-explained.md) | 为什么是二次方?分块为什么能使其变为线性?K 为什么重要? |
| [docs/2026-07-16-kn-estimator-overview.md](docs/2026-07-16-kn-estimator-overview.md) | 背景·模型·现状·改进总结 |
| [docs/2026-07-20-multi-project-calibration-campaign.md](docs/2026-07-20-multi-project-calibration-campaign.md) | 3 个项目的实测活动(54 次运行) —— 系数迁移性·模式反转·试点验证 |
| [docs/2026-07-26-cost-curve-and-unit-coefficients.md](docs/2026-07-26-cost-curve-and-unit-coefficients.md) | 成本曲线系数(a,b,c)推导与单位系数差异化检验 |
## 局限性
- **不保证绝对 USD 的准确性** —— 主要用途是对模式·模型·chunk 组合的相对成本进行对比以及制定 chunk 方案。
- 预测区间是 α 敏感度(窄区间)× 运行间方差(实测 ±30~46%)的综合结果 —— 因此不应将其视为点估计,而应作为区间来解读。
- 对于校准运行次数少于 2 次的单元格,工具不会给出估算值,而是标记为 `insufficient_calibration (原因)`。
- token 数量基于 文件大小/4 进行估算。静态切片可能会低估基于 reflection、动态路由和配置生成的 bean。
- 工作量 w 仅反映了代码规模 —— 未将分支数量等复杂度纳入考量
(背景:[总结文档 §4](docs/2026-07-16-kn-estimator-overview.md))。
## 许可证
[MIT](LICENSE)
标签:AI成本估算, LLM辅助测试, Python, SOC Prime, Spring, 代码静态分析, 开发工具, 无后门, 请求拦截, 逆向工具