291 lines
6.6 KiB
Markdown
291 lines
6.6 KiB
Markdown
|
|
# AI Agent Linux远程运行时
|
|||
|
|
|
|||
|
|
`Linux` `SSH` `AI Agent` `远程执行` `CLI` `审计日志`
|
|||
|
|
|
|||
|
|
# linux-remote-tool
|
|||
|
|
|
|||
|
|
CLI 名称是 `lrt`。
|
|||
|
|
|
|||
|
|
给 AI Agent 用的 Linux 远程操作运行时。
|
|||
|
|
|
|||
|
|
推荐结构:
|
|||
|
|
- 共享运行时
|
|||
|
|
- skill 编排
|
|||
|
|
- 薄接入壳
|
|||
|
|
|
|||
|
|
支持:
|
|||
|
|
- SSH 连通性检查
|
|||
|
|
- 持久会话执行命令
|
|||
|
|
- 上传文件
|
|||
|
|
- 下载文件
|
|||
|
|
- SQLite 审计日志
|
|||
|
|
- CLI 查询审计日志
|
|||
|
|
- Codex skill 接入
|
|||
|
|
- Alma 薄插件接入
|
|||
|
|
- Pi skill 接入
|
|||
|
|
|
|||
|
|
## 安装
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
uv sync --group dev
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
pip install -e .[dev]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 配置
|
|||
|
|
|
|||
|
|
先准备环境变量:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cp .env.example .env
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`.env` 只在私钥有口令时需要:
|
|||
|
|
|
|||
|
|
```env
|
|||
|
|
MY_SERVER_KEY_PASS=your_key_passphrase
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
再准备主机配置:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cp hosts.yaml.example hosts.yaml
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
最小配置:
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
hosts:
|
|||
|
|
my-server:
|
|||
|
|
host: 192.168.1.100
|
|||
|
|
username: root
|
|||
|
|
auth:
|
|||
|
|
method: key
|
|||
|
|
key_path: ~/.ssh/id_ed25519
|
|||
|
|
passphrase_env: MY_SERVER_KEY_PASS
|
|||
|
|
|
|||
|
|
session:
|
|||
|
|
idle_timeout_seconds: 300
|
|||
|
|
|
|||
|
|
audit:
|
|||
|
|
enabled: true
|
|||
|
|
db_path: ./logs/audit.db
|
|||
|
|
|
|||
|
|
policy:
|
|||
|
|
enabled: true
|
|||
|
|
default_mode: blocklist
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## CLI
|
|||
|
|
|
|||
|
|
查看帮助:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
uv run lrt --help
|
|||
|
|
uv run lrt --h
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
常用命令:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
uv run lrt list-hosts
|
|||
|
|
uv run lrt test-connection my-server
|
|||
|
|
uv run lrt run-command my-server "uname -a"
|
|||
|
|
uv run lrt upload-file my-server ./a.txt /tmp/a.txt
|
|||
|
|
uv run lrt download-file my-server /tmp/a.txt ./a.txt
|
|||
|
|
uv run lrt audit-logs
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
审计日志过滤:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
uv run lrt audit-logs --limit 10
|
|||
|
|
uv run lrt audit-logs --host-name my-server
|
|||
|
|
uv run lrt audit-logs --operation-type run_command
|
|||
|
|
uv run lrt audit-logs --start-time 2026-03-03T00:00:00Z --end-time 2026-03-03T23:59:59Z
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
默认输出 JSON。
|
|||
|
|
|
|||
|
|
## 架构
|
|||
|
|
|
|||
|
|
本仓库将三层职责分离:
|
|||
|
|
|
|||
|
|
- 运行时:`src/linux_remote_tool/runtime_adapter.py`
|
|||
|
|
- skill 编排:`skills/lr/SKILL.md`
|
|||
|
|
- 平台壳:`.codex-plugin/plugin.json`、`.alma-plugin/manifest.json`、`package.json`
|
|||
|
|
|
|||
|
|
各层职责:
|
|||
|
|
|
|||
|
|
- 运行时只负责工具定义和调用分发
|
|||
|
|
- skill 负责单 agent / 多 agent 的调用流程、约束和汇总方式
|
|||
|
|
- manifest 或 package 只负责宿主接入、发现和权限声明
|
|||
|
|
|
|||
|
|
不要把多 agent 编排写进平台接入壳。
|
|||
|
|
|
|||
|
|
## Codex
|
|||
|
|
|
|||
|
|
Codex 侧保留一个很薄的接入壳:
|
|||
|
|
|
|||
|
|
- `.codex-plugin/plugin.json`
|
|||
|
|
- `skills/lr/SKILL.md`
|
|||
|
|
|
|||
|
|
另外补了一个本地桥接入口,方便 Codex 或其他宿主进程直接调用现有运行时:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
uv run lrt-codex tools
|
|||
|
|
uv run lrt-codex invoke list_hosts
|
|||
|
|
uv run lrt-codex invoke run_command --args '{"host_name":"my-server","command":"uname -a"}'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`tools` 返回工具定义 JSON,`invoke` 返回调用结果 JSON。
|
|||
|
|
|
|||
|
|
Codex 侧通过接入壳暴露 skill,真正的调用流程放在 `skills/lr/SKILL.md`。
|
|||
|
|
|
|||
|
|
## Pi
|
|||
|
|
|
|||
|
|
本仓库支持 Pi 的 skill 模式:
|
|||
|
|
|
|||
|
|
- `package.json`
|
|||
|
|
- `skills/lr/SKILL.md`
|
|||
|
|
|
|||
|
|
说明:
|
|||
|
|
|
|||
|
|
- 不做 Pi extension
|
|||
|
|
- 不重复包装一层 TypeScript 工具注册
|
|||
|
|
- Pi 侧直接通过 skill 调用本地 `lrt-codex`
|
|||
|
|
- 多 agent 规则统一放在 skill
|
|||
|
|
- 远程执行、文件传输、审计逻辑仍只在 Python 核心里维护
|
|||
|
|
|
|||
|
|
如果要在 Pi 里接入本仓库,推荐用 package/skills 方式安装或加载此 skill。
|
|||
|
|
|
|||
|
|
## 多 Agent
|
|||
|
|
|
|||
|
|
建议规则:
|
|||
|
|
|
|||
|
|
- 优先复用 batch tool,不要一上来就拆多个 agent
|
|||
|
|
- 确实需要拆分时,按 host 集合或任务类型切分
|
|||
|
|
- 每个 agent 都走同一个 `lrt-codex` bridge
|
|||
|
|
- skill 负责约束和汇总
|
|||
|
|
- 接入壳不保存多 agent 状态,不承载编排逻辑
|
|||
|
|
|
|||
|
|
## 多平台接入
|
|||
|
|
|
|||
|
|
共享能力位于:
|
|||
|
|
|
|||
|
|
- `src/linux_remote_tool/tools.py`
|
|||
|
|
- `src/linux_remote_tool/session_manager.py`
|
|||
|
|
- `src/linux_remote_tool/runtime_adapter.py`
|
|||
|
|
|
|||
|
|
其中 `src/linux_remote_tool/runtime_adapter.py` 是共享运行时入口,负责:
|
|||
|
|
|
|||
|
|
- 返回统一工具定义
|
|||
|
|
- 按工具名分发调用
|
|||
|
|
|
|||
|
|
各平台只做薄适配,不复制 SSH、审计、配置等业务逻辑。
|
|||
|
|
|
|||
|
|
### Alma
|
|||
|
|
|
|||
|
|
Alma 相关文件:
|
|||
|
|
|
|||
|
|
- `.alma-plugin/manifest.json`
|
|||
|
|
- `.alma-plugin/runtime_adapter.py`
|
|||
|
|
|
|||
|
|
说明:
|
|||
|
|
|
|||
|
|
- `.alma-plugin/manifest.json` 是 Alma 接入清单
|
|||
|
|
- `.alma-plugin/runtime_adapter.py` 只做转发
|
|||
|
|
- 不在 Alma 接入壳里写多 agent 编排
|
|||
|
|
|
|||
|
|
### Codex
|
|||
|
|
|
|||
|
|
Codex 相关文件:
|
|||
|
|
|
|||
|
|
- `.codex-plugin/plugin.json`
|
|||
|
|
- `src/linux_remote_tool/codex_bridge.py`
|
|||
|
|
|
|||
|
|
说明:
|
|||
|
|
|
|||
|
|
- `.codex-plugin/plugin.json` 是 Codex 的薄接入壳
|
|||
|
|
- `codex_bridge.py` 提供本地桥接命令 `lrt-codex`
|
|||
|
|
- `lrt-codex tools` 输出工具定义
|
|||
|
|
- `lrt-codex invoke` 调用单个工具
|
|||
|
|
- skill 负责单 agent / 多 agent 的使用方式
|
|||
|
|
|
|||
|
|
### Pi
|
|||
|
|
|
|||
|
|
Pi 相关文件:
|
|||
|
|
|
|||
|
|
- `package.json`
|
|||
|
|
- `skills/lr/SKILL.md`
|
|||
|
|
|
|||
|
|
说明:
|
|||
|
|
|
|||
|
|
- `package.json` 只暴露 `pi.skills`
|
|||
|
|
- Pi 通过 `skills/lr/SKILL.md` 使用本地桥接
|
|||
|
|
- 执行时不直接重写 SSH 逻辑,统一转发到 `lrt-codex`
|
|||
|
|
- 多 agent 不单独做 extension,继续走 skill
|
|||
|
|
|
|||
|
|
### 目录约定
|
|||
|
|
|
|||
|
|
建议后续按此规则扩展:
|
|||
|
|
|
|||
|
|
- 平台专属清单放到 `.<platform>-plugin/`
|
|||
|
|
- 平台专属薄包装放到该目录,或放到 `src/linux_remote_tool/` 下单独命名
|
|||
|
|
- 单 agent / 多 agent 流程统一收在 `skills/`
|
|||
|
|
- Pi 这类 package 型宿主,优先放 `skills/` 和 `package.json`
|
|||
|
|
- 共享工具定义和调用逻辑继续收敛在 `src/linux_remote_tool/runtime_adapter.py`
|
|||
|
|
- 不要在不同平台重复实现同一套工具
|
|||
|
|
- 不要在 manifest 里塞编排逻辑
|
|||
|
|
|
|||
|
|
### 新增平台时的步骤
|
|||
|
|
|
|||
|
|
如果后续还要接入其他平台,建议只做以下几步:
|
|||
|
|
|
|||
|
|
1. 新建平台清单目录,如 `.<platform>-plugin/`
|
|||
|
|
2. 让平台入口转发到 `src/linux_remote_tool/runtime_adapter.py`
|
|||
|
|
3. 如果平台需要命令行桥接,再单独加一个类似 `lrt-codex` 的入口
|
|||
|
|
4. 在 `skills/` 里写单 agent / 多 agent 的调用规则
|
|||
|
|
5. 对 Pi 这类 package 宿主,优先用 skill 复用现有 CLI / bridge
|
|||
|
|
6. 不改现有 SSH、文件传输、审计逻辑
|
|||
|
|
|
|||
|
|
这样改动最小,也最不容易把各平台适配搞乱。
|
|||
|
|
|
|||
|
|
## Runtime Tools
|
|||
|
|
|
|||
|
|
可用工具:
|
|||
|
|
|
|||
|
|
- `list_hosts()`
|
|||
|
|
- `test_connection(host_name, timeout=15)`
|
|||
|
|
- `test_connection_batch(host_names, timeout=15, max_workers=5)`
|
|||
|
|
- `run_command(host_name, command, timeout=60)`
|
|||
|
|
- `run_command_batch(host_names, command, timeout=60, max_workers=5)`
|
|||
|
|
- `upload_file(host_name, local_path, remote_path)`
|
|||
|
|
- `upload_file_batch(host_names, local_path, remote_path, max_workers=5)`
|
|||
|
|
- `download_file(host_name, remote_path, local_path)`
|
|||
|
|
- `download_file_batch(host_names, remote_path, local_path_template, max_workers=5)`
|
|||
|
|
|
|||
|
|
入口:
|
|||
|
|
|
|||
|
|
- `.alma-plugin/runtime_adapter.py`
|
|||
|
|
- `.alma-plugin/manifest.json`
|
|||
|
|
- `src/linux_remote_tool/runtime_adapter.py`
|
|||
|
|
|
|||
|
|
## 规则
|
|||
|
|
|
|||
|
|
- 只支持密钥登录
|
|||
|
|
- 主机公钥必须已在本机 `known_hosts` 中
|
|||
|
|
- 默认复用持久会话
|
|||
|
|
- 空闲超时默认 300 秒
|
|||
|
|
- 危险命令会被拦截
|
|||
|
|
- 审计日志写入 `./logs/audit.db`
|
|||
|
|
|
|||
|
|
## 测试
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
uv run --group dev python -m pytest
|
|||
|
|
```
|