 到 withHeadroom 的 LLM 上下文压缩全链路)
Headroom TypeScript SDK 实战指南从 compress() 到 withHeadroom 的 LLM 上下文压缩全链路【免费下载链接】headroomCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.项目地址: https://gitcode.com/GitHub_Trending/head/headroom本篇指南基于 Headroom 仓库中的 TypeScript SDK 示例目录 sdk/typescript/examples 编写。它完整覆盖了 12 个可运行示例如何用compress()压缩任意消息格式、用simulate()做不消耗 LLM 调用的干跑分析、用CompressionHooks定制压缩策略、用SharedContext实现多 Agent 间低开销交接、用 CCR 无损取回被压缩的原始内容以及如何通过withHeadroom/headroomMiddleware把压缩透明地接入 Vercel AI SDK 与原生 OpenAI / Anthropic SDK。读完后你可以直接复制示例代码在本地跑通工具输出 → 压缩 → 送 LLM的完整闭环并理解每个 API 背后调用 Headroom 代理proxy的具体 HTTP 端点与默认行为。环境准备与运行方式SDK 示例的运行前提来自 sdk/typescript/examples/README.mdNode.js 18与 sdk/typescript/package.json 中engines: { node: 18.0.0 }一致一个正在运行的 Headroom 代理pip install headroom-ai[proxy] headroom proxy环境变量OPENAI_API_KEY多数示例使用 OpenAI可选ANTHROPIC_API_KEYAnthropic 示例需要统一运行方式cd sdk/typescript npm install npx tsx examples/filename.tsSDK 包名为headroom-ai当前版本 0.37.0Apache-2.0 许可提供 5 个入口见 sdk/typescript/package.json 的exports字段入口用途headroom-ai核心 APIcompress、simulate、HeadroomClient、SharedContext、CompressionHooks等headroom-ai/vercel-aiVercel AI SDK 适配器withHeadroom、headroomMiddlewareheadroom-ai/openai原生 OpenAI SDK 适配器withHeadroomheadroom-ai/anthropic原生 Anthropic SDK 适配器withHeadroomheadroom-ai/geminiGemini 适配器peer 依赖均为可选openai 4.0.0、anthropic-ai/sdk 0.30.0、ai 6.0.0、ai-sdk/provider 1.0.0只使用其中一条集成路径时只需安装对应包。示例总览三条集成路径sdk/typescript/examples/README.md 将 12 个示例分为三组正好对应三种集成深度1. Vercel AI SDK一行代码接入示例说明with-headroom-vercel.ts一行withHeadroom(openai(gpt-4o))—— 最简单的集成streaming-chat.tswithHeadroomstreamText实时流式输出tool-calling-agent.ts带工具的多步 Agent每步上下文自动压缩structured-output.ts从压缩后的上下文中用Output.object()提取结构化数据middleware-composition.ts将headroomMiddleware与其他中间件extractReasoningMiddleware叠加multi-provider.ts同一份压缩逻辑同时用于 GPT-4o 与 GPT-4o-mini2. Core SDK直接调用压缩 API示例说明basic-compress.tscompress()—— 先压缩、再发给任意 LLMsimulation-dry-run.tssimulate()—— 不调用 LLM 就能预演压缩效果hooks-custom-compression.tsCompressionHooks—— 前置/后置钩子与逐消息偏置shared-context-multi-agent.tsSharedContext—— Agent 间压缩交接示例注释称可省 70-90% tokenccr-retrieve.tsCCR —— 压缩后按需取回原始内容无损3. Native SDK Adapters不依赖 Vercel AI SDK示例说明openai-anthropic-adapters.ts原生 OpenAI 与 Anthropic SDK 的withHeadroom无需 Vercel AI SDK以下按先核心 API、再框架适配器的顺序逐个展开。Core SDK 基础compress() 压缩任意格式消息basic-compress.ts 演示了最直接的用法构造一段包含大工具输出的对话80 条服务器状态记录的 JSON先调用compress()再把压缩后的消息交给 Vercel AI SDK 发送import { compress } from headroom-ai; import { openai } from ai-sdk/openai; import { generateText } from ai; // 模拟大工具输出 —— 80 条服务器状态记录 const serverFleet Array.from({ length: 80 }, (_, i) ({ id: i 1, hostname: web-${String(i 1).padStart(3, 0)}.prod.internal, status: i 42 ? critical : i % 15 0 ? warning : healthy, cpu_percent: Math.round(Math.random() * 100), memory_mb: Math.round(Math.random() * 16384), region: [us-east-1, eu-west-1, ap-southeast-1][i % 3], last_heartbeat: 2025-06-15T10:30:00Z, uptime_hours: Math.floor(Math.random() * 8760), active_connections: Math.floor(Math.random() * 1000), })); const messages [ { role: system as const, content: You are a DevOps assistant. Analyze infrastructure data and report issues concisely. }, { role: user as const, content: Show me all servers }, { role: assistant as const, content: null, tool_calls: [ { id: call_1, type: function as const, function: { name: list_servers, arguments: {} } }, ], }, { role: tool as const, content: JSON.stringify(serverFleet), tool_call_id: call_1 }, { role: user as const, content: Which servers need attention? Be specific. }, ]; async function main() { // 压缩对话 const result await compress(messages, { model: gpt-4o }); console.log(Tokens: ${result.tokensBefore} → ${result.tokensAfter}); console.log(Saved: ${result.tokensSaved} tokens (${((1 - result.compressionRatio) * 100).toFixed(0)}%)); console.log(Transforms: ${result.transformsApplied.join(, )}); // 把压缩后的消息交给 Vercel AI SDK const { text } await generateText({ model: openai(gpt-4o), messages: result.messages, }); console.log(\nAssistant:, text); } main().catch(console.error);compress()的返回值CompressResult包含以下字段由 sdk/typescript/src/client.ts 的_doCompress组装字段含义messages压缩后的消息数组与输入同格式tokensBefore/tokensAfter压缩前/后的 token 数tokensSaved节省的 token 数compressionRatio压缩比after/before越小压得越狠transformsApplied实际应用的转换策略名称列表ccrHashesCCR 存储句柄可用于后续取回原文compressed是否实际发生了压缩从源码看compress()sdk/typescript/src/compress.ts的关键流程是执行preCompress钩子若提供 hooks允许在压缩前改写消息detectFormat()自动识别输入格式OpenAI / Anthropic / Vercel AI SDK / Gemini再经toOpenAI()统一转为 OpenAI 格式——源码注释称 OpenAI 格式是代理的通用语the proxys lingua franca计算computeBiases逐消息压缩偏置调用HeadroomClient.compress()发送POST /v1/compressfromOpenAI()把结果转回输入原格式再触发postCompress钩子。这个进来什么格式、出去什么格式的设计意味着即使你手里是 Anthropic 风格的tool_result块或 Vercel 的toolInvocations也能直接传入而无需手工转换。压缩失败时的降级行为HeadroomClient.compress()的重试与降级策略值得注意sdk/typescript/src/client.ts默认retries 1即最多 2 次尝试timeout 30sbaseUrl默认http://localhost:8787可用环境变量HEADROOM_BASE_URL/HEADROOM_API_KEY覆盖认证错误HeadroomAuthError和 500 以下的压缩错误会立即抛出不重试重试耗尽后若fallback默认true则原样返回未压缩消息并置compressed: false保证你的 LLM 调用不因代理故障而中断若显式关闭 fallback则抛出HeadroomConnectionError。这个 fail-open 语义对生产集成很重要代理挂掉时上下文退化回不压缩而不是整条链路报错。simulate()不调用 LLM 的压缩干跑simulation-dry-run.ts 演示simulate()只做压缩模拟不产生任何 LLM 调用适合调试压缩行为与估算成本import { simulate } from headroom-ai; // ……构造 100 条支付网关日志其中第 67 条为 FATAL后 const sim await simulate(messages, { model: gpt-4o }); console.log(Tokens before: ${sim.tokensBefore}); console.log(Tokens after: ${sim.tokensAfter}); console.log(Tokens saved: ${sim.tokensSaved}); console.log(Estimated savings: ${sim.estimatedSavings}); console.log(Transforms applied: ${sim.transforms?.join(, ) || none}); if (sim.wasteSignals Object.keys(sim.wasteSignals).length 0) { console.log(Waste signals detected:); for (const [signal, tokens] of Object.entries(sim.wasteSignals)) { if (tokens 0) console.log( ${signal}: ${tokens} tokens); } } console.log(Cache alignment score: ${sim.cacheAlignmentScore}); console.log(Stable prefix hash: ${sim.stablePrefixHash || none});从实现看sdk/typescript/src/client.tssimulate()并不是另一套管线而是向POST /v1/compress发送一个特殊请求体const body { messages: params.messages, model: params.model, config: { default_mode: simulate, generate_diff_artifact: true }, };即通过config.default_mode: simulate让代理走模拟模式并生成 diff 工件响应经deepCamelCase转为驼峰命名后返回。示例中展示的SimulationResult字段包括wasteSignals按浪费信号类型统计的可压缩 token、blockBreakdown按块类型的分布、cacheAlignmentScore缓存前缀对齐得分与stablePrefixHash稳定前缀哈希——最后两者用于评估压缩是否破坏了前缀缓存的稳定性。chat.completions.simulate()与messages.simulate()两个子客户端方法走的是同一条路径。CompressionHooks定制压缩与可观测性hooks-custom-compression.ts 展示了CompressionHooks的三个扩展点示例用其做压缩可观测性import { compress, CompressionHooks } from headroom-ai; import type { CompressContext, CompressEvent } from headroom-ai; const stats { calls: 0, totalSaved: 0, transforms: new Mapstring, number() }; class ObservabilityHooks extends CompressionHooks { // 1. 压缩前注入提示、改写消息 preCompress(messages: any[], ctx: CompressContext) { console.log([hook] Pre-compress: ${messages.length} messages, model${ctx.model}); console.log([hook] User query: ${ctx.userQuery.slice(0, 60)}...); console.log([hook] Tool calls in context: ${ctx.toolCalls.join(, ) || none}); return messages; } // 2. 设置逐消息压缩偏置越大越保留越小压得越狠 computeBiases(messages: any[], _ctx: CompressContext) { const biases: Recordnumber, number {}; for (let i 0; i messages.length; i) { if (messages[i].role system) biases[i] 2.0; // 系统消息完整保留 if (i messages.length - 1 messages[i].role user) { biases[i] 1.5; // 最后一条用户消息多保留 } } return biases; } // 3. 压缩后记录统计 postCompress(event: CompressEvent) { stats.calls; stats.totalSaved event.tokensSaved; for (const t of event.transformsApplied) { stats.transforms.set(t, (stats.transforms.get(t) ?? 0) 1); } if (event.ccrHashes.length 0) { console.log([hook] CCR hashes (retrievable): ${event.ccrHashes.join(, )}); } } } // 使用时把 hooks 传入 compress() const result1 await compress(messages, { model: gpt-4o, hooks });对照 sdk/typescript/src/compress.ts 可以看到钩子的确切调用时机CompressContextpreCompress的第二个参数自动携带model、userQuery经extractUserQuery提取、turnNumbercountTurns统计、toolCallsextractToolCalls提取——示例中的日志正是直接消费这些字段computeBiases在消息被转为 OpenAI 格式之后执行所以返回的偏置 key 是 OpenAI 格式消息的索引postCompress收到CompressEvent包含tokensBefore/tokensAfter/tokensSaved/compressionRatio/transformsApplied/ccrHashes与CompressResult的度量字段一一对应因此可以在每次压缩后做跨调用累计统计示例末尾输出了stats中的总调用数、总节省 token 与各 transform 出现频次。该行为的测试覆盖见 sdk/typescript/test/hooks.test.ts 与 sdk/typescript/test/integration.test.ts。SharedContext多 Agent 间的压缩交接shared-context-multi-agent.ts 演示 Agent A研究员把大段结构化研究结果存入SharedContextAgent B写作者只读压缩版并据此写作——示例注释称跨 Agent 通信可省 70-90% tokenimport { SharedContext } from headroom-ai; import { withHeadroom } from headroom-ai/vercel-ai; import { openai } from ai-sdk/openai; import { generateText } from ai; const ctx new SharedContext({ model: gpt-4o, maxEntries: 50 }); const model withHeadroom(openai(gpt-4o)); // Agent A存入压缩后的研究输出 const entry await ctx.put(k8s-scaling-research, JSON.stringify(researchOutput), { agent: researcher, }); console.log(Stored: ${entry.originalTokens} tokens → ${entry.compressedTokens} tokens); console.log(Savings: ${entry.savingsPercent.toFixed(0)}%); console.log(Transforms: ${entry.transforms.join(, )}); // Agent B只读压缩上下文 const compressed ctx.get(k8s-scaling-research); const { text } await generateText({ model, messages: [ { role: system, content: You are a technical writer. Create a concise blog post outline from research data. }, { role: user, content: Based on this research, create a blog post outline:\n\n${compressed} }, ], }); // 统计 const stats ctx.stats(); console.log(Entries: ${stats.entries}); console.log(Total saved: ${stats.totalTokensSaved} (${stats.savingsPercent.toFixed(0)}%));用法要点put(key, value, meta)返回ContextEntry含originalTokens、compressedTokens、savingsPercent、transformsget(key)同步返回压缩后的字符串stats()返回SharedContextStatsentries、totalOriginalTokens、totalCompressedTokens、totalTokensSaved、savingsPercent。构造参数支持model与maxEntries条目上限示例取 50。SharedContext由 sdk/typescript/src/shared-context.ts 实现并在 sdk/typescript/src/index.ts 中导出配套测试见 sdk/typescript/test/shared-context.test.ts。CCR压缩但不丢弃随时无损取回ccr-retrieve.ts 演示 CCRCompress-Cache-Retrieve语义压缩是激进的但原文被存储当 LLM 需要完整细节时用哈希取回什么都不会被丢弃import { HeadroomClient } from headroom-ai; const client new HeadroomClient(); // 压缩一份 200 条的审计日志其中混入未授权访问等异常记录 const result await client.compress(messages, { model: gpt-4o }); console.log(Compressed: ${result.tokensBefore} → ${result.tokensAfter} tokens); console.log(CCR hashes: ${result.ccrHashes.length}); if (result.ccrHashes.length 0) { // 按哈希取回原文 for (const hash of result.ccrHashes) { try { const original await client.retrieve(hash); console.log(Hash ${hash}:); console.log( Original tokens: ${(original as any).originalTokens}); console.log( Tool: ${(original as any).toolName}); console.log( Retrievals: ${(original as any).retrievalCount}); } catch (e: any) { console.log( Could not retrieve ${hash}: ${e.message}); } } // 在压缩内容内做关键词搜索 const search await client.retrieve(result.ccrHashes[0], { query: unauthorized access, }); console.log(Search results:, JSON.stringify(search, null, 2).slice(0, 300)); }底层端点sdk/typescript/src/client.tsclient.retrieve(hash, { query? })→POST /v1/retrievebody 为{ hash, query? }。不带query时取回完整原文返回RetrieveResult示例展示了originalTokens、toolName、retrievalCount字段带query时做内容内搜索返回RetrieveSearchResultclient.getCCRStats()→GET /v1/retrieve/stats查询 CCR 存储统计client.handleToolCall({ toolCall, provider })→POST /v1/retrieve/tool_call用于承接 LLM 侧发起的headroom_retrieve工具调用。这条链路的意义在于compress()/withHeadroom返回的ccrHashes把压缩掉的细节变成了可寻址资源Agent 在发现压缩版信息不够时可以主动取回而不必重新执行产生该输出的工具。Vercel AI SDK 集成withHeadroom 一行接入最简集成with-headroom-vercel.ts 展示零配置路径——把openai(gpt-4o)包一层压缩在每次调用前自动发生import { withHeadroom } from headroom-ai/vercel-ai; import { openai } from ai-sdk/openai; import { generateText } from ai; async function main() { // 一行包上模型压缩自动完成 const model withHeadroom(openai(gpt-4o)); const { text, usage } await generateText({ model, messages: [ { role: system, content: You are a research assistant. Summarize search results concisely. }, { role: user, content: Search for microservices best practices }, { role: assistant, content: null, toolInvocations: [] }, { role: tool, content: [ { type: tool-result, toolCallId: call_search, toolName: web_search, result: searchResults, // 50 条搜索结果的大 JSON }, ], }, { role: user, content: What are the top 3 most relevant results and why? }, ], }); console.log(Response:, text); console.log(Tokens used:, usage); }流式输出streaming-chat.ts 说明压缩发生在流开始之前先把大 diff示例生成 15 个文件 × 20 行的 PR diff压缩LLM 看到更少的 token然后streamText的textStream照常逐块输出const model withHeadroom(openai(gpt-4o)); const result streamText({ model, messages: codeReviewMessages }); process.stdout.write(Review: ); for await (const chunk of result.textStream) { process.stdout.write(chunk); }多步工具调用 Agenttool-calling-agent.ts 是压缩价值最直接的场景Agent 循环调用query_logs/query_users两个工具每一步工具返回的大结果200 条日志、100 条用户都在下一次 LLM 调用前被压缩防止上下文在多步间持续膨胀const model withHeadroom(openai(gpt-4o)); const { text, steps } await generateText({ model, stopWhen: stepCountIs(5), messages: [ { role: system, content: You are a database admin assistant. Use the available tools to investigate issues. Report findings concisely. }, { role: user, content: Check the logs for any critical errors, then find which users are affected. }, ], tools: { query_logs: tool({ description: Query application logs. Returns matching log entries., parameters: z.object({ level: z.string().optional().describe(Filter by log level: INFO, WARN, ERROR, FATAL), service: z.string().optional().describe(Filter by service name), limit: z.number().optional().describe(Max results to return), }), execute: async ({ level, service, limit }) { /* 过滤 mockDB.logs */ }, }), query_users: tool({ /* 同上过滤 mockDB.users */ }), }, });stopWhen: stepCountIs(5)限制最多 5 步由于withHeadroom包装的是模型对象多步循环里每一步的generateText内部调用都自动经过压缩无需手写任何压缩逻辑。结构化输出structured-output.ts 验证压缩后仍可准确提取150 条日志其中第 73、89 条是关键故障信号熔断器打开、重试耗尽先经压缩再用Output.object()按 Zod schema 提取结构化事故报告const IncidentReport z.object({ severity: z.enum([critical, high, medium, low]), title: z.string().describe(Short incident title), rootCause: z.string().describe(Root cause analysis), affectedServices: z.array(z.string()), affectedEndpoints: z.array(z.string()), timeline: z.array(z.object({ time: z.string(), event: z.string() })), impact: z.string().describe(Customer/business impact), suggestedFix: z.string(), }); const { output: report } await generateText({ model, output: Output.object({ schema: IncidentReport }), messages: [ { role: system, content: You are an SRE incident commander. Analyze logs and produce structured incident reports. }, { role: user, content: Analyze these production logs and create an incident report:\n\n${JSON.stringify(incidentLogs)} }, ], });示例开头会打印输入规模150 log entries (N chars)便于对比压缩前后的 token 消耗与提取质量。中间件组合middleware-composition.ts 展示headroomMiddleware与 Vercel AI SDK 其他中间件的叠加顺序——Headroom 先压缩其他中间件再处理结果import { headroomMiddleware } from headroom-ai/vercel-ai; import { generateText, wrapLanguageModel, extractReasoningMiddleware } from ai; const model wrapLanguageModel({ model: openai(gpt-4o), middleware: [ headroomMiddleware(), // 压缩大上下文 extractReasoningMiddleware({ tagName: think }), // 提取思维链 ], });配合要求模型把推理写在think标签内的系统提示generateText会同时返回reasoning与text两者可分开呈现。多 Provider 一致性multi-provider.ts 用同一份 60 行销售数据分别走withHeadroom(openai(gpt-4o))与withHeadroom(openai(gpt-4o-mini))对比两者的回答与usage.promptTokens / completionTokens——核心信息是withHeadroom与底层 LLM 无关换模型时压缩行为不变因此可以在贵模型 vs 便宜模型之间做成本对比时保证 prompt 侧条件一致。原生 SDK 适配器不装 Vercel AI SDK 也能用openai-anthropic-adapters.ts 面向已直接使用官方 SDK 的项目从两个子入口导入各自的withHeadroomimport { withHeadroom as withHeadroomOpenAI } from headroom-ai/openai; import { withHeadroom as withHeadroomAnthropic } from headroom-ai/anthropic; import OpenAI from openai; import Anthropic from anthropic-ai/sdk; // OpenAI包一层 client调用方式完全不变 if (process.env.OPENAI_API_KEY) { const openai withHeadroomOpenAI(new OpenAI()); const response await openai.chat.completions.create({ model: gpt-4o, messages: [ { role: system, content: You are a technical project manager. Prioritize issues for the sprint. }, ...messages, ], }); } // Anthropic同样透明压缩 if (process.env.ANTHROPIC_API_KEY) { const anthropic withHeadroomAnthropic(new Anthropic()); const response await anthropic.messages.create({ model: claude-sonnet-4-5-20250929, max_tokens: 1024, messages, }); const text response.content .filter((b: any) b.type text) .map((b: any) b.text) .join(); }从源码结构看这类适配器底层就是HeadroomClient的两个 passthrough 子客户端sdk/typescript/src/client.tschat.completions.create()路由到代理的POST /v1/chat/completions并透传Authorization: Bearer OPENAI_API_KEYmessages.create()路由到POST /v1/messages自动带上anthropic-version: 2023-06-01头与x-api-key且max_tokens缺省时代码会补 1024。两者都支持stream: true经parseSSE解析 SSE 流。这些调用还支持HeadroomParams透传压缩控制参数sdk/typescript/src/client.ts参数作用headroomMode压缩模式经x-headroom-mode请求头下发headroomCachePrefixTokens缓存前缀 token 控制headroomOutputBufferTokens输出缓冲 tokenheadroomKeepTurns保留轮数headroomToolProfiles按工具名的压缩配置例如client.chat.completions.create({ model, messages, stream: false, headroomMode: ... })即可在不改动业务代码的前提下调整单次请求的压缩策略。客户端与错误体系速查除压缩主链路外HeadroomClient还暴露了一组运维/观测端点供你在集成后验证代理状态sdk/typescript/src/client.ts方法端点用途health()GET /health代理是否存活validateSetup()基于它proxyStats()GET /stats综合统计总请求、压缩前/后 token、节省百分比、按模型分布prometheusMetrics()GET /metricsPrometheus 格式指标statsHistory(query?)GET /stats-history历史统计序列memoryUsage()GET /debug/memory代理内存占用clearCache()POST /cache/clear清空响应缓存getMetrics/getSummary/getStatsGET /stats请求级指标、聚合摘要、会话统计telemetry.*/feedback.*/toin.*/v1/telemetry/*、/v1/feedback/*、/v1/toin/*遥测、工具反馈提示、TOIN 模式统计错误处理方面sdk/typescript/src/errors.ts 提供完整异常层次HeadroomError为基类细分HeadroomConnectionError连不上代理、HeadroomAuthError认证失败不重试、HeadroomCompressError压缩失败携带statusCode等mapProxyError()负责把代理返回的 HTTP 错误体映射到对应异常类型。所有类型与工具函数均从 sdk/typescript/src/index.ts 统一导出包括detectFormat/toOpenAI/fromOpenAI格式转换、parseSSE/collectStream流处理、deepCamelCase/deepSnakeCase命名转换等方便你在自定义集成中复用。小结如何选择示例路径只想省 token、改动最少Vercel AI SDK 项目用withHeadroom(model)一行接入with-headroom-vercel.ts已用官方 SDK 的换 openai-anthropic-adapters.ts 的 client 包装。自己管理压缩时机调compress()拿到CompressResult把messages交给任意 LLMbasic-compress.ts并用ccrHashes保留取回原文的能力ccr-retrieve.ts。上线前评估与调优先用simulate()干跑看wasteSignals与缓存对齐得分simulation-dry-run.ts再用CompressionHooks注入逐消息偏置、累计压缩统计hooks-custom-compression.ts。多 Agent 协作用SharedContext做 Agent 间压缩交接shared-context-multi-agent.ts。所有示例均位于 sdk/typescript/examples对应的单元测试与端到端测试位于 sdk/typescript/test如 hooks.test.ts、shared-context.test.ts、vercel-ai-e2e.test.ts在sdk/typescript目录下执行npm test即可验证 SDK 行为。【免费下载链接】headroomCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.项目地址: https://gitcode.com/GitHub_Trending/head/headroom创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考