Files
deta-agent-plugins/plugins/studio/skills/aml-design/SKILL.md
T
ringo 26e293f916
CI / contract (push) Has been cancelled
feat(skill): 插件 skill 补设计流程知识(决策闸门/阶段准入/四轨与 GSA 端口/知识索引),studio 0.3.9
用户反馈:用 deta 插件时感觉 skills 知识利用不足——插件 skill 原本只是一份工具手册(206 行),不含 DSL 领域知识、四轨关系、决策门禁、阶段准入门槛、GSA 端口,也没告诉模型 read_reference 这条路存在(而领域知识(workflow-stages 9.8K/D0-D8 全套闸门等)其实已在 MCP 里可达)。

新增四节:★领域知识必须先加载(read_reference 索引表 + 何时读哪份)· 设计流程与决策闸门(三阶段 + D0-D8 + ask_user 用法 + 渐进生成 + 禁止替用户决策)· 阶段准入门槛(每个阶段必须先有什么数据、判据是什么,含'未编译不得宣称完成')· 四轨关系与 GSA 端口速查 + 脚本参数自愈用法。
2026-09-20 15:15:38 +08:00

287 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: aml-design
description: 以 AML 为唯一事实源读写建筑模型并编译校验;含设计流程决策闸门、阶段准入门槛与 GSA 端口口径。当用户要求创建/修改建筑方案、房间布局、层高、开洞、围护结构或做建筑性能相关的模型准备时使用。
---
# DETA 建筑性能设计(AML)
## ★ 先读:工具怎么找、模型怎么改(任意工作目录都适用)
**工具发现规则(重要)**:宿主对插件类 MCP 工具做**懒加载检索**,一次检索只返回少量结果
(实测 `Only 10 shown of 23`)。**搜不到不等于不存在**——不确定有哪些工具时,先调
**`list_capabilities`**(能力目录)拿到当前形态的**完整工具名清单**,再按名字**直接调用**。
**改建筑模型只有一个标准动作**(能力目录里有 `build_model` 时):
`build_model({ aml, projectId })` —— 写服务端工作区 → 编译成建筑模型 → 规范校验 → 写进云项目,
一次调用完成;返回 `gate`(校验是否通过)、编译摘要、校验明细、云工作区 `headSha`。
- **不要**把 AML 拷进 Studio 的代码编辑器手工点编译(那是没有闭环工具时的兜底,不是正常路径);
- **不要**用脚本自绘模型图代替 Studio;
- 校验不通过(`gate: failed`)就按 `validation` 明细改 AML 后重跑,直到通过;
- 冲突(`version_conflict`)说明云工作区被其它会话改过:确认要覆盖才传 `force: true`。
**看模型 / 打开 Studio**:`open_studio` 拿一次性免密链接,再用宿主内置浏览器(`iab`)打开——
不要手工在面板登录,也不要用 playwright 逐步点击。
**执行器在线是模拟类工具的前置条件**:`simulate` / `studio_command` / `query_simulation_db` /
`view_canvas` 的算力在 ant-model 浏览器里的执行器,经网关 host-call 中继干活;项目标签页一关
就离线,工具会 fail fast 报「执行器离线」。`open_studio` 会回报 `executor_online`,遇到离线提示
就再调一次它,不要改用手工登录。
## 何时使用
用户提到建筑方案、房间/空间布局、层高、墙体开洞(门窗)、围护结构、体形系数、
建筑模型校验,或需要为后续能耗/日照/CFD 模拟准备模型时使用本技能。
## ★ 领域知识必须先加载(read_reference),不要凭记忆写设计
本技能只讲**工具怎么用、流程怎么走**;建筑设计本身的领域知识在其他文档里,**动手前按需读**:
| 文档 | 什么时候必读 |
|:-----|:-------------|
| `workflow-stages` | **任何设计任务开始**:决策闸门 D0–D8 全套定义、三阶段流水线、脚本依赖链、用户确认点 |
| `tracks-and-gsa` | 搞不清「哪份文件是真值 / 该调哪个端口」时:设计源码四轨关系 + GSA 端口清单 |
| `dote-and-space` | 写 dote-bounds、切分房间、非正交轴网、场地红线前 |
| `combination-forms` | 排平面(户型/办公组合形式)前 |
| `candidate-generation` | 走 `generate_candidates` 前(顶层 program 构造、四步比选) |
| `door-placement` | 门窗阶段写任何 `<aperture>` 前 |
| `editing-strategy` | 改已有 AML 时 |
| `unit-design` / `building-design` | 住宅单户 / 整栋(`skill_name: "residential-design"`) |
| `core-detail` / `dimensions` | 办公核心筒 / 尺寸(`skill_name: "office-design"`) |
调用方式:`read_reference({ name: "workflow-stages" })`;`skill_name` 缺省全局搜索(同名多命中会全部返回)。
**语法与属性拼写一律以 `get_aml_schema` 为准**(GSA 实时获取),领域规则读上面的文档——两者都不是"凭经验列举"。
## 设计流程:三阶段 + 决策闸门(谁决定什么)
```
SITE 约束确认(D0) → 形态/楼型(D1) → 场地轴网方案 → 落 AML
MASSING 面积分配(D2) → 核心筒(D3) → 结构/网格(D6) → 动线骨架(D4) → 交通骨架 → 分区块(D5) → 房间填充(D7) → 编译 massing
STRUCTURE 按动线落 flows → 核心筒细化 → 编译 structure
FULL 门窗(D8) → 品质优化 → 编译 full → 交付
```
**必须让用户决策的节点**(一律用 `ask_user`,每题给 2–5 个具体方案 + 推荐度,**带 `gate` 字段标注闸门号**):
```
D0 需求/约束 D1 形态/楼型 D2 面积分配 D3 核心筒策略 D4 动线骨架
D5 分区/房间优先级 D6 结构选型/网格 D7 房间填充方案 D8 门窗方案
```
- **决策前置**:改动线 = 重排全平面,所以 D1–D4 必须在排房间之前定下来。
- **禁止替用户做这些决策**;也禁止用「是否合理?」这类确认代替方案选择。
- D0 的结论用 `manage_design_brief`(get/set/update)落成**项目级设计任务书**:用户已明确给出的字段直接写,没给的才问;后续补充用 update 增量合并。
- **渐进生成**:每个阶段只生成下一层所需的最小信息(交通骨架 → 分区 → 房间填充 → 细部),每步之后停下来让用户确认;**禁止一次性生成全模型再让用户确认**。
- 阶段之间、以及阶段内每个小步之后,都要等用户确认再继续。
## 阶段准入门槛:什么数据齐了才能进下一阶段
| 进入 | 必须先有 | 判据 |
|:-----|:---------|:-----|
| 任何设计 | **设计任务书**(D0:建筑类型/定位/目标客群/场地/硬约束/偏好) | `manage_design_brief({ action: "get" })` 有内容 |
| 排房间前 | 形态(D1) + 面积方案(D2) + 核心筒(D3) + 动线(D4) 已由用户选定 | `ask_user` 答复已落闸(流程状态段可见) |
| **手写 AML 前** | **面积预算** + **楼层/轴网规划** + **布局建议** + **邻接规则** 四份脚本产出 | `generate_aml` 会拒绝对缺项的场景直接生成 |
| 编译 massing 前 | AML 含完整轴网与空间(走廊必须显式写出),**不得含门窗** | `apply_design(level=massing)` 的 `verification.verdict` |
| 进 structure 前 | massing 档 `verification.verdict=pass` | 同上(状态机自动推进缺省档,不要手动跳) |
| 进 full 前 | structure 档 `verification.verdict=pass` | 同上 |
| **声称"完成"前** | **本次会话成功编译过**(拿到 N 层 / N 房间摘要与 `verdict`) | 编译摘要;没编译过不得宣称完成、不得输出成果汇总、不得把空画布当成果 |
| 进入模拟/性能评估 | full 档编译通过 + 面板执行器在线(`open_studio` 回报 `executor_online`) | — |
## 四轨关系与 GSA 端口(速查)
四轨:`aml.xml`(**建筑语义唯一事实源**,必参与编译)· `bss.md`(样式)· `rules.yml`(校验规则)· `behaviors.yml`(声明式行为)——后三者可选,缺省按「工具参数 > 宿主当前源码 > skill 默认附属源码 > 兜底」回落;`design-brief.md` 是设计任务书,**不参与编译**;`<solid script="…">` 的几何脚本必须存在于工作区(内容随编译请求携带,取不到即**显式失败**)。
```
GSA 默认 http://localhost:8000
/health GET 存活探测(编译类异常第一步)
/api/v1/compile POST AML → building.json(compile_level 决定档位与门禁)
/api/v1/schema GET 语法指南(?full=1 全文)
/api/v1/schema.json GET 单标签/分组 schema
/api/v1/aml-guide GET 话题索引(阶段/模板/behaviors/轴网)
/api/v1/validate POST AuditEngine 深查(编译已带 issues,别重复调)
/api/v1/envelope-stats POST 围护结构统计
/api/v1/analyze-adjacency POST 空间邻接拓扑
/api/v1/generate(+ /schema) POST/GET 规则驱动候选平面生成
```
错误码**没有**独立目录端点(实测 404):按编译/校验响应里的 `code` 处理,不要凭记忆猜。细节读 `read_reference({ name: "tracks-and-gsa" })`。
## 脚本怎么用(run_script / run_scripts)
- 命名用 kebab-case(写成下划线会自动归一);**不确定归属就不传 `skill_name`**(全局搜索)。
- **参数不确定就直接调**:缺必填参数时回执带 `params_hint`(完整参数表:类型/必填/默认/说明),按它补齐重调即可;脚本名不存在时回执会列出可用脚本。不要猜参数,也不要写一份参数副本进 AML。
- 依赖链由 `depends_on` 声明(如 面积预算 → 楼层/轴网规划 → 布局建议),**先跑前置**;已算过的结果在会话语境里保留(`get_design_params` 可查),不要重复跑。
- 评估/校验统一走 `design-review`(缺省全跑、数据不足的项自动跳过并给 note)。
## 编辑与校验分工(先搞清"哪份文件是真值")
本插件挂的是**本机 MCP**:引擎工作区才是编译/校验/模拟读的真值(启动器 stderr 会回显路径)。
两种用法:
- **工作区 = 项目目录**(启动宿主前设 `DETA_WORKSPACE=<项目目录>`):宿主原生文件工具与 MCP
工作区工具看的是同一份文件,直接改完就能编译,不需要同步步骤。
- **工作区 ≠ 项目目录**(缺省 `~/.deta/workspace`):本地改动要先同步进引擎工作区,
引擎工具读到的才是最新版本。
编辑手段按场景选:纯文本改动优先用宿主原生文件工具(read / patch / grep);需要按元素定向
读写 AML(按空间 ID 改属性、只取某实体块原文)时用 MCP 的工作区工具。编译、规范校验、
规则检查、围护结构统计、空间邻接一律走引擎工具。
当前形态到底有哪些工具、叫什么名字,以运行时调 `list_capabilities` 的结果为准。
| 要做的事 | 用什么 |
|----------|--------|
| 读取 / 修改 / 搜索 AML 与其它设计源文件(`aml.xml`、`bss.md`、`rules.yml`、`behaviors.yml`、`design-brief.md`) | **宿主原生工具**:read / patch / grep / shell(直接改文件,不走 MCP 编辑工具) |
| 云端编译(AML → building.json) | MCP `apply_design` |
| **改模型并让它出现在云项目/Studio(闭环单入口)** | **MCP `build_model`**(写工作区 → 编译 → 校验 → 云同步,一次调用完成) |
| 语法与几何校验 / 规则检查 | MCP `validate_model`(`checks` 一次要齐几何 + issues + rules,三类共用同一次编译) |
| 围护结构统计 | MCP `envelope_stats` |
| 空间邻接、交通空间合并 | MCP `query_spatial_graph`、`apply_design(merge_traffic_spaces=…)` |
| 领域脚本(面积预算 / 轴网 / 布局建议 / 校核) | MCP `run_script`、`run_scripts` |
| 把本地改动送上云端、取回云端工作区 | MCP `push_project`、`pull_project` |
| 语法规则与生成上下文 | MCP `get_aml_schema`、`generate_aml` |
固定顺序(工具面里有 `build_model` 时):**本地写 AML → `build_model` → 看 gate →(Studio 里看效果)**。
`build_model` 一次完成「写服务端工作区 → 编译 → 校验 → 写进云项目工作区」,Studio 里立即可见。
工具面里没有 `build_model`(部分部署形态会裁掉它)时才退化为:本地编辑 → `push_project` → `apply_design` →
`validate_model` → Studio 查看。引擎工具读的是**服务端工作区**的文件,没推送过就读不到你的最新改动。
**工具检索结果条数有限**:一次搜索没看到某个工具,不代表它不存在——先调
`list_capabilities` 拿当前形态的完整工具名,再按名字直接调用。
### 闭环单入口 build_model
```
build_model({ aml?: "<AML 全文>", files?: { "aml.xml": "…" }, projectId?: "24", force?: false })
```
- `aml` 给出则先写入引擎工作区 `aml.xml`;`files` 可一并写其它工作区文件(路径规则同 `push_project`)。
- `projectId` 缺省取工作区 `deta.json` 绑定的云项目;没有绑定就先
`push_project({ files, projectId })` 绑一次。
- 返回:`gate`(`passed` / `failed`)、编译摘要、校验明细、`cloud.headSha`、`studioUrl`。
- `gate: failed` → 按 warning/error 改 AML,再调一次 `build_model`,直到 `passed`。
- `status: conflict`(`version_conflict`)→ 云项目工作区被其它会话改过(例如 Studio 面板里编辑过),
确认要覆盖再传 `force: true` 重跑一次。
- `status: unavailable` → 当前没有云同步通道(未注入云令牌,或该部署形态未接云),改用
`apply_design` + `validate_model`(编译校验不依赖云)。
- **禁止**把 AML 拷进 Studio 的代码编辑器手工点编译:那是没有闭环工具时的兜底,不是正常路径。
### push 与 Studio 深链
- 需要云端校验、或想在 Studio 里看效果时,先
`push_project({ files: { "aml.xml": "<全文>", "rules.yml": "…" }, projectId?: "…" })`。
`files` 至少含 `aml.xml`;路径必须是工作区相对路径(绝对路径、`..` 穿越会被拒绝);
单次载荷上限 1 MiB。传 `projectId` 会同时把本项目绑定到云项目
(写入服务端工作区 `deta.json`,之后 `generate_aml` / `pull_project` 也带同一深链)。
- 返回的 `studioUrl`(`https://deta.city/design/<projectId>`,例:云项目 11 → `https://deta.city/design/11`):
**在宿主右侧的内置浏览器面板打开**(做法见下一节);已有相同 URL 的标签优先复用,不要重复开新标签。
- 反向核对 / 拉回云端工作区用 `pull_project`(返回 `{ files, projectId?, studioUrl? }`,
工作区为空时 `files` 为 `{}`)。
## 在右侧面板打开 Studio,并在其中跑模拟
Studio 就是deta.city 上的建筑性能应用。在 Codex 右侧内置浏览器面板打开它之后,
看模型、跑模拟、看结果图层都在面板里完成;本插件的 MCP 只负责把本地改动推上去,不执行模拟。
打开步骤(用宿主内置浏览器 = browser 插件的 `iab`):
1. **先调 `open_studio` 拿链接并确认执行器上线**(免手工登录)。返回 `url`
(`https://deta.city/mcp-api/portal-session/landing?ticket=…&next=/design/<id>`)、
`studioUrl`、`executor_online`、`expiresInSeconds`(180)。该链接在面板内会自动完成
deta.city 登录并跳到 Studio。
- 典型节奏:`open_studio()` 拿 `url` → 面板打开 → `open_studio({ waitSeconds: 20 })`
确认 `executor_online: true` → 再调 `simulate` / `studio_command` 等执行器侧工具。
- 若返回 `auth_required` → 未登录:**直接调 `login` 工具**(建议 `waitSeconds: 90`),把返回的 `url`
交给用户在内置浏览器打开——首次输一次账号密码或邮箱验证码,之后只需点「登录并授权」按钮。
**不需要终端,也不要去找 `codex mcp login`**;用户点完后本工具会自动换取令牌并写入当前会话
(凭据过期时 `login` 会先用 refresh token 静默续期,用户完全无感)。
仅当当前形态没有 `login` 工具(CLI 等)时,才让用户在终端运行 `~/.deta/bin/deta login`;
排查用 `~/.deta/bin/deta doctor`(自检运行时 / 凭据 / GSA / MCP 握手)。
若 `url` 报「票据无效或已过期」→ 重新调一次,不要改成手工登录。
2. 按 browser 插件技能(`control-in-app-browser`)的 Bootstrap 初始化,再取内置浏览器句柄:
`const iab = await agent.browsers.get("iab");`,并先读一次 `await iab.documentation()`。
3. 先 `await iab.tabs.list()` 看是否已有该 URL 的标签:**有就复用,不要调 `goto` 重载**
(重载会丢面板里正在进行的操作);没有才 `const tab = await iab.tabs.new(); await tab.goto(url);`
4. 打开后告诉用户「Studio 已在右侧面板打开(项目名/ID)」,并说明模拟在面板里运行。
旧路径(工具面里没有 `open_studio` 时):自己拼 `studioUrl`
(本机项目目录 `deta.json` 的 `projectId`,或 `push_project(…, projectId)` 的返回值,
形如 `https://deta.city/design/<projectId>`),按上面第 2–4 步打开——但需面板已登录。
在面板里跑模拟:
- 模拟入口在 Studio 界面内(分析/模拟面板、GH 模板等)。**默认交给用户在面板里操作**——
模拟参数与结果解读属设计决策,不要代替用户点。
- 用户明确要你代跑时:先 `await tab.ax.write()` 取当前界面元素,再 `await tab.ax.click(<元素序号>)`
逐步操作;每一步后重新取一次状态确认,**不要凭记忆点坐标**。
- 结果出来后用 `await tab.ax.write("both")` 或 `await tab.screenshot()` 确认图层与数值,再向用户汇报。
前置与故障:
- 面板未登录 deta.city:用 `open_studio` 的一次性链接即可免手工登录(见上);只有拿不到
`open_studio` 时才退化为手工:在面板里打开 `https://deta.city/login` 完成一次登录
(登录态写入该浏览器的 `ant_token` cookie 与 `ant-model-auth` localStorage,之后长期有效),
登录完成后重新打开 `studioUrl` 即自动加载项目。
- **本机形态没有 MCP 授权**(进程在本机由宿主拉起,无 OAuth、无 401、无令牌续期),要分清的是两件事:
- **MCP 侧的云令牌**:只影响项目列表 / 项目同步 / `open_studio` 这类云工具,`auth_required` 的处置见上;
- **面板侧的 deta.city 登录**:靠 `open_studio` 的一次性链接自动完成,登录态写在该浏览器的
`ant_token` cookie 与 `ant-model-auth` localStorage,之后长期有效。
两者互不替代——拿到云令牌不等于面板已登录,反之亦然。
- 没有 `projectId`(用户要"新建项目"):**先调 `create_project({ name })`** ——这是云端建项目的唯一工具入口,
返回 `projectId` 与 Studio 深链(`studioUrl`);随后用 `build_model`(写 AML → 编译 → 写入云项目工作区)
或 `push_project(…, projectId)` 把模型放进去。**不要**拿 `push_project` 去绑定一个不存在的 ID,
也不要让用户先去门户手工建项目。
- 宿主没有内置浏览器(CLI 等形态):直接把 `studioUrl` 给用户,让他自己打开,不要假装已经打开。
## 铁律
1. **AML 是建筑语义的唯一事实源**。任何几何或属性变更都必须落到 AML 文本,
不得用中间 JSON 表达修改意图。
2. **禁止凭记忆编写 AML 结构**。动手前必须先取真实语法:
- 已有模型:读工作区里的 `aml.xml`(宿主原生 read 工具,或 MCP 的 `read_source`)
- 语法规则:`get_aml_schema`(从编译服务实时获取,唯一权威)
3. **属性知识不硬编码**:房间用途、构造材料、洞口参数等可选值从工具返回中获取,
不要凭经验列举。
4. **局部修改优于整体重写**:改单个空间属性时只改该空间,不重写整个模型。
5. **控制单会话工具调用量**。编码代理在会话累积较多本插件工具调用后,会在请求里重复
声明 `deta` 命名空间,上游模型服务(Responses 兼容层)直接拒绝:
`Duplicate namespace name 'deta'; Namespace names must be unique`。
实测触发点随会话长度前移(并发调用会显著提前触发)。规程:
- 同一轮只调用一个本插件工具,不要并发;
- 单会话保持轻量,完成任务后另起会话继续;
- 一旦出现该错误,**停止重试并告知用户重开会话**(工作区文件不会丢失)。
6. **复杂形体(`<solid script="geometry/xxx.py">`)的脚本属于工作区文件,不是宿主本地文件**。
编译服务没有工作区访问权:编译前引擎会按 AML 声明的相对路径把脚本内容**随请求携带**
(键名必须与 AML 一字不差,含 `geometry/` 前缀)。因此:
- 脚本必须真实存在于**工作区**(用工作区文件工具读写,如 `geometry/shapes.py`);
- 脚本取不到时编译会**显式失败并列出原因**(而不是"编译通过但形体丢失");
- 改动脚本内容后无需重命名或改 AML;若 AML 里写了 `version="sha256:…"`,脚本内容变了
必须同步更新该版本号,否则编译报「几何脚本版本不匹配」。
## 标准工作流
1. **读**:用宿主原生工具读本地项目里的设计源码(`aml.xml` 等)。模型为空时先用
`generate_aml` 取生成上下文,再用 `get_aml_schema` 核对语法,然后在本地写出 AML。
2. **改**:在本地用 read / patch / grep 直接改 AML 文本(局部修改优于整体重写)。
3. **推**:`push_project({ files: { "aml.xml": … } })` 把改好的源码送到服务端工作区
(要绑云项目就带上 `projectId`)。
4. **编**:`apply_design` 提交编译 → 编译为建筑模型,产物落盘 `building.json`。
5. **校**:`validate_model` 做语法与规则校验,逐条读取错误码并修复,不得跳过;
规则类问题用 `validate_model({ checks: ['issues','rules'] })` 一次查齐(info 级提示只在 issues 视图可见)。
6. **看**:需要几何指标用 `envelope_stats`(围护结构/外窗面积)或 `query_spatial_graph`
(空间邻接与查询);要看模型、**跑模拟**、看结果图层,就在右侧面板打开 `studioUrl`
(见「在右侧面板打开 Studio,并在其中跑模拟」一节),模拟在 Studio 界面里运行。
## 错误处理
- 编译服务未在线时,编译/校验类工具会返回明确错误文本。此时**不要伪造结果**,
直接报告「编译服务未接入」,改用宿主原生文件工具(read / patch)核对与编辑本地 AML。
- 编译报错必须逐条修复后重新 `apply_design`,禁止在报错状态下声称完成。
## 工具名从哪来
本技能**不列工具清单**:工具面随部署形态(引擎形态 / 全量形态)裁剪,任何手写清单都会过期。
不确定有哪些工具时,调 `list_capabilities` 拿当前形态的**完整工具名**,再按名字直接调用;
每个工具能做什么、参数怎么给,以它自身的 description 与返回为准。