Headroom TypeScript SDK 实战:headroom-ai 在 Node.js 中压缩 LLM 上下文,跨 OpenAI / Anthropic / Vercel AI / Gemini 的接入方式
本文以 sdk/typescript 目录下的 TypeScript SDK(npm 包 headroom-ai)为主线,完整讲解它的安装与快速上手、compress() 的格式自动检测与七步压缩管线、四大框架适配器(OpenAI / Anthropic / Vercel AI SDK / Gemini)的拦截实现、HeadroomClient 的透传与 CCR 检索、dry-run 模拟、压缩 Hooks、多智能体 SharedContext、可观测性与配置类型。读完后,你可以在不改动业务调用逻辑的前提下,让任何 JavaScript/TypeScript LLM 应用在请求发出前先经过 Headroom 代理压缩上下文,并通过源码路径追踪每个行为的实际实现。
一、定位与架构:客户端只做转换与路由,压缩在代理侧完成
Headroom 项目的核心能力是“在工具输出、日志、文件、RAG 分块到达 LLM 之前压缩它们”,提供 Library、Proxy、MCP Server 三种形态。TypeScript SDK 是其中的客户端库:它本身不做压缩算法,而是把消息转换为 OpenAI 格式后发给本地运行的 Headroom 代理(默认 http://localhost:8787,由 headroom proxy 启动),再拿回同格式的压缩结果。
从源码结构看,整个 SDK 的职责划分非常清晰(见 入口导出):
compress()/HeadroomClient/simulate():核心压缩 API(compress.ts、client.ts、simulate.ts);adapters/:四个框架适配器的withHeadroom包装(openai.ts、anthropic.ts、vercel-ai.ts、gemini.ts);utils/format.ts:四种消息格式的结构化检测与互转;utils/case.ts/utils/stream.ts:snake_case ↔ camelCase 深度转换、SSE 流解析;hooks.ts/shared-context.ts/errors.ts:压缩钩子、多智能体共享上下文、错误层级。
package.json 中 exports 字段定义了五个子路径:根入口 headroom-ai,以及 headroom-ai/vercel-ai、headroom-ai/openai、headroom-ai/anthropic、headroom-ai/gemini 四个适配器入口,同时声明 node >= 18,并对 openai、@anthropic-ai/sdk、ai、@ai-sdk/provider 使用 optional peerDependencies——即只需要安装你实际用到的 SDK。
安装
npm install headroom-ai
前提条件:需要一个正在运行的 Headroom 代理进程(headroom proxy)。SDK 所有压缩能力都依赖该代理;若代理不可达,默认会触发 fallback 行为(见第四节)。
快速开始
import { compress } from 'headroom-ai';
const result = await compress(messages, { model: 'gpt-4o' });
console.log(`Saved ${result.tokensSaved} tokens (${((1 - result.compressionRatio) * 100).toFixed(0)}%)`);
// Use compressed messages with any LLM client
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: result.messages,
});
CompressResult 的完整字段在 types.ts 中定义:messages(与输入同格式的压缩后消息)、tokensBefore、tokensAfter、tokensSaved、compressionRatio、transformsApplied(实际应用的变换列表)、ccrHashes(CCR 存储句柄)、compressed(是否真正发生压缩)。
compress() 的七步管线
compress() 接受任意格式消息,其完整流程在 compress.ts 中一目了然,值得逐步拆解,因为它决定了 SDK “同格式进、同格式出”的语义:
- preCompress 钩子:若传入了
hooks,先调用hooks.preCompress(messages, ctx),允许在压缩前改写消息。钩子上下文CompressContext自动携带model、userQuery(最后一条 user 消息文本)、turnNumber(user 消息计数)、toolCalls(从tool_calls、tool_use、tool-call三种结构中抽取的工具名),见 hooks.ts 与三个抽取函数; - 格式检测:
detectFormat()基于结构化标记识别输入是 OpenAI / Anthropic / Vercel / Gemini 哪种格式(第十一节详述); - 统一转 OpenAI 格式:OpenAI 格式是代理的“通用语”,
toOpenAI()对四种格式分别处理; - 计算 biases:
hooks.computeBiases()可返回“消息下标 → 保留偏置”的映射(大于 1 表示更多保留,小于 1 表示更激进压缩); - 代理压缩:复用或新建
HeadroomClient调用POST /v1/compress; - 转回原格式:
fromOpenAI(result.messages, inputFormat)把压缩结果还原为输入格式; - postCompress 钩子:只读事件通知,携带 token 统计与变换列表,不能修改结果。
这个管线保证了:你传入 Anthropic 消息数组,拿回的 result.messages 仍是 Anthropic 格式,可以直接喂给 @anthropic-ai/sdk;传入 Vercel AI SDK 的 ModelMessage[],拿回的仍是 Vercel 格式。
二、框架适配器:withHeadroom 一行接入四种 SDK
四个适配器共同的设计模式是:用 ES Proxy 只拦截产生 LLM 请求的那一个方法,其余方法原样透传。例如 OpenAI 适配器只拦截 client.chat.completions.create,embeddings、images、audio 等全部不受影响(openai.ts)。
Vercel AI SDK
import { withHeadroom } from 'headroom-ai/vercel-ai';
import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const model = withHeadroom(openai('gpt-4o'));
const { text } = await generateText({ model, messages });
withHeadroom(model) 是 wrapLanguageModel + headroomMiddleware 的便捷封装:运行时动态 require("ai") 包,未安装会抛出提示安装 ai 的明确错误(vercel-ai.ts)。若需要更细粒度的控制,可以直接使用中间件:
import { headroomMiddleware } from 'headroom-ai/vercel-ai';
import { wrapLanguageModel } from 'ai';
const model = wrapLanguageModel({
model: openai('gpt-4o'),
middleware: headroomMiddleware({ baseUrl: 'http://localhost:8787' }),
});
headroomMiddleware 返回的 transformParams 会在每次调用前把 Vercel prompt 转成 OpenAI 格式压缩、再转回 Vercel 格式;未压缩成功时原样放行。它对 AI SDK v6 与更早版本都有兼容处理(input/args、output/result 字段差异),见 format.ts 中的 vercelToOpenAI。
OpenAI SDK
import { withHeadroom } from 'headroom-ai/openai';
import OpenAI from 'openai';
const client = withHeadroom(new OpenAI());
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: longConversation,
});
Anthropic SDK
import { withHeadroom } from 'headroom-ai/anthropic';
import Anthropic from '@anthropic-ai/sdk';
const client = withHeadroom(new Anthropic());
const response = await client.messages.create({
model: 'claude-sonnet-4-5-20250929',
messages: longConversation,
max_tokens: 1024,
});
Anthropic 适配器的格式转换细节最有代表性(anthropic.ts):user 消息中的 tool_result 块被拆成独立的 OpenAI tool 消息(tool_use_id → tool_call_id);assistant 消息中的 tool_use 块转成 OpenAI tool_calls(input 序列化进 function.arguments);反向转换时,OpenAI tool 消息再变回 Anthropic 的 user 消息 + tool_result 块。若压缩未发生(result.compressed === false,例如代理下线走了 fallback),则直接发送原始消息,保证格式零损耗。
Google Gemini
import { withHeadroom } from 'headroom-ai/gemini';
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
const model = withHeadroom(genAI.getGenerativeModel({ model: 'gemini-2.0-flash' }));
const result = await model.generateContent({
contents: longConversation,
});
Gemini 适配器同时拦截 generateContent 与 generateContentStream(gemini.ts)。Gemini 的 parts/functionCall/functionResponse 与 role: "model" 标记是格式检测的独有特征(见第十一节)。
适配器共有的行为
每个适配器在调用 compress() 时都会附带一个 stack 标识(如 adapter_ts_openai、adapter_ts_anthropic、adapter_ts_vercel_ai、adapter_ts_gemini),该值作为 X-Headroom-Stack 头随每个请求发出(client.ts),用于在代理侧按集成来源归因统计。所有适配器也完整继承 CompressOptions(baseUrl、apiKey、timeout、fallback、retries、tokenBudget、hooks、stack,定义于 types.ts)。
仓库 sdk/typescript/examples/ 目录提供了对应示例:with-headroom-vercel.ts、openai-anthropic-adapters.ts、tool-calling-agent.ts 等,可直接参照。
三、HeadroomClient:直连代理的完整 HTTP 客户端
HeadroomClient 提供对代理 OpenAI / Anthropic 透传端点以及 metrics、CCR、可观测性端点的直接访问:
import { HeadroomClient } from 'headroom-ai';
const client = new HeadroomClient({
baseUrl: 'http://localhost:8787',
providerApiKey: process.env.OPENAI_API_KEY,
config: {
smartCrusher: { enabled: true, maxItemsAfterCrush: 10 },
ccr: { enabled: true },
},
});
客户端默认值在 client.ts 中定义:baseUrl 缺省 http://localhost:8787(也读 HEADROOM_BASE_URL),timeout 30 秒,retries 1,fallback true。
透传式调用:Chat Completions(OpenAI 风格)
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: longConversation,
headroomMode: 'optimize',
});
从源码看(client.ts),headroomMode 等 headroom* 参数会被从请求体中剥离,headroomMode 通过 x-headroom-mode 请求头传递(取值为 audit / optimize / simulate 之一,见 types/config.ts);providerApiKey 则以 Authorization: Bearer 头携带,缺省时回退读 OPENAI_API_KEY 环境变量。请求打到代理的 POST /v1/chat/completions,代理完成压缩后再转发到真实上游。stream: true 时返回值是 parseSSE 解析后的异步流。此外还支持 headroomCachePrefixTokens、headroomOutputBufferTokens、headroomKeepTurns、headroomToolProfiles 四个细粒度参数(HeadroomParams)。
透传式调用:Messages(Anthropic 风格)
const response = await client.messages.create({
model: 'claude-sonnet-4-5-20250929',
messages: longConversation,
max_tokens: 1024,
headroomMode: 'optimize',
});
对应 POST /v1/messages,自动附加 anthropic-version: 2023-06-01 头;providerApiKey 走 x-api-key 头,缺省回退 ANTHROPIC_API_KEY;未显式给 max_tokens 时默认 1024(client.ts)。client.messages.stream(...) 与 client.chat.completions.simulate(...) 也已内置。
直接压缩
const result = await client.compress(messages, { model: 'gpt-4o', tokenBudget: 4000 });
compress() 走 POST /v1/compress。重试语义在源码中有明确定义(client.ts):
- 401 认证错误不重试,直接抛
HeadroomAuthError; - 状态码小于 500 的压缩错误视为客户端错误,不重试;
- 其余(连接失败、5xx)按
retries次数重试; - 全部失败后,若
fallback: true(默认),返回compressed: false的原始消息结果——代理宕机时业务请求不会中断,只是不省 token;若fallback: false,则抛出对应错误。
tokenBudget 会以 token_budget 字段发给代理,用于“压缩到适配该 token 上限”的场景(上下文压缩/compaction)。
四、Simulation:不花一次 LLM 调用的 dry-run
在决定是否开启压缩、或调整配置前,可以先看“如果压缩会发生什么”:
import { simulate } from 'headroom-ai';
const sim = await simulate(messages, { model: 'gpt-4o' });
console.log(`Would save ${sim.tokensSaved} tokens (${sim.estimatedSavings})`);
console.log('Transforms:', sim.transforms);
console.log('Waste signals:', sim.wasteSignals);
console.log('Cache alignment:', sim.cacheAlignmentScore);
实现上,simulate()(simulate.ts)并不是单独的端点,而是给 POST /v1/compress 注入 config: { default_mode: "simulate", generate_diff_artifact: true }——即以 simulate 模式执行整条压缩管线并生成 diff 工件,但不转发任何 LLM 请求。client.chat.completions.simulate({ model, messages }) 与 client.messages.simulate(...) 是等价的客户端方法。返回的 SimulationResult(含 wasteSignals 浪费信号、transforms、cachePrefixMetrics 等,定义见 types/models.ts)可以直接用于上线前的收益评估与回归对比。
五、Compression Hooks:与 Python 版对齐的压缩定制点
Hooks 用于在压缩前后注入自定义逻辑,与 Python SDK 的 CompressionHooks API 保持对齐:
import { compress, CompressionHooks } from 'headroom-ai';
import type { CompressContext, CompressEvent } from 'headroom-ai';
class MyHooks extends CompressionHooks {
// Modify messages before compression
preCompress(messages: any[], ctx: CompressContext) {
return [{ role: 'system', content: 'Always preserve error details.' }, ...messages];
}
// Set per-message importance biases
computeBiases(messages: any[], ctx: CompressContext) {
return { 0: 2.0 }; // preserve first message
}
// Observe compression results
postCompress(event: CompressEvent) {
console.log(`Saved ${event.tokensSaved} tokens via ${event.transformsApplied.join(', ')}`);
}
}
const result = await compress(messages, { model: 'gpt-4o', hooks: new MyHooks() });
从 hooks.ts 的基类实现看,三个方法都提供了安全的默认实现(preCompress 原样返回、computeBiases 返回空对象、postCompress 空操作),因此你可以只覆盖关心的一个方法。两个接口的语义边界值得注意:
CompressEvent(压缩后事件,hooks.ts)携带tokensBefore/After、tokensSaved、compressionRatio、transformsApplied、ccrHashes、model、userQuery、provider,是只读观测点;CompressContext(压缩前上下文)携带model、userQuery、turnNumber、toolCalls、provider,其中userQuery/turnNumber/toolCalls由 SDK 自动从任意格式的消息中抽取,方便你在computeBiases里按轮次或工具调用写策略。
配套的 Hook 助手函数 extractUserQuery(取最后一条 user 文本)、countTurns(user 消息计数)、extractToolCalls(跨三种格式抽取工具名)也都从包根导出,可独立使用。完整示例见 hooks-custom-compression.ts,行为验证见 hooks.test.ts。
六、SharedContext:多智能体间的压缩式上下文共享
在多 Agent 系统中,Agent A 的长输出常常要交给 Agent B。SharedContext 提供“存入即压缩、读取即省 token”的本地缓存,与 Python 的 SharedContext API 对齐:
import { SharedContext } from 'headroom-ai';
const ctx = new SharedContext({ model: 'gpt-4o', ttl: 3600, maxEntries: 100 });
// Agent A stores data (automatically compressed)
const entry = await ctx.put('research', bigAgentOutput, { agent: 'researcher' });
console.log(`Compressed: ${entry.savingsPercent.toFixed(0)}% savings`);
// Agent B reads it
const summary = ctx.get('research');
// Agent B gets original if needed
const full = ctx.get('research', { full: true });
// Stats
const stats = ctx.stats();
console.log(`${stats.entries} entries, ${stats.totalTokensSaved} tokens saved`);
从 shared-context.ts 的实现看,几个默认值和容错策略值得了解:
- 构造函数参数
model缺省claude-sonnet-4-5-20250929,ttl缺省 3600 秒,maxEntries缺省 100(shared-context.ts); put()把内容包成单条 user 消息调代理压缩,条目中同时保留original与compressed、originalTokens/compressedTokens、所用变换列表与savingsPercent;代理不可用时降级为存原文(token 数按length/4粗估),不会让 Agent 流程失败;- 过期策略双重保障:每次
get/keys/stats都会触发evictExpired(),且put前若已满maxEntries会淘汰最老条目(Map 插入序,shared-context.ts); - 除 README 示例外,还有
getEntry()(取完整元数据)与clear()方法,stats()返回entries、totalOriginalTokens、totalCompressedTokens、totalTokensSaved、savingsPercent。
多 Agent 场景示例见 shared-context-multi-agent.ts。
七、CCR Retrieve:压缩后按需取回原文
CCR(Compress-Cache-Retrieve)是 Headroom 的关键机制:大块内容被压缩进上下文的同时,原文被存入代理侧的 CCR 存储并返回哈希句柄;当 LLM 需要细节时,通过 headroom_retrieve 工具调用取回原文。SDK 端对应的代码:
const result = await client.compress(messages, { model: 'gpt-4o' });
// Later, when the LLM calls headroom_retrieve:
for (const hash of result.ccrHashes) {
const original = await client.retrieve(hash);
console.log(`${original.originalTokens} original tokens for ${original.toolName}`);
}
// Search within compressed content
const search = await client.retrieve('abc123', { query: 'error logs' });
// Handle LLM tool calls in an agent loop
const toolResult = await client.handleToolCall({
toolCall: assistantMessage.tool_calls[0],
provider: 'openai',
});
从 client.ts 看,三条对应链路是:
retrieve(hash, { query })→POST /v1/retrieve,带query时变为在原文内容中搜索;handleToolCall({ toolCall, provider })→POST /v1/retrieve/tool_call,接收 OpenAI 或 Anthropic 两种工具调用结构(发送前自动deepSnakeCase转换),供 Agent 循环里解析模型发起的headroom_retrieve调用;getCCRStats()→GET /v1/retrieve/stats,查看 CCR 存储规模。
HeadroomConfig 中的 ccr 配置块(enabled、storeMaxEntries、storeTtlSeconds、injectRetrievalMarker、injectTool、injectSystemInstructions、markerTemplate 等,types/config.ts)控制代理侧的标记注入与存储策略。端到端示例见 ccr-retrieve.ts。
八、Metrics、Telemetry、Feedback 与 TOIN
SDK 把代理的运维与学习系统也暴露成了方法。Metrics 部分:
// Proxy health
const health = await client.health();
// → { status: 'healthy', version: '...', config: { optimize: true, ... } }
// Proxy stats
const stats = await client.proxyStats();
// → { requests: { total, cached, failed }, tokens: { saved, savingsPercent }, ... }
// Request metrics
const metrics = await client.getMetrics({ model: 'gpt-4o', limit: 10 });
// Summary
const summary = await client.getSummary();
// Validate setup
const validation = await client.validateSetup();
// Clear cache
await client.clearCache();
// Prometheus metrics
const prom = await client.prometheusMetrics();
实现映射(client.ts):health() 与 validateSetup() 都读 GET /health(后者把 status === "healthy" 映射为 valid 并携带代理配置快照);proxyStats() 读 GET /stats;getMetrics() 实际取 /stats 的 recent_requests 后在客户端按 model/mode/limit 过滤;clearCache() 是 POST /cache/clear;prometheusMetrics() 读 GET /metrics 返回原始 Prometheus 文本。此外还有 statsHistory() 与 memoryUsage()(GET /debug/memory)两个 README 未展开的方法。
代理学习系统的访问入口:
// Telemetry
const telemetry = await client.telemetry.getStats();
const tools = await client.telemetry.getTools();
// Feedback — per-tool compression hints
const hints = await client.feedback.getHints('list_servers');
// → { hints: { maxItems: 8, skipCompression: false, preserveFields: ['id', 'status'] } }
// TOIN (Tool Output Intelligence Network)
const toinStats = await client.toin.getStats();
const patterns = await client.toin.getPatterns(20);
对应端点:telemetry 组提供 getStats / export / import / getTools / getTool(signatureHash)(/v1/telemetry*);feedback.getHints(toolName) 返回按工具名学习的压缩提示(maxItems、skipCompression、preserveFields 等),这正是 SmartCrusherConfig.useFeedbackHints 在代理侧消费的数据;toin 组提供 getStats / getPatterns(limit) / getPattern(hashPrefix)(/v1/toin/*),返回工具输出智能网络的统计与已学习模式。所有返回值都经过 deepCamelCase 转换,代理的 snake_case 字段在 TS 侧统一呈现为 camelCase。
九、配置类型、环境变量与错误层级
配置类型
HeadroomConfig 是 Python headroom.config 各 dataclass 的 TypeScript 全量镜像(types/config.ts),字段全部可选,省略时由代理用默认值:
import type { HeadroomConfig, SmartCrusherConfig, CCRConfig } from 'headroom-ai';
const config: HeadroomConfig = {
defaultMode: 'optimize',
smartCrusher: {
enabled: true,
minItemsToAnalyze: 5,
maxItemsAfterCrush: 10,
varianceThreshold: 2.0,
relevance: { tier: 'hybrid', relevanceThreshold: 0.25 },
anchor: { anchorBudgetPct: 0.25 },
},
ccr: { enabled: true, injectTool: true },
cacheOptimizer: { enabled: true, autoDetectProvider: true },
intelligentContext: { enabled: true, useImportanceScoring: true },
};
const client = new HeadroomClient({ config });
顶层除 defaultMode(audit / optimize / simulate)与 modelContextLimits 外,还有若干 README 示例未展示的配置块:toolCrusher(按 token 阈值压缩工具输出的数组/字符串/深度,含 preserveKeys 与按工具配置的 toolProfiles)、cacheAligner(动态内容检测:regex/NER/semantic 分级、熵阈值、空白归一化等)、rollingWindow、prefixFreeze(前缀冻结的缓存保护)、readLifecycle(陈旧/被取代读文件的压缩)、contentRouterEnabled、generateDiffArtifact。SmartCrusherConfig 的 relevance.tier 支持 bm25 / embedding / hybrid 三档相关性评分,anchor 子配置控制保留槽位与前后权重。完整的 HeadroomMode、RelevanceTier、ContentType(json/code/logs/text/html/diff/search/unknown)、BlockKind 等类型也都从包根导出。
config 传入 HeadroomClient 后,compress() 调用时会以 deepSnakeCase(this.config) 放入请求体的 config 字段(client.ts),simulate() 则将其与 default_mode: "simulate" 合并——即每次压缩都可以携带独立配置覆盖代理默认值。
运行配置与环境变量
import { compress } from 'headroom-ai';
const result = await compress(messages, {
model: 'gpt-4o',
baseUrl: 'http://localhost:8787', // proxy URL
apiKey: 'your-api-key', // optional, for authenticated endpoints
timeout: 30000, // ms
fallback: true, // return uncompressed if proxy is down (default)
retries: 1, // retry on transient failures (default)
tokenBudget: 4000, // compress to fit this limit
hooks: new MyHooks(), // pre/post compression hooks
});
等价的环境变量(client.ts 中可见解析优先级:显式参数 > 环境变量 > 默认值):
| 环境变量 | 作用 |
|---|---|
HEADROOM_BASE_URL |
代理地址,缺省 http://localhost:8787 |
HEADROOM_API_KEY |
访问代理自身的可选 API key(Authorization: Bearer) |
OPENAI_API_KEY / ANTHROPIC_API_KEY |
透传端点的 provider key 回退来源(providerApiKey 未显式给出时) |
注意区分两类密钥:apiKey 用于访问 Headroom 代理本身,providerApiKey 用于代理转发到 OpenAI/Anthropic 时的上游鉴权。
错误层级
SDK 提供与 Python SDK 对齐的完整错误层级(errors.ts):
import {
HeadroomError,
HeadroomConnectionError,
HeadroomAuthError,
HeadroomCompressError,
ConfigurationError,
ProviderError,
StorageError,
TokenizationError,
CacheError,
ValidationError,
TransformError,
} from 'headroom-ai';
try {
await client.compress(messages);
} catch (err) {
if (err instanceof HeadroomAuthError) {
console.error('Auth failed — check HEADROOM_API_KEY');
} else if (err instanceof HeadroomCompressError) {
console.error(`Compression error ${err.statusCode}: ${err.errorType}`);
} else if (err instanceof ConfigurationError) {
console.error('Bad config:', err.details);
}
}
映射规则由 mapProxyError() 决定:HTTP 401 → HeadroomAuthError;代理错误体中的 error.type 为 configuration_error / provider_error / storage_error / tokenization_error / cache_error / validation_error / transform_error 时分别实例化对应类;其余情况包装为携带 statusCode 与 errorType 的 HeadroomCompressError。网络层失败(fetch 异常、超时)则抛 HeadroomConnectionError。
十、格式检测与转换:detectFormat / toOpenAI / fromOpenAI
import { detectFormat, toOpenAI, fromOpenAI } from 'headroom-ai';
const format = detectFormat(messages); // 'openai' | 'anthropic' | 'vercel' | 'gemini'
const openaiMessages = toOpenAI(messages);
const back = fromOpenAI(openaiMessages, format);
compress() 会自动完成这一步——传任意格式、回同格式。检测逻辑(format.ts)不是模糊猜测,而是基于每种格式的独有结构标记:
| 格式 | 判定标记 |
|---|---|
| Gemini | 消息用 parts 而非 content;或 role === "model" |
| OpenAI | assistant 消息带 tool_calls;或 role: "tool" 且带 tool_call_id |
| Vercel AI SDK | content 部件类型用连字符:tool-call / tool-result |
| Anthropic | content 块类型用下划线:tool_use / tool_result;或 image 块带 source.type |
| 默认 | 无法识别时按 OpenAI 处理({role, content: string} 本身就是合法 OpenAI) |
互转层的几个易错点都做了显式处理:Anthropic tool_result ↔ OpenAI tool 消息(format.ts);Vercel 图片 URL 对象 ↔ image_url;Gemini functionCall/functionResponse 的 tool_call_id 用 gemini_ 前缀占位(format.ts)。测试覆盖见 detect-format.test.ts、format.test.ts 与 format-integration.test.ts。
十一、实用工具函数
// Case conversion for proxy communication
import { deepCamelCase, deepSnakeCase } from 'headroom-ai';
const tsObj = deepCamelCase({ tokens_before: 100 }); // { tokensBefore: 100 }
const pyObj = deepSnakeCase({ tokensBefore: 100 }); // { tokens_before: 100 }
// SSE stream parsing
import { parseSSE, collectStream } from 'headroom-ai';
// Hook helpers
import { extractUserQuery, countTurns, extractToolCalls } from 'headroom-ai';
deepCamelCase/deepSnakeCase(case.ts):递归转换嵌套对象与数组的键名,跳过Date实例。这是 SDK 与代理之间 snake_case(Python 侧)/ camelCase(TS 侧)边界的统一实现——所有客户端方法返回前都调用deepCamelCase,所有复杂请求体发出前都调用deepSnakeCase;parseSSE/collectStream(stream.ts):解析代理透传的 SSE 流,client.chat.completions.create({ stream: true })与client.messages.stream(...)的返回即由它产生;- Hook 助手三件套:
extractUserQuery(任意格式中取最后一条 user 文本,兼容 string 与 content 数组)、countTurns(user 消息计数)、extractToolCalls(同时识别tool_calls、tool_use、tool-call三种工具调用形态)。
十二、测试与验证
SDK 自带完整测试套件(vitest),可对照阅读以验证本文各行为结论:client.test.ts 与 client-expanded.test.ts(客户端与透传端点)、compress.test.ts(compress 管线与格式往返)、simulate.test.ts(dry-run)、hooks.test.ts、shared-context.test.ts、errors.test.ts、config.test.ts、parity.test.ts(与 Python 版的行为对齐校验),以及四个适配器的 adapters/ 测试目录(含 vercel-ai-e2e.test.ts 端到端用例)。构建与检查脚本定义在 package.json:npm run build(tsup 双产物 ESM/CJS)、npm test、npm run typecheck。
十三、选型速查
| 场景 | 推荐 API |
|---|---|
| 已有 OpenAI / Anthropic / Gemini 客户端,零侵入接入 | withHeadroom(client) / withHeadroom(model)(对应子路径导出) |
| Vercel AI SDK(generateText/streamText 等) | withHeadroom(openai(...)) 或 wrapLanguageModel + headroomMiddleware |
| 只需要压缩消息数组,不用代理透传 | compress(messages, options) |
| 上线前评估压缩收益 / 做回归 | simulate(messages, { model }) |
| 压缩策略定制(注入系统提示、按消息保留、观测统计) | 继承 CompressionHooks |
| 多 Agent 共享长输出 | SharedContext |
| LLM 需要取回被压缩原文 | client.retrieve / client.handleToolCall(CCR) |
| 监控与学习系统对接 | health / proxyStats / prometheusMetrics / telemetry / feedback / toin |
适用前提小结:所有能力都要求 headroom proxy 在 HEADROOM_BASE_URL(默认 http://localhost:8787)可达;Node.js ≥ 18;透传调用需要有效的上游 provider key;在 fallback: true(默认)下,代理故障会被静默降级为不压缩,生产环境建议结合 client.health() 或 validateSetup() 做可用性探测,并留意 result.compressed 标志判断本次请求是否真的被压缩。SDK 源码与示例均在 sdk/typescript 目录,可按上文各节给出的文件路径逐行核对实现细节。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00