---
name: aidc-sdk
description: Build, test and publish AIDC Nexus apps with the AIDC Developer SDKs and the aidc CLI — the UI SDK (ui.css + ui, shadcn/ui look), vision (camera, inspection, object detection, NVR / RTSP live view), voice, video, OpenAI-compatible models and agents with per-company billing, modeling (Marble 3D worlds, digital-twin anchors), and Semantic, the data platform (Palantir-style ontology, object sets, real-time subscriptions, governed Actions, data streams and datasources, SQL, access, Automate, logs and usage; agents change the ontology on branches, humans approve proposals; the ERP stays read-only), self-evolution (users change an app from inside it; evidence-driven proposals), and test / production publishing; an app is skills (SKILL.md) plus APIs (HTTP, CLI, MCP) that agents use from one copied sentence. Use when a task mentions AIDC Developer, AIDC Nexus apps, the aidc CLI, ai-dc.ai, Semantic, 语义层, 数据源, 工作流, 自动化, 应用卡片, 自进化, 账单, 界面, 建模, 数字孪生, 摄像头, NVR, 会议纪要, ERP 数据, Skills, MCP, or publishing an app to Nexus.
---

# AIDC Developer SDK · 智能体操作手册

AIDC Developer：九个 SDK（界面、视觉、语音、视频、模型、建模、语义、自进化、发布）+ `aidc` CLI + OpenAI 兼容模型 API。**语义（Semantic）是数据平台**：数据从哪来（数据流 → Object Type 定义里的 `datasources`）、对象与 Action、实时订阅、SQL、访问、自动化（Automate）、日志与用量都在 `semantic` 里（1.20.0 起原来的连接、数据、权限、工作流、日志、账单 SDK 并进来，旧名照样能用）。1.22.0 起自提升并进自进化（`aidc improve`、`improve.*` 是旧名，照样能用）。在 Developer 里开发与测试，发布到 Nexus。文档索引：https://www.ai-dc.ai/developer/llms.txt （每页可 `curl …/developer/docs/<页>.md`）；闭环：`…/developer/docs/loop.md`。

**企业数据的铁律**：读写都在 Semantic（`semantic.ontology()`），ERP / MES 只被发布端读，永远不直连、不回写。改数据只走 Action（参数校验、谁能做、留痕）；数据从数据源进来——哪条流、哪一列对哪个属性写在 Object Type 定义的 `datasources` 里，改它 = 改本体（智能体走分支与提案）。

**自进化的铁律**：用户在应用里说的改进落成白名单指令（token / style / text / attr / reset），不是代码——不要为了「让页面能被改」去给应用加 eval、动态 HTML 注入或自定义样式输入框；要给用户能改的区域，就在页面上标 `data-evolve="名字"`、在清单 `evolve.slots` 起名字、把尺寸 / 主色这类可预见的调整做成 `evolve.tokens`（带 min / max 的 CSS 变量）。全员改进叠到上限（40 条）前用 `aidc evolve bake` 固化进代码再发版；采纳成员的改进用 `aidc evolve adopt`，别替用户直接改他们的个人改进。

**建模（世界模型）的铁律**：生成世界花真钱（试稿约 US$0.18，正式约 US$1.26，Plus 最多 US$2.48）——先 `aidc modeling estimate` / `--dry-run` 看估价与额度，先用试稿模型 `marble-1.0-draft`，满意了再 `marble-1.1`；同样的请求会复用已有世界（不要加 `--regenerate` 除非确实要重新生成）；网络重试用同一个 `--idempotency-key`；`quota_exhausted` 是额度用完，不要换 Key 或绕路重试。官方公开应用只能看，不能生成。客户现场的照片 / 视频会发给 World Labs 处理，要有客户同意；生成的世界不是测绘，锚点没核验前标 `verified: false`。

**界面的铁律**：页面一律引 `/developer/sdk/v1/ui.css`，按钮、表单、卡片、表格、对话框用它的 `aidc-*` 类，确认 / 输入 / 提示用 `ui.confirm` / `ui.prompt` / `ui.toast`，等待用 `//` 加载动效（不用圆环 spinner）；不要在应用里另写一套按钮样式。类名与示例标记：`aidc ui components --json` 或 https://www.ai-dc.ai/developer/sdk/v1/ui.json 。

