SelenAI 实战教程:用沙箱化 Lua 让 AI 编程 Agent 安全执行代码
AI 编程 Agent 的「读文件 → 改代码 → 运行验证」链路看似简单,但当你真正放手让 Agent 操作工作目录时,一个关键问题就浮现了:你该怎么信任它调用的每个工具?
大部分 Agent 框架的解决方案是「把所有系统命令直接暴露给 LLM」——这等于告诉模型它可以跑任何 shell 命令。SelenAI 走了一条完全不同的路:给模型一个沙箱化的 Lua 虚拟机,让它在受限环境里执行代码。读完本文你会理解这套设计为什么比直接暴露 shell 更安全,以及如何上手使用它。
SelenAI 是什么
SelenAI 是一个终端原生的 AI 结对编程环境,用 Rust 编写,核心设计理念是透明度和沙箱安全。它不像 Cursor 或 Claude Code 那样让 Agent 直接操作文件系统,而是给 AI 一个 Lua 沙箱——模型只能通过沙箱暴露的有限 API 来读写文件和发起 HTTP 请求。写入操作还额外需要人工审批(/tool run)。
整个界面分为三个面板:
- 对话面板(顶部)——显示你和 AI 助理的聊天记录
- 工具活动面板(中间)——记录每个 Lua 脚本的执行状态和输出
- 输入面板(底部)——你的输入框
快速上手
SelenAI 需要 Rust 工具链。安装后只需要三步就能运行:
git clone https://github.com/Almclean/selenai cd selenai cp selenai.toml selenai.toml.local # 创建本地配置
编辑 selenai.toml.local,设置 LLM 提供商(也可以用内置的 stub 客户端离线测试):
provider = "openai" model_id = "gpt-4o-mini" streaming = true allow_tool_writes = false
然后运行:
export OPENAI_API_KEY="sk-..." cargo run
你会看到带 ASCII 标志的 TUI 界面,底部的输入框等待你的第一行消息。
沙箱 Lua 如何工作
这是 SelenAI 最值得关注的设计。LLM 在对话中可以调用一个工具:lua_run_script。该工具执行时,代码在一个完全隔离的 Lua 5.4 虚拟机中运行,没有 os 库,没有网络 require,没有文件系统全局权限。
沙箱暴露的 API 表:
| 函数 | 作用 |
|---|---|
rust.read_file(path) | 读取仓库内的 UTF-8 文件 |
rust.list_dir(path) | 列出目录内容 |
rust.write_file(path, contents) | 写入文件(需审批) |
rust.http_request({ url, method?, headers?, body? }) | 发起 HTTP 请求 |
rust.log({ level?, message }) | 写入工具日志 |
fs.read / fs.write / fs.list | 文件操作的简化封装 |
路径穿越被阻止——沙箱会验证所有路径都在仓库根目录内。写入操作需要配置 allow_tool_writes = true 并且 每次执行时用 /tool run 手动批准。
这种设计比直接暴露 bash 或 sh 给 LLM 更可控的几个原因:
- API 清单可审计——Lua 沙箱的 host 函数是有限且事先定义的,LLM 能做的事情都在预设范围内
- 没有 side channel——没有
os.execute(),LLM 无法启动子进程 - 写操作显式审批——AI 会提前告诉你它要写什么,你批准后才执行
日常工作流
在 SelenAI 的 TUI 中,三个面板用 Tab 切换焦点,Up/Down 滚动。核心交互模式:
自然语言对话:直接输入消息,LLM 会响应文本或调用 Lua 工具来验证代码。
直接执行 Lua:输入 /lua print(rust.read_file("Cargo.toml")) 可以绕过 LLM 直接测试沙箱。
审批工具调用:当沙箱尝试写入文件时,输入 /tool run 批准,或 /tool skip 跳过。
查看会话日志:每次退出后,会话记录会写到 .selenai/logs/ 目录下,按时间戳分目录保存,包含完整对话转录和工具调用日志。
实际场景演练
假设你要让 SelenAI 帮你修复一个 TypeScript 文件中的 bug:
- 发送「读取
src/index.ts并检查第 42 行的逻辑」 - LLM 会调用
rust.read_file("src/index.ts")—— 读取结果会出现在工具面板 - 看到问题后,LLM 提出修复方案
- 你确认后,LLM 调用
rust.write_file("src/index.ts", 修正后的内容) - 工具面板提示「写入等待批准」,你输入
/tool run确认
整个过程,LLM 无法 执行任意 shell 命令、安装依赖、或删除文件。就算模型被恶意 prompt 注入,它的破坏半径也被 Lua 沙箱限制。
配置深入
SelenAI 的配置在 selenai.toml(或 SELENAI_CONFIG 环境变量指向的文件)中。除了基本的 provider 设置,几个值得关注的选项:
streaming——开启后 LLM 响应增量显示,体验更流畅allow_tool_writes——全局写入开关,设为true后仍需/tool run逐次批准log_dir——日志输出目录,默认为.selenai/logsSELENAI_DEBUG_OPENAI=1——调试时打印 API 请求/响应
配置采用分层次加载:.env 文件 → TOML 配置 → 环境变量覆盖,密钥可以在 .env 中管理,避免提交到版本控制。
小结
SelenAI 给 AI 编程 Agent 的安全提供了一条不同于传统「白名单命令」的路径:不是限制 LLM 能调用什么外部命令,而是把 LLM 的能力本身装进一个沙箱。Lua 虚拟机作为工具执行层,既保持了表达能力(文件 I/O、HTTP 请求、日志记录),又把可能的破坏半径控制到最小。
对于关注代码 Agent 安全的开发者来说,这个架构思路值得借鉴——它把「信任」的问题从「相信 LLM 不会干坏事」转变为「相信沙箱能兜住所有坏事」,后者显然更容易验证和审计。
相关链接