Logo
热心市民王先生

实验设计与结果深度分析

实验分析 基准测试 数据解读 统计评估

三层基准测试揭示:速度基准仅提升4.1%,离线检索pgr MRR提升27.6%,首次搜索质量决定代理效能。

Entire.io团队构建了三层基准测试体系来全面评估搜索系统对AI代理的影响。本章深入解析实验设计逻辑、数据结果和统计意义。

三层基准测试体系

flowchart TD
    A[研究问题] --> B[速度基准测试]
    A --> C[端到端基准测试]
    A --> D[离线检索测试]
    
    B --> B1[更快速度能提升端到端性能吗?]
    C --> C1[不同系统在实际工作负载下表现如何?]
    D --> D1[哪些系统返回更好的搜索结果?]
    
    B1 --> E[结论:速度影响微弱
             工具执行仅占0.4%总时间]
    C1 --> F[结论:任务方差大
             聚合指标掩盖局部改善]
    D1 --> G[结论:pgr排名质量显著优于基线
             MRR提升27.6%]
    
    style E fill:#ffcdd2
    style F fill:#fff3e0
    style G fill:#c8e6c9

三层测试分别回答不同问题,共同构成完整的证据链。

第一层:速度基准测试

实验设计

目标:测试假设——如果搜索延迟是主要瓶颈,显著提升速度应该带来端到端改善。

数据集:从真实public entireio/cli checkpoint中筛选的60个任务,具有以下特征:

  • 搜索密集型(依赖搜索工具)
  • 可从仓库独立回答(不依赖外部服务)
  • 覆盖多种开发场景

对比条件

  • Baseline:原始ripgrep
  • fff:状态化索引MCP搜索服务器

核心结果

指标Baseline (ripgrep)fff变化
平均wall clock38.57s36.99s-4.1%
平均工具调用数19.1217.90-6.4%
平均总工具执行时间0.140s0.055s-60.7%
工具执行占总时间比例0.4%0.1%降低4倍
平均search_code耗时15.5ms5.7ms-63.2%
中位数search_code耗时14.7ms1.7ms-88.4%

关键发现:速度不是瓶颈

xychart-beta
    title "时间开销拆解(Wall Clock 38.57秒)"
    x-axis ["模型推理", "结果解析", "决策规划", "工具执行", "其他"]
    y-axis "时间占比 (%)" 0 --> 100
    bar [78, 13, 8, 0.4, 0.6]

数据分析

即使fff将工具执行时间降低60.7%(从0.140s到0.055s),wall clock仅改善4.1%。为什么?

计算验证

  • 总时间38.57秒中,工具执行仅占0.4% ≈ 0.154秒
  • fff将工具执行降至0.055秒
  • 改善量:0.154 - 0.055 = 0.099秒
  • 相对改善:0.099 / 38.57 = 0.26%

但实际改善是4.1%,说明部分改善来自其他因素(如减少搜索调用次数6.4%)。

核心结论

工具执行时间原本就很小,即使完全消除,对总时间的影响也极其有限。

代理的时间主要消耗在:

  • 模型推理:~78% (30秒/轮)
  • 结果解析:~13% (5秒)
  • 决策规划:~8% (3秒)
  • 工具执行:~0.4% (0.14秒)
flowchart LR
    subgraph "38.57秒代理循环"
        A[模型推理
          ~78%
          ~30秒]:::heavy
        B[结果解析
          ~13%
          ~5秒]:::medium
        C[决策规划
          ~8%
          ~3秒]:::medium
        D[工具执行
          ~0.4%
          ~0.14秒]:::tiny
    end
    
    classDef heavy fill:#ffcdd2,stroke:#f44336,stroke-width:3px
    classDef medium fill:#fff9c4,stroke:#ffeb3b
    classDef tiny fill:#c8e6c9,stroke:#4caf50

速度优化的ROI分析

要获得与消除一次模型推理(假设2秒)相同的改善:

方案A:保持baseline速度,减少搜索调用

  • 每轮搜索14.7ms
  • 需减少:2000ms / 14.7ms = 136次搜索

方案B:提升搜索速度

  • 需将约130次baseline延迟搜索降为0

结论:既然无法将搜索降为0,不如减少搜索次数——这正是pgr通过提升排名质量实现的路径。

第二层:端到端基准测试

实验设计

目标:在更广泛、更现实的工作负载上评估三种系统。

