npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agent-context/sift

v0.0.1-alpha.6

Published

LLM 上下文压缩核心(Rust sift 的 Node 绑定)

Downloads

882

Readme

@agent-context/sift

LLM 上下文压缩核心的 Node 绑定(Rust 实现)。在请求发送给 LLM API 之前,就地压缩 消息里的大型工具输出,节省 token 与成本;被压缩的原文卸载进本地持久化 stash store,可随时 按标记取回,保证端到端无损。

  • 纯 Rust 核心(sift)+ napi-rs 桥
  • 支持三种请求格式(自动检测):Anthropic /v1/messages、OpenAI Chat Completions、OpenAI Responses API
  • 另有 siftText:对单条字符串(如工具输出原文)直接压缩
  • 消息内压缩 + 冻结前缀保护 + stash 可恢复,三大不变量见 PROJECT_MAP

安装(本地构建)

尚未发布到 npm registry。本地构建后用:

cd npm/core
npm install
npm run build        # 本机平台
# 或 npm run build:cross   # 本机交叉编译 macOS/Linux 6 平台(需 zig)

产物:dist/(TS 编译)+ native/sift.<platform-triple>.node。发布后即可 npm install @agent-context/sift

发布包支持 macOS、Linux 与 Windows 的 x64/arm64;Linux 同时提供 GNU 与 musl 变体。

运行场景演示

仓库内提供了覆盖 JSON 数组、pretty JSON、构建日志、搜索结果、git diff、混合命令 输出、源代码和纯文本的 8 个独立用例。它通过包根目录加载 @agent-context/sift 的公开入口, 每个用例都会完整打印「压缩前原文」「压缩后输出」「运行指标」,并验证 stash 恢复和 冻结前缀保护:

cd npm/core
npm run build:native  # 首次运行或 Rust 代码变更后执行
npm run demo -- --list       # 查看用例名称
npm run demo -- json-array   # 单独运行一个用例
npm run demo                 # 按顺序运行全部用例
npm run demo -- --save       # 运行全部并分别保存到 demo/results/

演示会打印每个场景压缩前后的完整内容、字节数、压缩比、节省 token 和验证结果;stash 数据写入系统临时目录,不会使用正式的 ~/.sift/stash

快速开始

import { siftRequest, retrieve } from '@agent-context/sift';

// 1. 压缩(发送前)
const result = siftRequest(requestBody, userQuery);

// 2. 把压缩后的 body 发给 LLM API
const response = await client.messages.create({
  ...requestBody,
  messages: (result.body as any).messages,
});

// 3. 如需恢复原文:从压缩文本里提取 <<stash:KEY>>,取回
const key = extractStashKeys(result.body)[0];
const original = retrieve(key); // string | null

API

createSift({ stashDir })

创建绑定到独立 stash 目录的 API 实例。该实例的 siftRequestsiftTextretrieve 始终使用传入的目录,不受 SIFT_STASH_DIR 影响;相对路径按调用 createSift 时的工作目录 解析。

import { createSift } from '@agent-context/sift';

const sift = createSift({ stashDir: '/var/lib/my-app/sift-stash' });
const result = sift.siftText(toolOutput);
const original = result.stashKey ? sift.retrieve(result.stashKey) : null;

每次调用 createSift 都会创建独立实例,因此同一 Node.js 进程可以同时使用多个 stash 目录。直接导入的顶层 siftRequestsiftTextretrieve 保持原有行为,继续使用 SIFT_STASH_DIR~/.sift/stash、系统临时目录这一默认优先级。

siftRequest(body, query?)

就地压缩 body 中冻结前缀之外的工具输出。system/user/assistant prompt 默认保护; 若调用方明确要压缩一段普通文本,应使用 siftText。 格式自动检测(detectRequestFormat):

| 格式 | 压缩候选 | |---|---| | Anthropic /v1/messages | 非冻结区内、且 is_error != true 的 tool_result content | | OpenAI Chat Completions | role:"tool" 消息的字符串 content 或 text parts | | OpenAI Responses API | function_call_output 的字符串 output 或 text parts |

模型发出的结构化调用(tool_callsfunction_call)不会被动。OpenAI 格式没有 cache_control 前缀锚点,frozenMessages 恒为 0(live zone 从头开始)。

  • body:请求体对象(上述三种格式之一)
  • query?:当前用户 query,供相关性锚点压缩器优先保留相关行(可空)

返回 CompressResult

| 字段 | 含义 | |---|---| | body | 压缩后的 messages body(压缩文本尾部带 <<stash:KEY>> 标记) | | changed | 是否发生实际压缩 | | blocksExamined / blocksCompressed / blocksReverted | 检查 / 压缩 / 回退的 block 数 | | frozenMessages | 冻结前缀条数(cache 锚点,未触碰) | | stashStored | 写入 stash store 的原文条数 | | tokensSaved | 估算节省的 token 数 |

