内容
# aexp
[](https://go.dev/)
[](https://github.com/murasame612/aexp/releases)
[](https://github.com/murasame612/aexp/releases)
[English](README.md) | [中文](README_zh.md)
适用于 SSH 机器的实验控制工具。
`aexp` 为人类和代码代理提供了一个小型控制面板,用于在远程 GPU 盒上运行研究实验。它保留了 SSH 的便利性,但添加了运行记录、tmux 支持的执行、实时日志、资源监控、结构化指标和审计跟踪。

## 为什么使用 aexp?
研究实验通常从多个 SSH 会话、`nohup` 命令、tmux 窗格、复制的日志路径和半记得的 GPU 状态开始。这对人类来说很痛苦,对代理来说更糟糕:一旦聊天或终端会话更改,代理就不再知道提交了什么、在哪里、以及运行是否仍然存在。
`aexp` 使这些操作变得明确:
| 需要 | 使用原始 SSH | 使用 aexp |
|---|---|---|
| 运行快速检查命令 | `ssh host ...` | `aexp exec --resource gpu -- ...` |
| 启动长时间实验 | 手动 `tmux` / `nohup` | `aexp run submit ...` |
| 稍后查找日志 | 记住路径 | `aexp run logs <run_id>` |
| 查看 GPU/CPU/RAM | 运行远程命令 | Web 仪表板和资源快照 |
| 在上下文丢失后恢复 | 从 shell 历史重建 | 查询运行、事件、指标和标记 |
| 保持设置/烟雾/正式运行分开 | 命名约定 | 一级 `--kind setup|smoke|formal|ablation` |
目前,`aexp` 针对 SSH 资源。该架构为 Docker、Slurm、Kubernetes 和本地执行留有空间,但开源路径故意简单:一个本地二进制文件、一个 SQLite 数据库、带有 SSH + tmux 的远程机器。
## 功能
- 注册带有根目录、默认 Conda 环境、GPU 标签、SOCKS 代理或 ProxyCommand 的 SSH 资源。
- 将长时间运行的任务提交到确定的远程 tmux 会话。
- 捕获 stdout、stderr、退出代码、时间戳和实时终端日志。
- 从 CLI 或浏览器跟随日志,同时运行仍在活动。
- 运行短的一次性命令,而不创建正式的运行记录。
- 发现项目运行时配置文件:`.venv`、`uv run`、Conda、Python、Torch、CUDA、候选日志和候选指标文件。
- 使用 rsync 将本地项目文件同步到资源。
- 从脚本发出 JSONL UI 事件,用于进度、参数、注释和指标。
- 在本地 SQLite 中存储资源、运行、事件、标记和历史记录。
## 安装
### 二进制发行版
```bash
curl -fsSL https://raw.githubusercontent.com/murasame612/aexp/main/scripts/install.sh | sh
aexp --help
```
安装程序下载适用于您的操作系统/架构的最新 GitHub 发布版本,并将 `aexp` 以及旧版/调试版 `aexp-event` 兼容性入口点安装到 `~/.local/bin`。
要安装特定版本或目录:
```bash
AEXP_VERSION=v0.1.0 sh -c "$(curl -fsSL https://raw.githubusercontent.com/murasame612/aexp/main/scripts/install.sh)"
AEXP_INSTALL_DIR=/usr/local/bin sh -c "$(curl -fsSL https://raw.githubusercontent.com/murasame612/aexp/main/scripts/install.sh)"
```
更新或卸载后:
```bash
aexp update
aexp update --stop-serve
aexp uninstall --yes
aexp uninstall --yes --purge-data
```
`aexp update` 下载匹配的 GitHub 发布资产,验证 `checksums.txt`,对新二进制文件进行烟雾测试,备份旧二进制文件,并重新创建 `aexp-event` 兼容性入口点。`aexp uninstall` 默认删除二进制文件和 MCP 客户端配置;它保留 `~/.aexp` 除非显式传递 `--purge-data`。
### 从源代码
```bash
git clone https://github.com/murasame612/aexp.git
cd aexp
go build -o aexp ./cmd/aexp
./aexp --help
```
远程机器不需要 `aexp`。它们需要:
- 来自您本地机器的 SSH 访问
- `bash`
- `tmux`
- 您的实验运行时,例如 Python、uv、Conda、CUDA 或项目脚本
- 可选:用于项目同步的 `rsync`
## 快速入门
初始化本地状态并启动本地仪表板:
```bash
aexp init
aexp serve --port 8080
```
打开 `http://localhost:8080`。

如果您使用 Codex、Claude Code 或 Hermes Agent,请安装 MCP 工具:
```bash
aexp mcp install --target all
```
MCP 工具允许代理调用 `aexp_exec`、`aexp_submit_run`、`aexp_project_run`、`aexp_sync_push`、`aexp_mark_run` 等结构化接口,而无需手动编辑 MCP JSON/TOML。
探索远程主机:
```bash
aexp resource explore 192.168.1.100 --user root
```
添加资源:
```bash
aexp resource add \
--name gpu-box \
--host 192.168.1.100 \
--user root \
--root-dir /workspace \
--conda-env research \
--gpu-indices 0
```
您也可以在浏览器中添加资源:

运行快速检查命令:
```bash
aexp exec --resource gpu-box -- nvidia-smi
aexp exec --resource gpu-box --cwd /workspace/project --project-env auto -- 'python -V'
```
提交跟踪实验:
```bash
aexp run submit \
--resource gpu-box \
--name ecl-itransformer \
--kind formal \
--cwd /workspace/Time-Series-Library \
--project-env auto \
--gpu-index 0 \
--log-paths 'logs/**/*.log' \
--metric-paths 'results/**/*.json' \
-- python train.py --data ECL --model iTransformer
```
观看:
```bash
aexp run list
aexp run snapshot run_xxx --json
aexp run events run_xxx --tail 50 --json
aexp run logs run_xxx --tail 100
```
运行页面显示运行类型、状态、GPU、命令、收藏/垃圾箱操作和高亮的发现:

本地主机访问默认情况下无需令牌。如果您绑定到非本地地址,远程浏览器/API 访问需要服务器打印的 API 令牌。
## 常见工作流程
### 一次性远程检查
使用 `exec` 进行有界限的检查和操作。它不会创建运行记录。
```bash
aexp exec --resource gpu-box -- 'df -h /workspace'
aexp exec --resource gpu-box --json -- 'du -sh /workspace/.aexp/runs/*'
aexp exec --resource gpu-box --timeout 120 -- 'find /workspace -name "*.pt" | wc -l'
```
如果命令看起来像训练作业,`aexp exec` 除非您传递 `--force`,否则会拒绝它。对于长时间实验,请使用 `run submit`。
### 长时间实验
`run submit` 创建一个持久运行:
- 本地 SQLite 记录
- 远程目录 `<root-dir>/.aexp/runs/<run_id>`
- 远程 `command.sh`
- 确定的 tmux 会话命名为 `aexp_<run_id>`
- stdout/stderr/终端日志
- 退出状态和时间戳
结构化 argv 模式是默认的:
```bash
aexp run submit --resource gpu-box -- python train.py --epochs 20
```
仅当您需要 shell 语法时才使用 shell 模式:
```bash
aexp run submit \
--resource gpu-box \
--shell -- 'echo start; python train.py 2>&1 | tee train.log'
```
有目的地使用运行类型:
```bash
aexp run submit --kind setup --no-gpu --resource gpu-box --shell -- 'uv sync'
aexp run submit --kind smoke --resource gpu-box -- python train.py --epochs 1
aexp run submit --kind formal --resource gpu-box -- python train.py --epochs 100
```
烟雾运行是连接性或线路检查。不要将它们视为实验结果。
### 项目配置
对于重复的项目工作,将资源、cwd、同步设置和配方放入项目本地的 `.aexp.yaml` 中。
```bash
aexp project init --resource gpu-box --cwd /workspace/project
aexp project doctor
aexp project sync --dry-run
aexp project sync
aexp project run setup --dry-run
aexp project run train
```
参见 [examples/python-ml](examples/python-ml) 以获取最小项目布局。
### 结构化指标和进度
在提交的运行中,`aexp` 设置 `AEXP_RUN_ID`、`AEXP_RUN_DIR` 和 `AEXP_UI_EVENTS`。训练和评估代码应该在执行过程中使用生成的帮助器写入结构化 JSONL 事件:
```python
from aexp_events import metric, progress, param, note
param("model", "iTransformer", trial=trial_id, variant="raw")
progress("epoch", current=local_epoch, total=20, trial=trial_id, variant="raw", stage="train")
metric("train/loss", train_loss, epoch=local_epoch, trial=trial_id, variant="raw", stage="train")
metric("val/loss", val_loss, epoch=local_epoch, trial=trial_id, variant="raw", split="val", stage="eval")
note("first checkpoint written")
```
使用短的、稳定的 `name` 值来表示数量本身(`train/loss`、`val/mse`、`epoch`、`trial`、`fold`)。在诸如 `series`、`variant`、`split` 和 `stage` 等字段中放置模型/数据/拆分/阶段上下文。对于超参数搜索,在试验中保持指标名称相同,保持 `epoch` 仅限于每个试验,并使用试验 + 稳定 `variant` 或 `series` 标签标识试验。不要在运行后重建遥测;使用运行标记进行后验注释。
```python
for trial_id, cfg in enumerate(search_space):
param("learning_rate", cfg.lr, trial=trial_id)
progress("trial", current=trial_id + 1, total=len(search_space))
for epoch in range(max_epochs):
progress("epoch", current=epoch + 1, total=max_epochs, trial=trial_id, stage="train")
metric("train/loss", train_loss, epoch=epoch + 1, trial=trial_id)
metric("val/loss", val_loss, epoch=epoch + 1, trial=trial_id, split="val")
```
不要在指标名称中编码完整的模型、数据集或试验配置。仪表板按上下文分组重复的进度更新,并渲染具有相同名称的指标为可比较的系列在一个图表上。
当 `aexp run snapshot`、`aexp run events`、MCP 事件工具或 Web UI 成功读取运行的 UI 事件文件时,`aexp` 将该 JSONL 流镜像在 `~/.aexp/event_cache/<run_id>.jsonl` 下。如果远程资源后来离线或临时容器消失,事件读取器会回落到本地缓存,并报告原始远程读取错误以及缓存的行。
代理可以直接读取相同的低噪声事件流,而无需刮取原始日志:
```bash
aexp run snapshot run_xxx --json
aexp run metrics run_xxx --latest --json
aexp run events run_xxx --tail 50 --json
```

单击一个指标会在原地展开它,以便在保持网格可读的同时使整个图表保持在附近:

运行参数呈现为密集的对齐卡片,而不是原始 JSON:

发出相同指标名称的运行可以在一个图表上进行比较:

### Web 仪表板
旧版仪表板仍然嵌入在 `/`。React/TypeScript 仪表板并行提供在 `/ui-v2`,因此现有部署可以使用旧入口点同时验证新的高容量控制台。

它包括:
- 带有 CPU/RAM/GPU 快照的资源卡
- 运行列表和运行详情
- 实时 stdout/stderr/终端日志
- 虚拟化运行和执行表格 `/ui-v2`
- 工作器支持的 UI 事件解析和指标图表 `/ui-v2`
- 证据链白板,用于手动假设、运行、计划、注释和结论链接
构建 React 仪表板时更改前端代码:
```bash
pnpm --dir web install
pnpm --dir web build
go build -o aexp ./cmd/aexp
```
- 结构化进度和指标
- 代理发现和运行标记


代理和人类可以为重要的运行附加轻量级发现。突出显示的运行在列表中保持可见,并且发现文本保持附加到运行:

## CLI 概述
```text
aexp init
aexp serve [--port 8080] [--daemon]
aexp mcp
aexp mcp install [--target codex|claude|hermes|all]
aexp mcp uninstall [--target codex|claude|hermes|all]
aexp resource explore <host>
aexp resource add --name <name> --host <host> --root-dir <dir>
aexp resource list [--json] [--verbose]
aexp resource update <name> ...
aexp resource remove <name>
aexp exec --resource <name> -- <command>
aexp run submit --resource <name> [flags] -- <program> [args...]
aexp run list [--json]
aexp run status <run_id> [--short] [--json]
aexp run snapshot <run_id> [--json]
aexp run events <run_id> [--tail 50] [--json]
aexp run metrics <run_id> [--latest] [--json]
aexp run logs <run_id> [--follow] [--source stdout|stderr]
aexp run cancel <run_id>
aexp run mark <run_id> --title ... --reason ... --evidence ...
aexp project init
aexp project doctor
aexp project doctor
aexp project sync
aexp project run <recipe>
aexp sync doctor --resource <name> <source> <target>
aexp sync push --resource <name> <source> <target>
aexp sync pull --resource <name> <source> <target>
```
完整的命令参考,请参见 [USAGE.md](USAGE.md)。
## 适用于代理的 MCP
`aexp` 可以作为 stdio MCP 服务器运行:
```bash
aexp mcp
```
在本地代理客户端注册:
```bash
# 安装/更新 Codex、Claude Code 和 Hermes Agent 的 MCP 配置。
aexp mcp install --target all
# 或仅安装一个客户端。
aexp mcp install --target codex
aexp mcp install --target claude
aexp mcp install --target hermes
# 删除生成的配置。
aexp mcp uninstall --target all
```
安装程序使用客户端自己的 MCP CLI (`codex mcp ...`、`claude mcp ...` 和 `hermes mcp ...`),并管理名为 `aexp` 的服务器。默认情况下,它将 MCP 服务器指向当前的 `aexp` 二进制文件,并设置 `AEXP_API_URL=http://127.0.0.1:8080/api/v1`。Hermes 代理自定义 MCP 服务器通过 `/usr/bin/env ... aexp mcp` 接收此环境,匹配 Hermes 的 `--command ... --args ...` 安装样式。
MCP 服务器为代理公开结构化工具:
- `aexp_agent_card`
- `aexp_init`
- `aexp_project_init`
- `aexp_list_resources`
- `aexp_doctor`
- `aexp_resource_explore`
- `aexp_resource_add`
- `aexp_resource_add_local`
- `aexp_resource_update`
- `aexp_resource_remove`
- `aexp_exec`
- `aexp_submit_run`
- `aexp_list_runs`
- `aexp_refresh_runs`
- `aexp_get_run_status`
- `aexp_get_run_snapshot`
- `aexp_tail_run_events`
- `aexp_get_run_metrics`
- `aexp_latest_run_metrics` (别名)
- `aexp_tail_run_logs`
- `aexp_cancel_run`
- `aexp_mark_run`
- `aexp_list_run_marks`
- `aexp_list_evidence_chains`
- `aexp_create_evidence_chain`
- `aexp_get_evidence_chain`
- `aexp_add_evidence_node`
- `aexp_add_evidence_edge`
- `aexp_list_matrices`
- `aexp_create_matrix`
- `aexp_get_matrix`
- `aexp_set_matrix_cell`
- `aexp_exec_history`
- `aexp_exec_show`
- `aexp_project_detect`
- `aexp_project_doctor`
- `aexp_project_run`
- `aexp_project_sync`
- `aexp_sync_doctor`
- `aexp_sync_push`
- `aexp_sync_pull`
- `aexp_sync_remote_pull`
- `aexp_cli`
当前实现包装本地 `aexp` 二进制文件,而不是复制执行器逻辑。这样可以保持行为与 CLI 相同:短命令仍使用 `aexp exec`,包括本地 API 快速路径,可以重用一个温暖的 `aexp serve` SSH 池,而长时间任务通过跟踪的 `run submit` 进行。活动训练应首先监视 `aexp_get_run_snapshot`、`aexp_tail_run_events` 或 `aexp_get_run_metrics`;原始 stdout/stderr 日志用于调试故障、OOM、挂起或丢失事件。每 30-60 秒轮询快照,然后在进度未更改时退回到 120 秒。证据链工具公开研究白板作为语义图。 使用 `aexp_get_evidence_chain` 读取紧凑的节点和类型化的边(`run_id`,简短介绍,项目卡摘要,标记标题/语句),然后使用运行工具检查任何运行的详细信息。代理可以创建注释、假设、实验、计划、结论或运行节点,并用类型化的边链接它们,但不应排列板:新节点仅接收一个简单的非重叠起始位置,以便稍后人类可以放置 UI。

`aexp_cli` 是一个兼容性逃生孔,用于完整的 `aexp` CLI,包括 `run cancel`、`run submit`、`sync push` 和 `resource update` 等变异操作。它仅阻止会使 MCP 进程本身挂起的命令(`serve`、`mcp` 和无边界 `--follow`)。优先使用专用工具,因为它们的模式更容易让代理调用正确,但通用 CLI 路径故意不是只读的。
## 数据模型
`aexp` 在 SQLite 中存储其本地控制平面状态:
```text
~/.aexp/aexp.db
```
远程运行文件位于注册资源根目录下:
```text
<root-dir>/.aexp/runs/<run_id>/
command.sh
status
exit_code
started_at
finished_at
logs/
stdout.log
stderr.log
terminal.log
```
## 安全模型
`aexp` 是个人或小型团队的研究工具,而不是多租户调度器。
- 它以您配置的 SSH 用户执行命令。
- `--cwd` 对于 aexp 管理的路径仅限于资源 `root_dir`。
- 诸如 `rm -rf /` 之类的危险命令模式被拒绝。
- 默认情况下,本地主机浏览器访问是方便的;远程访问需要 API 令牌。
- 绑定 `aexp serve --host 0.0.0.0` 公开服务。将其置于 SSH、VPN 或另一个受信任的访问层后面。
## 文档
- [USAGE.md](USAGE.md):完整的用户指南和命令示例
- [docs/concepts.md](docs/concepts.md):资源、运行、快照、事件
- [docs/development.md](docs/development.md):架构、实现说明、模块映射
- [docs/deployment.md](docs/deployment.md):守护进程和部署说明
- [docs/testing.md](docs/testing.md):构建和烟雾测试工作流程
- [docs/mod-security.md](docs/mod-security.md):安全边界
- [docs/mod-api.md](docs/mod-api.md):REST 和 WebSocket API
- [docs/mod-agent.md](docs/mod-agent.md):MCP 工具曲面
## 开发
```bash
go test ./...
go build -o aexp ./cmd/aexp
```
该存储库故意保持二进制文件自包含:Go 后端,嵌入式 HTML/CSS/JS 仪表板,SQLite 存储,并且没有 Node 构建管道。
## 状态
`aexp` 是从真实的研究工作流痛点中构建的早期软件。它今天对基于 SSH 的实验跟踪很有用,但对于多用户部署、非 SSH 后端以及与外部实验跟踪器的集成,存在粗糙的边缘。
欢迎贡献提高可靠性、文档、提供程序支持和面向代理的工作流的贡献。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器