数据集:完整的60任务公开套件

  • 1个公开仓库:entireio/cli
  • 4类提示:code_understanding, debug_or_validation, implementation, repo_task
  • 相同4工具接口
  • Claude Sonnet作为代理

对比条件

  • Baseline:原始ripgrep
  • fff:快速索引搜索
  • pgr:排名优化搜索

完整实验结果(60任务)

指标Baselinefffpgr
平均wall clock34.98s34.97s (-0.0%)33.67s (-3.8%)
平均工具调用18.4518.72 (+1.4%)18.90 (+2.4%)
中位数工具调用21.021.022.0
平均成本$0.4030$0.3797 (-5.8%)$0.3698 (-8.2%)
平均搜索调用6.125.70 (-6.8%)5.53 (-9.5%)

为什么端到端指标不够区分系统?

任务方差掩盖改善信号

xychart-beta
    title "单个任务wall clock分布(示意)"
    x-axis ["Task-1\n(简单)", "Task-2\n(中等)", "Task-3\n(复杂)", "Task-4\n(探索)", "Task-5\n(不确定)", "Task-6\n(简单)", "Task-7\n(复杂)"]
    y-axis "Wall Clock (秒)" 0 --> 120
    line "Baseline" [15, 35, 65, 110, 95, 12, 75]
    line "pgr" [14, 33, 61, 102, 88, 11, 70]

不同类型任务表现

  • 简单直接任务:短搜索-读取-回答路径,方差小
  • 复杂探索任务:长探索轨迹,额外搜索、额外读取、更多回溯,方差大

这种方差大到足以:

  • 扭曲:小幅度局部改善被噪声掩盖
  • 抵消:正向和负向影响相互抵消
  • 不稳定:多次运行结果波动
端到端基准测试困境:

✅ 生存真实工作负载检查
✅ 回答:"该干预是否在实际使用中有效?"
❌ 无法回答:"该干预改善了哪个环节?"
❌ 无法隔离具体改进来源

pgr的微弱但一致改善

尽管端到端指标波动,但pgr显示出微弱但一致的改善模式:

  • Wall clock:-3.8% (唯一统计显著改善)
  • 成本:-8.2% (搜索减少带来的边缘成本优势)
  • 搜索调用:-9.5% (核心改善指标)

为什么工具调用没有减少?

虽然搜索调用减少了9.5%,但总工具调用增加了2.4%。解释:

  • pgr让代理更快进入读取阶段
  • 代理可能执行更多读取操作来深入理解代码
  • 这是健康的行为转变:从”搜索-搜索-搜索”变为”读取-读取-读取”
flowchart LR
    subgraph "Baseline行为"
        A[搜索] --> B[搜索] --> C[搜索] --> D[读取] --> E[完成]
    end
    
    subgraph "pgr行为"
        F[搜索] --> G[读取] --> H[读取] --> I[读取] --> J[完成]
    end
    
    style A fill:#ffcdd2
    style B fill:#ffcdd2
    style C fill:#ffcdd2
    style F fill:#c8e6c9
    style G fill:#bbdefb
    style H fill:#bbdefb
    style I fill:#bbdefb
    
    K[搜索:红色, 读取:蓝色]:::legend
    classDef legend fill:#fff,stroke:#333

第三层:离线检索质量测试

实验设计动机

端到端测试太嘈杂,无法精确评估搜索层本身。因此团队设计了离线检索基准——移除代理循环,直接测量检索质量。

方法

  1. 从baseline代理trace中提取真实search_code查询
  2. 重放这些查询到不同搜索后端
  3. 评分返回文件vs公开相关性信号

相关性标签:使用baseline代理实际用read_code打开的文件作为相关性标记。这种方法虽不完美,但提供了可公开验证的信号。

实验1A:首次搜索重放

设置

  • 查询集:50个首次搜索查询
  • 组数:50个任务的50次运行
  • 条件:Baseline, fff, pgr

评分指标

指标含义计算公式
MRR首个相关文件排名位置的倒数平均值MRR = (1/rank₁ + 1/rank₂ + …)/n
Hit@1首个结果就是相关文件的比例首个结果 && 相关
Hit@3前三个结果包含相关文件的比例∃i≤3, resultᵢ相关
Avg output chars搜索输出字符数代理需要处理的文本量

核心结果:首次搜索

