问题描述

Headroom proxy 的 /v1/compress 端点虽然能够正常返回压缩结果(压缩后的 messages、tokens_before/tokens_after),但压缩数据没有被记录到 Dashboard

  • GET /statsrequest_logs 为空
  • summary.compression.requests_compressed 始终为 0
  • tokens.proxy_compression_saved 始终为 0
  • Dashboard 页面无法显示该请求的记录

原因分析

handle_compress() 方法在成功压缩后直接返回 JSONResponse没有调用 self._record_request_outcome() —— 这是 Headroom 中所有其他请求处理方法(如 handle_openai_chathandle_openai_responses)用来统一记录请求数据的函数。

相关代码位置:

  • 文件: /home/montarius/.local/share/uv/tools/headroom-ai/lib/python3.11/site-packages/headroom/proxy/handlers/openai.py
  • 方法: handle_compress() — 第 7053 行
  • 数据流: _record_request_outcome()RequestOutcomeMetrics(Prometheus/SavingsTracker/CostTracker)+ RequestLogger(Dashboard 数据源)

修复方案

handle_compress() 成功压缩后,构造 RequestOutcome 并调用 self._record_request_outcome()

修改内容

handle_compress() 中,于 result = await self._run_compression_in_executor(...) 成功返回后,在 return JSONResponse 之前添加如下代码:

python
from headroom.proxy.outcome import RequestOutcome
from headroom.proxy.helpers import compute_turn_id
 
tokens_before = result.tokens_before
tokens_after = result.tokens_after
tokens_saved = tokens_before - tokens_after
compression_ratio = (
    tokens_after / tokens_before
    if tokens_before > 0
    else 1.0
)
 
await self._record_request_outcome(
    RequestOutcome(
        request_id=await self._next_request_id(),
        provider="headroom",
        model=model,
        original_tokens=tokens_before,
        optimized_tokens=tokens_after,
        output_tokens=0,
        tokens_saved=tokens_saved,
        attempted_input_tokens=tokens_before,
        total_latency_ms=0.0,
        overhead_ms=0.0,
        transforms_applied=tuple(result.transforms_applied),
        num_messages=len(messages),
        turn_id=compute_turn_id(model, None, messages),
        tags=extract_tags(dict(request.headers)),
        client="compress",
    )
)

注意: 变量 tokens_beforetokens_aftertokens_savedcompression_ratio 在修改前是内联在 JSONResponse 字典字面量中的。为了在 _record_request_outcome 中也能使用它们,提取为局部变量后再传入 JSONResponse

关键参数说明

参数说明
provider"headroom"专有 provider 标识,区别于 openai/anthropic
client"compress"Dashboard 中显示请求来源
attempted_input_tokenstokens_before用于计算 active_savings_percent
total_latency_ms / overhead_ms0.0compress 不涉及上游调用,无此维度

文件修改

只修改了一个文件:

text
/home/montarius/.local/share/uv/tools/headroom-ai/lib/python3.11/site-packages/headroom/proxy/handlers/openai.py

验证结果

修复前

text
$ curl http://127.0.0.1:8787/stats
request_logs: 0 条
summary.compression.requests_compressed: 0
tokens.proxy_compression_saved: 0

修复后

text
request_logs: 2 条(comrpess 请求)
summary.compression.requests_compressed: 1
tokens.proxy_compression_saved: 1
tokens.saved: 1

Dashboard 页面现在可以正确显示 compress 请求的记录,包括:

  • Provider(headroom)
  • Model(如 claude-sonnet-4-6、gpt-4o)
  • 压缩前后的 token 数
  • Token saved
  • 应用的 transforms(如 router:protected:system_messagerouter:text:0.95

备注

  • 修复后需要重启 Headroom proxy 才能生效
  • 如果后续 /v1/compress 的 bypass/x-headroom-bypass 分支也想记录,可以考虑增加同理的 _record_request_outcome 调用(当前仅在成功压缩后记录)
  • 压缩失败/timeout(503)的分支暂未添加记录,因其不产生有效的压缩数据