Open Interpreter skill-installer 技能实战:从 GitHub 仓库检索并安装 Skills 到 $CODEX_HOME/skills
本文为 Open Interpreter 内置的 skill-installer 技能编写技术解析。该技能用于把存放在 GitHub 仓库中的 Codex 技能(Skill)按目录结构安装到本地 $CODEX_HOME/skills,支持列出自定义精选列表、批量安装、私有仓库认证与多种下载策略。读完后,你将掌握其全部命令行参数、fallback 下载链路,以及技能安装后为何"下一轮对话才生效"的运行时原理。
技能定位与文件结构
skill-installer 是随本仓库分发的一个系统技能(system skill),其定义入口为 SKILL.md。frontmatter 声明了技能身份:
---
name: skill-installer
description: Install Codex skills into $CODEX_HOME/skills from a curated list or a GitHub repo path. Use when a user asks to list installable skills, install a curated skill, or install a skill from another repo (including private repos).
metadata:
short-description: Install curated skills from openai/skills or other repos
---
这段 frontmatter 不是摆设——运行时的技能解析器 parser.rs 会对每个 SKILL.md 做严格校验:name 缺失时回退为目录名、超过 64 字符会报错;description 为必填字段,它决定了技能何时被模型选中;metadata.short-description 则用于界面展示。此外,agents/openai.yaml 为该技能提供了 display_name 与图标等界面元数据。
技能本体由三个 Python 辅助脚本组成:
skill-installer/
├── SKILL.md
├── agents/openai.yaml
├── assets/ # 图标
└── scripts/
├── github_utils.py # GitHub 请求公共工具
├── list-skills.py # 列出可安装技能
└── install-skill-from-github.py # 安装技能
按 SKILL.md 的说明,技能默认从 openai/skills 仓库的 skills/.curated 目录安装精选技能;用户也可以指定其他任意 GitHub 仓库/路径(包括私有仓库)。实验性技能位于 skills/.experimental,安装方式相同。
列出可安装技能:list-skills.py
当用户询问"有哪些技能可以安装"、或触发该技能但没说明具体要做的事时,应运行列表脚本(参数相对技能目录):
scripts/list-skills.py # 默认列出 skills/.curated
scripts/list-skills.py --format json # JSON 输出,便于程序消费
scripts/list-skills.py --path skills/.experimental # 列出实验性技能
完整参数(来自 list-skills.py 的 argparse 定义):
| 参数 | 默认值 | 说明 |
|---|---|---|
--repo |
openai/skills |
目标仓库,owner/repo 格式 |
--path |
skills/.curated |
仓库内要列举的目录路径 |
--ref |
main |
Git 分支/标签/提交 |
--format |
text |
输出格式,text 或 json |
实现要点(见 list-skills.py#L50-L65):
- 通过 GitHub Contents API 拉取目标目录的条目列表(API 端点构造见 github_utils.py#L20-L21),只保留
type == "dir"的条目,即"一个子目录 = 一个技能",结果按名称排序。 - 本地扫描
$CODEX_HOME/skills(CODEX_HOME未设置时回退为~/.codex)下已有的子目录名,对已安装项在输出末尾追加(already installed)标注;JSON 模式则输出{"name": ..., "installed": true/false}数组。 - 出错时(如路径 404)向 stderr 打印
Error: ...并以非零码退出——文档明确要求此时"解释错误并退出",而不是静默吞掉。
安装技能:install-skill-from-github.py
参数与典型用法
安装脚本支持两种互斥的源描述方式(--repo + 一个或多个 --path,或直接给一个 --url),核心参数定义见 install-skill-from-github.py#L247-L266:
| 参数 | 默认值 | 说明 |
|---|---|---|
--repo <owner>/<repo> |
无 | 与 --path 搭配使用 |
--url <github.com URL> |
无 | 形如 https://github.com/<owner>/<repo>/tree/<ref>/<path>,自动解析出 owner/repo/ref/path |
--path <path> [...] |
无 | 仓库内技能路径,可传多个,一次安装多个技能 |
--ref <ref> |
main |
源 ref;--url 中若含 /tree/<ref>/ 则以 URL 中的 ref 为准 |
--dest <path> |
$CODEX_HOME/skills |
安装根目录 |
--name <name> |
路径 basename | 目标技能目录名;仅在单路径时生效 |
--method auto|download|git |
auto |
下载策略 |
文档给出的典型命令:
# 从 openai/skills 的实验性目录安装某个技能
scripts/install-skill-from-github.py --repo openai/skills --path skills/.experimental/<skill-name>
# 直接用一个 tree URL 安装
scripts/install-skill-from-github.py --url https://github.com/<owner>/<repo>/tree/<ref>/<path>
--path 传多个值时,每个路径的 basename 自动成为各自的目标技能名(因此 --name 只在单路径时生效,逻辑见 main 函数)。
三种获取方法与 fallback 链
下载策略的核心是 _prepare_repo(install-skill-from-github.py#L187-L206),与文档"默认直连下载、鉴权失败回退 git"的描述一一对应:
- download:请求
codeload.github.com/<owner>/<repo>/zip/<ref>整仓压缩包,解压后要求顶层恰好只有一个目录(<repo>-<ref>形态),否则报错; - git:使用
git clone --filter=blob:none --depth 1 --sparse --single-branch --branch <ref>做浅层稀疏克隆,再sparse-checkout set <paths>只检出技能目录,最后checkout <ref>——对大仓库非常省流量; - auto(默认):先尝试 download,若返回
HTTP 401/403/404(典型的鉴权/权限信号)则自动降级到 git;其他错误不降级。git 分支内部还有一次重试:先试 HTTPS 地址(https://github.com/<owner>/<repo>.git),失败后再试 SSH(git@github.com:<owner>/<repo>.git)。
私有仓库正是依赖这条链路工作:git 侧使用本机已有 git 凭据;download 侧则可读取 GITHUB_TOKEN 或 GH_TOKEN 环境变量——公共请求工具 github_utils.py#L10-L17 在检测到 token 时会自动附加 Authorization: token <token> 请求头,并携带 codex-skill-install/codex-skill-list 的 User-Agent。
内置的安全校验
安装过程包含多道防护,这也是脚本比"一行 curl"稳健的原因:
- Zip Slip 防护:解压前逐条校验归档内每个条目 realpath 必须落在目标临时目录内,发现越界直接抛错(_safe_extract_zip);
- 路径校验:
--path必须是仓库内相对路径,拒绝绝对路径与..上跳(_validate_relative_path); - 技能名校验:目标名必须是单一路径段且不能是
./..; - 技能完整性校验:每个候选目录必须是目录且内含
SKILL.md,否则该技能安装失败(_validate_skill)——这与上文提到的运行时 frontmatter 解析形成闭环,装进来的技能才能被正确识别; - 幂等保护:目标技能目录已存在则整体中止(
Destination already exists),不做覆盖,避免误删用户修改过的技能; - 临时目录清理:下载发生在
mkdtemp临时目录中,finally分支保证无论成败都会清理。
沙箱网络提示
SKILL.md 特别指出:这些脚本全部走网络,因此当会话运行在沙箱中时,执行它们前应请求提权(escalation)出沙,而不是在受限网络中静默失败。
与运行时的协作:安装为何"下一轮生效",.system 为何免装
安装完成后,脚本打印 Installed <name> to <dest>,技能文档要求告知用户"该技能将在下一轮对话可用"。这与运行时的技能加载机制一致:技能元数据在每轮开始时从磁盘索引,新落盘的 SKILL.md 自然要到下一轮才被解析进上下文。
另外两个源码层面的佐证值得了解:
- 系统技能是内嵌分发的。lib.rs#L49-L95 通过
include_dir!把src/assets/samples下的整套技能(含本技能)编译进二进制,启动时经install_system_skills写入$CODEX_HOME/skills/.system;并用.codex-system-skills.marker记录内嵌目录指纹,指纹匹配即跳过重复写入。正因如此,文档说明openai/skills仓库中skills/.system下的技能已随产品预装,无需通过本技能安装;若用户坚持,才允许下载覆盖。 - 运行技能脚本会被识别为该技能的隐式调用。invocation.rs#L16-L84 会对命令做词法切分,识别
python scripts/xxx.py这类执行器 + 脚本扩展名组合,再沿路径向上匹配所属技能的scripts/目录——所以本技能的辅助脚本在沙箱中运行时,运行时同样能把它关联回skill-installer这个技能本身,其权限与审批行为按技能策略执行。
交互规范小结
按 SKILL.md 的 Communication 一节,列表结果应组织为:
Skills from {repo}:
1. skill-1
2. skill-2 (already installed)
3. ...
Which ones would you like installed?
用户询问实验性技能时改从 .experimental 列举并相应标注来源;安装完成后明确告知"下一轮对话可用"。整个技能的设计可以概括为:用三个小脚本把"GitHub 目录浏览 + 受控下载 + 安全落盘"封装成模型可以直接驱动的能力,而参数表、fallback 链与安全校验的实现细节都能在上文列出的源码文件中逐一核对。
相关文件索引:
- 技能定义:SKILL.md
- 界面元数据:agents/openai.yaml
- 脚本实现:list-skills.py、install-skill-from-github.py、github_utils.py
- 运行时配套:系统技能安装、frontmatter 解析、隐式调用检测
- 技能目录与组织方式总览:docs/skills.md
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00