**成本的铁律**：能用触发的不用定时——数据一变才需要做的事用数据流 + `trigger.change`（`when` 条件、`cooldown` 冷却）；定时（`trigger.schedule`）只给日报、月底对账、断供看门狗，每天一次是常态，≤ 1 小时一次部署时会告警、< 5 分钟拒收。不写 `setInterval` 轮询服务端。每个应用都有上限（清单 `limits`，计算分钟缺省 2000 / 月，用完 `429 quota_exhausted`），调高要说明理由；`aidc app usage <应用> --json` 看用量。开发中临时开的服务、Key、测试数据用完就关。

## 0. 准备

```bash
curl -fsSL https://www.ai-dc.ai/developer/cli/install.sh | sh     # 需要 Node ≥ 18
aidc --version
```

安装输出的最后一行（`下一步：… login`）就是在这台机器上能用的命令：`aidc` 不在 PATH 上时它给完整路径 `~/.aidc/bin/aidc`，照它敲，不用自己找。

登录：AIDC 密码只由人本人输入，**不要向人索要、转述或保存密码**。

- 人就在这台机器的终端前（你跑在人的电脑上）：请人在**自己的终端**里运行 `aidc login`，输入账号和密码（还没有账号时它会提示去 `https://www.ai-dc.ai/login` 注册）。你执行的命令不是交互终端，替人运行 `aidc login` 会立即以退出码 2 报错——这是设计如此，不是故障。
- 身边没有终端（你在客户的服务器上、经 IM 和人对话）：用浏览器批准，把链接交给人——

```bash
aidc login --browser --no-wait --json    # 输出 {"event":"authorize","url":…,"userCode":…}；把 url 交给人（10 分钟内有效）
aidc login --continue --no-wait --json   # 查一次：没批准 → {"event":"authorization_pending"}、退出码 3；批准了 → {"event":"logged_in"}
aidc whoami --json
```

批准要等人，别干等：把链接交给人之后先做不需要登录的事（读文档、写代码；`aidc` 命令都要登录，包括 `aidc app check`），每做完一步查一次 `--continue --no-wait`；一条终端命令里别循环超过一两分钟。不带 `--no-wait` 的 `--continue` 会一直等到批准或过期（最长 10 分钟），终端命令有超时的环境里别这么用。链接过期了就重新 `aidc login --browser --no-wait`。无人值守时用环境变量 `AIDC_API_KEY=aidc-dk-…`。凭证只有这几个来源：人登录的 `aidc login`（终端密码或浏览器批准），或人明确交给你的 `AIDC_API_KEY`——不要在机器上翻 `.env`、别的项目的配置去找 Key（那是别人的凭证，用量与责任都会记错）。**永远不要把 aidc-dk- 开发者 Key 写进前端代码或提交到仓库。**

## 1. 做一个 Nexus 应用

一个应用 = **一组 Skills + 一组 APIs，界面可选**（https://www.ai-dc.ai/developer/docs/apps，照 OpenAI Plugin 的定义）。智能体照 Skills 调 APIs，程序直接调 APIs，人要看和确认时才打开界面。

```bash
aidc app init <slug> --template skills|camera|voice|data|blank --title "<标题>" --json
```

生成 `aidc.app.json` + `skills/<slug>/SKILL.md`（+ 有界面的模板：`index.html` + `app.js` + `style.css`；`skills` 模板没有界面，清单 `"entry": null`）。规则：

- **Skills**：`skills/<名字>/SKILL.md`，frontmatter `name`（与目录同名）+ `description`（写「用户要做什么时用」，≤ 1024 字符，有「: 」就整句加引号）；正文写输入、步骤（调哪些 API / 命令）、输出、不能推断的事、什么时候问人。清单里不登记，部署时逐条校验。
- **示例说法**：清单 `examples`（≤ 6 条，用户会说的话）；`description` 写应用做什么、给谁用。
- **APIs**：清单 `exports`（显式导出）+ `semantic` 登记的类型与 Action（自动提取）+ `workflow`（run / get_run / list_runs）。调：`aidc app call <命名空间>/<slug> <API> --param 名=值 --json`，写入先 `--preview`。

