Download OpenAPI specification:
Skill 是一个文件包——一份 SKILL.md 加上配套脚本与资源,描述「怎么做一件
事」。Agent 按需装载它,而不是把全部说明塞进上下文。
与算子 / 工具的区别:算子和工具是可调用的函数,Skill 是给 Agent 读的
工作手册 + 随手册附带的可执行文件。召回入口在 context-loader 的
find_skills,那边只返回最小元数据;真正的内容读取与下载在这里。
三条读取路径,别用错:
| 接口 | 视角 | 读的是 |
|---|---|---|
/skills/{id}/content、/files/read、/download |
消费态 | 已发布的版本 |
/skills/{id}/management/* |
管理态 | 当前草稿,含未发布改动 |
/skills/{id}/history + history/publish / history/republish |
历史 | 已发布过的版本 |
Studio 的编辑页读管理态,Agent 运行时读消费态。拿错会看到不一致的内容。
上传不是 JSON:注册与更新技能包只接受 multipart/form-data 或
application/x-www-form-urlencoded,发 JSON 直接 400
(unsupported content type)。
时间戳一律是纳秒:所有 *_time 字段由 time.Now().UnixNano() 生成。
认证:Authorization: Bearer <token>(OAuth access token 或 bak_ 前缀的
AppKey)。本面所有接口都要求 x-business-domain 头(路由组统一加了中间件)。
内部面(internal-v1)的读授权按档位:/content 与 /files/read 在公开面
一律按账户判定(execute / public_access / view 三者有其一),内部面则看
SKILL_INTERNAL_READ_AUTHZ——shadow(默认)查了但不拦、判定不通过只打日志,
enforce 与公开面一致返回 403,off 完全不查。分档是为了不打断存量内部调用方:
context-loader 已把这两个接口包成 MCP 工具,skill_id 由调用方自填,内部面无条件
放行等于任意账户可读任意技能全文,但直接翻强制会误伤,先影子观察再翻。
调用方没带账户身份时任何档位都跳过判定——那是「无从判断」,不是「判定为无权」。
/execute 不受该档位影响,一直按账户强制。
上传一个技能包。**Content-Type 只接受 multipart/form-data 或
application/x-www-form-urlencoded**,发 application/json 会被直接拒绝,
报 unsupported content type。
file_type 决定 file 字段怎么解读:
file_type |
file 是什么 |
|---|---|
zip |
技能包压缩文件(multipart 上传) |
content |
直接给的技能内容 |
响应里的 files 列出解包后识别到的文件。
| file_type required | string (SkillFileType) Enum: "zip" "content" 上传形态: |
| file required | string <binary> 技能包。 |
| category | string Default: "other_category" 分类。 |
| source | string Default: "custom" Enum: "custom" "internal" 来源。 |
| extend_info | string 扩展信息(JSON 字符串)。 |
{- "skill_id": "string",
- "name": "string",
- "description": "string",
- "version": "string",
- "status": "unpublish",
- "files": [
- "string"
]
}按业务域分页列出技能,支持按名称、状态、分类、创建人过滤。
| page | integer >= 1 Default: 1 页码,从 1 开始。 |
| page_size | integer [ 1 .. 100 ] Default: 10 每页数量,1–100。 |
| sort_by | string Default: "update_time" Enum: "create_time" "update_time" "name" 排序字段。 |
| sort_order | string Default: "desc" Enum: "asc" "desc" 排序方向。 |
| name | string 按名称过滤。 |
| status | string (BizStatus) Enum: "unpublish" "published" "offline" "editing" 按状态过滤。 |
| category | string 按分类过滤。 |
| create_user | string 按创建人过滤。 |
| all | boolean 忽略分页返回全部。 |
{- "total": 0,
- "page": 0,
- "page_size": 0,
- "total_pages": 0,
- "has_next": true,
- "has_prev": true,
- "data": [
- {
- "skill_id": "string",
- "name": "string",
- "description": "string",
- "version": "string",
- "status": "unpublish",
- "source": "string",
- "business_domain_id": "string",
- "category": "string",
- "category_name": "string",
- "dependencies": { },
- "extend_info": { },
- "create_user": "string",
- "create_time": 0,
- "update_user": "string",
- "update_time": 0,
- "release_user": "string",
- "release_time": 0
}
]
}与 /operator/names、/tool-box/names 同契约:不存在的 ID 静默略过、不占位。
| ids | Array of strings 待取名的技能 ID 列表。空列表返回空 |
{- "ids": [
- "string"
]
}{- "entries": [
- {
- "id": "string",
- "name": "string"
}
]
}已发布技能的列表。比工作区列表少一个 status 过滤——市场里的都是已发布的。
| page | integer >= 1 Default: 1 页码,从 1 开始。 |
| page_size | integer [ 1 .. 100 ] Default: 10 每页数量,1–100。 |
| sort_by | string Default: "update_time" Enum: "create_time" "update_time" "name" 排序字段。 |
| sort_order | string Default: "desc" Enum: "asc" "desc" 排序方向。 |
| name | string 按名称过滤。 |
| category | string 按分类过滤。 |
| create_user | string 按创建人过滤。 |
| all | boolean 忽略分页返回全部。 |
{- "total": 0,
- "page": 0,
- "page_size": 0,
- "total_pages": 0,
- "has_next": true,
- "has_prev": true,
- "data": [
- {
- "skill_id": "string",
- "name": "string",
- "description": "string",
- "version": "string",
- "status": "unpublish",
- "source": "string",
- "business_domain_id": "string",
- "category": "string",
- "category_name": "string",
- "dependencies": { },
- "extend_info": { },
- "create_user": "string",
- "create_time": 0,
- "update_user": "string",
- "update_time": 0,
- "release_user": "string",
- "release_time": 0
}
]
}市场视角的技能详情,结构与 GET /skills/{skill_id} 一致。
| skill_id required | string 技能 ID。 |
{- "skill_id": "string",
- "name": "string",
- "description": "string",
- "version": "string",
- "status": "unpublish",
- "source": "string",
- "business_domain_id": "string",
- "category": "string",
- "category_name": "string",
- "dependencies": { },
- "extend_info": { },
- "create_user": "string",
- "create_time": 0,
- "update_user": "string",
- "update_time": 0,
- "release_user": "string",
- "release_time": 0
}取技能的元数据。文件清单与内容走 /content,包体走 /download。
| skill_id required | string 技能 ID。 |
{- "skill_id": "string",
- "name": "string",
- "description": "string",
- "version": "string",
- "status": "unpublish",
- "source": "string",
- "business_domain_id": "string",
- "category": "string",
- "category_name": "string",
- "dependencies": { },
- "extend_info": { },
- "create_user": "string",
- "create_time": 0,
- "update_user": "string",
- "update_time": 0,
- "release_user": "string",
- "release_time": 0
}删除技能及其全部版本。已被 Agent 挂载的技能删除后装载会失败;
knowledge network 里的 skills 对象类记录也会随之失效
(context-loader 的 find_skills 依赖它)。
| skill_id required | string 技能 ID。 |
{- "code": "Public.BadRequest",
- "description": "string",
- "solution": "string",
- "link": "string",
- "details": null
}只接受 published 与 offline 两个值——不能通过这个接口把技能改回
unpublish 或 editing,那两个状态由注册与编辑动作产生。
本面用的是 PUT(工具箱与算子的同类接口用 POST),注意区别。
| skill_id required | string 技能 ID。 |
| status required | string Enum: "published" "offline" 目标状态。只接受这两个值。 |
{- "status": "published"
}{- "skill_id": "string",
- "status": "unpublish"
}改名称 / 描述 / 分类,不动技能包本身。三个字段都是必填——整体覆盖。
更新会产生新 version。
| skill_id required | string 技能 ID。 |
| name required | string |
| description required | string |
| category required | string |
| source | string Enum: "custom" "internal" |
object |
{- "name": "string",
- "description": "string",
- "category": "string",
- "source": "custom",
- "extend_info": { }
}{- "skill_id": "string",
- "version": "string",
- "status": "unpublish"
}换掉技能的文件内容。与注册一样只接受 form / multipart,不接受 JSON。
更新产生新 version,原版本进历史。
| skill_id required | string 技能 ID。 |
| file_type required | string (SkillFileType) Enum: "zip" "content" 上传形态: |
| file required | string <binary> 新的技能包内容。 |
{- "skill_id": "string",
- "version": "string",
- "status": "unpublish"
}列出该技能发布过的版本,含每次发布的说明与发布人。
| skill_id required | string 技能 ID。 |
[- {
- "skill_id": "string",
- "name": "string",
- "description": "string",
- "version": "string",
- "status": "unpublish",
- "category": "string",
- "source": "string",
- "release_desc": "string",
- "release_user": "string",
- "release_time": 0,
- "create_user": "string",
- "create_time": 0,
- "update_user": "string",
- "update_time": 0
}
]取某个历史版本的内容,写回当前草稿——不直接发布。用于「拿旧版本当起点 继续改」。改完再走正常发布流程。
与 history/publish 的区别:那个是直接发布旧版本,跳过草稿。
| skill_id required | string 技能 ID。 |
| version required | string 要回灌的历史版本。 |
{- "version": "string"
}{- "skill_id": "string",
- "version": "string",
- "status": "unpublish"
}把某个历史版本直接发布成当前版本,跳过草稿。回滚用。 草稿里未发布的改动不受影响,仍留在草稿态。
| skill_id required | string 技能 ID。 |
| version required | string 要发布的历史版本。 |
{- "version": "string"
}{- "skill_id": "string",
- "version": "string",
- "status": "unpublish"
}返回已发布版本的文件清单与包地址。Agent 运行时读的是这个。
要看草稿里未发布的改动,用 /management/content。
| skill_id required | string 技能 ID。 |
{- "skill_id": "string",
- "url": "string",
- "status": "unpublish",
- "files": [
- {
- "rel_path": "string",
- "file_type": "string",
- "size": 0,
- "mime_type": "string"
}
]
}按包内相对路径读一个文件。返回的是文件的下载 URL 而不是内容本身——
拿到 url 再去取。路径从 /content 返回的 files[].rel_path 里挑。
| skill_id required | string 技能 ID。 |
| rel_path required | string 包内相对路径,取自 |
{- "rel_path": "SKILL.md"
}{- "skill_id": "string",
- "rel_path": "string",
- "url": "string",
- "mime_type": "string",
- "file_type": "string"
}/content 的管理态版本:读的是当前草稿,含尚未发布的改动。
Studio 的编辑页用它。
响应结构与消费态不同,比 /content 多了 name / description /
version / source / file_type,以及 response_mode=content 时的
content 正文——编辑页要一次拿全,不想再跑一趟详情接口。
| skill_id required | string 技能 ID。 |
| response_mode | string Default: "url" Enum: "url" "content"
|
{- "skill_id": "string",
- "name": "string",
- "description": "string",
- "version": "string",
- "status": "unpublish",
- "source": "string",
- "file_type": "zip",
- "url": "string",
- "content": "string",
- "files": [
- {
- "rel_path": "string",
- "file_type": "string",
- "size": 0,
- "mime_type": "string"
}
]
}/files/read 的管理态版本:读草稿里的文件。
| skill_id required | string 技能 ID。 |
| rel_path required | string 包内相对路径。 |
{- "rel_path": "string"
}{- "skill_id": "string",
- "rel_path": "string",
- "url": "string",
- "mime_type": "string",
- "file_type": "string"
}在沙箱里跑技能包里的一条命令。技能包被上传到沙箱工作目录,然后执行
entry_shell 指定的命令。
mocked 字段要看:为 true 表示这次并没有真的在沙箱里执行
(沙箱不可用等原因下的降级),返回的 stdout/stderr 不是真实结果。
与函数执行一样,命令失败不体现在 HTTP 状态码上——看 exit_code。
| skill_id required | string 技能 ID。 |
| entry_shell required | string 要执行的命令。 |
| timeout | integer 超时(秒)。 |
{- "entry_shell": "python scripts/run.py --mode full",
- "timeout": 0
}{- "skill_id": "string",
- "session_id": "string",
- "work_dir": "string",
- "file_name": "string",
- "uploaded_path": "string",
- "command": "string",
- "exit_code": 0,
- "stdout": "string",
- "stderr": "string",
- "execution_time": 0,
- "mocked": true
}重建技能的检索索引——find_skills 的语义召回依赖它。
execute_type 决定范围:full 全量重建,incremental 只处理游标之后
变更的技能。任务异步执行,用返回的 task_id 查进度。
| execute_type required | string (IndexExecuteType) Enum: "full" "incremental" 索引构建范围:全量 / 增量。 |
{- "execute_type": "full"
}{- "task_id": "string",
- "status": "pending",
- "execute_type": "string"
}分页列出索引构建任务。
**status 过滤不接受 canceled**:任务状态本身有 5 个值
(pending / running / completed / failed / canceled),
但这个查询参数的白名单只有前 4 个,传 canceled 会 400。
| page | integer >= 1 Default: 1 页码,从 1 开始。 |
| page_size | integer [ 1 .. 100 ] Default: 10 每页数量,1–100。 |
| sort_by | string Default: "update_time" Enum: "create_time" "update_time" "name" 排序字段。 |
| sort_order | string Default: "desc" Enum: "asc" "desc" 排序方向。 |
| status | string Enum: "pending" "running" "completed" "failed" 按状态过滤。**不接受 |
| execute_type | string (IndexExecuteType) Enum: "full" "incremental" 按执行类型过滤。 |
| create_user | string 按创建人过滤。 |
| all | boolean 忽略分页返回全部。 |
{- "total": 4,
- "page": 1,
- "page_size": 2,
- "total_pages": 2,
- "has_next": true,
- "has_prev": false,
- "data": [
- {
- "task_id": "83039781-8fea-43ba-bc13-11b4fd6f0d39",
- "status": "completed",
- "execute_type": "full",
- "queue_state": "",
- "total_count": 1,
- "success_count": 1,
- "delete_count": 0,
- "failed_count": 0,
- "retry_count": 0,
- "max_retry": 3,
- "cursor_update_time": 1784869482749304600,
- "cursor_skill_id": "bf93eab9-d2f6-4db3-b564-f47e5e35d4c1",
- "error_msg": "",
- "create_user": "266c6a42-6131-4d62-8f39-853e7093701c",
- "create_time": 1785228741173540600,
- "update_time": 1785228742311942400,
- "last_finished_time": 1785228742311942100
}
]
}取单个任务的进度与计数。
| task_id required | string 索引构建任务 ID。 |
{- "task_id": "string",
- "status": "pending",
- "execute_type": "string",
- "queue_state": "string",
- "total_count": 0,
- "success_count": 0,
- "delete_count": 0,
- "failed_count": 0,
- "retry_count": 0,
- "max_retry": 0,
- "cursor_update_time": 0,
- "cursor_skill_id": "string",
- "error_msg": "string",
- "create_user": "string",
- "create_time": 0,
- "update_time": 0,
- "last_finished_time": 0
}以失败任务为模板新建一个任务重跑。响应里 source_task_id 是原任务、
task_id 是新任务——原任务记录保留不变。
| task_id required | string 索引构建任务 ID。 |
{- "source_task_id": "string",
- "task_id": "string",
- "status": "pending",
- "execute_type": "string"
}