Adaptive Token Compressor — Guide#
This guide covers single-compressor metrics collection, multi-compressor usage, compressor principles and workflow, configuration reference, available metrics, testing, FAQ, and resources. For installation and a single-compressor quick start, see the README.
Single-Compressor Metrics Collection with CompressionManager#
Metrics collection requires using CompressionManager. Register a single
compressor, attach metrics, and read the aggregated snapshot:
from adaptive_token_compressor import (
CompressionManager,
CompressionContext,
create_compressor,
CompressionRatio,
TotalSaved
)
# Metrics collection requires using CompressionManager
manager = CompressionManager()
# Register compressor first
harness_compressor = manager.register_compressor(
"harness",
create_compressor("harness", lingua_url="http://localhost:8001/compress"),
)
# Then register metrics with names
manager.register_metric("compression_ratio", CompressionRatio(sources="harness"))
manager.register_metric("total_saved", TotalSaved(sources="harness"))
# Compress multiple requests
for i in range(5):
messages = [...] # Different messages each time
ctx = CompressionContext(messages=messages)
result = harness_compressor.compress(ctx)
# View aggregated metrics (returns dict with all registered metric names)
stats = manager.snapshot()
print(f"Compression ratio: {stats['compression_ratio']:.2%}")
print(f"Total saved: {stats['total_saved']} tokens")
Multi-Compressor Usage with CompressionManager#
Metrics support both per-source tracking (single source string) and cross-compressor aggregation (list of sources). Cross-compressor metrics let you track combined statistics — e.g. average duration per request across the harness and tool compressors together.
from adaptive_token_compressor import (
CompressionManager,
CompressionContext,
create_compressor,
TotalSaved,
AvgDurationPerRequest,
)
# Initialize manager
manager = CompressionManager()
# Register compressors first
harness_compressor = manager.register_compressor(
"harness",
create_compressor("harness", lingua_url="http://localhost:8001/compress"),
)
tool_compressor = manager.register_compressor(
"tool",
create_compressor(
"tool",
predictor_url="http://localhost:8000/v1/chat/completions",
),
)
# Register one per-source metric plus two aggregate metrics
manager.register_metric(
"harness_saved",
TotalSaved(sources="harness")
)
manager.register_metric(
"total_saved_all",
TotalSaved(sources=["harness", "tool"])
)
manager.register_metric(
"avg_dur_per_request_all",
AvgDurationPerRequest(sources=["harness", "tool"])
)
# Process multiple requests
for i in range(10):
messages = [...] # Different messages each time
tools = [...] # Full tool list
# IMPORTANT: use the SAME req_id for all compressors in one request so
# request_count() counts unique requests, not per-compressor calls. This
# makes avg_dur_per_request_all = total duration / number of requests.
req_id = f"req-{i}"
ctx = CompressionContext(messages=messages, tools=tools)
# Compress tools
result = tool_compressor.compress(ctx, req_id=req_id)
ctx = CompressionContext(messages=result.messages, tools=result.tools)
# Compress messages
result = harness_compressor.compress(ctx, req_id=req_id)
# Use result.messages and result.tools for LLM inference
# View aggregated metrics (snapshot returns all registered metrics)
stats = manager.snapshot()
print(f" Harness saved: {stats['harness_saved']} tokens")
print(f" Total saved (all): {stats['total_saved_all']} tokens")
print(f" Avg duration per request (all): {stats['avg_dur_per_request_all']:.1f} ms")
Note on PerRequest metrics (
AvgDurationPerRequest,AvgSavedPerRequest, etc.): these divide by the number of unique requests. You must either passreq_idtocompressor.compress(ctx, req_id=...)(as above), or callmanager.set_per_anchor("<source>")to use one compressor’s call count as the request denominator. Without either,manager.snapshot()raises aRuntimeError(the denominator is checked at snapshot time, not at registration).
Compressor Principles#
This section explains how each compressor works conceptually and what the runtime pipeline looks like.

HarnessCompressor#
Principle
HarnessCompressor focuses on conversation-message compression for the prompt assembly stage. It combines lightweight rules (message slicing / role-aware handling) with Lingua-based lossy compression for long text blocks, reducing token cost while preserving instruction-critical content.

ToolCompressor#
Principle
ToolCompressor reduces tool-schema prompt cost by selecting only likely-needed tools for the current request. It uses an external predictor LLM to score tool relevance from conversation context, then keeps high-value tools only. The ToolCompressor supports configurable tool-injection placements to flexibly trade off token savings against prefix-cache hit rate.

