pi-kimi-keepalive
v0.3.6
Published
Prompt-cache keepalive for Kimi (kimi-coding) sessions in the Pi coding agent. Replays the last real provider request while idle so the automatic prefix cache never expires.
Maintainers
Readme
pi-kimi-keepalive
English | 中文文档
Prompt-cache keepalive for Kimi (kimi-coding provider) sessions in the Pi coding agent.
Kimi 的自动 prompt 缓存名义上在空闲 ~5 分钟后过期,但实测实际 TTL 更长——间隔 8 分钟的探测仍基本稳定命中。缓存真正过期后,整个上下文以全价 input($3 / 1M)重新计算。本扩展捕获最后一条真实 provider 请求,在会话空闲期间以固定间隔将其重放至同一端点,使缓存前缀在 TTL 内保持有效,后续请求按 cache-read 价格($0.3 / 1M)计费。
重放请求直接发送到 provider 端点,不经过 Pi 会话管道:不产生合成消息、不产生模型回合、不改动对话历史,仅在界面上展示聚合统计。
环境要求
- Node ≥ 20,pi ≥ 0.84(提供
before_provider_headers/before_provider_request钩子) kimi-codingprovider(建议 OAuth 订阅),kimi-openai-completionsAPI
安装
方案一:npm 安装(推荐;可收到更新)
pi install npm:pi-kimi-keepalive包已发布到 npm,新版本发布后可随时更新:
pi update npm:pi-kimi-keepalive方案二:GitHub 安装(不用 npm 时;无更新渠道)
pi install git:github.com/realoliversama/pi-kimi-keepalive该方式安装的是仓库默认分支在安装时刻的状态,不会收到更新——想升级需重新执行同一安装命令(或先 pi remove git:github.com/realoliversama/pi-kimi-keepalive)。
单次会话试运行(不安装)
pi -e npm:pi-kimi-keepalive # 从 npm
pi -e git:github.com/realoliversama/pi-kimi-keepalive # 从 GitHub初始化
首次启动(~/.pi/cache-keepalive/state.json 不存在)且有交互 UI 时,扩展运行初始化向导配置五项设置。提示符留空或按 Esc 保留默认值;之后可用 /keepalive setup 重新运行;headless 会话自动跳过并保留默认值。
| 步骤 | 设置项 | 命令 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| 1 | Max idle cutoff | maxidle | 30m | 空闲超过该时长后停止探测;0 表示不设限 |
| 2 | Miss pause threshold | miss | 1 | 连续 N 次探测未命中前缀缓存后暂停;命中会重置计数。仅在 default 模式下生效 |
| 3 | Error circuit breaker | errors | 3 | 连续 N 次探测失败(网络错误、HTTP 5xx)后暂停;HTTP 401/403 不受此值约束,直接暂停 |
| 4 | Session spend cap | cap | $1.00 | 会话探测花费(估算 USD)上限;0 表示不设上限 |
| 5 | Probing mode | mode | default | default 固定间隔;smart 自适应(见下文) |
向导结束时询问是否立即启用 keepalive。探测在下一次真实请求(完成捕获)之后开始。全部配置持久化到 ~/.pi/cache-keepalive/state.json。
探测模式
两种模式共用一套护栏,区别仅在间隔的确定方式。
default(默认模式)——间隔固定为 interval= 所设值,默认 8 分钟。实测该间隔的探测基本稳定命中前缀缓存(实际 TTL 长于名义的 ~5 分钟),因此默认间隔本身就是常热心跳:每次探测以缓存读价(约为全价 input 的 1/10)续期缓存,循环持续到 maxidle 截断。
若缓存确实在下方过期(服务端逐出、TTL 变更),该模式会自愈而非直接失效:miss 的那次探测本身会以相同前缀重建缓存条目,因此档位自动回退至 5 分钟安全档(名义 TTL 之内)、继续探测,下一次探测即续期成功。只有在 5 分钟档再 miss 才计入 miss 暂停阈值——连 5m 都无法重建缓存的属于环境异常,默认 miss=1 在此暂停。降档会持久化;/keepalive interval=8m 可调回原档位。
smart(/keepalive mode=smart)——不猜测 TTL,而是自适应逼近真实值:
- 从 8 分钟起跳。
- 连续 3 次命中后该间隔即被确认,档位 +30s。只有确认过的值才会持久化,因此
~/.pi/cache-keepalive/state.json中始终保存的是实测可连续命中的最大档位。 - 一次 miss 立即停靠探测:档位回退 30s 到最近确认值(至多退到 8m 下限)并持久化,随后探测停止。下一次真实轮次不会自动恢复——只有重新选择 smart 模式(
/keepalive mode=smart)才会从停靠档位继续探测。 - 上下文保护: 只有最近一次探测的 prompt tokens ≤ 200k 才允许升档;一旦超过,档位立即回退至 8m 下限并冻结升档(200k+ 上下文一次全价 miss 代价太高,不冒这个险)。
- smart 探测运行期间通用护栏(
maxidle、cap、errors、HTTP 401/403)仍然生效。
每个学习周期的花费极小:3 次缓存读价探测确认一档,一次全价探测结束本轮——停靠后的档位让之后的每个会话都直接运行在实测可行的最高值上。
命令
/keepalive 查看状态
/keepalive setup 重新运行初始化向导
/keepalive on|off 启用 / 停用(持久化)
/keepalive now 手动探测一次(绕过暂停)
/keepalive resume 清除 sticky 暂停
/keepalive mode=smart 自适应间隔(下限 8m;每 3 连中 +30s;一次 miss 即停靠,mode=smart 恢复探测)
/keepalive mode=default 固定间隔(即 interval= 的值)
/keepalive interval=4m45s default 模式下的探测间隔(≥ 30s;默认 8m 实测基本稳定命中)
/keepalive maxidle=30m 空闲上限(0 = 不设限)
/keepalive miss=1 连续 N 次缓存 miss 后暂停
/keepalive errors=3 连续 N 次探测失败后熔断
/keepalive cap=1.0 会话探测花费上限(USD,0 = 无上限)
/keepalive token=512 判定 miss 的最小 prompt token 数
/keepalive maxoutput=16 探测 max_tokens
/keepalive reset 清零会话统计统计(hits / misses / spend)为会话级;配置项持久化。PI_KEEPALIVE_DEBUG=1 输出调试日志到 stderr。
工作机制
捕获。
before_provider_request钩子快照每条真实kimi-coding请求的 payload(structuredClone)。只存内存,不落盘。重放。捕获的请求 POST 至
{baseUrl}/chat/completions(kimi-openai-completions 路由),仅修改终端参数:| 修改 | 原因 | | --- | --- | | 移除
stream/stream_options| 非流式响应中 usage 可直接解析 | | 移除thinking/store| 与输出收紧参数兼容性未知;非前缀组成部分 | |max_completion_tokens: 16| 限制探测输出成本 | | HTTP 400 时重试 | 去掉prompt_cache_retention(终端参数,非缓存键) |messages/tools/prompt_cache_key/prompt_cache_retention保持 byte-identical——这些是 provider 前缀缓存键的输入,重放因此命中既有缓存条目并重置 TTL,按 cache-read 计费。实测对 48k 上下文的探测实现 48,116/48,116 全量命中。认证。pi 在
before_provider_headers钩子之后才注入 OAuth 凭据,捕获的 headers 通常不含认证;探测时从 pi 的凭据存储(~/.pi/agent/auth.json的kimi-coding.access)读取当前 token,与 pi 的自动刷新保持同步。判定。解析响应 usage(
prompt_tokens_details.cached_tokens,回退 Anthropic 风格字段)将探测分类为 hit 或 miss;响应其余部分丢弃。
捕获的业务 headers 原样合并(去除 hop-by-hop 与长度头)。
护栏
- 回合运行中跳过探测;
agent_settled重新 arm 定时器。 maxIdle在长空闲期停止探测。miss/errors连续次数达到阈值,或 HTTP 401/403,暂停探测;下一次真实请求重新捕获凭据并自动解除暂停。- 会话探测花费按模型定价估算,达到上限即暂停。
- 定时器
unref(),不阻止进程退出。
成本
Kimi K3 官方单价($/1M tokens):input 3,output 15,cache read 0.3,cache write 0。
- 命中的探测约等于整个上下文的 cache-read 费用:50k tokens ≈ $0.015,100k ≈ $0.03,200k ≈ $0.06。
- 未命中的探测按全价 input 重读同一前缀;连续 miss 达到阈值即暂停。
saved统计 =cacheReadTokens × (input − cacheRead) / 1M,即等效冷恢复在全价下的开销的估算。
Kimi 订阅按 quota 计费,USD 数值仅供参考。
限制
- 名义 ~5 分钟 TTL、实测更长的有效 TTL 与上述定价均为观测行为,非 API 契约;
saved仅为估算。 - 仅支持
kimi-coding(kimi-openai-completionsAPI,含anthropic-messages回退);其他 provider 缓存键语义不同,不在范围内。 - 捕获内容仅存内存;探测仅发往
https://端点。
开发
npm install
npm run typecheck
npm test # 26 项测试;stub fetch、临时 $HOME、无网络测试依赖 Node 原生 TypeScript 剥离(Node ≥ 22.18 / 24)。
License
MIT,见 LICENSE。
