快速上手
sift 以 npm 包 @agent-context/sift 提供 Node.js API,核心为纯 Rust(napi-rs 绑定)。安装时自动命中当前平台的二进制子包。适合"上下文里塞了大量机器产出"的场景——这些内容 token 多、冗余高,但真正对任务有用的信息密度低。
安装
npm install @agent-context/sift最小示例
import { siftRequest, siftText, retrieve } from "@agent-context/sift";
// 1. 压缩请求体:自动检测 Anthropic /v1/messages、
// OpenAI Chat Completions、OpenAI Responses 三种格式
const { body, changed, tokensSaved } = siftRequest(requestBody, "用户当前的问题");
// 2. 或直接压缩单条字符串(如工具输出原文)
const r = siftText(toolOutput, "error mismatched");
if (r.lossy) {
// 有损:原文已入 stash store,输出尾部带 «stash:HASH» 标记
const original = retrieve(r.stashKey!);
}典型场景
Agent 的工具输出
编码 Agent 每轮都会往上下文里塞构建日志、grep 结果、git diff。几轮之后,工具输出占了绝大部分 token,而且旧轮次的输出早就没用了。
for (const step of agentSteps) {
const out = await runTool(step);
// 送进模型前先压缩,query 用当前任务描述
const r = siftText(out, step.intent);
messages.push({ role: "tool", content: r.text });
if (r.lossy) keepForRecovery(r.stashKey);
}要点:每步都传 query(当前意图),压缩器会保留与任务相关的行(错误、匹配项、改动),丢弃重复样板。
长对话的历史消息
对话越长,每轮的输入成本越高。在发送请求前对整个 body 跑一遍 compress,早期消息里的日志、JSON、diff 会被压缩,而最近的轮次与冻结前缀保持原样。
// 发送前一步,自动检测 Anthropic / OpenAI 格式
const { body, tokensSaved, frozenMessages } = siftRequest(requestBody, userQuestion);
await fetch("/v1/messages", { method: "POST", body: JSON.stringify(body) });要点:cache_control 以下的消息是缓存锚点,sift 一个字节都不动,不会破坏你的 prompt cache 命中。
把大文件喂给 LLM
分析线上问题、读监控数据时,原始文件往往几十 KB 起步。先 siftText 再送入:
- 监控 / 导出的 JSON 数组:schema 去重 + 采样,异常行优先保留;
- 构建 / 测试日志:错误与堆栈全保留,重复 warning 折叠成一条;
- git diff:hunk 采样,改动行保留;
- 会议纪要等长文本:BM25 抽取关键句,支持中文。
API 一览
siftRequest(body, query?)
压缩请求 body(就地透传或压缩),返回:
| 字段 | 说明 |
|---|---|
body | 压缩后的请求 body(格式与输入一致) |
changed | 是否发生了实际压缩 |
blocksExamined / blocksCompressed / blocksReverted | 检查 / 压缩 / 因 token 校验回退的 text block 数 |
frozenMessages | 冻结前缀消息条数(cache 锚点,未被触碰;OpenAI 格式恒为 0) |
stashStored | 写入 stash store 的原文条数 |
tokensSaved | 估算节省的 token 数 |
siftText(text, query?)
压缩单个字符串(把工具输出原文送进任意 API 之前),返回 text / changed / lossy / stashKey / tokensSaved。内容类型自动检测分发,单 block 最小 512 字节才参与压缩。
retrieve(key)
按 stashKey 从 stash store 取回有损压缩的原文,端到端无损。
detectContentType(text) / detectRequestFormat(body)
类型探测:返回内容类型(JSON 数组 / 构建日志 / 搜索结果 / git diff / 源代码 / 纯文本 / HTML)或请求格式(anthropic / chat_completions / responses)。
最佳实践
- 总是传 query:用户当前的问题、Agent 当前步骤的意图。相关性打分依赖它,不传则保留策略更"盲"。
- 保留 stashKey:有损压缩的原文在 stash store 里,把 key 记下来,模型追问细节时用
retrieve(key)取回原文再注入,端到端无损。 - 不用担心理解偏差:压缩只发生在消息内部,对话结构、tool_use/tool_result 配对完整保留;API key 等高熵凭证被强制识别并保留。
- 短内容不用管:单 block 小于 512 字节不参与压缩,直接透传,零开销。