DinoxDinox AI笔记

Skills API

列出 Dinox 技能,获取短期下载链接,将当前笔记导出为 Agent Skills tar.gz;包含认证、响应字段、Python 示例、版本与错误处理。

通过两个只读接口,把 Dinox 中保存的技能下载到自己的工具或 Agent:先列出技能,再按笔记 ID 获取下载链接。导出包包含当前技能说明及附属文件,并保留相对目录。

还没有技能笔记?先按 移动端技能库指南 从 GitHub 或 ZIP 导入,等待正文同步、附件上传完成。

先在手机中导入和同步,再由 Skills API 分发到 Agent 的流程

基础信息与认证

项目
服务地址https://aisdk.chatgo.pro
列表GET /api/openapi/skills
获取下载信息GET /api/openapi/skills/{noteId}
请求认证Authorization: Bearer <token>
OAuth 权限dinox.notes.read
成功响应HTTP 200,code: "000000"
导出格式单技能 tar.gz

可以使用现有 App API Token,或具备上述 scope 的 OAuth token。App Token 在 设置 → 同步设置 → API Token 获取。接口只返回当前账号有权访问的技能;即使笔记公开,也不能匿名导出。

Token 是账号凭证。不要写进网页前端、公开仓库、截图或日志。下面的 Python 示例在终端隐藏输入 token;下载对象存储链接时不会携带这个 token。

这两个 Skills 路由使用自己的限流:每个账号在每个服务实例每分钟最多 60 次请求。同一账号在单实例最多同时打包 1 个技能,单实例最多同时打包 2 个技能。多实例不代表可以依赖额度倍增,客户端应顺序下载并处理 429。JSON 响应使用 Cache-Control: no-store

1. 列出技能

GET /api/openapi/skills?page_size=20
Authorization: Bearer <token>

查询参数

参数类型必填说明
page_size整数默认 20,范围 1–50
start_cursor字符串上一页的 next_cursor;首屏省略

按笔记 UUID 升序分页。游标绑定当前账号,应原样传回并正确 URL 编码,不要自行解析或跨账号复用。

成功响应

以下 ID 和版本均为示意值,请使用实际返回结果。

{
  "code": "000000",
  "msg": "success",
  "data": {
    "results": [
      {
        "id": "00000000-0000-4000-8000-000000000001",
        "name": "pdf",
        "description": "Read, create and transform PDF files.",
        "version_id": "opaque-version-id",
        "exportable": true,
        "error": null
      }
    ],
    "has_more": false,
    "next_cursor": null
  }
}
字段含义
results[].id技能笔记 ID;下载接口使用它,不使用技能名称
name / description技能标识和用途描述
version_id当前可导出内容的版本,不透明字符串;不可导出时为 null
exportable当前元数据与资源状态是否通过导出前置校验
error正常为 null;异常时为 {code, message}
has_more / next_cursor是否还有下一页,以及下一页游标

技能正文未同步、附件未上传或属性无效时,条目仍可能出现在列表中:

{
  "id": "00000000-0000-4000-8000-000000000001",
  "name": "pdf",
  "description": "Read, create and transform PDF files.",
  "version_id": null,
  "exportable": false,
  "error": {
    "code": "SKILL_NOT_READY",
    "message": "技能附件尚未上传完成"
  }
}

列表不会下载附件或访问对象存储,因此 exportable: true 不保证随后的真实存储读取一定成功。一个技能不可导出也不会使整页查询失败。

2. 获取技能下载信息

GET /api/openapi/skills/00000000-0000-4000-8000-000000000001
Authorization: Bearer <token>

此请求会按当前内容生成归档,返回 JSON,不会直接返回压缩包字节

{
  "code": "000000",
  "msg": "success",
  "data": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "pdf",
    "version_id": "opaque-version-id",
    "url": "https://storage.example.com/skill.tar.gz?signature=example",
    "expires_at": "2026-09-18T12:10:00.000Z",
    "format": "tar.gz",
    "sha256": "<64 位十六进制 SHA-256>",
    "size_bytes": 17804
  }
}
字段含义
id / name本次归档所属笔记与技能标识
version_id本次归档的版本;可能与更早列表中的版本不同
url私有归档的签名下载地址,约 10 分钟有效
expires_at下载地址过期时间,UTC ISO 8601
format当前固定为 tar.gz
sha256压缩包字节的 SHA-256,64 位十六进制
size_bytes压缩包大小,单位字节