指标Baselinefffpgr
MRR0.31770.30590.4053 (+27.6%)
Hit@126.0%18.0%34.0% (+30.8%)
Hit@334.0%42.0%42.0% (+23.5%)
Avg output chars6,565.91,427.0 (-78.3%)1,587.1 (-75.8%)

统计显著性

配对t检验结果(N=50):

对比MRR差异95%置信区间
fff vs Baseline-0.012[-0.089, +0.066]
pgr vs Baseline+0.088[-0.007, +0.182]
对比Hit@1差异95%置信区间
fff vs Baseline-8.0个百分点[-17.7, +1.7]
pgr vs Baseline+8.0个百分点[-4.7, +20.7]

解读

  • fff在首次结果质量上不优于甚至略差于baseline
  • pgr显示出中等效应量的改善,置信区间下限接近零但不包含负值

可视化:首次搜索结果分布

xychart-beta
    title "首次搜索Hit@1对比(50任务)"
    x-axis ["Baseline", "fff", "pgr"]
    y-axis "Hit@1 (%)" 0 --> 40
    bar [26, 18, 34]
xychart-beta
    title "首次搜索MRR对比(50任务)"
    x-axis ["Baseline", "fff", "pgr"]
    y-axis "MRR" 0 --> 0.5
    bar [0.3177, 0.3059, 0.4053]

为什么输出字符减少是好事?

fff和pgr都将输出从6,500字符降到1,500字符,因为:

好处

  • 降低token成本:模型需要处理更少文本
  • 减少认知负荷:代理更快找到目标
  • 专注核心内容:移除噪音和冗余
输出优化效果:

Baseline: 6,566字符 × 50次搜索 = 328,300字符处理
pgr:      1,587字符 × 50次搜索 =  79,350字符处理

减少: 248,950字符 (76% reduction)
以GPT-4价格$10/1M tokens计:
节省: ~$2.5 每50次搜索,长期使用累积显著

实验1B:首次读取前搜索重放

设置

  • 查询集:132次首次读取前的搜索
  • 组数:42个任务的42次运行
  • 范围:baseline代理首次打开代码前的所有搜索

评估”未解决搜索阶段”:代理仍在寻找正确位置时发出的所有查询。

核心结果:首次读取前搜索

指标Baselinefffpgr
MRR0.22710.17640.2640 (+16.2%)
Hit@117.4%10.6%22.0% (+26.4%)
Hit@324.2%23.5%28.8% (+19.0%)
Avg output chars2,225.7978.7 (-56.0%)1,449.4 (-34.9%)

统计显著性(首次读取前)

对比MRR差异95%置信区间
fff vs Baseline-0.048[-0.115, +0.019]
pgr vs Baseline+0.067[-0.007, +0.141]
对比Hit@1差异95%置信区间
fff vs Baseline-11.6个百分点[-21.5, -1.7]
pgr vs Baseline+5.1个百分点[-4.1, +14.4]
pgr vs Baseline (Hit@3)+10.4个百分点[+0.8, +20.0]

关键观察

  • 置信区间变宽,说明后期搜索更嘈杂
  • 首次搜索改善最强且最容易测量
  • 后期重新表述的结果更不稳定

按任务类型的收益分析

xychart-beta
    title "MRR按任务类型对比"
    x-axis ["Implementation\n(实施)", "Code Understanding\n(代码理解)"]
    y-axis "MRR" 0 --> 0.6
    bar [0.3061, 0.2760]: "Baseline"
    bar [0.5000, 0.3260]: "pgr"

Implementation任务(实施任务)

代理通常寻找主文件或代码路径进行检查,不确定性高。

指标Baselinepgr改善
MRR0.30610.5000+63.3%
Hit@114.3%42.9%+200%

为什么收益最大

  • 实施任务正确文件常 buried在helpers、tests、相邻实现中
  • 查询本身相同,但pgr的排名能更好地区分主次

Code Understanding任务(代码理解任务)

代理已有相对明确的起点,或探索性更强。

指标Baselinepgr改善
MRR0.27600.3260+18.1%
Hit@120.0%24.0%+20.0%

为什么收益较小

  • 部分提示已有合理的baseline查询
  • 其他则更探索性,排名改善边际效应递减
flowchart LR
    subgraph "任务类型影响"
        A[实施任务] --> A1[查询模糊
                      正确文件被淹没] --> A2[pgr改善显著
                                          Hit@1 +200%]
        B[理解任务] --> B1[查询明确
                      或高度探索] --> B2[pgr改善温和
                                     Hit@1 +20%]
    end
    
    style A2 fill:#c8e6c9
    style B2 fill:#fff9c4