- 单页应用；包内用**相对路径**；SDK 用绝对路径 `import { ui, semantic, data, auth, log, billing, evolve, vision, voice, video, model, modeling, connect } from "/developer/sdk/v1/aidc.js";`
  - 界面：`<head>` 里第一张样式表是 `<link rel="stylesheet" href="/developer/sdk/v1/ui.css" />`（`aidc app init` 已接好；已有应用 `aidc ui add <dir> --dry-run` 再 `aidc ui add <dir>`），自己的 `style.css` 只写版面与业务特有的东西；
  - `sdk`：**登记用到的每个 SDK**（部署时静态分析 import，用了没登记的直接拒收）；
  - `semantic`：`{ "types": [读的对象类型], "actions": [能执行的 Action], "write": [developer 访客可直接写的类型] }`；
  - `auth.access`：`company`（本公司成员，缺省）/ `restricted`（只有开发者和被分享的人）；`auth.publicLink`：公开链接的访客（一律登录）`signin`（缺省，登录后外人只读）/ `members`（登录后只有本公司的人）；旧值 `open` 按 `signin`；
- 清单 `aidc.app.json`（Schema：https://www.ai-dc.ai/developer/schemas/aidc.app.schema.json）：
  - `permissions.camera / microphone`：用到才开；
  - `version`：**版本号**（`1.0.0` 起，语义化）；改了任何东西（文件或清单）就要升，否则部署返回 `version_conflict`；
  - `models`：列出会调用的模型（票据只放行这些）；`datasets`：会读的数据集；`streams`：会订阅的实时数据流（同一命名空间）；
  - `storage` 只有 `{"type":"none"}`（Nexus 应用无状态：业务数据在语义层，改数据 = 执行 Action）；
  - `limits`：`dailyTokens`、`requestsPerMinute`、`realtimeSessionsPerDay`；
  - 第三方脚本只能来自 `cdn.jsdelivr.net` / `cdnjs.cloudflare.com`，并写进 `cdn`。
- 包 ≤ 200 个文件、≤ 3 MB；不要有 `_v/` 目录（保留）；不要带 SDK 的副本（`developer/sdk/…` 路径的文件，部署拒收——SDK 只从 `/developer/sdk/v1/` 引入）。

## 2. 校验、预览、发布

```bash
aidc app check <dir> --json      # 本地校验，与服务端同一份契约；失败时 details.issues 逐条列出
aidc app dev <dir>               # http://localhost:5173，API 经本机代理（Key 不进浏览器）
aidc app deploy <dir> --json     # → test 通道；返回 test（Developer 预览）与 production 地址
aidc app publish <dir> --notes "<这次改了什么>" --json    # 把 test 上测过的版本发到 Nexus
aidc app rollback <slug> --version 1.1.0 --notes "<为什么>"
aidc app status <slug> --json    # 每个版本的版本号、构建序号、更新状态（live / testing / tested / superseded / rolled_back / untested）
aidc app history <slug> --json   # 发布记录
```

- **给人看的预览 = `aidc app deploy` 返回的 Developer 预览链接**（要先登录）。`aidc app dev` 只在人和你用同一台电脑时有用——你在远程机器上时，人打不开你的 localhost。没登录就先把代码写好、`aidc app check` 通过，等人登录；不要自己写一份假的 SDK 或起本地服务器来「预览」（包里带 SDK 副本，部署直接拒收）。
- 发布是**幂等**的：内容相同不产生新版本，出错直接重试。
- 先预演：任何写命令加 `--dry-run`。
- 用别人做好的应用：人交给你「帮我用 AIDC 应用「…」：…/about.md」时，读那份说明（公司应用 `aidc app about <命名空间>/<slug>`），照其中的 Skill 调 `aidc app call`；`aidc app apis <命名空间>/<slug>` 列出全部 API。
- production 只接受进过 test 的版本；退出码 6 = 冲突（例如版本未测）。

## 3. SDK 速查