retrieve(key)

<<stash:KEY>> 里的 key 取回压缩时卸载的原文,返回 string | nullnull 表示 key 不存在或已过期(见「限制」)。

siftText(text, query?)

压缩单个字符串(不包请求体),适合在把工具输出原文送进任意 API / 存储之前处理。 返回 { text, changed, lossy, stashKey, tokensSaved }:有损时 text 尾部带 <<stash:KEY>> 标记、stashKey 非空,可用 retrieve(stashKey) 取回原文;无损压缩 (如 JSON minify)时 lossyfalse 且无标记。小于 512 字节的输入直接透传。

detectRequestFormat(body)

返回 'anthropic' | 'chat_completions' | 'responses' | 'unknown'。 无法判别时(如全部 content 为纯字符串)默认按 Anthropic 处理;这类请求没有明确工具 输出候选,因此 siftRequest 会安全透传。需要压缩单条字符串时使用 siftText

detectContentType(text)

返回内容类型:json_array | build_output | search_results | git_diff | source_code | plain_text | html,便于诊断。

什么时候调用 siftRequest

一句话:在任何 LLM 客户端把请求发给 API 之前,对 messages 做一次拦截压缩

收益最大的场景,是消息里含以下大型工具输出(这几类有专门压缩器):

| 内容 | 示例 | 压缩器 | |---|---|---| | JSON 数组 | ls/API 返回的对象列表、数据库查询结果 | smart_crusher(schema 去重、采样、错误行保留) | | 构建/测试日志 | pytest/npm/cargo/jest 输出 | log_compressor(错误/堆栈/摘要保留) | | grep/ripgrep 结果 | 代码搜索结果 | search_compressor(按文件/分数抽稀) | | git diff | git diff / PR diff | diff_compressor(hunk 采样) |

适合的接入位置:

  • 代理 / 中间件:放在 LLM 客户端与 API 之间对出站请求统一压缩。
  • 应用层发送前:直接 SDK 调用前,把 messages 传给 siftRequest
  • 边缘函数 / 无服务器:发送前压缩,降低首字节与计费 token。

不需要调用的情况:

  • 消息都很小:单个文本块 < 512 字节会自动跳过(MIN_BLOCK_BYTES)。
  • HTML:当前没有专用压缩器;纯文本和源代码已有各自压缩器,但 siftRequest 仍只会 对工具输出候选启用它们,普通文本请显式调用 siftText
  • stash 目录不可创建或原文无法落盘:有损结果会回退原文,不会留下不可恢复的压缩内容。

有损压缩与恢复(stash)

压缩是有损的(丢弃了部分行/样本),但原文会被卸载进 stash store,压缩文本尾部追加 <<stash:KEY>> 标记,其中 KEY 是原文的 BLAKE3 哈希(24 hex)。

原文 ──compress──▶ 压缩文本 + <<stash:KEY>>        (发给 API,省 token)
                        │
                        └── store.put(KEY, 原文)   (留在进程内)

需要原文时:从消息里找 <<stash:KEY>> → retrieve(KEY) → 原文

典型恢复流程:模型看到压缩内容后说「我需要看完整数据」,应用从最近的压缩消息里 提取 <<stash:KEY>>retrieve 取回原文,把原文补发给模型。Sift 当前不会自动向模型 注入 retrieve tool;需要模型自主取回时,调用方必须显式提供相应工具。

提取 key 的辅助:

const STASH_RE = /<<stash:([0-9a-f]+)>>/g;
function extractStashKeys(body: any): string[] {
  const text = JSON.stringify(body);
  return [...text.matchAll(STASH_RE)].map((m) => m[1]);
}

与 prompt cache 的关系(cache 安全)

siftRequest 只改冻结前缀之后的工具输出候选。 cache_control 标记以下的冻结前缀字节不动,因此不会破坏 prompt cache 的命中。 result.frozenMessages 报告了被保护的冻结条数。

限制

  • stash store 是落盘文件FileStashStore):每个 key 一个文件,默认目录 ~/.sift/stash(环境变量 SIFT_STASH_DIR 可覆盖),TTL 1800 秒(按文件 mtime 判定,get 时惰性删除过期项);也可以通过 createSift({ stashDir }) 为实例指定 独立目录。单机重启不丢、同机多进程互见。 多实例 / 集群需把该目录挂到共享文件系统(NFS / 对象存储),或改用外部 store 后端(Redis 等,StashStore trait 已抽象好),否则不同机器取不到对方的原文。
  • 压缩的是已解析的 JSON 对象,不是原始 HTTP 字节。若在代理层做「字节级 cache SHA 不变」的区间手术,需在更高层处理(见 PROJECT_MAP 待办)。
  • 当前 tokensSaved 用字节/4 × 1.2 粗估,仅作参考。