2026年6月27日 1 分钟阅读

SelenAI 实战教程:用沙箱化 Lua 让 AI 编程 Agent 安全执行代码

tinyash 0 条评论

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 手动批准。

这种设计比直接暴露 bashsh 给 LLM 更可控的几个原因:

  1. API 清单可审计——Lua 沙箱的 host 函数是有限且事先定义的,LLM 能做的事情都在预设范围内
  2. 没有 side channel——没有 os.execute(),LLM 无法启动子进程
  3. 写操作显式审批——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:

  1. 发送「读取 src/index.ts 并检查第 42 行的逻辑」
  2. LLM 会调用 rust.read_file("src/index.ts") —— 读取结果会出现在工具面板
  3. 看到问题后,LLM 提出修复方案
  4. 你确认后,LLM 调用 rust.write_file("src/index.ts", 修正后的内容)
  5. 工具面板提示「写入等待批准」,你输入 /tool run 确认

整个过程,LLM 无法 执行任意 shell 命令、安装依赖、或删除文件。就算模型被恶意 prompt 注入,它的破坏半径也被 Lua 沙箱限制。

配置深入

SelenAI 的配置在 selenai.toml(或 SELENAI_CONFIG 环境变量指向的文件)中。除了基本的 provider 设置,几个值得关注的选项:

  • streaming——开启后 LLM 响应增量显示,体验更流畅
  • allow_tool_writes——全局写入开关,设为 true 后仍需 /tool run 逐次批准
  • log_dir——日志输出目录,默认为 .selenai/logs
  • SELENAI_DEBUG_OPENAI=1——调试时打印 API 请求/响应

配置采用分层次加载:.env 文件 → TOML 配置 → 环境变量覆盖,密钥可以在 .env 中管理,避免提交到版本控制。

小结

SelenAI 给 AI 编程 Agent 的安全提供了一条不同于传统「白名单命令」的路径:不是限制 LLM 能调用什么外部命令,而是把 LLM 的能力本身装进一个沙箱。Lua 虚拟机作为工具执行层,既保持了表达能力(文件 I/O、HTTP 请求、日志记录),又把可能的破坏半径控制到最小。

对于关注代码 Agent 安全的开发者来说,这个架构思路值得借鉴——它把「信任」的问题从「相信 LLM 不会干坏事」转变为「相信沙箱能兜住所有坏事」,后者显然更容易验证和审计。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。