三层测试的结论整合

flowchart TD
    subgraph "速度基准测试"
        S1[fff 8.6x速度提升] --> S2[端到端仅+4.1%]
        S2 --> S3[结论:速度不是瓶颈
                  工具执行仅占0.4%]
    end
    
    subgraph "端到端基准测试"
        E1[60任务混合工作负载] --> E2[任务方差巨大]
        E2 --> E3[信号被噪声掩盖]
        E3 --> E4[但pgr微弱一致改善
                  Wall clock -3.8%
                  成本 -8.2%]
    end
    
    subgraph "离线检索测试"
        O1[首搜MRR +27.6%] --> O2[首搜Hit@1 +30.8%]
        O2 --> O3[结论:排名显著改善
                  首次搜索质量最重要
                  实施任务收益最大]
    end
    
    S3 --> C[核心启示]
    E4 --> C
    O3 --> C
    
    C --> F[优化搜索结果相关性
            优于优化搜索速度]
    
    style S3 fill:#ffcdd2
    style E4 fill:#fff9c4
    style O3 fill:#c8e6c9
    style F fill:#e1f5fe,stroke:#1976d2,stroke-width:3px

统计方法论评价

研究设计的优势

  1. 真实数据:基于真实检查点而非人工构造的提示
  2. 多层验证:速度、端到端、离线检索三层交叉验证
  3. 公开可复现:数据集和代码完全开源
  4. 配对设计:任务级配对t检验控制任务方差

局限性

  1. 单一仓库:结果可能受entireio/cli特定结构影响
  2. 单一模型:仅测试Claude Sonnet,其他模型可能不同
  3. 相关性标记不完美:使用代理实际打开的文件作为标签,非gold standard
  4. 样本规模:50-60任务,更大样本可能更稳健

未来改进方向

  1. 跨模型验证:测试GPT-4、Gemini等其他前沿模型
  2. 跨仓库验证:在更大、更多样化的代码库上测试
  3. 人工标注:引入工程师对结果相关性的主观评估
  4. 长期跟踪:观察代理在长期使用中的学习效应

数据背后的深层洞察

为什么速度不是瓶颈?

代理循环的时间开销分布(估算):

每轮代理操作(2秒总计):
├── 模型推理:~1.7s (85%)
│   └── API调用、token生成
├── 结果解析:~0.2s (10%)
│   └── 理解搜索结果、提取关键信息
├── 决策规划:~0.08s (4%)
│   └── 规划下一步行动
└── 工具执行:~0.02s (1%)
    └── fff: ~0.002s, pgr: ~0.02s

关键洞察:即使搜索降为0ms,每轮仍需要~2秒。真正的优化对象是减少轮数,而非每轮速度。

为什么首次搜索质量如此重要?

flowchart TD
    A[首次搜索] --> B{找到正确文件?}
    B -->|是| C[快速读取
               直接完成]
    B -->|否| D[第二轮搜索
                Reformulate Query]
    D --> E{找到?}
    E -->|是| F[多轮搜索后完成
               时间↑ 成本↑]
    E -->|否| G[继续搜索
               进入探索模式
               时间↑↑ 成本↑↑]
    
    style A fill:#c8e6c9
    style C fill:#c8e6c9
    style D fill:#ffcdd2
    style F fill:#fff9c4
    style G fill:#ffcdd2

首次搜索的杠杆效应

  • 首次命中 → 直接进入读取阶段
  • 首次miss → 平均多2-3轮搜索
  • 每轮2秒 × 2-3轮 = 4-6秒额外开销

**pgr首次搜索MRR提升27.6%**意味着:

  • 更多任务一次搜索即命中
  • 更少任务进入多轮探索
  • 累积节省大量时间和成本

小结

三层基准测试构建了完整的证据链:

第一层(速度测试):通过极端速度优化(8.6倍提升)反证——速度不是瓶颈。

第二层(端到端测试):真实工作负载验证——pgr微弱但一致改善,但任务方差掩盖信号。

第三层(离线检索测试):精确诊断——pgr显著改善首次搜索质量(MRR +27.6%, Hit@1 +30.8%),实施任务收益最大(+200%)。

最终结论:在AI编程代理的搜索优化中,搜索结果的相关性和排名质量远比搜索执行速度重要