@wosnxn123/billion-context-pi
v0.1.31-1
Published
One billion, not one million. Model-driven context management for the Pi coding agent.
Downloads
937
Maintainers
Readme
为什么选择 billion-context
当对话变长,模型的上下文会耗尽。多数工具采用硬截断 —— 静默丢弃早期消息。billion-context 把 compress 工具交给模型:由 LLM 决定何时压缩、压缩什么,将内容压缩成高保真摘要,在回收上下文空间的同时保留关键细节(文件路径、决策、错误字符串)。
与 Pi 内置的自动压缩(把所有内容替换成单个摘要)不同,billion-context:
- 保留结构 — 压缩的范围变成带标签的块,可后续解压
- 多级压缩 — 摘要可被进一步蒸馏(T1 → T2 → T3),随会话增长保持有界
- 可搜索 —
search_context无需解压即可搜索已压缩块内的信息 - 有选择性 — 受保护的工具、用户消息、近期工作集永不被压缩
这使得:
- 一个会话即可支撑海量工作。 根据三级压缩架构的模拟测试(见 opencode-acp),单会话累计可处理约 100 亿至 600 亿 token —— 同时对遥远的关键信息(路径、决策、签名)保持长久记忆。用户可以在同一个会话里连续工作几个月,而无需因为上下文膨胀而开新会话丢上下文。
- 上下文长期保持精简。 实际运行中上下文通常稳定在 15 万 token 以下(opencode-acp 实测维持在 20 万以下),相比传统压缩方案动辄撑到 100 万上下文,单会话累计可节省近 5 倍的 token 费用。
安装
pi install npm:billion-context-pi完成。扩展在下次 Pi 启动时自动加载。无需配置 —— 它会自动读取模型的上下文窗口。
建议先卸载
pi-subagents(可选,推荐)。 billion-context-pi 自带acp_delegate子代理工具(见下文),以极低的上下文成本(~600 tok vs ~7K tok/轮)替代 pi-subagents。如果你已安装 pi-subagents,卸载它以避免重复的委派工具:pi remove npm:pi-subagents
工作原理
billion-context 拦截 Pi 的 context 事件(每次 LLM 调用前触发),运行一个 8 阶段管线:
assign refs → sync blocks → prune → filter → hide calls → recommend → nudge → emergency truncate每条消息获得一个不可见的 <acp> 引用标签(m00001、m00002、...),对模型可见但用户不可见。模型用这些引用来指定压缩范围。
Pi 内置的自动压缩会被取消 —— billion-context 是唯一的上下文管理者。
插件兼容性与排序
billion-context 通过拦截 Pi 的 context 事件接管上下文管理。Pi 没有插件优先级机制 —— 当多个扩展为同一个事件注册 handler 时,它们按固定顺序(加载顺序)执行,没有 priority/weight 字段,用户也无法控制顺序。context 事件尤其是一个管线:每个 handler 都接收上一个 handler 的输出,没有短路,最后一个 handler 对发给模型的内容拥有最终决定权。
这带来两个实际影响:
只保留一个上下文压缩插件。 如果同时运行两个压缩插件(例如 billion-context-pi 和另一个),它们都会改写消息列表、互相覆盖 —— 已压缩的范围可能被重新展开或破坏。Pi 的内置自动压缩已由 billion-context-pi 自动取消,但任何第三方压缩/compaction 扩展都应卸载。
即使只有一个压缩插件,在少数情况下仍可能出现干扰。 Pi 下的加载顺序由文件系统发现顺序(
fs.readdirSync遍历.pi/extensions/→ 全局 → 包)决定,并不完全确定。如果另一个(非压缩类)扩展也 hook 了context事件、且恰好加载在 billion-context-pi 之后,它可能修改压缩后的输出。billion-context-pi 从会话日志重建工作集(而非链式输入),这让它对排在它之前的 handler 鲁棒 —— 但无法防御排在它之后的 handler。这是 Pi 扩展模型的固有限制;若你观察到上下文行为异常,请检查是否有其他已安装扩展拦截了context事件。
模型工具
| 工具 | 作用 |
|------|------|
| compress | 用详细摘要替换连续的消息范围 |
| decompress | 恢复之前压缩的块内容 |
| search_context | 按关键词搜索已压缩块摘要(及可见消息) |
| acp_status | 显示上下文用量、已压缩块、可压缩范围 |
| acp_delegate | 为某个任务派生一个干净上下文的子代理(审查 / 调研 / 实现 / 规划 / 建议) |
| acp_delegate_wait | 阻塞等待委派任务完成(返回结果,否则超时) |
| acp_delegate_cancel | 按 runId 取消正在运行的委派任务 |
acp_delegate — 干净上下文委派
把一个自包含的任务交给一个运行在干净上下文中的新 pi 进程。五个内置角色,各自有系统提示和软工具护栏:
| 角色 | 工具 | 适用场景 |
|------|------|----------|
| reviewer | read, bash, grep, find, ls + ACP | 只读代码审查(bug、风险、file:line) |
| researcher | read, bash, grep, find, ls + ACP | 只读代码库调研 |
| worker | read, edit, write, bash | 修改代码 |
| planner | read, bash, grep, find, ls + ACP | 分析 + 提出分步计划 |
| oracle | read, bash, grep, find, ls + ACP | 回答问题 / 建议 |
只读角色(reviewer、researcher、planner、oracle)获得受限工具白名单(read, bash, grep, find, ls)+ ACP 上下文工具(compress, decompress, search_context, acp_status),以便管理自己的上下文。这能防止意外修改文件,但 bash 可绕过 - 这是护栏,不是安全边界。
Worker 运行在 Pi 的完整默认工具集上 - 不应用 --tools 白名单,因此任何已加载的扩展或自定义工具(如 ACP、LSP、MCP)保持可用。这确保主任务委派能力完整。上表中的 read, edit, write, bash 仅反映核心工具。
委派的完整结果保存到文件(/tmp/acp-delegate/<runId>.out);工具结果和注入通知只携带任务标题 + 文件路径(无预览)- 需要细节时用 read 读取。这让父上下文保持精简。
- 交互(TUI)与 RPC 模式:
async:true(默认)在后台运行子进程;完成时一条简短通知注入到聊天框。 - Print / JSON 模式(
pi -p、SDK):async:true自动降级为同步 — 结果在同一轮作为工具结果返回(父进程一轮后即退出,后台注入会丢失)。
在交互 TUI 中,异步运行还会在编辑器下方显示一个实时状态 widget(角色、已运行秒数、任务预览),让你随时知道什么在跑、跑了多久。RPC/print/JSON 模式自动禁用。
/acp 命令
为用户提供丰富的状态显示:
╭─────────────────────────────────────────────╮
│ ACP Context Analysis │
╰─────────────────────────────────────────────╯
[email protected]
Context: 12% (120K / 1.0M)
Growth: +15K since last nudge
Token Breakdown:
System ░░░░░░░░░░░░░░░░░░░░ 2% 2.1K
Tool ████████████░░░░░░░░ 58% 69.6K
Summaries ████░░░░░░░░░░░░░░░░ 20% 24.0K
Code ██░░░░░░░░░░░░░░░░░░ 10% 12.0K
Text █░░░░░░░░░░░░░░░░░░░ 5% 6.0K
Blocks: 3 active (3.7K summary, 15.2K original compressed)
b1 (T1) 3.7K→599 age=5m "API exploration"
b2 (T1) 8.2K→2.1K age=2m "Debug session"
b3 (T2) 3.3K→1.0K age=1m "Architecture review"配置
billion-context-pi 开箱即用,无需任何配置。可以在 JSON 配置文件中设置三个可选 key。
配置文件
创建 ~/.pi/acp.json(全局)和/或 <项目>/.pi/acp.json(项目级,覆盖全局):
{
"debug": false,
"autoUpdate": true,
"modelContextLimit": 200000,
"delegate": true,
"toolBashDefaultTimeout": 60,
"toolOutputMaxBytes": 200000
}| Key | 默认值 | 说明 |
|-----|--------|------|
| debug | false | 启用诊断日志(error/warn/info 始终写入 ~/.pi/acp.log,此开关仅额外打开详细 debug 事件)。也可用环境变量 ACP_DEBUG=1 启用。 |
| autoUpdate | true | Pi 启动时检查 npm 是否有更新版本并自动安装(限频:每 3 分钟最多一次检查)。禁用以避免所有启动时的网络请求。 |
| modelContextLimit | (自动) | 覆盖上下文上限(token 数)。默认为模型的 contextWindow。 |
| delegate | true | 启用 acp_delegate 工具(delegate/wait/cancel)及其系统提示词段落。设为 false 则不注册这些工具(例如你用了别的子代理扩展,或跑 headless 场景异步注入没有意义)。 |
| toolBashDefaultTimeout | 60 | 当模型未指定 timeout 时注入 bash 工具的超时秒数。Pi 本身没有默认超时,不加这个,一次遗漏的超时可能挂起几千秒。超时后会提示模型用更大的 timeout 重跑。设为 0 恢复 Pi 的无界行为。 |
| toolOutputMaxBytes | 200000 | 工具结果文本硬上限(字节,约 5000 行 @ ~40 字节/行,通过 tool_result hook 应用)。用于兜住 Pi 自身 50KB/2000 行截断管不到的输出(例如 Pi 未加限制的工具)。触发截断时会告诉模型如何查看完整输出——对 bash,完整输出在其临时文件(BashToolDetails.fullOutputPath)中;设更小(如 8192)可更省上下文,设 0 关闭。 |
只有这六个 key 会被
acp.json读取。 其他调优参数(preserveRecentMessages、protectedTools、nudge 阈值)是代码级的,不向用户开放。
环境变量
| 变量 | 作用 |
|------|------|
| ACP_AUTO_UPDATE | 设为 0 / false / no / off(不区分大小写)以禁用自动更新,覆盖配置值。 |
| ACP_MODEL_CONTEXT_LIMIT | 覆盖上下文上限。优先级高于配置值。 |
| ACP_DEBUG | 设为 1 或 true 启用 debug 日志(error/warn/info 始终写入,无需此开关)。 |
| ACP_LOG_FILE | 覆盖日志文件路径(默认 ~/.pi/acp.log)。 |
日志
billion-context-pi 会向 ~/.pi/acp.log(可用 ACP_LOG_FILE 覆盖)写入结构化的始终开启日志,覆盖模型工作的整个会话,便于排查问题:
error— 详细记录所有报错(含message与stack):上下文变换、压缩/解压/搜索执行失败、delegate 子进程错误、状态读写失败、子代理工具注册失败等。原本被静默吞掉的异常现在一律落盘。warn— 值得注意的非致命情况:紧急 nudge 注入、配置加载失败、自动更新网络错误、工具输出被截断、委派结果注入被跳过。info— 生命周期事件:会话启动、每轮上下文变换摘要(消息数/token/压缩比/活跃块数)、压缩/解压、delegate 派发与完成、自动更新检查。debug—— 仅在debug: true时额外写入(细粒度的字段级事件)。
每行格式:<ISO 时间戳> [<级别>] [<范围>] key=value key=value。文件达到 10 MB 时轮转为 ~/.pi/acp.log.old。
tail -f ~/.pi/acp.log # 实时观察会话
grep '\[error\]' ~/.pi/acp.log # 汇总所有记录的失败压缩策略
模型接收(在其系统提示中)关于何时压缩、逐字保留什么(路径、签名、错误、决策、用户意图)、丢弃什么(冗长日志、重复内容、已消费的探索)的详细指导。这段指导每轮都注入,确保它始终在模型的注意力范围内。
哪些内容会被保护
billion-context 保护三类内容不被压缩:
- 永久保护的工具 —
compress调用被硬保护(它们是承载关键元数据的;压缩它们会破坏 decompress 和"摘要是历史"的契约)。 - 软近期区 — 最后 N 条消息(默认 5)和最后约 5K token 被软保护,让模型保留工作集。来自
decompress、search_context、read、bash的工具结果被排除出此区:它们体量大、消费后就该能压缩,所以不该占用保护预算。 - 最后一条用户消息 — 始终保护(用户意图必须存活)。
基于 acp-kernel
压缩引擎是 acp-kernel — 平台无关、MIT 许可的库,有 208 个测试。它被内联打包进 dist/index.js,因此零运行时依赖。
许可证
MIT.