```js
// 界面（样式表 /developer/sdk/v1/ui.css；类名：aidc ui components --json）
ui.toast("已保存", { variant: "success" });                           // default / success / error，可带 action
if (await ui.confirm({ title: "删除这张工单？", destructive: true })) remove();
const text = await ui.prompt({ title: "标记问题", label: "问题描述", required: true });   // 取消 → null
el.append(ui.loader("dial"));                                          // 等待：// 加载动效（dial 刻度轮 / cadence / sequence…）
ui.download("验收记录.csv", data.toCsv(rows, ["治具", "结论"]));        // 导出文件；CSV 自动加 BOM，Excel 直接打开中文不乱码
ui.tabs("#tabs"); ui.theme.set({ mode: "system" });

// 视觉
const camera = await vision.openCamera({ video });            // 或 vision.pickImage()
const photo = await camera.capture();
const r = await vision.inspect(photo, { task: "检查什么", criteria: "什么算不合格" });   // gpt-6-luna
// r = { verdict: "pass"|"fail"|"uncertain", summary, findings: [{label, severity, confidence, box}] }
const canvas = await vision.annotate(photo, r.findings);
const d = await vision.detect(photo, { labels: ["人", "叉车"] });   // 物体检测 → { objects: [{ label, confidence, box: [x0,y0,x1,y1] 归一化 }] }；vision.annotate(photo, d.objects) 画框
// 公司 NVR / 网络摄像机（清单 "cameras": ["nvr"]；开发者先 aidc vision camera add 登记，口令只走 AIDC_CAMERA_PASSWORD）
const view = vision.live(canvas, { camera: "nvr", channel: 1, onStatus });   // 子码流实时，WebCodecs 硬解；页面隐藏 1 分钟自动断
const shot = await vision.cameraSnapshot("nvr", { channel: 1 });             // 主码流高清截图 → 可直接 vision.detect(shot)
// 不要 setInterval 反复截图当实时；摄像头口令永远不进应用代码、不进命令行参数

// 语音
const s = await voice.startTranscription({ languages: ["zh","en"], onPartial, onFinal });   // 每场 ≤ 5 分钟
const t = await voice.translate(text, ["ja","en","ar-EG","bn"]);
const m = await voice.minutes(transcript);                    // {title, summary, decisions, actionItems, topics, markdown}

// 视频
const v = await video.openVideo({ video }); v.sampleFrames(3000, onFrame);
await video.analyze(file, { task, everySeconds: 5, transcribe: true });

// 模型（OpenAI 兼容）
await model.text({ model: "deepseek-flash", messages });
await model.json({ model: "gpt-5.4-mini", messages, schema: { name, schema } });
await model.decide(state, { q: { instructions, criteria: { a: "…", b: "…" } } });           // Jev

// Semantic（数据平台）：读对象集、实时订阅、改数据只走 Action
const client = semantic.ontology();
const issues = client.objects("production.order_line").where({ status: "异常" });
const page = await issues.fetchPage({ $orderBy: { gap: "desc" } });
issues.subscribe({ onChange: ({ object, state }) => draw(object, state), onOutOfDate: reload });   // 页面隐藏 1 分钟自动断、切回续上
const v = await client.action("production.flag_issue").applyAction({ order_line: pk, issue: "缺料" }, { $validateOnly: true });   // 先只校验
// 原始数据流（没接进 Ontology 的信号）：先全量、后增量，断线带序号续传；publisher.live=false 要在界面上提示
semantic.stream("orders").subscribe({ onUpdate: ({ rows }) => render(rows), onStatus: ({ publisher }) => badge(publisher) });
const agent = model.agent(agentKey); await agent.send(text, { sessionId });   // 智能体：访客自带 aidc-sk- Key
// 本地分析小工具（旧的数据 SDK，照样能用）：data.parseCsv(text); data.groupBy(rows, "k", { total: ["amount","sum"] }); data.barChartSvg(points)
// 演示用的合成 ERP 固定报告：connect.datasets.report("aidc-demo-erp", "overview")（只含聚合；你公司的数据在 Semantic 里）

// 建模（世界模型）：文字 / 照片 / 全景 / 视频 → 3D 世界；页面先放 modeling.importMap() 的 import map，清单 sdk 登记 modeling、cdn 登记 cdn.jsdelivr.net
modeling.estimate("marble-1.0-draft", "text");                                        // 纯函数：{ maxCredits: 230, maxUsd: 0.184 }
const { world } = await modeling.generate({ input: { kind: "text", text: "装配工位…" } });  // 缺省试稿模型；自动带 Idempotency-Key
const done = await modeling.wait(world.id);                                           // 约 5 分钟；assets.splats / collider / frame（米、Y 向上、地面 y = 0）
const view = await modeling.viewer(el, done, { collider: true, onAnchor: (a) => open(a.object) });
await modeling.setAnchors(done.id, [{ id: "r1", label: "机械臂 R-01", position: [1.2, 0.8, -3.4], object: { type: "production.equipment", pk: "R-01" } }], { ifRev: done.anchorsRev });

// 自动化（Automate，§5b）：组合已发布应用的能力；预演不写数据
const { run } = await semantic.automate.run({ rfq_no: "RFQ-1" }, { mode: "preview" });
semantic.automate.watch(run.id, { onRun: (r) => draw(r.steps), onDone: (r) => show(r.output) });
const card = await appCard("quote-sales");                    // 应用卡片：负责部门、版本、SDK、连了哪些数据
```

