@hicaru/pi-rlm0.3.28
Save 99% tokens, Recursive Language Model (RLM) for the Pi
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
rlm.pi PI plugin
pi-rlm — 大上下文,廉价模型:为 Pi 提供的递归语言模型 (RLM)
安装
pi install npm:@hicaru/pi-rlm
以后要移除:
pi uninstall npm:@hicaru/pi-rlm
然后在 Pi 中运行 /reload —— /rlm、/rlm-config 和 /rlm-stop 会出现在 [Extensions] 下。使用 Ctrl+Shift+R 或 /rlm 切换。
什么是 pi-rlm?
一个把 Pi 会话变成递归语言模型 (RLM) 的插件:不必把庞大的文档塞进提示词,上下文
驻留在 Python REPL 中,由你最好的模型编排 —— 检索、分解,并把叶子读取递归地委派给
廉价的工作模型。同一个 Pi 会话、同样的工具、同样的密钥 —— 打开 /rlm 即可。
方法基于 RLM 论文;详见下方的工作原理。
基准测试
OOLONG (oolong-synth) —— paper 级长上下文套件;取每个模型最新的日志,每任务成本
来自真实 costUsd(旧日志按 OpenRouter 牌价估算):
| 模型 | 得分 | 每任务成本 |
|---|---|---|
qwen/qwen3.8-27b |
100% | $0.0127 |
google/gemma-3-27b-it |
83.3% | $0.0013 |
qwen/qwen3-30b-a3b-instruct-2507 |
66.7% | $0.0009 |
mistralai/mistral-small-3.2-24b-instruct |
66.7% | $0.0025 |
精简套件 —— needle(多针召回)、codeqa(代码库问答)、coding(修复任务;
每模型 7 个任务 × 2 轮,确定性评分,无 LLM 评审):
| 模型 | 得分 | 准确率 |
|---|---|---|
qwen/qwen3-30b-a3b-instruct-2507 |
14/14 | 100% |
google/gemma-3-27b-it |
12/14 | 86% |
mistralai/mistral-small-3.2-24b-instruct |
12/14 | 86% |
逐任务原始数据(正确性、召回率、延迟、token、成本)位于 bench/runs/*.jsonl
—— 每个任务一行 JSONL,作为历史记录提交。
运行基准测试
export OPENROUTER_API_KEY=sk-or-... # 必需 —— 密钥仅通过环境变量传递
bun run bench # 精简套件:needle + codeqa + coding
bun run bench --suite needle --limit 1 # 单个套件,仅第一个任务
bun run bench --model openrouter/qwen/qwen3-30b-a3b-instruct-2507
bun run bench --list # 仅列出任务,无需引擎和密钥
bun run bench --suite paper # paper 套件:s_niah, oolong, browsecomp, codeqa_lb(需下载数据集)
套件:all(精简版,默认) · needle · codeqa · coding · paper · s_niah ·
oolong · browsecomp · codeqa_lb。
工作原理
pi 进程 (TypeScript)
├─ /rlm ──► 引擎逐轮驱动 SMART (根) 模型 (编写 ```repl``` Python)
│ │ 每轮:解析 repl 块 ──► 在沙箱中运行 ──► 将 stdout 反馈回去
│ ▼
├─ bridge ── llm_query / llm_query_batched ──► WORKER 模型 (serverless, 进程内)
│ rlm_query ──► 递归子 RLM (自有沙箱), 设有深度限制
├─ AgentTree ──► 编辑器上方的实时 agent/subagent 树 (角色, 深度, 成本, token)
└─ PythonSandbox ── `python3 worker.py` ──[基于 stdio 的 JSONL, 双向]── 持久化 REPL
- 无需服务器,无需 socket,无需 Docker。 唯一的外部进程是一个本地
python3沙箱。 当沙箱代码调用llm_query时,worker 在 stdout 上写入请求并在 stdin 上阻塞; Pi 在进程内提供服务并将回复写回。供应商 API 密钥绝不会进入沙箱。 - 沙箱公开了
context,llm_query,llm_query_batched,rlm_query,rlm_query_batched,SHOW_VARS(),ask_user_question()以及一个answer字典。 模型通过设置answer["ready"] = True来提交最终结果。
从源码安装(开发)
pi-rlm 是一个 Pi 包。Pi 提供了 @earendil-works/pi-* 和 typebox peer
依赖;请不要在该包中安装它们的独立副本。要求 PATH 中有 python3 (仅限标准库)。
开发时的本地安装方式:
pi install /path/to/this-repo/pi-plugin/rlm
Git 安装要求包清单位于安装的仓库根目录下。 对于像这样一个 monorepo 子目录,请优先使用上述的本地路径流程。
如果您之前直接复制了扩展文件夹,请将其删除,以免遮蔽 (shadow) 该包:
rm -rf ~/.pi/agent/extensions/rlm
然后运行 /reload 或重启 Pi。使用 pi list 验证该包是否出现在
settings.packages 中,并检查 /rlm, /rlm-config 和 /rlm-stop 是否出现在 [Extensions] 下。
命令
| 命令 | 快捷键 | 描述 |
|---|---|---|
/rlm |
Ctrl+Shift+R |
切换持久化 RLM 模式 (通过 RLM 引擎路由普通提示词) |
/rlm-stop |
终止正在运行的任务 | |
/rlm-config |
选择 smart + worker 模型并调整运行设置 |
在任务激活期间,一个实时树会显示根编排器和每个子 LLM /
递归子节点的状态、模型、成本、token 和持续时间。最终答案将以 markdown 形式发布
到聊天中;任何代码修改将作为 diff 收集并通过弹出窗口进行审核 (除非开启了 yolo)。
沙箱 API
这些函数被注入到 REPL 内部模型的 Python 命名空间中:
| 函数 | 签名 | 描述 |
|---|---|---|
context |
list[dict] |
打包为 [{"path","content","tokens"}, ...] 的仓库 —— 完整的代码库 |
llm_query |
(prompt) -> str |
单次子 LLM 调用(配置的 RLM LLM) |
llm_query_batched |
(prompts) -> list[str] |
并发子 LLM 调用 (池上限) |
llm_query_chunked |
(text, prompt) -> list[str] |
将大文本拆分为不超过上限的块并通过子 LLM 处理 |
rlm_query |
(prompt, paths=None) -> str |
具有自有沙箱的递归子 RLM (设有深度限制)。继承父级的 context;paths 按前缀缩小范围 |
rlm_query_batched |
(prompts, paths=None) -> list[str] |
并发递归子 RLM,共享同一个 paths 切片 |
ask_user_question |
(questions) -> list[dict] |
向用户提出结构化问题 (仅限深度 0) |
SHOW_VARS |
() -> str |
列出当前定义的变量及其类型 |
answer |
dict |
设置 answer["content"]=...; answer["ready"]=True 以结束 |
设置 (/rlm-config)
| 设置 | 默认值 | 含义 |
|---|---|---|
| Smart model | Pi 的当前活动模型 | 根编排器 |
| Worker model | 最便宜的可用模型 | 响应 llm_query |
| Max recursion depth | 4 |
超过此深度的 rlm_query 将回退到 llm_query |
| Max iterations | 30 |
引擎完成前的最大轮数 |
| Budget ceiling | none | 当美元支出超过此值时停止整个树 |
| Max consecutive errors | 5 |
在 N 轮连续错误后停止 |
| REPL block timeout | 120s |
每个 repl 块的墙上时钟时间 (worker 中的 SIGALRM) |
| Max concurrent sub-calls | 4 |
*_batched 的池大小 |
| Orchestrator addendum | on | “委派,而非自行解决”的引导 |
| Trajectory compaction | on (0.85) | 当历史记录接近上下文窗口时进行总结 |
yolo |
off | 立即应用建议的修改,跳过审核弹出窗 |
askUserQuestion |
on | 向模型公开 ask_user_question() |
并发注意: 每个
rlm_query子节点都会启动自己的python3worker (冷启动约 50–150 毫秒)。 最坏情况下的并发解释器数量 ≈maxConcurrentSubcalls^(depth−1);在 默认设置下 (深度 4, 并发 4),极端情况下为 4³ = 64。预算和错误 上限 (见上文) 无论扇出 (fan-out) 如何都会限制总支出。
采样与可复现性
r3 基准测试表明:最大的能力杠杆不是模型,而是采样。仅 temperature 0 就让 OOLONG 从
71% (pooled) / 40% (flips) 提升到 91.7–100% all-stable,总计仅花费 $1.74。这些旋钮在
rlm.json (~/.pi/agent/rlm.json) 和 /rlm-config 面板中都是一等公民:
| 字段 | 位置 | 默认值 | 作用范围 |
|---|---|---|---|
rootSampling.maxTokens |
rlm.json, 面板 | 16384 |
根模型每轮的输出上限 (包括 finalize) |
rootSampling.temperature |
rlm.json, 面板 | 提供商默认 | 根轮次与 finalize 的采样温度;0 = 确定性 |
smartReasoning |
rlm.json, 面板 | 无 | 根模型的思考强度 |
subSampling.maxTokens |
rlm.json, 面板 | 8192 |
每个叶子子调用 (llm_query, llm_batch, map_files) 的输出上限 |
subSampling.temperature |
rlm.json, 面板 | 提供商默认 | 叶子调用的采样温度 |
enableVerificationNudge |
rlm.json | 关 | 当根节点过早以“裸数字”定稿时,给予一次带提示的重做 |
可复现性配方 (经 r3 验证):
{
"config": {
"rootSampling": { "maxTokens": 8192, "temperature": 0, "reasoning": "high" }
}
}
思考 token 与答案共享补全预算——开启 thinking 时请保持充裕的 maxTokens
(基准测试将其翻倍至 8192;若过紧,引擎会在第 0 轮警告一次)。
作用边界: rlm.json 的采样适用于 RLM 模式运行、rlm() 委托以及任意深度的子递归
(同一个引擎函数)。Pi 原生代理循环遵循 Pi 自身的会话设置——rlm.json 不会触及它。
模型能力: reasoning 要求模型的注册表条目为 reasoning: true。其他情况会在发送给
提供商之前丢弃该级别 (pi-ai 会将不支持的级别钳制为 off);能力来自注册表,而非配置。
运行日志
- 密钥隔离:供应商密钥仅存在于 TypeScript (
AuthStorage) 中;沙箱 接收提示词并返回文本 —— 绝不接触密钥。 - 环境清理:在 worker 启动前会剥离敏感环境变量 (API 密钥, token)。
worker 无法从
os.environ读取供应商凭据。 - 并非安全沙箱:Python worker 公开了
__import__和open。模型编写的 代码可以导入网络模块、读写本地文件,并向 stdout 写入符合协议格式的 JSON。 此层级信任根模型的代码;stdio 协议隔离的是供应商密钥和 进程生命周期,而非对抗性代码的隔离。以后可以在不改变协议的情况下, 通过设置添加更强的沙箱 (Docker, seccomp)。 - 限制内置函数:禁用
eval/exec/compile/input/globals/locals;每块 SIGALRM 超时 + 父进程监视器 (挂起时 SIGKILL);预算 / token / 超时 / 连续错误上限。 - 信任:本地安装需要 Pi 项目信任。
项目布局
src/
sandbox/ py/ (worker.py · guards · retrieval · tasks) · sandbox.ts · interrupts · protocol · sandbox-manager · context-file
bridge/ model.ts (single completion) · subcall-handlers.ts (the one llm/rlm impl) · ask-user · library
core/ engine.ts (the loop) · iteration · limits · resource-limits · answer · compaction · history · types
prompts/ glossary (shared REPL vocabulary) · system (headless) · native · user
text/ parsing (repl blocks) · tokens · preview
tool/ repl-tool · repl-result · repl-render · rlm-tool · rlm-events · rlm-aggregator · subcall-store · background-tasks
config/ defaults · settings (rlm.json persistence + validation)
context/ native walker + anydoc document conversion + add_context
ui/ status · model-picker · config-panel · intro · theme
commands/ rlm · rlm-config
mode/ rlm-mode (controller) · worker-model (cheapest pick) · native-guards
util/ errors · concurrency · trace
test/ phase suites · native-smoke · native-mode · helpers
测试
运行时为 Bun (bun install, bun run … —— 绝不要使用 npm/pnpm/yarn)。
bun run test/phase1.ts # 沙箱:执行, 持久化, 密钥隔离, 超时终止
bun run test/phase4.ts # 递归深度限制逻辑 (不消耗 token)
bun run test/phase5.ts # 实时 agent 树渲染 (不消耗 token)
RLM_TEST_LIVE=1 bun run test/phase2.ts # 通过沙箱进行真实的 llm_query
RLM_TEST_LIVE=1 bun run test/phase3.ts # 在文件上下文中进行真实的端到端 /rlm 运行
RLM_TEST_LIVE=1 bun run test/phase4.ts # 引擎解决 20 个文档的“大海捞针”测试
背景
基于 RLM 论文 中的方法,为 Pi 原生重新实现。
如果您在研究中使用此项目,请引用原始 RLM 工作:
@misc{zhang2026recursivelanguagemodels,
title={Recursive Language Models},
author={Alex L. Zhang and Tim Kraska and Omar Khattab},
year={2026},
eprint={2512.24601},
archivePrefix={arXiv},
primaryClass={cs.AI},
url={https://arxiv.org/abs/2512.24601},
}