在 OpenCode 中集成 SkillLite:为 AI 代码执行加上一道“原生沙箱防火墙” 1. 为什么 OpenCode 的 bash 工具需要一层 SkillLite 沙箱OpenCode 这类 AI 编程助手最让人上瘾的能力就是它可以直接调用 bash 工具把「帮我看下这个目录」「跑一下这段脚本」变成一句话的事。但便利背后有个被严重低估的问题当 Agent 开始自动构造命令、替你执行脚本时它到底在你的真实系统上跑了什么你其实并不完全清楚。我见过几种典型场景用户从搜索结果里粘一段 Python 代码让 AI「帮忙跑一下看结果」Agent 为了完成「清理临时文件」的任务自己拼出一条带通配符的删除命令第三方示例脚本里藏着一行curl xxx | bash。这些代码如果直接落到 bash 上执行你的本地研发环境、运维配置、甚至 SSH 密钥目录都暴露在不确定性里。更麻烦的是事后审计——出了事你很难还原「是哪一段 AI 生成的代码」动了手。SkillLite 要解决的正是这个执行层的信任问题。它的定位不是替代 bash而是在 bash 之外加一个「安全执行层」可信操作比如git status、tail -f继续走 bash来源不明、AI 临时生成的代码片段统一丢进 SkillLite 的原生沙箱里跑。底层执行引擎是 Rust 写的 skillboxmacOS 上走 SeatbeltLinux 上走 Namespace Seccomp做到系统级隔离而不是靠进程内拦截这种容易被绕过的软隔离。它提供三档安全模式这个分级设计很实用。Level 1 只做资源限制不做沙箱适合已经高度审查过的内部工具Level 2 开启系统级沙箱隔离代码跑得出去但碰不到宿主文件系统Level 3 是默认档在沙箱基础上叠加静态代码扫描会识别os.system、subprocess.Popen、rm -rf这类危险 API命中高危行为时不直接执行而是返回requires_confirmation加一个scan_id把最终决定权交回给人。对 OpenCode 用户来说这套机制的价值在于Agent 依然能自动完成 90% 的重复劳动但那 10% 可能真危险的操作你有完整的扫描报告和上下文来做决策。而且它是通过 MCP 协议接入的对 OpenCode 官方生态属于低侵入的标准扩展企业内部也能和其他 MCP 服务并列管理。下面就从环境准备开始一步步把这条「执行前拦截」的链路在本地复现出来。2. TaoToken 前置准备给 OpenCode 配好模型入口在折腾沙箱之前得先让 OpenCode 能正常调用模型否则后面验证沙箱拦截时你连触发执行的入口都没有。OpenCode 支持任意 OpenAI 兼容的提供商这里用 TaoToken 作为模型接入层它的 API 地址是https://taotoken.net/api兼容 OpenAI 的/v1/chat/completions协议配置起来比较直接。先拿到 API Key。登录 TaoToken 控制台在 API Keys 页面创建一个新密钥复制出来备用。这个 Key 就是 OpenCode 调用模型时的凭证格式上是一串以sk-开头的字符串。创建时建议给它起个能认出来的名字比如opencode-local方便以后在控制台里区分不同用途的密钥。拿到 Key 之后OpenCode 的模型配置有两种方式。一种是通过环境变量在启动 OpenCode 前设置export OPENAI_API_KEYsk-你的TaoToken密钥 export OPENAI_BASE_URLhttps://taotoken.net/api另一种是写进 OpenCode 的配置文件。如果你用的是较新版本的 OpenCode它会在项目根目录或用户配置目录读取opencode.json可以在里面指定 provider。这里要注意 Base URL 的写法TaoToken 的 API 根地址是https://taotoken.net/apiOpenCode 内部拼接路径时会自动补上/v1/chat/completions所以填根地址即可不要手动加/v1否则会拼成/v1/v1/...导致 404。模型 ID 这块TaoToken 支持多种主流模型你在控制台的模型列表里能看到可用的 ID。填进 OpenCode 配置时用完整的模型标识比如claude-sonnet-4-5或gpt-4o这类。如果你不确定某个模型 ID 是否可用可以先用 curl 直接打一次接口验证curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的TaoToken密钥 \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, messages: [{role: user, content: 回复 ok}] }返回里能看到choices[0].message.content就说明模型入口通了。这一步很关键因为后面 SkillLite 的沙箱拦截验证需要 OpenCode 真的能驱动 Agent 去构造并请求执行代码模型不通的话整个链路跑不起来。配置好模型之后建议先在 OpenCode 里做一次最简单的对话测试确认它能正常响应。如果这一步就报 401多半是 Key 复制时带了空格或者少了字符如果报连接超时检查一下网络出口是否正常。模型入口稳定之后再进入 SkillLite 的集成环节这样出问题时能快速定位是模型层还是沙箱层的问题。3. 可复制配置SkillLite 接入 OpenCode 的完整步骤环境准备要求三样东西Python 3.x、可用的opencode命令、以及当前目录是你的 OpenCode 工程根目录。确认之后SkillLite 提供了一键集成命令三条命令就能把 MCP 服务、沙箱二进制和技能目录全部配好。第一条装包注意方括号里的mcp不能省它决定了是否安装 MCP 支持pip install skilllite[mcp]第二条初始化 OpenCode 集成它会检测并安装 Rust 沙箱二进制 skillbox然后生成或更新opencode.jsonskilllite init-opencode第三条启动 OpenCode让它加载新的 MCP 配置opencode这三步背后做的事不少安装 SkillLite 本体、校验 skillbox 沙箱二进制、往opencode.json里写入 skilllite 的 MCP 服务定义、在.opencode/skills/skilllite/SKILL.md生成使用说明、自动扫描.skills/目录注册已有技能。对普通用户来说从「没有沙箱」到「不可信代码都在沙箱里跑」就是这三条命令的距离。如果你需要完全掌控配置比如企业内部要统一规范可以手动编辑项目根目录的opencode.json。下面这份配置可以直接复制注意路径和原文保持一致{ mcp: { skilllite: { type: local, command: [skilllite, mcp], environment: { SKILLBOX_SANDBOX_LEVEL: 3, SKILLLITE_SKILLS_DIR: ./.skills }, enabled: true } } }这里三个关键点值得展开。command告诉 OpenCode 通过skilllite mcp启动 MCP 服务器这是标准输入输出模式的本地 MCP不需要额外端口。SKILLBOX_SANDBOX_LEVEL设成3表示启用「沙箱 静态扫描」的最高安全模式这是默认推荐值如果你在某些性能敏感场景想降级可以改成2只做隔离不做扫描。SKILLLITE_SKILLS_DIR指定预定义技能目录默认是./.skills你可以改成自己的路径但要注意这个路径是相对于 OpenCode 工程根目录的。配置写完后OpenCode 启动时会读取这个文件并拉起 skilllite MCP 服务。你可以在 OpenCode 里让它列出可用工具如果能看到skilllite_list_skills、skilllite_scan_code、skilllite_execute_code这些以skilllite_开头的工具说明 MCP 接入成功了。如果没看到先检查opencode.json的 JSON 格式是否合法——一个多余的逗号就会让整个配置解析失败OpenCode 会静默忽略这个 MCP 服务。4. 验证请求复现一次「执行前拦截」的完整动作配置好之后最有说服力的验证就是让 OpenCode 去执行一段带危险操作的代码看 SkillLite 是否在真正落地前把它拦下来。这个验证分两步先看扫描再看拦截。第一步让 OpenCode 调用skilllite_scan_code只做扫描不执行。在 OpenCode 对话框里输入类似这样的请求用 skilllite_scan_code 扫描这段代码不要执行 import os os.system(rm -rf /tmp/test_dir)SkillLite 在 Level 3 下会做静态分析识别出os.system这个危险 API 和rm -rf这个高危模式。返回结果里你会看到requires_confirmation为true同时带一个scan_id和风险报告报告里会列出命中的危险模块和 API。这一步证明扫描层是工作的代码没有真正跑起来。第二步验证执行拦截。让 OpenCode 直接调用skilllite_execute_code执行同样的代码用 skilllite_execute_code 执行这段代码 import os os.system(rm -rf /tmp/test_dir)因为扫描命中了高危行为SkillLite 不会直接执行而是返回需要二次确认的结果。OpenCode 会把风险报告展示给你你能清楚看到这段代码打算做什么。只有当你明确确认OpenCode 才会带着confirmedtrue和之前的scan_id再次调用执行。这个scan_id的作用是绑定「你确认的就是刚才扫描的那段代码」防止确认和执行之间代码被替换。如果你想验证沙箱隔离本身可以换一段不触发静态扫描但会尝试越权访问的代码比如读取宿主机的敏感文件用 skilllite_execute_code 执行 open(/etc/passwd).read()在 Level 2 及以上的沙箱里这段代码会因为文件系统隔离而拿不到宿主机的/etc/passwd返回权限错误或空结果。这就直观展示了「即使代码跑起来了也只能在沙箱里折腾」的效果。两次验证结合起来扫描层拦高危 API沙箱层拦越权访问两道防线都覆盖到了。验证过程中有个细节要注意scan_id是有时效的如果你扫描完隔了很久才确认执行可能会因为 scan_id 过期而需要重新扫描。这是设计上的安全考虑避免一个旧的确认被复用到新代码上。5. 常见报错排查从 401 到沙箱启动失败集成过程中最容易踩的坑集中在几个地方这里按真实报错逐个拆解。401 Unauthorized这个几乎都出在模型层不是 SkillLite 的问题。检查OPENAI_API_KEY或opencode.json里的 Key 是否正确特别注意复制时有没有带上首尾空格。如果 Key 确认没问题还是 401去 TaoToken 控制台看下这个 Key 是否被禁用或额度耗尽。另外确认 Base URL 填的是https://taotoken.net/api填成带/v1的地址会导致路径拼接错误有时也会表现为认证异常。local proxy failed / MCP 服务启动失败OpenCode 报这个通常是skilllite mcp命令没找到。先在终端手动跑一次skilllite mcp如果提示 command not found说明 pip 安装的脚本目录不在 PATH 里用python -m skilllite mcp试试或者把 pip 的 bin 目录加进 PATH。如果手动能跑但 OpenCode 里报错检查opencode.json里command数组的写法必须是[skilllite, mcp]这种形式不能写成单个字符串。reading choices 相关报错这个出现在模型返回解析阶段通常是模型返回的 JSON 结构不符合预期。常见原因是模型 ID 填错了比如填了一个 TaoToken 不支持的模型名接口返回了错误结构。去控制台核对模型 ID或者用第 2 节的 curl 命令直接验证该模型是否可用。沙箱启动失败 / skillbox not foundskilllite init-opencode会尝试安装 skillbox 二进制如果这一步因为网络或权限失败后续执行代码时会报沙箱不可用。手动检查skilllite安装目录下有没有 skillbox 可执行文件没有的话重新跑一次skilllite init-opencode或者按仓库文档手动下载对应平台的二进制放到指定路径。OAuth 相关报错如果你在 OpenCode 里同时配了其他需要 OAuth 的 provider可能会和 TaoToken 的 Key 认证冲突。检查opencode.json里是否有多个 provider 配置互相干扰把不用的先注释掉确保当前会话用的是 TaoToken 这个 provider。排查时有个通用思路先分层定位。模型层的问题用 curl 直接打接口验证MCP 层的问题在终端手动跑skilllite mcp验证沙箱层的问题单独跑一段测试代码验证。三层各自通了整条链路就不会有大问题。6. 把沙箱用成日常习惯接入入口与后续动作验证通过之后真正要让安全基线生效得把它变成日常操作习惯。我自己的做法是划一条简单的规则线所有git、文件查看、构建、测试类命令继续走 OpenCode 的 bash 工具因为这些都是可信操作走沙箱反而增加开销所有用户粘贴的、AI 临时生成的代码片段、脚本、批量操作命令一律走skilllite_execute_code或skilllite_run_skill。一句话概括就是「不确定是不是安全的就进 SkillLite 沙箱跑」。对于经常重复执行的脚本建议沉淀成标准 Skill而不是每次用execute_code临时跑。一个 Skill 目录包含SKILL.md和scripts/main.py这类结构通过skilllite_run_skill调用。好处是输入输出结构化、更适合 LLM 调用而且可以给不同 Skill 分配不同的权限边界和资源限制版本管理也更清晰。如果你还没配好模型入口先去 TaoToken 控制台创建 API Key接入文档在 https://taotoken.net/doc 有完整的参数说明。想先感受下模型对话效果可以直接用 https://taotoken.net/chat 试几句。长期做编码和 Agent 任务的可以了解下 Coding Planhttps://taotoken.net/coding-plan 。API Keys 管理页面在 https://taotoken.net/api-keys 配置过程中随时可以回来核对密钥状态。SkillLite 的项目仓库在 GitHub 上刚开源遇到沙箱策略或 MCP 配置的细节问题可以去仓库的 issue 区翻一翻很多坑别人已经踩过了。把沙箱这层加上之后你会发现自己敢让 OpenCode 更大胆地自动执行了因为知道危险操作会在落地前被拦下来这份底气才是安全层真正的价值。