davebcn87/pi-autoresearch
GitHub: davebcn87/pi-autoresearch
为 pi 注入自主实验循环能力,自动化尝试、度量与迭代优化,持续改进目标指标。
Stars: 7211 | Forks: 427

# pi-autoresearch
### pi 的自主实验循环
**[安装](#install)** · **[用法](#usage)** · **[工作原理](#how-it-works)**
*尝试一个想法,进行测量,保留有效的,丢弃无效的,永远重复。*
这是为 **[pi](https://pi.dev/)** 开发的一个扩展——pi 是一个在终端中运行的 AI 编程智能体。pi-autoresearch 为 pi 提供了运行自主优化循环的工具和工作流:尝试一个想法,进行基准测试,保留改进,回退衰退,不断重复。
灵感来自 [karpathy/autoresearch](https://github.com/karpathy/autoresearch)。适用于任何优化目标:测试速度、打包体积、LLM 训练、构建时间、Lighthouse 分数。

## 快速开始
```
pi install npm:pi-autoresearch
```
## 包含内容
| | |
|---|---|
| **扩展** | 工具 + 实时小组件 + `/autoresearch` 面板 |
| **技能** | 收集需要优化的内容,写入会话文件,启动循环 |
### 扩展工具
| 工具 | 描述 |
|------|-------------|
| `init_experiment` | 一次性会话配置——名称、指标、单位、方向 |
| `run_experiment` | 运行任何命令,计算实际耗时(wall-clock duration),捕获输出 |
| `log_experiment` | 记录结果,自动提交,更新小组件和面板 |
### `/autoresearch` 命令
| 子命令 | 描述 |
|------------|-------------|
| `/autoresearch
` | 进入 autoresearch 模式。如果 `.auto/prompt.md` 存在,则以 `` 作为上下文恢复循环。否则,将设置一个新会话。 |
| `/autoresearch off` | 退出 autoresearch 模式。停止自动恢复并清除运行时状态,但保持 `.auto/log.jsonl` 不变。 |
| `/autoresearch clear` | 删除 `.auto/log.jsonl`,重置所有状态,并关闭 autoresearch 模式。使用此命令进行干净的重启。 |
| `/autoresearch export` | 在浏览器中打开实时面板。在实验运行时自动更新。 |
**示例:**
```
/autoresearch optimize unit test runtime, monitor correctness
/autoresearch model training, run 5 minutes of train.py and note the loss ratio as optimization target
/autoresearch export
/autoresearch off
/autoresearch clear
```
### 键盘快捷键
| 快捷键 | 描述 |
|--------------|-------------|
| `Ctrl+Shift+F` | 打开全屏可滚动面板覆盖层。使用 `↑`/`↓`/`j`/`k`、`PageUp`/`PageDown`/`u`/`d`、`g`/`G` 跳转至顶部/底部进行导航,按 `Escape` 或 `q` 关闭。 |
为避免与其他 pi 扩展冲突,请在
`/extensions/pi-autoresearch.json` 中覆盖或禁用这些快捷键。`` 是当前活动的 pi 配置
文件目录(通常是 `~/.pi/agent`,或在设置了 `PI_CODING_AGENT_DIR` 时使用该值):
```
{
"shortcuts": {
"fullscreenDashboard": "ctrl+shift+y"
}
}
```
使用 `null` 跳过注册快捷键。省略的快捷键将保留其默认值。
### UI
- **面板小组件** —— 始终在编辑器上方可见:包含 commit、指标、状态和描述列的完整结果表。
- **置信度分数** —— 运行 3 次以上后,显示最佳改进与会话基线噪声的对比情况。≥2.0×(绿色)= 可能是实质性改进,1.0–2.0×(黄色)= 高于噪声但幅度较小,<1.0×(红色)= 属于噪声范围内。
- **全屏覆盖层** —— `Ctrl+Shift+F` 打开可滚动的全终端面板。为正在运行的实验显示带有耗时的实时动态图标(spinner)。
### 技能
**`autoresearch-create`** 会询问几个问题(或根据上下文推断)关于你的目标、命令、指标和涉及文件的信息——然后写入两个文件并立即启动循环:
**`autoresearch-finalize`** 将充满干扰项的 autoresearch 分支转化为干净、独立的分支——每个逻辑更改一个分支,每个分支都从 merge-base 开始。分组之间不能共享文件,因此每个分支都可以独立审查和合并。
**`autoresearch-hooks`** *(可选)* 帮助为会话编写 `.auto/hooks/before.sh` 和 `.auto/hooks/after.sh`。它在 [`skills/autoresearch-hooks/examples/`](skills/autoresearch-hooks/examples/) 中附带了十个参考脚本(外部搜索、学习日志、原生通知、防抖、想法轮换等)——该技能负责处理约定,你只需选择灵感来源。核心 autoresearch 循环本身对 hook 无感知。
所有会话文件都存放在工作目录根目录下的单个 `.auto/` 子文件夹中——只需在回退、gitignore 和清理期间保留这一个文件夹。(仍在运行中的会话仍会读取旧的扁平化 `autoresearch.*` 文件。)
| 文件 | 用途 |
|------|---------|
| `.auto/prompt.md` | 会话文档——目标、指标、涉及文件、已尝试的内容。新的智能体仅凭此文件即可恢复工作。 |
| `.auto/measure.sh` | 基准测试脚本——预检查、运行工作负载、输出 `METRIC name=number` 行。 |
| `.auto/log.jsonl` | 每次运行仅追加的日志(由工具写入)。 |
| `.auto/checks.sh` | *(可选)* 背压检查——测试、类型、lint。在每次通过的基准测试之后运行。失败会阻止 `keep`。 |
| `.auto/hooks/` | *(可选)* 在迭代前后触发运行的可执行脚本(`before.sh`,`after.sh`)。其标准输出将作为引导消息传递给智能体。 |
## 安装
```
pi install npm:pi-autoresearch
```
手动安装
```
cp -r extensions/pi-autoresearch ~/.pi/agent/extensions/
cp -r skills/autoresearch-create ~/.pi/agent/skills/
```
然后在 pi 中运行 `/reload`。
## 用法
### 1. 启动 autoresearch
```
/skill:autoresearch-create
```
智能体会询问你的目标、命令、指标和涉及文件——或者从上下文中推断它们。然后它会创建一个分支,写入 `.auto/prompt.md` 和 `.auto/measure.sh`,运行基线测试,并立即开始循环。
### 2. 循环
智能体自主运行:编辑 → 提交 → `run_experiment` → `log_experiment` → 保留或回退 → 重复。除非被打断,否则它永远不会停止。
每个结果都会作为一行追加到你项目中的 `.auto/log.jsonl` 里——每次运行一行。这意味着:
- **重启后依然存活** —— 智能体可以通过读取该文件来恢复会话
- **上下文重置后依然存活** —— `.auto/prompt.md` 记录了已经尝试过的内容,因此新的智能体可以获得完整的上下文
- **人类可读** —— 随时打开它以查看完整历史记录
- **感知分支** —— 每个分支都有其自己的会话
### 3. 整理为可审查的分支
```
/skill:autoresearch-finalize
```
智能体读取 `.auto/log.jsonl`,将保留的实验分组为逻辑变更集,提出分组方案供你批准,然后从 merge-base 创建独立的分支。每次提交的消息中都包含指标改进情况。各分组之间不能共享文件,因此各个分支可以独立审查和合并。
### 4. 监控进度
- **小组件** —— 完整的结果表,始终在编辑器上方可见
- **`Ctrl+Shift+F`** —— 全屏可滚动面板覆盖层(配置键:`shortcuts.fullscreenDashboard`)
- **`/autoresearch export`** —— 在浏览器中打开带有图表和分享卡片的实时面板
- **`Escape`** —— 随时打断并要求总结
## 示例领域
| 领域 | 指标 | 命令 |
|--------|--------|---------|
| 测试速度 | 秒数 ↓ | `pnpm test` |
| 打包体积 | KB ↓ | `pnpm build && du -sb dist` |
| LLM 训练 | val_bpb ↓ | `uv run train.py` |
| 构建速度 | 秒数 ↓ | `pnpm build` |
| Lighthouse | 性能分数 ↑ | `lighthouse http://localhost:3000 --output=json` |
## 工作原理
**扩展** 是与领域无关的基础设施。**技能** 编码了领域知识。这种分离意味着一个扩展可以服务于无限的领域。
```
┌──────────────────────┐ ┌──────────────────────────┐
│ Extension (global) │ │ Skill (per-domain) │
│ │ │ │
│ run_experiment │◄────│ command: pnpm test │
│ log_experiment │ │ metric: seconds (lower) │
│ widget + dashboard │ │ scope: vitest configs │
│ │ │ ideas: pool, parallel… │
└──────────────────────┘ └──────────────────────────┘
```
有两个文件能让会话在重启和上下文重置后依然保持活动状态:
```
.auto/log.jsonl — append-only log of every run (metric, status, commit, description)
.auto/prompt.md — living document: objective, what's been tried, dead ends, key wins
```
一个没有记忆的全新智能体也可以读取这两个文件,并从上一次会话中断的地方继续工作。
## 配置(可选)
在你的 pi 会话目录中创建 `.auto/config.json` 以自定义行为:
```
{
"workingDir": "/path/to/project",
"maxIterations": 50
}
```
| 字段 | 类型 | 描述 |
|-------|------|-------------|
| `workingDir` | string | 覆盖所有 autoresearch 操作(文件 I/O、命令执行和 git)的目录。支持绝对或相对路径(基于 pi 会话的 cwd 进行解析)。配置文件本身始终保留在会话 cwd 下。如果目录不存在则失败。 |
| `maxIterations` | number | 自动停止前的最大实验次数。智能体会收到停止指令,并且在初始化新片段之前不会运行更多实验。 |
### 长时间运行的循环和上下文
该循环旨在跨越上下文限制进行无人值守运行。当 pi 的 [auto-compaction](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/compaction.md) 总结了对话中较早的部分时,autoresearch 会检测到由此产生的空闲状态,并重新提示智能体在继续之前重新读取 `.auto/prompt.md`、`.auto/log.jsonl` 的尾部、`.auto/ideas.md` 和 `git log`。所有进度都持久化存储在这些文件中,因此压缩后的对话回合会从事实来源中重新注水,而不是依赖于在压缩中幸存下来的任何内容。无需调整——如果 pi 的自动压缩功能已启用(默认情况),它就会直接生效。
## 置信度评分
在会话中进行 3 次以上的实验后,pi-autoresearch 会计算一个 **置信度分数** —— 即最佳改进与会话的基线噪声相比的情况。这有助于将真正的提升与基准测试的波动区分开来,尤其是在 ML 训练、Lighthouse 分数或不稳定的基准测试等嘈杂数据信号中。
**工作原理:**
- 使用当前片段中所有指标值的 [Median Absolute Deviation (MAD)](https://en.wikipedia.org/wiki/Median_absolute_deviation) 作为可靠的噪声估计器。
- 置信度 = `|best_improvement| / MAD`。分数为 2.0× 意味着最佳改进是基线噪声的两倍。
- 显示在小组件、全屏面板和 `log_experiment` 输出中。
- 每次结果都会持久化到 `.auto/log.jsonl` 中,以便进行事后分析。
- **仅供参考** —— 绝不自动丢弃。当置信度较低时,系统会引导智能体重新运行实验,但最终保留/丢弃的决定权仍在智能体。
| 置信度 | 颜色 | 含义 |
|-----------|-------|---------|
| ≥ 2.0× | 🟢 绿色 | 改进很可能是实质性的 |
| 1.0–2.0× | 🟡 黄色 | 高于噪声但幅度较小 |
| < 1.0× | 🔴 红色 | 属于噪声范围内 —— 考虑重新运行以进行确认 |
## 背压检查(可选)
创建 `.auto/checks.sh` 以在每次通过基准测试后运行正确性检查(测试、类型、lint)。这确保优化不会破坏原有功能。
```
#!/bin/bash
set -euo pipefail
pnpm test --run
pnpm typecheck
```
**工作原理:**
- 如果文件不存在,一切行为与以前完全相同 —— 对循环没有任何改变。
- 如果存在,它会在每次以退出代码 0(通过)结束的基准测试之后自动运行。
- 检查执行时间**不会**影响主要指标。
- 如果检查失败,实验将被记录为 `checks_failed`(与崩溃行为相同 —— 不提交,回退更改)。
- `checks_failed` 状态在面板中单独显示,以便你可以将正确性失败与基准测试崩溃区分开来。
- 检查具有独立的超时时间(默认为 300 秒,可通过 `run_experiment` 中的 `checks_timeout_seconds` 进行配置)。
## Hooks(可选)
将可执行脚本放入 `.auto/hooks/` 中,以便在迭代边界处运行代码。Hooks **对智能体是透明的** —— 智能体调用工具并查看结果;hook 在后台运行,没有任何直接暴露给智能体的界面。
- `.auto/hooks/before.sh` —— 在每次迭代之前触发(在 `/autoresearch` 激活时以及每次 `log_experiment` 结束时,在 `after.sh` 之后)。用于前瞻性工作:获取研究数据,为下一次尝试预设上下文。
- `.auto/hooks/after.sh` —— 在每次 `log_experiment` 结束时触发。用于回顾性:记录学习心得、发送通知。
**约定:**
- 必须是可执行文件(`chmod +x`)。在回退操作中会被保留 —— 整个 `.auto/` 文件夹都会存活(旧的 `autoresearch.*` 工件也一样)。
- **Stdin** —— 单行上的 JSON 对象。结构取决于阶段(见下文)。使用 `jq` 提取字段。
- **Stdout** 作为引导消息传递给智能体(上限为 8 KB)。空的 stdout = 静默。
- 非零退出或超过 30 秒超时将向智能体发送错误提示。
- 每次触发都会向 `.auto/log.jsonl` 追加一条 `{"type":"hook",…}` 记录,以便进行监控。
**`before.sh` 的 stdin**(在全新激活时,`last_run` 为 `null`):
```
{
"event": "before",
"cwd": "/path/to/workdir",
"next_run": 6,
"last_run": {
"run": 5, "status": "discard", "metric": 42.1,
"description": "…",
"asi": { "hypothesis": "…", "next_focus": "…" }
},
"session": {
"metric_name": "total_ms", "metric_unit": "ms", "direction": "lower",
"baseline_metric": 40.7, "best_metric": 33.5,
"run_count": 5, "goal": "optimize sort speed"
}
}
```
**`after.sh` 的 stdin:**
```
{
"event": "after",
"cwd": "/path/to/workdir",
"run_entry": {
"run": 6, "status": "discard", "metric": 38.9,
"description": "…",
"asi": { "hypothesis": "…", "learned": "…" }
},
"session": { "metric_name": "total_ms", "direction": "lower", "baseline_metric": 40.7, "best_metric": 33.5, "run_count": 6, "goal": "…" }
}
```
**智能体信号。** 智能体在其 `log_experiment` 调用中写入 `description` 和 `asi.*` 字段,是为了供其未来的自身进行推理。Hook 会机会性地挖掘智能体自然使用的任何字段 —— `asi.hypothesis`、`asi.next_focus`、`description` 等。这里没有专门的“hook 输入”字段;智能体并不知道 hook 的存在。
**示例。** 两个阶段的参考脚本位于 [`skills/autoresearch-hooks/examples/`](skills/autoresearch-hooks/examples/) —— 外部搜索、qmd 文档搜索、持久化学习记录、原生通知、git 打标签、防抖、想法轮换、假设反思、上下文轮换。将其中一个复制到会话的 `.auto/hooks/` 目录中,进行修改,然后执行 `chmod +x`。
## 前置条件
1. **安装 pi** —— 按照 [pi.dev](https://pi.dev/) 上的说明进行操作
2. 用于你首选的 LLM 提供商的 **API key**(在 pi 中配置)
## 控制成本
Autoresearch 循环自主运行,可能会消耗大量 token。有两种方法可以限制支出:
- **API key 限制** —— 大多数提供商允许你设置每个 key 或每月的预算。请查看你的提供商的面板。
- **`maxIterations`** —— 在 `.auto/config.json` 中限制每个会话的实验次数:
{
"maxIterations": 30
}
## 许可证
MIT标签:AI编程助手, SOC Prime, 人工智能, 实验跟踪, 开发工具, 性能优化, 检测绕过, 用户模式Hook绕过, 自动化攻击, 自动化测试