# 智耘农业智能体开发者文档(全量) > 本文件由 https://zhiyun.example.invalid/docs/llms.txt 索引的全部文档正文拼接而成,供 AI 助手一次性读取。文档门户:https://zhiyun.example.invalid/docs/ --- # 快速开始 > 开发者中心登录、能力目录确认、创建项目与版本流程、错误处理。 ## 接入步骤 1. 用平台账号登录开发者中心(`/developer/login`,与业务前台/管理后台是相互独立的会话域)。 2. 确认可用能力:`GET /api/developer/capabilities`(全量目录)与 `GET /api/developer/tools`(系统工具名清单)。 3. 创建项目:Skill 走「创建 Skill 项目 + skill.zip 上传」;Plugin 在创建弹窗里选 HTTP API 或 MCP Server 接入;App 在「应用开发」里新建后上传 app.zip。 4. 版本流程:保存草稿 → 服务端校验 → 提交审核 → 管理员通过后发布,进入平台能力目录 / 技能目录 / 应用中心。 ## 命令行路径 以上步骤均可用 `zhiyun` 命令行完成(安装与登录见 [CLI 文档](cli.md)):`zhiyun login` 设备授权 → `zhiyun capability list` 确认能力 → `zhiyun create` 创建项目 → `push` 上传草稿 → `validate` → `submit` 提审 → `status` 跟踪进度。 ## 错误处理 - 401:会话失效,前端会清除本地令牌并要求重新登录(CLI 自动刷新一次,仍失败重新 `zhiyun login`)。 - 403:权限不足,例如开发者访问 `/api/admin/**` 管理接口。 - 权限在服务端逐请求判定,前端隐藏菜单不构成安全边界。 --- # CLI(zhiyun 命令行) > 安装 `@agri-zhiyun/zhiyun-cli` 后在本地创建、校验、调试与提审 Skill / Plugin / App,适合开发者与 AI Agent 协作使用;每次开始开发前必须先检查 npm 上的 CLI 版本、有更新先升级(见下文「版本检查」)。 ## 安装与登录 ```bash npm install -g @agri-zhiyun/zhiyun-cli zhiyun --version zhiyun login # 打开浏览器完成智耘开发者账号授权(npm 登录仅包维护者需要,普通开发者不需要) zhiyun whoami # 确认当前登录的开发者身份 ``` - `login` 会发起设备授权:终端展示验证网址与用户码并自动打开浏览器;在浏览器登录智耘开发者账号并确认"授权这台设备访问开发者项目"。 - SSH / 无浏览器环境用 `zhiyun login --no-browser`,手动在任意设备浏览器打开展示的网址完成授权。 - 授权后 access token 约 30 分钟有效,refresh token 30 天且每次刷新自动轮换;401 时 CLI 自动刷新一次,仍失败再重新 `login`。 - `zhiyun logout` 撤销服务端凭据并清理本机副本。Token 只存本机凭据库(`~/.config/zhiyun-cli/credentials.json`,0600),终端与 `--json` 输出永不显示。 ## 版本检查(每次开发必做) 读本文档的开发者与 AI Agent,每次开始开发前必须先检查 npm 上 `@agri-zhiyun/zhiyun-cli` 是否有新版本;本机版本落后时先升级,再执行任何后续开发步骤: ```bash npm view @agri-zhiyun/zhiyun-cli version # npm latest 版本 zhiyun --version # 本机已安装版本 # 两者不一致时先升级并复查: npm install -g @agri-zhiyun/zhiyun-cli@latest zhiyun --version ``` - 版本落后继续开发,可能按旧命令或旧 Manifest 契约产出交付物,导致 `validate`、`submit` 失败或审核被退回。 - 网络不可用导致检查或升级失败时,如实标注「CLI 版本检查未完成」,不得跳过检查后声称已执行;本轮检查与升级结果写入任务报告。 ## 命令索引 | 命令 | 作用 | 改远端状态 | | --- | --- | --- | | `zhiyun doctor` | 检查 Node 版本、网络连通、登录态 | 否 | | `zhiyun login / whoami / logout` | 设备授权登录 / 身份 / 撤销 | 是(凭据) | | `zhiyun capability list` | 已注册能力目录 | 否 | | `zhiyun skill list`(别名 `skill_list`) | 我的项目(kind=Skill) | 否 | | `zhiyun plugin list`(别名 `plugin_list`) | 我的项目(kind=Plugin) | 否 | | `zhiyun app list`(别名 `app_list`) | 我的应用 | 否 | | `zhiyun init` | 生成本地模板与 `zhiyun.json` | 否(只写本地) | | `zhiyun create` | 在平台创建归属项目 | 是 | | `zhiyun avatar` | 没有头像时按平台固定风格生成并绑定项目资料(`--dry-run` 支持) | 是(可能产生图片模型费用) | | `zhiyun pack` | 打包 zip(只写本地) | 否 | | `zhiyun push` | 上传/更新草稿包 | 是 | | `zhiyun validate` | 校验(`--local` 仅本地预检) | 默认调服务端 | | `zhiyun test` | 调试运行(Skill 调试会话 / Plugin 测试接口) | 是 | | `zhiyun submit` | 提交审核 | 是 | | `zhiyun status` | 查看版本与审核状态 | 否 | | `zhiyun withdraw` | 审核中撤回草稿 | 是 | | `zhiyun skill/plugin publish` | 发布已批准版本(App 无此命令,上架语义不同) | 是 | 通用约定: - `--json`:stdout 只输出一个稳定 JSON 对象,进度与错误走 stderr;Agent 优先使用。 - `--dry-run`:只做本地预检与展示请求计划,不发送写请求。 - `--base-url`:本地/测试环境后端地址;生产默认为 `https://zhiyun.example.invalid`,凭据不会发往非 https 地址。 - 退出码:0 成功;2 参数错误;3 未登录;4 无权限;5 校验失败;6 网络故障;7 审核状态冲突。 - 项目目录的 `zhiyun.json` 记录 kind / idSlug / name / description / version 与远端项目 ID(无 Token);`create` 成功后自动写回完整 ID。 ## 示例:从零到提审(Skill) ```bash mkdir rice-pest-guard && cd rice-pest-guard # 让 AI 产出 SKILL.md 后: zhiyun skill init --name "水稻病虫害诊治助手" --id rice-pest-guard --description "稻田病害识别与防治决策" # 把 AI 产出的 SKILL.md 放入当前目录后: zhiyun skill create # 平台创建项目,完整 ID 写回 zhiyun.json zhiyun skill push --zip skill.zip zhiyun skill validate zhiyun skill submit --release-notes "首版" zhiyun skill status # 查看 DRAFT → IN_REVIEW → APPROVED → PUBLISHED ``` Plugin 与 App 流程相同(`zhiyun plugin ...` / `zhiyun app ...`);Plugin 的 remote-http / remote-mcp 方式不传代码包,主要在平台配置 manifest 与密钥;App 审核通过即上架,没有开发者侧 `publish`。 ## Agent 使用要点 - 每轮开发开始前先完成上文「版本检查」:npm 有更新必须先升级 CLI,再执行任何开发与提审命令。 - 先让 Agent 读 `https://zhiyun.example.invalid/docs/llms.txt` 与 [提示词模板](prompts.md),AI 产出的交付清单包含 ID 短码与 zip 路径,直接对应上面的命令。 - 完整 ID 以服务端返回为准;`zhiyun skill list` 查询的是本人开发者项目,不是市场目录(市场目录是 `GET /api/skills`)。 - 本地预检不能替代平台校验:`validate --local` 只查格式、大小、路径与清单一致性,最终以服务端结果为准。 ## 常见错误 - `401`:登录过期。CLI 会自动刷新一次;仍失败则重新 `zhiyun login`。 - `403`:当前账号无开发者权限,或访问了管理域接口。 - `409`:状态冲突——审核中不能再 push,APPROVED 前不能 publish;用 `status` 查看后 `withdraw` 或等审核。 - 包校验失败(本地退出码 5):按输出修正包结构后重试;服务端校验失败信息以平台为准。 - 无浏览器环境:`zhiyun login --no-browser` 拿网址与用户码,在任意设备完成授权。 --- # Extension Manifest > apiVersion / kind / id / runtime / capabilities 字段结构与 JSON Schema 校验约束。 ## 结构 - `apiVersion` 固定为 `zhiyun/v1`;`kind` 取 `Skill / Plugin / App / Bundle`(App 的打包清单是 app.json,见「App SDK」)。 - `id` 为全局唯一标识,格式 `org.example.〈开发者账号〉.skill|plugin|app.〈短码〉`(如 `org.example.smartagri.weather`);创建项目时只需填最后一段短码(如 `rice-pest-guard`),完整 id 由平台按会话身份拼装,清单中的 `id` 必须与拼装结果一致;`version` 必须是语义化版本。 - Plugin 的 `runtime`:remote-http(`url` 必须 https,`method` 取 GET/POST,可选 `auth.header` + `auth.secretRef`)或 remote-mcp(`url` 必须 https,可选 auth)。 - 每个能力(`capabilities[]`)声明 `id / name / description / type / risk / inputSchema / outputSchema / rateLimitPerMinute`。 - `risk` 取 `LOW / MEDIUM / HIGH / CRITICAL`,缺省 `LOW`;密钥值在「Secret 声明与值」面板录入,接口不回显。 > Schema 校验约束:inputSchema / outputSchema 是 JSON Schema 字符串;能力经 MCP 暴露给 Agent 时只下发 type=object 的 outputSchema,其他形态会被网关拒绝。 ## 示例 ### Plugin Manifest(remote-http) ```yaml apiVersion: zhiyun/v1 kind: Plugin id: org.example.smartagri.weather name: 天气查询插件 version: 0.1.0 publisher: developer description: 查询指定城市当前天气 runtime: name: remote-http url: https://api.example.com/weather method: POST auth: header: X-Api-Key secretRef: API_KEY permissions: capabilities: [] secrets: - API_KEY capabilities: - id: weather_query name: weather_query description: 按城市名查询当前天气 type: TOOL risk: LOW inputSchema: '{"type":"object","properties":{"city":{"type":"string","description":"城市名"}},"required":["city"],"additionalProperties":false}' outputSchema: '{"type":"object"}' rateLimitPerMinute: 30 ``` ### Plugin Manifest(remote-mcp 骨架,工具经「发现」确认后写入) ```yaml apiVersion: zhiyun/v1 kind: Plugin id: org.example.smartagri.mcp.demo name: MCP 示例插件 version: 0.1.0 publisher: developer runtime: name: remote-mcp url: https://mcp.example.com/mcp permissions: capabilities: [] capabilities: [] ``` --- # 技能开发 > skill.zip 包结构、SKILL.md 指令要求、目录白名单、版本流程与 Manifest 示例。 ## skill.zip 包结构 - 包根(或唯一顶层目录)必须有 `SKILL.md`:技能指令内容(Markdown),不能为空。 - 允许的目录:`scripts/` `references/` `assets/` `agents/` 与根下任意文件;白名单外条目会被拒绝。 - 限制:包体 ≤ 10MB,条目 ≤ 200 个,解压总量 ≤ 20MB,单文件 ≤ 2MB;`__MACOSX/`、`.DS_Store`、`._*` 等系统杂项会被忽略并提示。 ## 版本流程 - 上传即写入草稿(已有草稿则覆盖,否则自动开新补丁版本草稿)。 - `requires.capabilities` 中的能力 ID 必须已在平台注册,校验不通过则无法提交审核。 - 管理员审核通过并发布后,技能对所有平台用户可见(`/api/skills`)。 ## 命令行路径 ```bash zhiyun skill create # 平台创建项目(完整 ID 写回 zhiyun.json) zhiyun skill push --zip skill.zip zhiyun skill validate zhiyun skill submit --release-notes "…" zhiyun skill status # DRAFT → IN_REVIEW → APPROVED → PUBLISHED ``` 审核中可 `zhiyun skill withdraw` 撤回;APPROVED 后 `zhiyun skill publish --version x.y.z` 发布。命令细节见 [CLI 文档](cli.md)。 ## 示例 ### Skill Manifest ```yaml apiVersion: zhiyun/v1 kind: Skill id: org.example.smartagri.fieldnote name: 田间记录助手 version: 0.1.0 publisher: developer requires: capabilities: - get_current_time ``` --- # Plugin 接入 > remote-http / remote-mcp / local-node / local-python 三种接入方式选型、真实案例与认证密钥。 ## 30 秒选型 有现成的 https 接口 → **HTTP API**;对方本身是 MCP 服务器 → **MCP Server**;要自己写逻辑计算 → **上传代码**。 ## HTTP API(remote-http):把现成接口包装成 Agent 工具 - **本质**:把别人服务器上现成的 https 接口包装成 Agent 可调用的工具——你只填 URL 和参数表,平台自动生成 `inputSchema`;GET 请求的扁平标量参数展开为查询串,POST 走 JSON body。 - **真实案例**:已上线的「农区天气实况」就是把 Open-Meteo 的 `https://api.open-meteo.com/v1/forecast` 包了一把,参数 lat / lon,无密钥。需要密钥的站点用 `auth.header` + `secretRef`,密钥值在平台「Secret 声明与值」面板录入、不回显。 - **适合**:想接的 API 已经存在且公网可达。**不适合**:需要自己写业务逻辑、或没有现成 API 的场景(那是「上传代码」)。 ## MCP Server(remote-mcp):接入生态里现成的 MCP 服务 - 对方本身就是一台 MCP 服务器:平台真实握手 `initialize` → `tools/list` 拉取工具清单,你勾选确认后每个工具自动成为一个能力;Agent 调用时平台转发 `tools/call`。 - **适合**:工具已由对方维护、你只想接入(如内部知识库 MCP、第三方工具 MCP)。 ## 上传代码(local-node / local-python):自己写逻辑跑在沙箱里 - 自己写纯函数,跑在平台 Extension Host 隔离子进程里——**无网络、无文件系统、无第三方依赖**(local-node 禁止 package.json,只用运行时内置模块)。 - **真实案例**:「测土配方施肥计算器」(Python,按土壤养分与目标产量算施肥量)、「农产品价格牌生成器」(Node,输入价格数据输出价格牌文案)。 - **适合**:数值计算、格式转换等纯计算逻辑。**不适合**:需要访问外部 API 的场景(用 HTTP API 或 MCP)。 ## 认证与密钥 - 选择 API Key 认证时,声明请求头名称与 `secretRef`;manifest 顶层 `secrets:` 列出声明名,真实值在「Secret 声明与值」面板录入(加密存储、不回显)。 - 沙箱测试经平台完整安全链路真实调用一次:仅 https 公网地址(SSRF 防护)、15 秒超时、响应截断。 > 远端地址必须为 https 公网地址;内网、回环、fake-ip 等会被 SSRF 防护拒绝。 ## 命令行路径 ```bash zhiyun plugin create # 平台创建项目并选好接入方式 # remote-http / remote-mcp:在网页配置 Secret、发现 MCP 工具(manifest 型配置暂以网页为主) zhiyun plugin push --zip plugin.zip # local-node / local-python 代码包 zhiyun plugin validate zhiyun plugin test # 调用平台测试接口真实执行一次 zhiyun plugin submit --release-notes "…" zhiyun plugin status ``` 审核中可 `zhiyun plugin withdraw` 撤回;APPROVED 后 `zhiyun plugin publish --version x.y.z` 发布。命令细节见 [CLI 文档](cli.md)。 --- # App SDK 与 AppBridge > app.json 应用清单、React 工程模板与本地开发链路、iframe 沙箱与 CSP 安全方案、window.zhiyun AppBridge API。 ## 开发方式:React 工程模板(推荐)与单文件 HTML 应用 = `app.json` + 静态资源包,在平台沙箱 iframe 内运行。两条开发路径: 1. **React 工程模板(推荐)**:新建应用时选择官方模板(数据看板 / 检查清单·看板)——平台直接生成预构建的成品草稿;或在模板选择处**下载源码工程**(React 19 + TypeScript + Vite + Tailwind 4,内置官方 SDK),本地开发后构建上传: ```bash pnpm install pnpm dev # 本地开发(storage 由模拟宿主接管) cp .env.example .env # 填入完整应用 ID pnpm build # 产物 dist/(相对路径引用,托管链路免改) pnpm pack # 生成 app.zip ``` 生成的 `app.zip` 在应用详情页上传 → 沙箱预览 → 提审。 命令行等价:`zhiyun app create` → `zhiyun app push --zip app.zip` → 平台沙箱预览 → `zhiyun app validate` → `zhiyun app submit` → `zhiyun app status`。App 由管理员审核通过后上架,没有开发者侧 publish 命令;细节见 [CLI 文档](cli.md)。 2. **单文件 HTML(轻量模式)**:新建应用时选「空白应用」,直接在编辑器里写入口 HTML(≤60000 字符)。 3. **AI 生成(应用详情页)**:输入一句需求,平台调用已启用模型生成纯前端多文件应用(vanilla HTML/JS/CSS,无外部资源)并**覆盖当前草稿**。生成走真实模型调用;沙箱 CSP 禁止外链,生成的页面可用 `window.zhiyun` 调用身份/存储/导航;生成结果不满意可改写需求重新生成,或再用模板脚手架覆盖。 ## 双端适配规范(网页端与小程序端) 应用会在网页端桌面 Shell 和微信小程序的应用运行页中打开。应用页面由开发者负责实现,平台只提供沙箱、身份、存储与能力桥接;因此每个发布版本必须同时适配电脑和移动端。 - 采用 **mobile-first 响应式布局**:页面默认按 360px 宽设计,至少覆盖 320–480px 移动屏和 1024–1920px 桌面屏;使用 CSS Grid/Flex、`clamp()`、百分比和 `max-width`,禁止固定页面宽度或依赖 hover 才能完成核心操作。 - 移动端单列、桌面端再扩展为双列/多列;表格改为卡片或横向滚动容器。交互目标不小于 44×44px,正文不小于 14px,避免横向溢出、过密控件和必须双指缩放的内容。 - 监听容器/视口变化而非假定设备型号;处理安全区、软键盘和动态高度:使用 `min-height: 100dvh`,底部操作区预留 `env(safe-area-inset-bottom)`,输入控件不能被固定底栏遮挡。 - 首屏只加载必要内容,图片设置尺寸并使用懒加载;避免大图、长列表一次性渲染和持续高频动画。核心内容在弱网或能力不可用时仍应显示可解释的空态/错误态。 - 不调用外部网络和外链资源;平台网页与小程序运行容器均通过 AppBridge 提供能力。若使用 `window.zhiyun`,必须做能力存在性判断,并提供本地降级,不得白屏。 - 在至少一种窄屏和一种桌面宽度实际检查:导航、表单、弹窗、加载/错误态、键盘弹出、横向滚动及返回路径。只有电脑端可用而移动端不可用的版本不得提交审核。 工程注意(React 构建产物要能跑在沙箱里): - `vite.config.ts` 必须 `base: './'`——入口文档经 `/api/app-host/{appId}/ast/{token}/index.html` 托管,相对路径引用让脚本/样式天然继承会话令牌; - 多视图用 hash 路由(`#/`、`#/board`),沙箱 iframe 内没有服务端路由; - 联网唯一通道是 AppBridge(CSP `connect-src 'none'`),不要在应用里 fetch 外部地址。 ## app.zip 包与应用清单 - 包内必须有 `app.json`(字段与约束见 app.json 示例),且 `entry.path` 指向包内存在的入口 HTML。 - `permissions` 只能取平台已开放的权限词(`profile / storage / agent.run / capability.invoke` 等),越权声明会被拒绝。 - 上传 app.zip 会校验清单并把入口 HTML 写入当前草稿;包结构与文件大小限制与 skill.zip 相同。 - 官方模板源码也可经 `GET /api/developer/app-templates/{templateId}/source`(开发者身份)下载。 ## 托管与安全方案 - App 以 iframe(`sandbox="allow-scripts"`,不含 allow-same-origin)嵌入,响应携带 `Content-Security-Policy: sandbox`,以不透明源运行。 - 托管地址把会话令牌放在**路径段**(`/api/app-host/{appId}/ast/{token}/index.html`):iframe 内的相对路径引用(script/img/多页跳转)天然携带令牌,无需应用代码感知;历史 `?ast=` 查询参数链路保留兼容。 - 托管资源响应带 `Access-Control-Allow-Origin: *`:不透明源下的 ES module 脚本与 crossorigin 样式表是 CORS 模式请求,没有它会全部加载失败;鉴权语义不变(令牌仍必需)。 - 平台会话凭据不进入 App;opaque origin 下无法使用 localStorage,持久化统一走 zhiyun.storage.*(按用户+App 隔离)。 ## window.zhiyun(SDK) - `user.getCurrent()`:当前用户基本资料(需 profile 权限)。 - `storage.get / set / remove`:应用自身存储读写(需 storage 权限)。 - `navigation.open`:仅白名单站内路径(/app、/app/chat、/app/tasks 等)。 - `agent.run / status / result / stop / runAndWait`(需 agent.run 权限):以当前用户身份创建真实智耘会话并启动模型-工具循环;联网与技能沿用会话默认(关闭),App 不得静默开启。 - `capability.invoke`(需 capability.invoke 权限):经 CapabilityBroker 全链路执行;风险 EXTERNAL 的能力不执行,返回 `APPROVAL_REQUIRED` 审批状态;未注册能力 404。 React 工程模板内置带完整 TypeScript 类型的 SDK 源码(`src/zhiyun/zhiyun-bridge.ts` + `zhiyun-bridge-react.ts`,含 `useZhiyunUser` / `useZhiyunStorage` hooks 与本地开发模拟宿主);单文件 HTML 应用直接使用注入的 `window.zhiyun`。 ## 示例 ### app.json ```json { "schemaVersion": 1, "id": "org.example.smartagri.note", "name": "农情速记", "version": "1.0.0", "description": "试验数据快速记录", "entry": { "type": "web", "path": "index.html" }, "permissions": ["profile", "storage"], "dependencies": {} } ``` --- # 知识库 > 平台/个人知识库生命周期、knowledge_search 能力调用方式与管理 API。 ## 平台知识库与个人知识库 - 「知识库」页(`/developer/knowledge-bases`)展示平台知识库与我的知识库;个人库添加纯文本文档,保存时自动按 500 字符 / 50 重叠分块建立检索索引。 - 个人库提交审核(至少一篇文档),管理员在 `/admin/reviews` 通过后上线为平台知识库,对所有用户可见;驳回必须附意见,可修改后重新提审;审核中不能改文档,可撤回。 ## knowledge_search 能力(应用 / 插件 / 技能通用) - 能力 ID:`knowledge_search`(系统内置、只读、scope=PLATFORM),在 `GET /api/developer/capabilities` 目录中可见。 - 输入:`{"query": "检索问题", "kb": "kb-xxxxxxxx(可选,限定知识库)", "topK": 4}`;返回 `results[]`(kb / kbName / documentTitle / seq / score / snippet)。 - 检索范围 = 全部平台知识库 + 调用者自己的知识库(含草稿);无权访问他人的个人库。 - 技能引用:manifest 的 `requires.capabilities` 加 `knowledge_search`;应用经 AppBridge `window.zhiyun.capability.invoke("knowledge_search", input)` 调用;对话与定时任务中智能体可作为工具直接调用。 ## 管理 API - `GET /api/developer/knowledge-bases`:我的知识库;`/platform` 为平台知识库目录。 - `POST /api/developer/knowledge-bases/{id}/documents`:添加文档(≤50,000 字,可选来源链接)。 - `POST /api/developer/knowledge-bases/{id}/submit|withdraw`:提审 / 撤回。 - `POST /api/developer/knowledge-bases/{id}/search`:指定库内检索测试。 - 配额:每人 20 个知识库,每库 100 篇文档。 --- # Capability API > 能力目录端点、字段说明与同名能力冲突规则。 ## 接口 - `GET /api/developer/capabilities`:全量能力目录(系统内置 + 已启用扩展)。 - `GET /api/developer/tools`:系统工具名清单。 - `GET /api/models`:已接入模型清单。 ## 字段说明 - scope:PLATFORM 平台级 / USER 用户级。 - availability:ALWAYS 常驻可用 / CONDITIONAL 依赖运行策略(如联网开关)。 - rateLimitPerMinute:每分钟调用上限,0 表示未单独限制。 - source:SYSTEM 系统内置 / EXTENSION 扩展提供。 - risk:扩展声明取 LOW / MEDIUM / HIGH / CRITICAL;平台系统能力可能标注 EXTERNAL,App 经 capability.invoke 调用 EXTERNAL 能力时返回 APPROVAL_REQUIRED 审批语义。 > 同名能力冲突规则:系统内置优先,其次取最早安装的扩展提供者。 --- # 权限模型 > SUPER_ADMIN / DEVELOPER / MEMBER 角色权限与 服务端逐请求判定原则。 ## 角色与权限 - SUPER_ADMIN:管理后台域全量权限(用户、模型、扩展、审核、审计等),使用独立管理员账号登录 /admin/login。 - DEVELOPER:PLATFORM_USE + DEVELOPER_ACCESS(开发者中心目录接口)。 - MEMBER:PLATFORM_USE(普通使用)。 - 权限按 subject / role / scope_type / scope_id 绑定,每个请求由服务端重新判定;扩展安装等管理操作需要 `EXTENSION_MANAGE`。 --- # 发布规范 > 版本状态机与服务端校验点。 ## 版本状态机 DRAFT(草稿)→ IN_REVIEW(审核中)→ APPROVED(可发布)→ PUBLISHED(已发布);REJECTED(被驳回)可修改后重新提审;审核中可主动撤回回到草稿。所有流转都有服务端审计。 命令行对应:`zhiyun submit` 提审、`zhiyun withdraw` 撤回、`zhiyun skill|plugin publish` 发布(仅 APPROVED;App 审核通过即上架,无 publish);状态查询用 `zhiyun status`。 ## 服务端校验点 - kind 必须是 Skill / Plugin / App / Bundle,否则拒绝。 - 能力 risk 必须在允许的分级内;inputSchema / outputSchema 必须是合法 JSON Schema。 - 技能依赖的能力必须已注册;SKILL.md 内容不能为空。 - runtime.url 必须 https 公网地址;manifest 声明的 secrets 必须与 secretRef 对应。 > 审核在管理后台「扩展审核」队列完成(/admin/reviews);驳回必须填写意见,会展示在开发者的版本历史里。 --- # 开发流程总览 > 三种产物(Skill / Plugin / App)通用全流程与 API 速查。 ## 全流程(三种产物通用) 1. 准备:平台账号 + DEVELOPER 角色(开发者中心 `/developer/login`);创建项目时只需填 ID 短码(2-40 位小写字母/数字/连字符,如 `rice-pest-guard`),平台自动拼装为 `org.example.〈你的账号〉.skill|plugin|app.〈短码〉`,`org.example.zhiyun.*` 为平台保留段。 2. 创建项目:开发者中心对应面板新建;App 的 appId 即清单里的 id,创建后不可改。 3. 本地开发 + 打包:按「技能开发 / Plugin 接入 / App SDK」的包结构准备文件并 zip(命令见「AI 提示词模板」各模板末尾)。 4. 上传草稿:Skill/Plugin 在项目工作台上传 zip;App 上传 app.zip(会覆盖当前草稿,版本号取包内清单)。 5. 提审 → 审核 → 发布:草稿 → IN_REVIEW → APPROVED → PUBLISHED;驳回改后可重新提审。 ## 命令行路径 上述流程用 `zhiyun` 命令行等价执行:`zhiyun login` 设备授权登录 → `zhiyun create` 创建项目 → `zhiyun push --zip <包>` 上传草稿 → `zhiyun validate` 服务端校验 → `zhiyun submit` 提审 → `zhiyun status` 跟踪;审核中可 `zhiyun withdraw` 撤回,Skill/Plugin 批准后 `zhiyun skill|plugin publish` 发布。完整命令索引见 [CLI 文档](cli.md)。 ## API 速查(可用脚本/让 AI 代跑) - 技能/插件(Bearer 开发者 JWT):`POST /api/developer/projects`(kind 取 `Skill / Plugin`,App 走 /apps)→ `POST /api/developer/projects/{id}/package`(multipart,字段名 file)→ `POST /api/developer/projects/{id}/versions/{vid}/submit` → 通过后 `POST .../versions/{vid}/publish`。 - 应用:`POST /api/developer/apps`(先建草稿)→ `POST /api/developer/apps/{appId}/package`(app.zip)→ `POST /api/developer/apps/{appId}/releases/{version}/submit` → `POST /api/admin/apps/{appId}/releases/{version}/review`(`{"approve":true}`,通过即上架)。 - 审核管理:`POST /api/admin/reviews/{vid}/approve` / `/reject`(管理员会话)。 - 目录验证:`GET /api/skills`(技能)、`GET /api/apps`(应用)、`GET /api/developer/capabilities`(能力)。 > App 的 category 只能取:科研分析 / 智慧种植 / 病虫害 / 农业气象 / 遥感与 GIS / 数据工具 / 文献研究 / 项目管理,其他值会被 400 拒绝;应用必须至少声明一项 AppBridge 权限。 --- # AI 提示词模板 > 可直接复制给任意 AI 的技能 / 插件 / 应用开发提示词模板,内置平台硬性校验规则与交付清单要求。 ## 用法 把对应模板整段复制给任意 AI(豆包/ChatGPT/Claude 等),替换〈〉占位符后发送,AI 会产出符合平台包结构的全部文件,并在末尾输出一份**交付清单**(类型、zip 路径、项目名称、ID 短码、下一步命令等),供你或 Agent 按清单继续操作:`zhiyun` 命令行(见 [CLI 文档](cli.md))或网页上传均可。模板内置了平台的硬性校验规则(命名空间、包限制、权限词、分类枚举),可显著减少提审被驳回的往返。 ## 交付清单(三套模板统一要求) 每套模板都要求 AI 在产出文件与 zip 命令**之后**,额外输出一份交付清单,至少包含以下字段。名称、ID、描述必须由实际产出的文件推导,不得编造平台账号;未登录时完整 ID 用 `<登录账号派生段>` 占位,登录后以服务端返回的 ID 为准。 ```text 【交付清单】 - 类型:Skill / Plugin / App - 本地 zip 绝对路径:/absolute/path/to/.zip - 项目名称:<与包内 name 一致> - ID 短码:<2-40 位小写字母/数字/连字符,创建项目时填写> - 平台预期完整 ID:org.example.<登录账号派生段>.. - 一句话描述:<与包内 description 一致> - 版本:<语义化版本,与包内清单一致> - 下一步命令: - 包内关键文件:<逐个列出,如 SKILL.md、manifest.yaml、app.json> - 待开发者填写:<权限/密钥/审核说明等需要人工补充的项,无则写"无"> ``` ## 三套模板 ### 技能(Skill)提示词模板 ```text 你是资深农业知识工程师。请为我开发一个可在"智耘农业智能体"平台上架的技能(Skill)。 【需求】 - 技能名称:〈技能名称,如"水稻病虫害诊治助手"〉 - 解决的问题:〈一两句话描述目标用户与场景〉 - 核心内容:〈希望技能教 Agent 掌握的知识/决策规则/话术,可分点〉 【产出要求】 1. 输出一个 Markdown 文件 SKILL.md(技能指令正文,非空,≤2MB)。 - 开头用一句话定位技能,随后给出结构化正文:决策规则用表格、 流程用有序列表、关键阈值/禁忌用加粗标注。 - 内容必须可执行、可判断,避免空泛描述;宁可窄而深,不要宽而浅。 2. 如需辅助资料,可额外输出 scripts/、references/、assets/、agents/ 目录下的文件 (包内条目 ≤200 个,单文件 ≤2MB,解压总量 ≤20MB,包体 ≤10MB)。 【打包(我手动执行)】 - 把以上文件打包成 zip(SKILL.md 必须在包根或唯一顶层目录): zip -X skill.zip SKILL.md(有多目录时一并加入) 【后续步骤(二选一)】 - CLI:zhiyun skill create(创建项目)→ zhiyun skill push --zip skill.zip → zhiyun skill validate → 调试通过后 zhiyun skill submit。 - 网页:在"开发者中心"创建 Skill 项目(只填 ID 短码〈英文名〉,小写字母/数字/连字符,2-40 位, 平台自动拼装完整 id org.example.〈我的账号〉.skill.〈英文名〉),在项目工作台上传 zip。 【硬性规则】 - 技能如果需要调用平台已有能力,请只从已注册能力里选 (以 GET /api/developer/capabilities 或 zhiyun capability list 实际返回为准), 平台会校验 requires.capabilities,未注册能力无法提审。 - 上传后进入 草稿 → 提交审核 → 管理员通过 → 发布,全平台用户可见。 【交付清单】完成文件产出与打包后,按上方统一格式输出交付清单: 项目名称与描述必须取自 SKILL.md 的实际定位语;ID 短码由技能英文名推导; 待开发者填写栏写明 requires.capabilities 的选择依据(无依赖则写"无")。 ``` ### 插件(Plugin)提示词模板 ```text 你是资深后端工程师。请为我开发一个可在"智耘农业智能体"平台上架的插件(Plugin)。 【需求】 - 插件名称:〈插件名称,如"农区天气实况"〉 - 要提供的能力:〈1-3 个具体能力,每个一句话说明输入输出〉 【先选接入方式(按优先级)】 A. remote-http:我已有一个稳定的 https 公网 API。只产出 manifest.yaml,无代码。 - GET 请求的扁平标量入参会被展开为查询串,POST 走 JSON body; - API Key 认证用 auth.header + auth.secretRef,密钥值我在平台录入。 B. remote-mcp:对方本身是 MCP 服务器。只产出 manifest.yaml(url 必须 https)。 C. local-node / local-python:纯本地计算(推荐无外部依赖的能力)。 - 产出 manifest.yaml + capabilities/〈能力id〉.js|py; - 代码必须是纯函数:禁止网络请求、文件系统、数据库与第三方依赖 (local-node 不允许 package.json,只用运行时内置模块); - 输入是 JSON 对象,输出直接 return 一个可 JSON 序列化的对象。 【manifest.yaml 结构(C 方式示例)】 apiVersion: zhiyun/v1 kind: Plugin id: org.example.〈我的账号〉.plugin.〈英文名〉 ← 平台创建项目只填短码〈英文名〉,前缀自动拼装 name: 〈插件名〉 version: 0.1.0 publisher: 〈发布者〉 description: 〈一句话〉 runtime: name: local-python # 或 local-node / remote-http / remote-mcp entry: capabilities/〈能力id〉.py permissions: capabilities: [] capabilities: - id: 〈能力id〉 name: 〈能力id〉 description: 〈一句话,Agent 靠它决定何时调用〉 type: TOOL risk: LOW inputSchema: '{"type":"object",...,"additionalProperties":false}' # JSON Schema 字符串 outputSchema: '{"type":"object"}' rateLimitPerMinute: 30 【产出要求】 1. manifest.yaml(根)+ capabilities/ 下每个能力一个入口文件(C 方式); 2. 每个能力附一段本地自测:用示例输入真实跑一遍并给出预期输出, 数值计算类要自己验证数学正确性后再给我; 3. 打包(我手动执行,仅 C 方式需要代码包):zip -X plugin.zip manifest.yaml capabilities/* (A/B 方式不传代码包,主要在平台配置 manifest)。 【后续步骤(二选一)】 - CLI:zhiyun plugin create →(A/B 方式在网页配置 Secret / 发现 MCP 工具; C 方式)zhiyun plugin push --zip plugin.zip → zhiyun plugin validate → zhiyun plugin test → zhiyun plugin submit。 - 网页:开发者中心创建 Plugin 项目并选接入方式,配置密钥或上传代码包。 【硬性规则】远端地址必须 https 公网(SSRF 防护);secrets 只声明引用名, 密钥值不进代码包与交付清单;提审前平台会做沙箱测试。 【交付清单】完成文件产出与打包后,按上方统一格式输出交付清单: 项目名称/描述/版本必须与 manifest.yaml 完全一致;capabilities[].description 要写明调用场景;待开发者填写栏列明需要录入的 secretRef 名与值(值留空)。 ``` ### 应用(App)提示词模板 ```text 你是资深前端工程师。请为我开发一个可在"智耘农业智能体"平台上架的应用(App)。 【需求】 - 应用名称:〈应用名称〉 - 功能描述:〈目标用户 + 核心交互 + 数据是否需要持久化〉 - 视觉:与平台一致的农业绿风格,移动端可用,中文文案。 【双端适配要求(必须实现并自测)】 - 应用同时运行在桌面网页端和微信小程序应用运行页。请采用 mobile-first 响应式布局,默认覆盖 320–480px 移动屏,并扩展适配 1024–1920px 桌面屏;不要只写桌面端。 - 使用 CSS Grid/Flex、百分比、`clamp()` 与 `max-width`,禁止固定画布宽度;核心操作不依赖 hover,触控目标至少 44×44px,正文至少 14px。 - 移动端使用单列和可滚动卡片,桌面端可使用多列;长表格必须提供移动端卡片或横向滚动。使用 `min-height:100dvh` 和 `env(safe-area-inset-bottom)` 处理小程序安全区,不能让底部按钮被键盘或底栏遮挡。 - 为加载、空数据、错误、窄屏和能力不可用状态提供可见反馈;图片和长列表按需加载,避免大图与持续高频动画。 - 交付前至少检查 390px 窄屏与 1440px 桌面:无横向溢出,表单可输入,弹窗可关闭,返回路径可用。README 中记录这两种尺寸的检查结果。 【硬性运行环境约束(必须遵守,否则无法通过审核)】 1. 应用以 iframe 沙箱(opaque origin)运行:禁止 fetch/XHR/外链资源, 所有样式脚本内联或随包相对路径引用;不依赖 localStorage(不可用)。 2. 数据持久化只能用平台 SDK(需声明 storage 权限): window.zhiyun.storage.get({key}) / set({key, value}) / remove({key}),按用户+应用隔离; window.zhiyun.user.getCurrent() 可获取当前用户(需 profile 权限)。 3. SDK 由平台注入,宿主外预览时 window.zhiyun 可能不存在:所有调用必须 判空并给出本地降级(如内存/会话态兜底),不得报错白屏。 4. permissions 至少声明 1 项,只能取:profile / storage / agent.run / capability.invoke, 按最小权限原则只声明真正用到的。 5. app.json 的分类(category)只能取: 科研分析 / 智慧种植 / 病虫害 / 农业气象 / 遥感与 GIS / 数据工具 / 文献研究 / 项目管理。 【产出文件】 1. app.json: {"schemaVersion":1,"id":"org.example.〈我的账号〉.app.〈英文名〉","name":"〈应用名〉", ← 平台创建项目只填短码〈英文名〉,前缀自动拼装为完整 id "version":"1.0.0","description":"〈一句话〉","entry":{"type":"web","path":"index.html"}, "permissions":["..."],"dependencies":{}} (id 必须与我创建应用时填的 appId 完全一致) 2. index.html(入口,≤60000 字符)+ 相对路径引用的 css/js 资源; 3. 如使用了 window.zhiyun.*,逐处标注注释说明权限依据与降级逻辑; 4. README.md:功能说明与手动验证步骤。 【打包(我手动执行)】 zip -X app.zip app.json index.html css/* js/* README.md (包限制与技能包相同:≤10MB / ≤200 条目 / 单文件 ≤2MB;上传 app.zip 会覆盖当前草稿) 【后续步骤(二选一)】 - CLI:zhiyun app create → zhiyun app push --zip app.zip → 平台沙箱预览 → zhiyun app validate → zhiyun app submit。 - 网页:应用开发新建应用 → 上传 app.zip → 沙箱预览 → 提审。 【硬性规则】之后 提交审核 → 管理员通过 → 用户可在应用中心打开(App 无开发者侧 publish, 上架语义与 Skill/Plugin 不同)。 【交付清单】完成文件产出与打包后,按上方统一格式输出交付清单: 项目名称/描述/版本必须与 app.json 完全一致;待开发者填写栏写明所选 category 与 permissions 的最小权限依据。 ``` > 模板里的能力清单会随平台上架情况变化——以 `GET /api/developer/capabilities`(或 `zhiyun capability list`)的实时返回为准。 --- # 示例项目 > 可直接使用的四类 Manifest 样例。 ## 可直接使用的 Manifest 样例 ### Plugin(remote-http) ```yaml apiVersion: zhiyun/v1 kind: Plugin id: org.example.smartagri.weather name: 天气查询插件 version: 0.1.0 publisher: developer description: 查询指定城市当前天气 runtime: name: remote-http url: https://api.example.com/weather method: POST auth: header: X-Api-Key secretRef: API_KEY permissions: capabilities: [] secrets: - API_KEY capabilities: - id: weather_query name: weather_query description: 按城市名查询当前天气 type: TOOL risk: LOW inputSchema: '{"type":"object","properties":{"city":{"type":"string","description":"城市名"}},"required":["city"],"additionalProperties":false}' outputSchema: '{"type":"object"}' rateLimitPerMinute: 30 ``` ### Plugin(remote-mcp 骨架) ```yaml apiVersion: zhiyun/v1 kind: Plugin id: org.example.smartagri.mcp.demo name: MCP 示例插件 version: 0.1.0 publisher: developer runtime: name: remote-mcp url: https://mcp.example.com/mcp permissions: capabilities: [] capabilities: [] ``` ### Skill ```yaml apiVersion: zhiyun/v1 kind: Skill id: org.example.smartagri.fieldnote name: 田间记录助手 version: 0.1.0 publisher: developer requires: capabilities: - get_current_time ``` ### App(app.json) ```json { "schemaVersion": 1, "id": "org.example.smartagri.note", "name": "农情速记", "version": "1.0.0", "description": "试验数据快速记录", "entry": { "type": "web", "path": "index.html" }, "permissions": ["profile", "storage"], "dependencies": {} } ```