## 4. Semantic：读、写、订阅、数据源、定义

```bash
aidc semantic ontology --json                  # 先看有什么：Object Type、Link Type、Action Type、Interface
aidc semantic objects <类型> --where '{"status":"异常"}' --order-by gap:desc --json
aidc semantic object <类型> <主键> --json · aidc semantic edits-history <类型> --pk <主键> --json   # 对象 + 每次修改（谁、何时、哪个 Action）
aidc semantic aggregate <类型> --select '{"$count":"unordered","costUsd:sum":"desc"}' --group-by '{"month":"exact"}' --json
aidc semantic apply <Action> --param 名=值 --validate-only --json   # 先只校验（参数逐项、提交条件逐条），再去掉 --validate-only 执行——改数据的唯一方式
aidc semantic subscribe <类型> --where '{"status":"异常"}' --json    # 实时：对象进来 / 变了 / 离开，每行一个 JSON
aidc semantic sql 'SELECT stage, count(*) FROM organization GROUP BY 1' --json   # Ontology SQL：每个组织一个只读 Postgres schema（≤ 10,000 行、20 秒）
aidc semantic streams create <流名> --title … --key <主键> --field 名:类型 …   # 数据流（发布端：aidc semantic streams pipe）
aidc semantic datasource set <类型> --stream <流名> --map 属性=列 … [--mode upsert]   # 数据源写进 Object Type 定义（ERP 只读）
aidc semantic datasource sync                                                  # 平台数据源立即同步
aidc semantic define ontology/ --dry-run --json && aidc semantic define ontology/ && aidc semantic publish --notes "…"
aidc semantic filesystem list --scope public --json   # 访问：Public 的资源；档位 aidc semantic filesystem access <rid> --tier private|group|public|internet；分享 … share <rid> --user … | --group cell-…[:dept:<部门>] | --everyone
```

旧命令照样能用（`aidc data …`、`aidc semantic act`、`aidc data bind`、`aidc resources …`），新任务用上面的写法。

**要做一个会执行的 Action（定义 → 只校验 → 执行 → 应用 → 自动化）**：照一个完整的、每一步都跑通的例子来——`developer/docs/samples.md` 的「座位申请」（定义在 `developer/apps/seat-desk-data/`，应用 `seat-desk`，自动化 `seat-auto-approve`），讲解在 Academy 课程 https://www.ai-dc.ai/academy/semantic-action 。要点：参数限制只看参数、要和对象当前的值比就写提交条件并配一句失败信息；一个 Action 的多条规则在同一个事务里；给自动化的 Action 单做一个、把策略写进提交条件；写入先 `--validate-only` / `--preview`。

**本体的铁律**：智能体不直接改 main 上的本体（会得到 409 `branch_required`）。设 `AIDC_AGENT_ID=<你的智能体 id>`，`aidc semantic branch create <分支>` → `branch modify <分支> <目录> --dry-run` → `branch modify` → 带 `--branch <分支>` 读来验证 → `branch propose <分支> --title … --trigger "为什么要改" --self-test "自测结果"`，把输出里的 `reviewUrl` 交给人。批准、合并只有人能在网页上做；破坏性改动人要输入资源名确认。名字照 Palantir：Object Type / Property camelCase，Action Type kebab-case，Interface UpperCamelCase。

