# 自进化 SDK

应用的用户**直接在应用里改进它**：点右下角「// 改进」，说一句「对话框变大」「隐藏侧边栏」「标题改成客服工作台」，页面马上变。不用改代码、不用发版、不用再去钉钉 / 企业微信 / WorkBuddy 的群里提需求、等人排期。

```js
import { evolve } from "/developer/sdk/v1/aidc.js";
evolve.mount();
```

试一试：[智能问答台 · 自进化演示](samples.md#自进化演示)（`/nexus/cell-aidc/apps/evolve-demo`，AIDC 成员登录后打开）。

## 改进工程

用户在应用里提的每一次改进，是一个**改进工程**：一段对话（「对话框变大」→「再大一点」）、编译出的一组**改进指令**、作用范围与状态。

```
说一句 ──▶ 预览（只有自己看得到）──┬─▶ 只给我保留（个人改进，立即生效）
                                   ├─▶ 提交给所有人 ──▶ 开发者采纳 ──▶ 对所有人生效
                                   │   （开发者提交：直接对所有人生效）
                                   └─▶ 界面改不了的（加功能、改逻辑）──▶ 交给开发者（自提升提案）
对所有人生效的改进 ──aidc evolve bake──▶ 固化进代码，发新版本 ──▶ 覆盖层清空
```

| 状态 | 个人改进 | 全员改进 | 交给开发者的改动 |
| --- | --- | --- | --- |
| 生效中 | 只对提出的人 | 对所有访客 | 已采纳，待开发 |
| 待采纳 | —— | 对提出的人已生效，等开发者 | 等开发者处理 |
| 未采纳 | —— | 退回成提出人的个人改进（他的页面不会突然变回去） | 不做 |
| 已撤销 | 提出人撤销 | 开发者撤销 | 提出人撤回 |

谁能做什么：有 AIDC 账号的访客都能给**自己**改；本公司成员（member / editor）可以提交给所有人；采纳、不采纳、撤销全员改进只给本公司开发者。没登录的访客（公开链接）只能预览。权限只在服务端裁决，面板按返回的 `can` 显示按钮。

## 接入：三步

**1. 在页面上标出能改的区域（槽位）**

```html
<section class="chat" data-evolve="chat">
  <div class="messages" data-evolve="messages">…</div>
  <textarea data-evolve="composer" placeholder="输入问题"></textarea>
  <button data-evolve="send">发送</button>
</section>
```

部署时平台从包里扫出所有 `data-evolve="…"`（HTML 属性、脚本里的 `el.dataset.evolve = "…"`），它们就是这个版本的**改进面**；改进只能落在改进面上。另有内置槽位 `page`（整个页面）。

**2. 在清单里给槽位起名字、声明可调参数**

```json
{
  "sdk": ["evolve", "ui"],
  "evolve": {
    "slots": {
      "chat": { "title": "对话框", "aliases": ["聊天框", "对话窗口"] },
      "send": { "title": "发送按钮" }
    },
    "tokens": {
      "--chat-width": { "title": "对话框宽度", "type": "length", "min": "360px", "max": "1100px", "slot": "chat" },
      "--accent": { "title": "强调色", "type": "color" }
    }
  }
}
```

- `slots.<名>.title / aliases`：用户说「对话框变大」就是按它认出来的。没起名字的槽位只能在页面上点选。
- `tokens`：带范围的**可调参数**（CSS 变量，样式里写 `width: var(--chat-width)`）。「对话框变大」优先调挂在对话框上的参数，而且永远落在 `min`–`max` 里——布局不会被改坏。能预见到的调整（尺寸、字号、主色、圆角）都建议做成参数。
- `model`：编译用的模型，缺省 `deepseek-flash`（可选 `gpt-5.4-mini`）。不用写进清单 `models`。

**3. 挂上面板**

```js
const panel = evolve.mount();             // 右下角「// 改进」
panel.open(); await panel.send("对话框变大");   // 也可以从你自己的按钮触发
```

宽屏时面板停靠在右侧（页面让出位置，改动不会被面板挡住）；手机上是底部抽屉，预览生效后收成一条。面板在 Shadow DOM 里，应用的样式影响不到它，改进也改不到它。`aidc evolve slots` 在本机列出页面上的槽位与清单声明，谁有谁没有。

## 改进指令

一句话编译成的不是代码，是一组白名单里的指令：

| 指令 | 做什么 | 例子 |
| --- | --- | --- |
| `token` | 改应用声明的可调参数（按范围夹紧） | `{"op":"token","name":"--chat-width","value":"768px"}` |
| `style` | 改一个槽位的样式（宽高、间距、字号字重、颜色背景、边框圆角阴影、透明度、显示方式、排列、顺序、缩放） | `{"op":"style","slot":"send","set":{"background-color":"#1e3a8a"}}` |
| `text` | 改只出现一次的槽位的文字 | `{"op":"text","slot":"title","text":"客服工作台"}` |
| `attr` | 改提示文字：`placeholder` / `title` / `aria-label` | `{"op":"attr","slot":"composer","name":"placeholder","value":"问点什么…"}` |
| `reset` | 恢复原样（可只恢复几个属性；个人的恢复也能盖住全员改进） | `{"op":"reset","slot":"sidebar","props":["display"]}` |

- **安全**：值走文法白名单（数字、单位、颜色、关键字、`calc` / `rgb` / `var` 等函数），拼不出 `url(`、`@import`、`;` `{}`、引号、`!important`，也就越不出它改的那条声明；没有定位类属性（`position` / `z-index`），改进只调整应用自己的元素，不能往页面上叠东西；文字一律按纯文本写入。模型编出来的指令逐条校验，不合规的丢掉并告诉用户。
- **快速意图**：常见说法不调模型，在浏览器里 0 毫秒算完——变大 / 变小 / 宽一点 / 高一点 / 字大一点 / 「宽度改成 800」/ 隐藏 / 显示 / 恢复，「稍微」≈ ×1.1、「很多」≈ ×1.5、「两倍」= ×2。话里要提到槽位名字（或先选中一块）；复合要求（「变大并改成橙色」）交给模型。
- **预览 = 保存后**：预览、保存、入口页内联用的是同一个折叠函数（服务端与浏览器共用一份代码），预览看到什么，保存后所有人看到的就是什么。

## 为什么快、为什么便宜

| | 实测（本机 → DeepSeek，2026-09-27） |
| --- | --- |
| 快速意图（变大 / 隐藏 / 恢复…） | 浏览器里 **2 ms**，不联网、不花钱 |
| 模型编译（「发送按钮改成深蓝、气泡圆一点、标题改成客服工作台」） | **1.6–2.0 s**，约 1.2k tokens ≈ **$0.0002–0.0005 / 次**（按应用计费，计入计算分钟） |
| 打开页面 | 覆盖层由服务端**内联进入口页**（CSS 排在应用样式表之后，唯一槽位的文字直接写进 HTML）：首屏就是改进后的样子，不闪、**不多一次请求**；只多一次走索引的查询，只对登记了 `evolve` 的应用 |
| 预览 / 保存后重画 | 只替换一段 `<style>` 的文本 + 少量文字，不重新渲染页面 |

不常驻：没有轮询、没有长连接。别人刚采纳的全员改进，在你下次打开页面、或切回这个页面（离上次核对超过 1 分钟）时带着指纹核一次，没变只回 `changed: false`。

## 长期维护：覆盖层是暂存区，代码才是家

改进叠在版本之上，但不会无限叠下去：

1. **固化**：`aidc evolve bake <slug> --dir <应用目录>` 把对所有人生效的改进写进源码——样式与参数进 `evolve.css`（与覆盖层同一段 CSS，页面渲染逐字节一样，入口页自动链上），文字直接写进静态 HTML；清单 `evolve.baked` 记下固化了哪些，版本号 patch +1。然后照常 `aidc app deploy` → 在 Developer 里看一眼 → `aidc app publish`。新版本上线后这些改进不再叠加，改进工程里显示「已固化进 1.0.1」。文字改在脚本画出来的元素上的改进不固化，继续由覆盖层生效。
2. **改版不怕**：改进指向的是槽位与参数的名字，不是页面结构。新版本去掉了某个槽位，指向它的改进自动跳过（改进工程里标「当前版本已失效」），不报错；回滚到旧版本，它们又回来。
3. **有上限**：每个应用同时叠加的全员改进最多 40 条，到了就先固化；每人的个人改进最多 20 条。
4. **是证据**：用户改了什么、改了几次，是下一个版本最直接的需求。交给开发者的改动就是[自提升](improve.md)的应用类提案（原话作证据），开发者 / 智能体改代码发版后 `aidc improve apply <id> --version …` 闭环。

## 让智能体参与

开发者 Key（`aidc login`）可以管本公司任何登记了 `evolve` 的应用：

```bash
aidc evolve list tj8100-live --status proposed          # 待采纳的改进
aidc evolve adopt tj8100-live <id>                      # 采纳（--dry-run 预演）
aidc evolve compile tj8100-live "合格率那一列加粗，标红低于 95% 的"   # 看一句话会变成什么指令
aidc evolve save tj8100-live --ops 指令.json --title "合格率加粗" --scope app   # 智能体直接提交
aidc evolve bake tj8100-live --dir ./tj8100-live && aidc app deploy ./tj8100-live
```

## API

| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | `/api/v1/developer/evolve/{命名空间}/{slug}/overlay` | 调用方看到的覆盖层（`?since=<指纹>` 没变只回 `changed:false`；`?scope=app` 只要全员的） |
| POST | `/api/v1/developer/evolve/{命名空间}/{slug}/compile` | 一句话 → 改进指令（不落库） |
| GET / POST | `/api/v1/developer/evolve/{命名空间}/{slug}/improvements` | 改进工程列表 / 保存（`clientKey` 幂等，`x-aidc-dry-run` 预演） |
| PATCH | `/api/v1/developer/evolve/{命名空间}/{slug}/improvements/{id}` | `propose` / `adopt` / `reject` / `revert` |

凭证：应用里是页面注入的应用票据（只能改它自己那个应用），CLI / 智能体是开发者 Key（`?channel=test|production`，缺省正式版）。只开给公司命名空间的应用；官方公开应用没有访客身份，只能在页面上预览。

## 浏览器 SDK

| 函数 | 做什么 |
| --- | --- |
| `mount(options?)` | 挂上改进面板，返回 `{ open, close, toggle, send, destroy }`；`label` / `position` / `placeholder` / `open` |
| `compile(text, { slot, thread, draft })` | 一句话 → `{ via: "quick" \| "model", ops, delta, reply, summary, needsCode }`（`ops` 是这一轮之后的完整草稿） |
| `preview(ops)` / `clearPreview()` | 预览一组指令 / 丢掉草稿 |
| `save({ title, thread, ops, scope, kind })` | 保存改进工程（`scope: "personal" \| "app"`，`kind: "request"` = 交给开发者） |
| `list(filters)` / `decide(id, action)` | 改进工程列表 / 提交、采纳、不采纳、撤销 |
| `pick()` / `flash(slot)` | 在页面上点选一块 / 闪一下某块 |
| `overlay()` / `surface()` / `snapshot()` / `refresh()` / `onChange(fn)` | 当前覆盖层、改进面、页面现状、和服务端核一次、变化回调 |

## 和自提升 SDK 的分工

| | 自进化（evolve） | [自提升](improve.md)（improve） |
| --- | --- | --- |
| 谁发起 | 应用的**用户**，在应用里 | 开发者 / 智能体，在 CLI 里 |
| 改什么 | 这个页面的样子：尺寸、颜色、文字、显示隐藏 | 语义层定义、应用代码 |
| 多快生效 | 立即（预览 0–2 秒，保存即生效） | 发新语义版本 / 新应用版本 |
| 怎么连起来 | 界面改不了的 → 交给开发者 = 一条自提升提案；固化 = 把改进写进代码发新版本 | 证据里带着用户在应用里说过的话 |