拿到 url 后发起普通 HTTPS GET 即可下载,不要向对象存储转发 Dinox Authorization 请求头。持有签名链接即可下载,请勿公开或写入日志;链接过期时重新调用此接口获取新地址。

停止技能分发不会立即撤销此前签发且尚未过期的链接。

3. 可运行的下载示例

下载 Python 示例脚本,保存后在自己的终端运行。仅使用 Python 3.10+ 标准库,无需安装第三方依赖。

# 列出所有分页中的技能;运行后按提示输入 API Token
python3 download-dinox-skill.py

# 用列表返回的实际 ID 下载;目标文件必须不存在
python3 download-dinox-skill.py \
  --note-id 00000000-0000-4000-8000-000000000001 \
  --output pdf.tar.gz

脚本隐藏输入 token,列出全部分页;下载时校验 size_bytessha256,校验失败会删除本次不完整文件。已有文件不会被覆盖,签名链接不会被打印,也不会自动解压或执行技能。

核心请求逻辑如下(完整脚本还包含分页、错误处理和流式校验):

import getpass
import json
from urllib.request import Request, urlopen

origin = "https://aisdk.chatgo.pro"
token = getpass.getpass("Dinox API Token: ").strip()
request = Request(
    origin + "/api/openapi/skills?page_size=20",
    headers={"Authorization": "Bearer " + token},
)
with urlopen(request, timeout=30) as response:
    page = json.load(response)
for skill in page["data"]["results"]:
    print(skill["id"], skill["name"], skill["exportable"])

示例适合个人终端验证。长期同步程序还应实现重试、版本记录和目标 Agent 的安装步骤,见下文。

下载包的目录与兼容范围

pdf/
├── SKILL.md
├── LICENSE.txt
├── forms.md
├── reference.md
└── scripts/
    └── convert_pdf_to_images.py

这里只有一个以 skill_name 命名的顶层目录,没有额外的 skills/ 包装层,也没有 plugin.json。下载格式采用 Agent Skills 的目录与 SKILL.md 结构

SKILL.md 由当前笔记重新生成:

---
name: pdf
description: Read, create and transform PDF files.
---

# PDF 工作指南

在这里保存你在 Dinox 中维护的技能指令。
  • namedescription 取当前属性,不从导入时的历史快照回填。
  • 指令取当前已同步的 Markdown 正文。
  • 导入时的 licensecompatibilityallowed-toolsmetadata 会在合法时保留;其他自定义 frontmatter 字段不保证导出。
  • 附属文件保留字节内容和相对路径。普通文件权限固定为 0644,不恢复可执行位或符号链接,时间戳固定以减少无意义差异。
  • Markdown 经过保存与生成,不保证原始排版或字节完全相同。

解压前应校验路径,拒绝绝对路径、越界路径和不安全链接。先解压到独立目录、检查内容,再安装到目标 Agent 支持的技能目录;避免覆盖本地修改。脚本按解释器运行,例如 python scripts/example.py,并自行安装它声明的依赖。API 不执行任何包内代码。

哪些笔记会被识别为技能

手机的技能导入流程会自动留下识别信息,普通用户无需额外添加开关。

开发者需要了解下面的优先级:

  1. properties.skill === false:停止后续分发,优先于导入标记。
  2. properties.skill === true:明确标记为技能;账号中须存在 key 为 skill、类型为 checkbox 的属性定义。
  3. 否则兼容移动端导入标记:extra_data.skill.version === 1

仅有 skill_name,或标题中出现「Skill」,不会把普通笔记自动识别成技能。extra_data.skill.version 是内部数据格式标记,与 API 内容版本不同,不应拿它做更新判断。

导出还要求账号的属性定义类型正确:

key要求
skill_nametext;有效技能标识
skill_descriptiontext;非空描述
skill_filesfiles;附件包含资源 ID 和相对路径,无附件可为空
skill_source_url来源追溯字段,不参与技能识别
skill_source_revision上游提交记录,不作为 API 内容版本

文件属性的结构示例:

{
  "skill_files": [
    {
      "resourceId": "00000000-0000-4000-8000-000000000002",
      "path": "scripts/convert_pdf_to_images.py"
    }
  ]
}

resourceId 指向文件内容,path 表示它在技能根目录中的位置。只有资源 ID、没有路径的附件无法可靠重建技能目录,导出会拒绝猜测路径。资源必须属于当前账号、未删除并已上传。

以上是数据模型说明,本页两个接口均为只读,不提供技能创建、属性修改或 GitHub 同步接口