**敏感数据（财务、薪资、采购价、配方）**：用 Markings 与对象 / 属性安全策略管（[数据安全](https://www.ai-dc.ai/developer/docs/semantic.md)）。策略写在 Object Type 定义里，Marking 一律用 id（`aidc semantic admin markings list`）；你改不了安全策略，只能在分支上改、开提案——`define --dry-run` 权限不够时照样出结果，「要谁来批」在 warnings 里。先用 `aidc semantic security test <类型> --user <账号 id> --object '{…}'` 自测再提案。看不见的属性读到 null：不要把 null 当成「没有值」写进结论。

```js
const me = await semantic.admin.getCurrentUser(); if (semantic.admin.can(me, { action: "production.flag_issue" })) showButton();
if (!me.signedIn) semantic.admin.signIn(); else if (!me.member) ui.toast("仅限本公司成员");   // 公开链接：登录绑定，判断是不是本公司的人
semantic.observability.feedback({ topic: "看板", message }); semantic.observability.track("filter", { line });
evolve.mount();   // 自进化 · 应用里直接改：右下角「// 改进」，用户说「对话框变大」页面马上变（页面上用 data-evolve 标出能改的区域）
```

## 5. 分享、成员、日志、自进化、登记表

```bash
aidc share <应用> --user <邮箱> --role editor --days 30 | --company | --public     # 公开链接只读，只显示一次
aidc share list <应用> · aidc share revoke <id>
aidc semantic admin members import users.json --source <来源名> --dry-run   # 已有名单导入本公司（member；developer 不降级；本人用邮箱验证码登录即激活）
aidc semantic observability summary <应用> --json          # 使用、反馈、操作、各版本号状态、语义版本
aidc evolve evidence <应用> --json · aidc evolve suggest <应用> --file f --conversation f --json   # 自进化 · 证据与提案
aidc evolve accept <id> && aidc evolve apply <id>                       # 提案：语义类 → 自动发新语义版本
aidc evolve list <应用> --status proposed --json · aidc evolve adopt <应用> <id>   # 自进化 · 应用里的改进：用户提的，采纳后对所有人生效
aidc evolve bake <应用> --dir <目录> && aidc app deploy <目录>                    # 全员改进固化进代码（evolve.css + 文字 + 清单 evolve.baked）
aidc app registry --json               # 每个应用用了哪些 SDK / 语义类型 / Action
aidc app card <应用> --json             # 应用卡片：负责部门、版本、SDK、连了哪些数据、对外能力与依赖
```

## 5b. 自动化（Automate，原工作流）：把各部门已发布的应用串起来

```bash
aidc semantic automate capabilities --json       # 能力目录：清单 exports 显式导出 + 从登记的类型 / Action 自动提取（ref = <应用>/<能力>）
aidc app init my-flow --template workflow
aidc app deploy <目录> --dry-run         # 对照能力目录校验：提供方已发布、能力存在、参数名与必填
aidc semantic automate run <工作流> --param rfq_no=RFQ-1 --preview --json   # 预演：读、算、AI 分析照常，Action 只给计划
aidc semantic automate runs <工作流> --json · aidc semantic automate status <工作流> <运行 id> --json
```

- 清单 `sdk` 登记 `semantic`（旧名 `workflow` 照收）。清单 `workflow.steps`：`use`（`<应用>/<能力>` + `with` 参数）/ `compute`（`from` 逐行、`join`、`fields`、`summary`）/ `model`（`prompt` 里 `{{ steps.x }}`，`output` 声明字段）；表达式以 `=` 开头（`=steps.bom.rows`、`=round(sum(cost), 2)`）。
- `trigger.change: { type, when, input, cooldown }`：语义层数据一变（`when` 为真）自动跑，`cooldown`（如 `12h`）内同一对象只跑一次；能力以提供方应用 × 成员身份执行，不越权。
- `trigger.schedule: { every: "1d", at: "01:30" }`：时间本身是条件时才用（UTC；最密 `5m`，≤ `1h` 高频告警）。
- `notify` 步骤发邮件：`to`（本公司账号的邮箱，写死在清单里）、`subject` / `body`（可用 `{{ }}`）、`dedupe` + `cooldown` 去重；每天上限 `limits.notificationsPerDay`。`aidc notify test` 验证邮件通道。
- 提供方要先发布到正式通道；自己的应用想被组合，就把可以对外的查询 / Action 写进 `exports`，并写好 `owner`（应用卡片）。文档：https://www.ai-dc.ai/developer/docs/workflow.md 、…/app-card.md

## 5c. 建模：生成世界、下载、绑锚点

```bash
aidc modeling models --json                        # 模型、价目、当前策略、上游是否已配置
aidc modeling estimate -m marble-1.1 --input video --json
aidc modeling budget --json                        # 公司本月额度：上限 / 已结算 / 进行中预留 / 剩余
aidc modeling generate --text "…" --dry-run --json # 先看估价与额度（decision.ok）
aidc modeling generate --image a.jpg --image b.jpg --reconstruct --name "工位 A" --json   # 本地文件自动直传，等到完成
aidc modeling download <id> --out ./cell-a         # SPZ + 碰撞网格 + world.json（坐标系、锚点）
aidc modeling anchors <id> --file anchors.json --if-rev 0 --dry-run
```

## 5d. 用量与账单：花了多少、还能花多少

```bash
aidc semantic usage summary --json                       # 全公司当月：今日 / 本月 / 累计，按应用 / 开发者 Key / 模型 / 天，月底预测、未计价
aidc semantic usage summary --app <应用> --month 2026-09 --json
aidc semantic usage estimate -m deepseek-flash --calls 200 --input 1500 --cached 1000 --output 300 --budget 20 --json   # 上线前先算
aidc semantic usage check --json                         # 对账：对不上退出码 1
aidc semantic usage prices --json                        # 每个模型怎么计量、单价、来源
```

- 金额是**美元标价**（六位小数的字符串，不是发票）；给人看人民币加 `--fx <汇率>`，别自己换算后当成账单。
- `unpriced` 里的调用是**不知道多少钱**（实时转写按场次、价目里没有的模型），不是 0 元：汇报时单独说，并给出 `upperBoundUsd`。
- 给应用设上限：清单 `limits.monthlyBudgetUsd`（美元 / 月），到了模型调用返回 `quota_exhausted`，下月 1 日（UTC）恢复。
- 报数字之前先 `aidc semantic usage check`：`ok: true` 才说「对得上」。

## 6. 直接调模型（不用 SDK）

OpenAI 兼容：`base_url = https://www.ai-dc.ai/api/v1/models`，`api_key = $AIDC_API_KEY`。支持 `/chat/completions`（文本、`image_url`、`stream`、`response_format`）、`/audio/transcriptions`（≤ 4 MB）、`/models`。目录：`aidc models --json`。用量按调用方公司记账，花了多少看 `aidc semantic usage summary`。

## 7. 出错怎么办

| 退出码 / 错误码 | 处理 |
| --- | --- |
| 3 / `unauthorized` | 重新 `aidc login` 或检查 `AIDC_API_KEY` |
| 4 / `forbidden` | 清单没声明模型 / 数据集，或 Key 不能写这个命名空间 |
| 2 / `bundle_invalid` | 按 `details.issues` 逐条修 |
| 6 / `version_not_tested` | 先 `aidc app deploy`（进 test），再 publish |
| 7 / `rate_limited` · `quota_exhausted` | 等 `retryAfterSeconds`；每日额度按 UTC 自然日恢复，月预算（`limits.monthlyBudgetUsd`，`details.spentUsd`）与计算分钟（`limits.computeMinutesPerMonth`，`details.resetsAt`）下月 1 日恢复。`quota_exhausted` 不要循环重试：减少实时连接 / 定时，或调高清单 `limits` |
| 8 / `model_upstream_failed` | 上游故障，稍后重试 |
| 5 / `semantic_type_not_found` · `action_not_found` · `object_not_found` | 类型 / Action 没定义，或应用清单 `semantic` 没登记；对象主键写错 |
| 6 / `rev_mismatch` | 对象刚被别人改过：重新读取再改 |
| 2 / `invalid_schema` | 定义引用不闭合（Action 改了不存在的属性、外键目标不存在…），按 message 修 |
| 6 / `branch_required` | 你是智能体作者：本体改动走分支和提案（见「本体的铁律」） |
| 4 / `forbidden`（安全策略） | 改安全策略要满足改前改后涉及的全部 Marking（新加要 USE，去掉要 DECLASSIFY）；智能体只能开提案，由人批准 |
| 5 / `marking_not_found` | Marking id 写错，或它在你看不到的 Hidden 类别里 |
| 2 / `action_validation_failed` · `validation.result = INVALID` | 按 `details.validation` 里的参数与提交条件逐项改；不要换参数反复试 |
| 6 / `branch_conflict` · `proposal_not_mergeable` | 分支和 main 冲突：`aidc semantic branch conflicts` 看哪里，`branch rebase` 跟上 main；提案还有资源没批准就等人 |
| 2 / `invalid_bundle`（用了没登记的 SDK） | 把 SDK 名加进清单 `sdk` |
| 7 / `quota_exhausted`（建模，details.scope = request / company / platform / app） | 单次上限：换试稿模型或调低输入；月度额度：等下个月或请 AIDC 平台开通；不要换 Key 重试 |
| 8 / `modeling_unconfigured` | 平台还没配置世界模型上游，找 AIDC 平台 |
| 5 / `media_not_found` · `world_not_found` | 媒体要先 upload 到同一个命名空间；世界 id 写错或已删除 |