Configuration Reference#
Lingua Server Configuration#
Lingua server uses the llmlingua2 (LLMLingua-2) compression mode.
Docker Compose Environment Variables#
Parameter |
Default |
Allowed / Notes |
|---|---|---|
|
|
|
|
|
|
|
|
Used when |
|
|
Compression mode: |
|
empty |
Optional fixed model id. Empty -> mode default |
|
|
Host port mapping for |
|
|
Host port mapping for |
|
|
Bind address for the container service |
Default model when LINGUA_MODEL_NAME_ID is empty:
llmlingua2->microsoft/llmlingua-2-bert-base-multilingual-cased-meetingbank
HarnessCompressor Configuration#
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
str |
|
Compression profile (sectioning strategy) |
|
str |
|
Lingua server URL |
|
float |
|
Target compression rate (0.0-1.0) |
|
int |
|
Minimum chars to trigger compression |
|
float |
|
Backend request timeout (seconds) |
|
bool |
|
Enable Claw Compactor QuantumLock stabilization |
Example:
from adaptive_token_compressor.harness import HarnessCompressor
compressor = HarnessCompressor(
profile="openclaw",
lingua_url="http://localhost:8001/compress",
compress_rate=0.5,
compress_min_chars=500,
timeout=60.0
)
ToolCompressor Configuration#
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
str |
Required |
Tool predictor LLM endpoint (e.g., vLLM |
|
str |
|
Model used by predictor |
|
float |
|
Minimum score for tool selection |
|
int |
|
Predictor request timeout (seconds) |
|
Literal |
|
|
|
Literal |
|
|
|
Literal |
|
Where the predicted tool schema is placed. See Placement modes below. |
|
bool |
|
Union the predicted tool set per conversation (append-only, never removed/reordered) so each turn’s tool block is a strict prefix-extension of the previous turn’s — keeping the prefix cache stable while still admitting tools that only emerge in later turns. Required by |
Placement modes:
"schema"(default, production): predicted subset returned inresult.tools, rendered inside the system message’s<tools>block by the chat template."user_inline_delta": tools appended as a trailing synthetic user message. The carrier is persisted per-conversation and re-spliced at a fixed offset each turn (prefix-cache stable), but delta-only — appends a carrier only when new tools appear, carrying just the delta over the running union. Requires accumulate=True.
Note:
schema+accumulate=True: reduces tool-schema tokens while keeping the prefix-cache hit rate from dropping significantly.user_inline_delta+accumulate=True: reduces tokens while further improving the prefix-cache hit rate (still lower than baseline). This depends on the tool-predictor model’s own capability; verified to run stably on Qwen3.5-35B.
Example:
from adaptive_token_compressor.tool import ToolCompressor
compressor = ToolCompressor(
predictor_url="http://localhost:8000/v1/chat/completions",
predictor_model="Qwen/Qwen3.6-35B-A3B",
score_threshold=3.0,
timeout=120,
prompt_mode="dynamic",
tool_descriptions_mode="dynamic",
placement="schema"
)
Available Metrics#
The library provides 15 metric types for tracking compression performance. Most metrics require a sources parameter specifying which compressor(s) to track (e.g., "harness", "tool", or ["harness", "tool"]). The exception is RequestCount, which is source-agnostic.
First-Order Metrics (Direct Aggregation)#
Metric |
Description |
Formula |
|---|---|---|
|
Total number of compression calls |
Sum of all calls |
|
Total input tokens |
Sum of |
|
Total output tokens |
Sum of |
|
Total tokens saved |
Sum of |
|
Total compression time |
Sum of |
Example:
manager.register_metric("total_calls", CallCount(sources="harness"))
manager.register_metric("total_saved", TotalSaved(sources=["harness", "tool"]))
Second-Order Metrics (Per-Call Averages)#
Metric |
Description |
Formula |
|---|---|---|
|
Compression ratio (lower = better) |
|
|
Average tokens saved per call |
|
|
Average duration per call |
|
|
Average input tokens per call |
|
|
Average output tokens per call |
|
Example:
manager.register_metric("ratio", CompressionRatio(sources="harness"))
manager.register_metric("avg_saved", AvgSavedPerCall(sources="tool"))
Third-Order Metrics (Per-Request Averages)#
These require passing req_id to compress() or using manager.set_per_anchor().
Metric |
Description |
Formula |
|---|---|---|
|
Average tokens saved per request |
|
|
Average duration per request |
|
|
Average input tokens per request |
|
|
Average output tokens per request |
|
|
Number of unique requests (source-agnostic) |
|
Note:
RequestCountis the only metric without asourcesparameter — it counts requests across the whole manager, not per-compressor calls. Construct it with no arguments:RequestCount().
Example:
manager.register_metric("avg_per_req", AvgSavedPerRequest(sources="harness"))
manager.register_metric("request_count", RequestCount()) # no sources arg
# Option 1: Pass req_id explicitly
harness_compressor.compress(ctx, req_id="request-123")
# Option 2: Use anchor fallback
manager.set_per_anchor("harness")
Testing#
# Run all tests
pytest
# Specific module
pytest tests/core/test_metrics.py
# With coverage
pytest --cov=adaptive_token_compressor