版本比较与同步策略

version_id 当作不透明字符串,只比较相等与否,不要依赖其长度或内部编码。它覆盖生成的 SKILL.md、排序后的文件路径以及资源上传版本等信息。

变化是否影响 API 内容版本
修改技能正文、标识或描述
增删附件、修改相对路径、替换上传资源
仅修改来源链接或来源 commit
仅改变资源 OCR、摘要或缩略图

sha256 则只用于校验本次压缩包。不要把 GitHub commit、version_id 和压缩包 SHA-256 当作同一个值。

建议按以下顺序同步:

  1. 拉完所有分页,记录本轮完整列表。exportable: false 单独报错,不视为删除。
  2. 以笔记 ID 作为稳定身份,比较本地记录的 version_id。名称可能更改,也可能重复。
  3. 对新增或变化的条目顺序请求下载信息,下载并校验归档。
  4. 安全解压和安装成功后,保存下载信息返回的版本,再更新本地状态。
  5. 只有完整列举成功后才考虑处理缺失项;权限错误、网络失败不能作为删除依据。需要覆盖本地修改时,应先保留旧内容或进行人工确认。

打包期间如果正文或附件发生变化,服务会返回 409,避免混合不同版本。重新查询后再试。跨页查询不是同一数据库快照,持续同步客户端应在后续轮次再次扫描,让并发新增或修改最终收敛。

同一上传资源应保持内容不变。替换文件请经过 Dinox 的上传流程更新资源记录;直接在对象存储中覆盖同一个 key 而不更新 Dinox 元数据,不属于受支持的版本更新方式。

错误与重试

业务错误一般返回以下形状;鉴权错误由公共认证层返回,客户端首先判断 HTTP 状态码:

{
  "code": "SKILL_NOT_READY",
  "msg": "技能附件尚未上传完成",
  "data": null
}

列表条目内部的错误使用 error.message,顶层失败响应使用 msg,不要混用。

HTTP常见 code / 情况建议处理
400INVALID_IDINVALID_PAGEINVALID_CURSOR修正 ID、页大小或重新开始分页
400INVALID_SKILLINVALID_PROPERTY_TYPEINVALID_PATHPATH_CONFLICT检查元数据、属性类型和文件路径,修复后重试
401token 无效或未登录重新获取有效凭证
403缺少 OAuth scope授予 dinox.notes.read
404SKILL_NOT_FOUND笔记不存在、未标记为技能、停止分发或无访问权限
409SKILL_NOT_READY等待正文同步及附件上传
409RESOURCE_CHANGEDSKILL_CHANGED内容在打包时变化,重新查询后重试
409RESOURCE_UNAVAILABLESTORAGE_UNAVAILABLE检查附件和对应存储配置
413SKILL_TOO_LARGE缩减文件、正文或附件数量
429EXPORT_BUSYRATE_LIMITED顺序下载,遵循返回的 Retry-After(如有),退避重试
502EXPORT_FAILEDSTORAGE_UNAVAILABLE稍后重试,持续失败时检查存储可用性
500SKILLS_UNAVAILABLE暂时性服务异常,退避重试

对 429/5xx 使用带随机抖动的指数退避,并限制次数;不要对 400/401/403 无限重试。文件下载地址过期时,重新申请地址,不必反复请求旧链接。

导出边界

单个文件最多 5 MiB,每技能最多 50 个附件,正文最多 512 KiB,总未压缩内容最多 64 MiB。非法路径、大小写冲突、文件与目录冲突及嵌套 SKILL.md 会被拒绝。打包处理期限为 120 秒,客户端应留出适当超时余量。

官方存储与账号配置的自定义 S3 都通过资源归属校验读取。自定义存储需要可从服务端访问的公共 HTTPS 443 端点;私网地址或重定向端点不受支持。

接入验收清单

  • 在 App 导入一个带脚本的技能,等待同步后能在列表中找到。
  • 下载后 size_bytes 与 SHA-256 校验通过,顶层目录名与 name 一致。
  • scripts/ 等相对目录还在,SKILL.md 包含当前描述和正文。
  • 修改正文并同步后,version_id 变化,下载得到新内容。
  • 正确处理未就绪、过期链接和限流;失败时不覆盖已安装版本。
  • 日志和仓库中不保存 token 或签名下载地址。

继续阅读:手机端导入和管理 · 其他 OpenAPI 接口 · Dinox CLI Skills

On this page