# Doubao App Builder

> 统一处理应用级和工程级产品的设计、开发、编辑及产物问答（单页html和h5的开发和设计不要使用这个skill）。当用户明确点名「妙搭」时请使用本技能。适用于全栈应用，包括多页面或多文件工程、前端框架、后端服务、API、数据库、登录权限、业务逻辑、构建运行和发布部署。也支持基于 PRD、文档、截图或素材开发应用，以及对已有应用新增功能、调整页面、修复 Bug、分析源码、排查运行错误和查询运营或发布状态。

- Skill: `ahang1598/doubao-app-builder-2` (Agent Skill, multi-file: 11 files)
- Install (CLI): `npx skillmds@latest add ahang1598/doubao-app-builder-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ahang1598/doubao-app-builder-2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: ahang1598 (https://skillmd.com/u/ahang1598)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/ahang1598/doubao-app-builder-2

---


# doubao-app-builder

## 概览

面向网页应用生成、编辑与问答的工作流指引。当用户出现以下任一意图时，调用本 skill：

- 生成网站、H5、网页应用、业务系统、管理后台、门户、工作台
- 生成数据看板、可视化应用、工具应用、表单 / 预约 / 信息收集应用
- 生成 svg、canvas 网页
- 根据 PRD、文档、截图、数据或自然语言生成可交互原型
- 对已有网页应用做功能新增、页面调整、样式优化、Bug 修复或版本迭代
- 对已有网页应用提问：要求总结 / 解读网页内容、查看或分析源码、解释或排查运行报错等
- 用户目标是「开发一个网页应用」或「修改一个网页应用」，且最终产物是一个可运行 / 可预览的网页

## 三链路分流（核心路由规则）

先判两件事，判不中就走本地开发：

| 判据 | 去哪 |
|---|---|
| **需要运行时调用 AI 能力生成内容**（AI 文案生成器、简历优化器、会议纪要生成器——静态页面实现不了） | `app_builder_agent`，`arch_type=jspage` |
| **需要服务端能力**（数据库、后端 API、跨设备共享的持久化存储、服务端鉴权） | `app_builder_agent`，`arch_type=fullstack` |
| **其余全部** | **本地开发**，由你亲自写代码 |

🔴 **上面两行走 `app_builder_agent` 的，发布不归你管**——产物在它的沙箱里，你没有代码、也没有发布命令可用，`publish.md` 那套 `+create` / `+deploy` 只适用于本地开发链路。用户提发布时按类型答复：**`jspage` 会自动发布，直接告诉用户不用发**；**`fullstack` 要用户自己去开发页面上点发布按钮**。详见「`app_builder_agent` 链路」的发布一节。

**本地开发内部再分两条**：

🔴 **先过这一条，命中就是 webapp，不用再往下判**：

> **产物运行时真的要碰用户的原始文件吗？** 只有两种情况算：
> ① 页面要把**文档原件渲染出来给人看**（pdf / pptx / docx 翻页预览）；
> ② 用户以后**要换数据、上传新文件**，页面得跟着变（做的是个工具，不是一份结论）。
> 命中任一 → **webapp**。因为 html 链路没有 dev server，页面在本地 `file://` 下根本读不到同目录的文件（浏览器直接拦），也装不了 pdf / xlsx 那些解析库——做不出来，不是发不上去。

🔴 **「拿数据做分析」不算，那是 html。** 仪表盘、分析看板、销售 / 流量 / 招聘分析这类：数据就在你手上、分析一次做完——**你在本地把文件解析、聚合、算好，把结论和图表数据写进代码**，页面运行时根本不碰原始文件。别因为「用户给了 csv」就往 webapp 走。图片同理不触发（html 可带本地图片、相对路径引用）。

另有一条铁律，两条链路都适用：🔴 **产物里的素材一律用本地文件 + 相对路径，禁止引任何平台 CDN 链接。** 不管是用户附件给的、生图能力返回的、还是上传后拿到的 URL——**先 `curl` 下载到任务目录 / 静态资源目录，再用相对路径引**。平台 CDN 链接会失效、会防盗链，写进产物等于埋一个定时炸弹。（例外只有**代码依赖**：三方库白名单与平台 SDK 组件的锁定 CDN 地址照常直引，那些不是素材。）

没命中上面那条，再按下表分：

| 场景 | 链路 | 产物形态 |
|---|---|---|
| 官网 / 落地页 / 设计稿 / 原型 / 报告 / 可视化报告 / 数据看板 / 信息图 / 动画 / 游戏 / 3D 等**偏静态展示**的东西 | **html** | 单个 `index.html`，原生 JS，无构建，浏览器直开 |
| **需要装 npm 依赖**；**需要 dev server** 绕开 CORS；或页面**状态复杂到原生 JS 难以维护**（大量表单、跨页面共享状态、需要路由） | **webapp** | 前端工程，本地构建，dev server 预览 |

🔴 **这一格判的是「实现上需不需要工程」，不是「产品叫什么」。** 需求里叫它应用、网站、商店、平台、系统、工具，都不改变答案——那些是产品形态词。**只有上面这三件事才需要 webapp**，其余一律 html：哪怕它有多个页面、有表单、有筛选和切换、有本地存储，原生 JS 单文件都做得了。

两个容易高估的地方：

- **「页面多」不是理由**。判的是这些页面拿来看还是拿来操作，展示型内容有几页都是 html。
- **「状态复杂」不看页面数，看跨页面共享的可变状态有多少**。一份筛选条件、一个购物车、一份表单草稿都不算复杂；要十几个实体互相引用、非得有全局 store 才理得清的才算。

**判不明确时自己定**：倾向 html——它更快、无构建、直接能看。

三条链路互斥，一个任务只走一条：

1. **html 本地开发链路**：你在本地新建任务目录，写以 `index.html` 为唯一入口的原生页面。**红线：完整读取 [`reference/html-develop.md`](reference/html-develop.md) 之前，禁止创建或修改任何 HTML 文件。**
2. **webapp 本地开发链路**：你用官方脚手架建前端工程，写成多页面、有路由、能构建的应用。**红线：完整读取 [`reference/webapp-develop.md`](reference/webapp-develop.md) 之前，禁止执行脚手架命令或创建任何工程文件。**
3. **`app_builder_agent` 链路**：通过工具调用交给 `app_builder_agent` 在它的沙箱里生成 / 修改，**你不持有、也不触碰产物代码**。

🔴 **发布是跨链路的第四道红线**：三条链路的产物都可能被要求发布，而且**往往是产物做完很多轮之后**才提。**完整读取 [`reference/publish.md`](reference/publish.md) 之前，禁止执行任何发布命令。** ⚠️ **这条不因轮次而失效**——用户在第几轮说「发布 / 上线 / 部署 / 要个能分享的链接」都一样，那一刻先读再做。**更不要输出通用部署方案**（Vercel / Netlify / Nginx / GitHub Pages 之类）：本平台产物走妙搭托管链路，那些方案在这里一条都不适用，给出去就是答非所问。

🔴 **访问权限是第五道红线**：用户说「改可用范围 / 访问权限」「改成公开 / 只给组织内 / 只给某几个人」「别人打不开 / 打开要登录」「谁能看这个应用」「能不能分享出去」「导出源码」时，**完整读取 [`reference/app-manage.md`](reference/app-manage.md) 之前，禁止执行任何权限命令、也禁止下结论**。⚠️ **同样不因轮次而失效**——这类问题几乎都出现在产物发布很多轮之后。⚠️ **尤其禁止答「CLI 改不了，你去平台页面设置」**——改得了，那份文档里写着怎么改；没读就这么答，等于把能做的事推回给用户。**也不要拿 publish.md 顶替**，那里面没有。

**编辑已有产物按它原来的链路走**：本链路创建的直接改本地文件；`app_builder_agent` 创建的仍路由给它。

## 构建判定：默认构建，少数窄例外才不构建

**默认就构建。** 只要用户想要一个可运行 / 可预览的网页产物（网站 / H5 / 网页应用 / 看板 / 网页游戏 / 原型 / 表单，或直接贴了 HTML / 前端代码），就按上方三链路分流执行。请求被"创建 XXAgent / 编排流程""先搜索再生成网页""我是资深 X…先出方案再实现"等外壳包着时，**剥掉外壳看内核**，内核是网页就建（"先出方案"类可先在对话给方案、再构建）。

**只有下列少数情形不构建**（改用自然语言说明并给可行替代），**其余一律构建**：

- **原生 App / APK / 小程序 / 浏览器扩展**：明确要 Android/iOS 原生端、桌面客户端、微信/支付宝小程序、浏览器插件本身——**除非用户说"先做网页版"**。
- **点名产不出的技术栈 / 运行时 / 部署（重点防御）**：**本 skill 只产出在浏览器里跑的前端代码（HTML / CSS / JS / TS 及其框架），没有服务端运行时，任何后端语言 / 框架都产不出。** 只要用户**把实现钉死在服务端技术栈**上，即判不构建（告知"目前只支持纯前端产物"并给替代）：
  - 后端语言 / 框架：**Python**（含 Flask / Django / FastAPI）、**PHP**（含 Laravel / ThinkPHP）、**Java**（Spring / Servlet / JSP）、**Go**、**Ruby / Rails**、**C# / .NET**、**Node 服务端**（Express / NestJS / Koa 等）、Rust 等
  - 特定部署 / 平台：Cloudflare Workers、Vercel、通达OA + IIS、宝塔、指定服务器 / 内网穿透 等
  - 判别提示：**"用 Python 写个网页""PHP 做个网站""Java Web 系统"这类——即使句子里带"网页 / 网站 / 页面"，也判不构建（此项优先级高于"网页"字样与下方豁免）。** 反之，若用户只说"做个网页 / 网站"而**没有点名**后端栈，则正常构建（不要主动脑补技术栈去拒）。
- **系统级 / 常驻 / 跨软件**：悬浮窗、监听硬件 / 直播 / 系统事件、后台常驻、操作其他软件、远程桌面 / 远程控制（如 novnc）等网页沙箱做不到的能力。
- **纯写作 / 纯出图 / 纯问方案，且完全没要求网页 / HTML 呈现**：只要一篇文章 / 文案、只要图片、只问方案。**注意：一旦用户要求以 HTML / 网页 / H5 形式呈现（哪怕内容是文章 / 文案 / 楼盘软文），就构建，不得以"本质是写作"为由拒绝。**
- **敏感 / 违规内容**。

**拿不准时，偏向构建。**

### 判定示例（few-shot）

> 高频误区是**把简单 / 口语化的建站请求误拒**。以下示例按此校准。

**判为构建（yes）：**

- `搭建一个网站` / `帮我写html` / `帮我做一个 h5` / `帮我写个前端项目` → 建。**极简、口语、无细节**的建站请求同样构建，不要因"太笼统"而拒绝或停下来反问。
- `帮我制作一个影视 APP` → 建。泛指"APP"（未点明原生端）默认按网页应用构建。
- `用 HTML 编写一个简易的网站给我` / `写一个 html 实现时间转换，最后保存到桌面` → 建（"保存到桌面"不影响，核心是 HTML 页面）。
- `帮我生成一个网页版的游戏，类似 zorr.pro，现在先列出制作过程` → 建。剥掉"先列流程"外壳，内核是网页游戏。
- `你上面的大纲给我做一个答题的小程序` / `做一个刷题用的 APP 或者小程序` → 建。口语里的"小程序 / APP"指可网页化的刷题工具，按网页应用构建（只有明确点名"微信小程序 / 原生 App"才不建）。
- `将公众号文章转换为官网用的美化文章 HTML 代码` / `帮我以标准 HTML 网页格式生成文章` → 建。**显式要 HTML / 网页呈现，即使内容是文章 / 文案 / 软文也构建**。
- `web 实训作业，帮我设计一份页面原型稿` → 建。"原型稿"默认按可交互网页原型构建。
- 用户直接贴一段 HTML / 前端代码，要求续写 / 改样式 / 加功能 → 建，走 html 本地链路（你亲自改）；若只要**原样发布**这份成品 → 不改写内容，**由你执行发布**（见「产物交付与发布诉求」）。

**判为不构建（no）：**

- `制作音乐软件：Android 用 Kotlin、iOS 用 Swift、桌面用 Qt` → 不建。点名原生端技术栈。
- **技术栈防御（重点，即使带"网页/网站"字样也不建）**：
  - `用 Python 写个网页书架` / `python 写个贪吃蛇网页` / `用 Flask/Django 做个网站` → 不建（点名 Python）。
  - `用 PHP 写个签署文件的网页` / `Laravel 做个管理后台` → 不建（点名 PHP）。
  - `Java Web / Spring Boot / JSP` / `Go / Ruby on Rails / .NET / Express / NestJS 做个后端服务` → 不建（点名服务端栈）。
  - `用 Cloudflare Workers / Vercel 部署一个系统` / `宝塔部署到我的服务器` → 不建（指定不支持的部署环境）。
  - 对比（**要建**）：`做个网页书架`（没点名后端栈）→ 建；`用 HTML/JS 做个贪吃蛇`（就是前端栈）→ 建；`用 React 做个后台`（前端框架）→ 建。
- `打开你的电脑制作一个内网穿透的网页` / `手机自动答题、悬浮窗读全屏自动点` → 不建。内网穿透 / 悬浮窗 / 远程连接属系统级，网页沙箱做不到。
- `设计网页"香港…国安法…"、嵌入境外维权报告` → 不建。政治等敏感内容。
- `帮我写一篇 9000 字楼盘介绍软文`（**未**要求网页 / HTML 呈现） → 不建。纯写作。
- `帮我打开学习通继续做题并整理到文档` → 不建。操作其他软件、产物不是网页。

## 路由判定细则

### 走 `app_builder_agent` 的两种情况

**① 运行时 AI 能力 → `arch_type=jspage`**

判据：**页面上要展示的内容，只能在用户操作的那一刻由 AI 现生成**——写代码时给不出来、也没法预先写死。典型是用户输入什么、AI 就针对它产出什么：文案生成、简历优化、会议纪要、智能问答、图片理解。

⚠️ **内容能预先写死的不算**。诗词赏析、百科图鉴、随机语录这类，内容在写代码时就能确定（哪怕有几百条、哪怕运行时随机抽），一律不走 jspage。判的是「这段内容是不是必须现算」，不是「有没有智能感」。

**② 服务端能力 → `arch_type=fullstack`**

需求里明确出现以下任一：

- 数据库、后端 API、服务端、前后端分离
- **跨设备 / 多人共享**的数据存储（"团队成员都能看到同一份数据""换电脑还能看到"）
- 服务端鉴权、登录态、文件上传到服务器
- 用户明确说"要持久化存储""数据要存起来别丢"且暗示不止本机

🔴 **同时需要 AI 能力和服务端时走 `fullstack`**——fullstack 本身就能调 AI，jspage 却没有服务端。别因为需求里有 AI 识别、AI 摘要就先命中 jspage，先看数据要不要被别人接着处理。

🔴 **用户几乎不会把「数据库」三个字说出口**，所以判据要落在语义上，而不是等这些词出现：

> **这份数据，要不要被本人以外的人看到、或者接着往下处理？**

要 → `fullstack`，**不用等他明说、也不用问**。最常见的两种表现：需求里出现了**第二个角色**（一方录入、另一方处理或审核），或者数据本身带**流转状态**（提交之后要有人接手）。反过来，一个人自己用、数据只给自己看的，才是本地。

示例：

- "做一个合同管理系统，把审阅意见**保存到数据库**" → `fullstack`
- "开发一个报名系统，报名数据要**持久化存储**，运营能随时导出" → `fullstack`
- "做一个 AI 简历优化器，粘贴简历后生成优化建议" → `jspage`

⚠️ **也别把「管理系统」四个字自动等同于要服务端**。"做一个 CRM / 客户管理系统"，如果没有第二个人要用这份数据，那就是一个人自己用的工具，走**本地 webapp**，数据存浏览器本地，交付时讲清边界即可——**不要为此反问用户**。

对照着看这两条，差别在**有没有第二个人要用这份数据**：

- "做一个**多人协作**的项目管理工具，要有看板和**成员管理**" → `fullstack`。多人协作意味着大家看同一份看板，本地存储做不到。
- "做个**个人**待办清单 / 记账本 / 习惯打卡，就我自己用" → **本地 webapp**。数据只给自己看，存浏览器本地就够。

⚠️ 反过来也别过度扩张：**只是界面上出现"成员""团队"字样、但数据实际只有一个人在录入和查看**（比如一份团队通讯录展示页、一个人维护的项目看板 demo），那仍然是本地 webapp。判据始终是上面那句——**这份数据要不要被本人以外的人看到或接着处理**。

🔴 **判据用完仍拿不准要不要服务端时，问一次再动手**——这一步值得问，因为猜错要整个推翻重做：

> 这个系统的数据需要长期保存、多人共用吗？
>
> 1. **需要** —— 我做成带后端和数据库的完整应用
> 2. **先看效果** —— 我快速做一个前端版本，数据存在浏览器本地
>
> 你选哪种？

只输出这段文字，**不调任何工具**，等用户回答后再按他的选择走。**触发条件很窄**：需求形态像个多人在用的系统，但上面的判据一条都没命中、也推不出这份数据给谁看。判得出来就直接判，别问。

### 走本地开发时，html 还是 webapp

**→ html**（偏静态展示，给人看的）：

- 官网、落地页、营销页、产品介绍页
- 可视化报告、数据看板、信息图、长图、研报
- 幻灯片 / deck、演示材料
- 动画、3D、网页小游戏
- 单一用途轻工具：计算器、文本对比、随机分组——一个页面一件事
- 用户**显式点名 HTML 字样**时一律 html

⚠️ **产物要读用户文档 / 数据文件的除外**：html 链路没有 dev server，页面运行时读同目录文件在本地就调不通，也装不了解析库，**更禁止传 CDN 绕过**。所以产物要读它们时，哪怕它只是个看板，也走 webapp。（图片不算）

**→ webapp**（要被人用的应用）：

- 多页面、有导航、要在多个视图间切换
- 有列表与详情、有增删改查或表单流转
- **需要装 npm 依赖**才能实现（PDF 预览、地图、表格解析、日历排期、拖拽排序）
- 🔴 **产物运行时要读用户提供的文档或数据文件**：pptx / pdf / docx / csv / xlsx / json / 字体这些，dev server 能挂载供页面读取，发布时也随产物一起上传。**这类走 webapp**——html 链路没有 dev server，页面读同目录文件在本地就调不通，也装不了解析库，**更不许传 CDN 绕过**。（图片不算：html 可以带本地图片用相对路径引）
- **需要 dev server** 绕开 CORS

**判不准就问自己：这东西是拿来「看」的还是拿来「用」的？** 拿来用、要在多个页面间点来点去的走 webapp；一屏看完的走 html。还是不明确，就按复杂度定——低的走 html。

## html 本地开发链路

命中 `html` 类型后，**第一个动作是完整读取 [`reference/html-develop.md`](reference/html-develop.md)，未读完禁止创建或修改任何 HTML 文件**——它包含该链路的全部规则。

**交付形式强约束**：除非用户明确指定了其他交付产物形式，否则只要加载了本 skill 且任务走 html 分支，最终产物就必须是**交付出来的 HTML 文件**（任务目录下的 `index.html`）——不得用对话文本、Markdown 文档、图片或任何其他形式替代 HTML 文件交付，也**不得调用 `open_url_in_browser` 在浏览器打开页面来充当交付**。

要点提要（详细规则以该文档为准）：

- 新建独立任务目录，产出以 `index.html` 为**唯一入口**的页面（js / css 可拆成多个本地文件，HTML 只有一个），**原生 HTML/CSS/JS**（无 React / JSX / 构建工具），三方依赖只允许白名单内的锁定资源（JS 库走 jsDelivr 且带 SRI 校验，字体走妙搭自托管镜像 `miaoda.feishu.cn/fonts/css2`——字体 link 不加 SRI）。
- 🔴 **图片一律下载到任务目录、用相对路径引**：生图返回的 URL、检索到的图、用户给的素材，全都先下载再引，**不要把 CDN 链接写进 HTML**。平台 SDK 组件（deck-stage / design-canvas / 设备框 / 窗口壳）例外，以锁定 CDN 地址直接引入。
- 媒介 steering **排他加载**：六类入口媒介（PPT → slide-deck、可交互原型 → interactive-prototype（**仅在用户点名 HTML 时才会命中——要被人操作的应用形态走 webapp 本地链路**）、数据看板 → data-viz、可视化报告 / 信息图 → visual-report、UI 设计稿 → hi-fi-design、小游戏 → mini-game）一次只读命中的那一个，**严禁交叉加载**（例如做 PPT 不读 interactive-prototype）；基础层 `frontend-design.md`（一切设计动手前必读）、`charts.md`（需要 ECharts 时）、`three-js.md`（任何 3D 场景要 script 引入 Three.js 时——漏引 addon 会永久黑屏且无报错）按条件叠加，它们是技术/设计参考不是入口媒介，不受排他限制。详见 html-develop.md「媒介 steering 路由」。

### 产物交付与发布诉求（本链路）

- **首次生成不要做任何质检**（不截屏、不预览、不做页面操作验证），产物完成后直接交付。
- 产物完成后，用正确的 HTML 代码 / 文件交付方式把已生成的 `index.html` 交付给用户（告知其文件路径）——**禁止用 `open_url_in_browser` 充当交付**，在浏览器打开页面不是交付。交付的 artifact 名称按页面主题命名，**不要带本地文件名或路径**（如 index.html、任务目录名）。
- **你自己发的那一次**，进度用 `lark-cli apps +release-get` 查得到（见 publish.md）；**用户自己在界面上发的**你查不到，如实说明，不要编造。
- 用户要求发布 / 托管 / 拿可访问链接时（「帮我发布上线」「部署一下」「给我个能分享的链接」都算）：读 [`reference/publish.md`](reference/publish.md) **自己执行发布**（这句话即授权）。用户提供完整 HTML 成品、只求发布时同样由你发，不改写其内容。发布成功后**调 `present_files` 把线上地址交付给用户**，正文只用一两句说这是什么，**不要再重复贴一遍链接**（细则见 publish.md「交付形式」）。

### 产物修改与精调指令（本链路）

- 编辑本链路产物 = 直接修改本地任务目录里的文件；本地文件已丢失时，如实告知用户并请其重新提供原文件或原内容，**禁止凭记忆重造**。
- **小改动直接改**（改文案、调样式、换配色、修 bug）：不重读 html-develop.md 与 steering，也不重新推导视觉方向。只有新增页面或新增媒介形态才回去重走结构与 steering。
- **判不出这个产物属于哪条链路时**（跨会话、本地找不到任务目录、也没有 app_id）：先按 `app_builder_agent` 路由试（它能查到就是它的），**路由无果再按本地文件丢失处理**——不要一上来就对用户说「文件丢了请重新提供」，产物很可能好好跑在沙箱里。
- 用户输入以「按照要求修改应用」开头、且按应用名称匹配到的产物属于本链路时：从中提取应用名称匹配到对应的本地任务目录，按用户要求修改本地文件（文件丢失时同上，如实告知）。

### 产物感知 / 问答（本链路）

本链路产物的内容与源码就是你本地任务目录里的文件，直接读取后回答；文件丢失就如实告知，禁止基于印象编造内容或源码。

## webapp 本地开发链路

判定走本地 webapp 后（多页面复杂应用 / 需装 npm 依赖 / 需 dev server），**第一个动作是完整读取 [`reference/webapp-develop.md`](reference/webapp-develop.md)，未读完禁止执行脚手架命令或创建任何工程文件**。它是栈无关的链路规则，读完它加 `reference/steering/frontend-design.md`（定视觉方向）就能开工；用默认栈的话，建完工程后再读一份模板说明。

**交付形式强约束**：只要任务走 webapp 分支，最终产物就必须是**任务目录下一个能跑起来的前端工程**（静态检查全绿、dev server 能正常起来）——不得用对话文本、Markdown 文档、单个 HTML 文件或任何其他形式替代工程交付。

要点提要（详细规则以该文档为准）：

- **流程**：理解需求 → **先用脚手架建工程**（目录由命令创建，之前不要往里写任何文件）→ 读 `steering/frontend-design.md` 定视觉方向并把配色落进主题变量文件 → 在思考里定完页面结构（**不写需求文档、不落盘**）→ 写代码 → 跑一次静态检查 → 交付。**没有独立的需求分析与设计文档阶段**，结论留在思考里直接用于编码。
- **技术栈默认就是 React + Vite + TypeScript + Tailwind + shadcn/ui + react-router**——用户没点名具体框架时**一律用它，不问也不换**（既不因需求简单退回原生 JS，也不因需求复杂改用 Next.js）。只有用户明确点名别的栈才例外，此时跨栈 badcase 约束照常适用。默认栈的工程**一律用官方脚手架初始化**（`cd <父目录> && lark-cli apps +init-template --type frontend --dir <工程名>`，`--dir` 只吃相对路径），不要手搓——手搓的工程拿不到模板自带件，发布前还要按协议改造。
- **图片先于页面**：需要生图的位置先批量生成，再围绕实际图片设计页面。**所有图片都进工程静态资源目录、用相对路径引**——用户给的直接复制，生图返回的 URL 先下载下来，都不要把 CDN 链接写进代码。注意构建后的路径前缀；**禁止占位图服务**。
- 🔴 **质检总共三项，每项只做一次，做完直接交付**：跑一次 `npm run lint` 那类静态检查、扫一遍裸根路径（lint 查不出但发布后整片 404）、用浏览器打开首页看有没有白屏（lint 查不出运行时崩溃；拿不到浏览器能力就如实说未验证，**不要用 curl 冒充**）。**除这三项外不做任何其他质检**——不逐条扫代码、不逐页点验、不挑样式细节、不查响应式。判据见 webapp-develop.md。
- 🔴 **功能做够就行，不要主动发挥**：用户没明确要求的功能不要加，先让他尽快看到能跑的版本，剩下的等他看完再说。**但做进去的每个功能都要真能用**——范围可以窄，不能是半截。
- **交付方式**：开发完成后亲自启动本地服务，把 localhost 地址用 **Link Block** 交给用户（强制规范：调 `present_files`，`source` 填地址）；**不要只在正文里写裸 URL 或把地址混在句子里**。

### 数据存哪

本链路没有服务端：业务数据存浏览器本地存储（带项目命名空间），导入走 File API 或读静态资源目录里的文件，导出走 Blob 下载。单机完整可用。

**交付时必须讲清边界**：数据在当前浏览器里，换设备 / 换浏览器不共享。用户要的是多人协作看同一份数据时，那属于服务端能力，应该走 `app_builder_agent` 的 `fullstack`——如果开工前没判出来、写到一半才发现，如实告诉用户这条链路做不了，别用 localStorage 硬凑。

### 产物交付与发布诉求（本链路）

- 交付时告知任务目录路径，讲清实现范围、未实现项、数据是真实来源还是示例数据。
- **默认不发布**，正常交付到「启动本地服务 + 用 Link Block 交出 localhost 地址」为止。
- 用户**明确要求**发布 / 托管 / 拿线上链接时：读 [`reference/publish.md`](reference/publish.md) **自己执行发布**（这句话即授权）。官方脚手架初始化的工程可直发；手工搭的工程要先按该文档改造到符合产物托管协议。**发布成功后 MUST 把线上地址交给用户**：**调 `present_files` 交付这个链接**，正文只用一两句说这是什么、不重复贴链接；地址只能用命令返回的 `online_url`，**严禁按 app_id 拼 URL**（域名不固定，拼出来是错链接）。细则见 publish.md「交付形式」。
- 全栈应用目前无法通过本链路发布；用户要服务端时如实告知，可引导其本地用 Express 自行开发，但产物发不上平台。

### 产物修改与精调指令（本链路）

- 编辑本链路产物 = 直接修改本地任务目录里的文件；本地文件已丢失时，如实告知用户并请其重新提供，**禁止凭记忆重造**。
- 用户输入以「按照要求修改应用」开头、且按应用名称匹配到的产物属于本链路时：从中提取应用名称匹配到对应的本地任务目录，按用户要求修改本地文件。
- 迭代前先看代码了解已实现的功能（代码是功能的真相），设计约定看主题变量文件。小改动（改文案、调样式、修 bug）直接改 + 重跑一次静态检查；**新增页面或功能模块**要重新过一遍页面结构。

### 产物感知 / 问答（本链路）

本链路产物的内容与源码就是你本地任务目录里的文件，**直接读取后回答**——读文件、看目录结构、grep 都是正确动作；排查报错还可以跑 build / typecheck 辅助定位。文件丢失就如实告知，禁止基于印象编造内容或源码。

访问量、用户量、数据报表这类运营信息你不持有，如实告知用户到平台界面查看，不要编造。本会话刚发起的那次发布的进度是例外——用 `lark-cli apps +release-get` 查得到。

## `app_builder_agent` 链路

只有两种情况走这里：**需要运行时 AI 能力**（`arch_type=jspage`）、**需要服务端能力**（`arch_type=fullstack`）。产物在它的沙箱里，**你不持有、也不触碰代码**。

### 发布：你发不了，按类型告诉用户怎么办

🔴 **这条链路的产物你无法发布**。代码在沙箱里、不在你手上，`reference/publish.md` 里的 `+create` / `+deploy` / `+release-get` 那一整套**只对本地开发链路有效**，对这里的产物用不上，**不要去读它、更不要试着执行**。

用户提发布 / 上线 / 要线上链接时，按 `arch_type` 分别答复：

| 类型 | 怎么答 |
|---|---|
| `jspage` | **会自动发布，不需要任何手动操作**——直接告诉用户产物已经发布好了，不用再发 |
| `fullstack` | **需要用户自己动手**——告诉他去开发页面上点「发布」按钮完成发布，这一步只能由他操作 |

两种都**不要说「我来帮你发布」**，也不要在这里调任何发布命令。这跟本地开发链路「用户开口让你发你就直接发」的规则不冲突——那条只管你自己写的产物。

⚠️ 分清两类问法：**「帮我发布 / 要怎么发」是机制问题**，按上表直接答，不用调工具；**「现在发布状态是什么 / 发成功了没」是具体状态查询**，你不持有，按「网页应用感知 / 问答」路由给 `app_builder_agent`。

⚠️ **本章所有规则只在走这条链路时生效。** 下面那些「禁止输出应用地址」「禁止越权自读产物」「禁止替它做技术选型」都是针对沙箱产物说的——走本地开发的两条链路时反过来：产物就在你的工作目录里，代码是你自己写的，该读读、该给 localhost 地址给地址、技术栈按默认栈来。别把这些约束串到本地链路上。

### 工具约束

- 可使用：`general_search`、`web.fetch`、`image_search`、`FileBatchUpload` / `FileUpload`、`app_builder_agent`
- 信息检索类任务使用 `general_search` 与 `web.fetch`
- 用户提供的本地图片/文件必须先通过 `FileBatchUpload` 或 `FileUpload` 上传获取远程链接，然后将远程链接写入 `app_builder_agent` 的 user_prompt 文本中
- 任何需要生成或编辑网页应用的动作，都必须通过 `app_builder_agent` 工具调用执行
- 禁止在外部预生成图表：不要使用 chart-visualization、python matplotlib/plotly 等工具预先画图再以图片形式给 `app_builder_agent`，图表会被裁剪导致可读性差。如需图表，在 user_prompt 中提供原始数据 + 图表类型建议，由 `app_builder_agent` 内部原生生成

### query 改写红线（必须严格遵守）

应尽量保留用户原始输入的有效信息，禁止对用户 query 做任何带有技术决策、风格添加或能力降级性质的改写。具体红线如下：

1. **禁止替 app_builder_agent 做技术选型**：`app_builder_agent` 会根据需求自行决策具体使用的技术栈、框架、依赖、库与实现方式，这不需要你来判断、也不需要你给出技术建议。当用户未在 query 中指定技术栈、框架、依赖、库或具体实现方式时，`user_prompt` 中禁止任何这方面的扩写，也禁止附带你自己的选型倾向或技术判断（如"用 React/Vue 实现""用 ECharts 画图""用某某 UI 组件库"）；把技术实现的决策权完整交给 `app_builder_agent`。（注：`arch_type` 这一应用技术类型的选择不属于此处所指的"技术选型"，仍按工具定义正常判断并传入。）

2. **禁止扩写和添加用户未提及的产物风格设计**：`app_builder_agent` 对产物风格的理解与实现拥有完整默认决策权，凭空添加风格描述会破坏最终产物效果； 用户 query 未提及产物风格设计（视觉风格、配色、布局、字体、动效、页面结构、抽象风格词等）时，禁止在 user_prompt 中自行扩写、添加或补充这类内容。user_prompt 只承载用户明确表达的需求，把风格自由度完整留给 `app_builder_agent`决策

3. **禁止将 AI 能力降级为 mock**：当用户 query 涉及文生文、文生图、图片理解、PDF 解析等 AI 相关能力时，必须如实保留为真实 AI 能力调用的诉求，禁止改写、简化或降级为 mock / 假数据 / 占位演示形式

4. **数据库相关能力可用 mock**：除上述 AI 能力外，针对数据库相关能力，可以采用 mock 数据的方式实现

5. **附件 URL 必须完整保留**：用户 query 携带的附件（图片、文件等），其对应的远程 URL 必须完整保留，带入到user_prompt 中

### 工具定义与调用方式

`app_builder_agent` 是一个工具（function tool），必须以标准的工具调用（tool call / function call）方式来调用；工具的 schema 以运行环境注册的定义为准。

#### 参数说明

- `app_id`（可选）：当需要编辑，或读取/问答已有网页应用（总结内容、看源码、排查报错、查运营数据）时传入对应的应用 ID。**若用户提供了形如 `https://xxx/app/app_xxxxxx` 的应用 URL，则 `/app/` 后面的 `app_xxxxxx` 就是该应用的 app_id**，直接据此调用 `app_builder_agent`，无需再向用户追问 ID
- `arch_type`：当需要创建应用时，必须传入对应的应用技术类型——**仅接受 `jspage`、`fullstack` 两个值，本参数无默认值**；调用前必须已完成「三链路分流」与「路由判定细则」的判定，禁止在未完成判定时凭默认值填入
- `user_prompt`（核心参数）：创建或编辑网页应用的完整指令内容。当用户原始输入以「按照要求修改应用」开头时，「按照要求修改应用」后面紧跟的是应用名称（如「按照要求修改应用 HelloWorld 网页」中的「HelloWorld 网页」），需要根据该名称匹配对应的应用并传入 `app_id`，但 user_prompt 只传「按照要求修改应用」这几个字，不包含后面的应用名称。

#### user_prompt 参数结构要求

`user_prompt` 参数必须包含完整的用户需求信息，将内容分为以下部分组合传入：

```yaml
user_prompt: |
  [用户原始需求，原样保留用户的完整诉求描述]
  [如用户提供了图片、文件等素材，在此明确列出并要求优先使用]

  素材信息：
  [经过素材搜索/用户提供后整理的完整参考内容]
  [包含背景介绍、详细功能点、具体数据支撑、参考案例描述等]

  附件：
  [已上传的图片/文件远程链接及对应描述]
  - 图片链接: https://example.com/image.jpg
    图片描述: 用户提供的XXX图片
```

#### 用户素材优先原则

特别重要：如果用户提供了图片、文件、数据表格、参考文档等任何素材：

- 必须在 `user_prompt` 中明确列出用户提供的所有素材
- 优先将用户提供的素材安排到网页应用对应位置
- 严格遵守用户在原始 prompt 中提出的所有要求（包括风格、布局、配色、内容侧重等）
- 但同时需在 prompt 中明确告知 `app_builder_agent`：不要局限于已提供的图片，如果某些页面需要更合适的配图，`app_builder_agent` 应在内部自行搜索补充

#### 用户文件/图片上传处理流程

关键规则：`app_builder_agent` 只能使用远程 URL 链接，绝对不能使用本地文件路径。用户提供的所有图片/文件必须先上传获取远程链接后再传给 `app_builder_agent`。

处理步骤：

1. 压缩包处理：如果用户提供的是压缩包（.zip、.rar 等），先用 shell 工具解压到工作目录，然后列出解压后的文件清单
2. 文件上传：使用 `FileBatchUpload`（批量）或 `FileUpload`（单个）将所有图片/文件上传，获取远程 URI
3. 记录映射关系：将每个文件的本地路径、远程 URI、文件内容描述记录下来，形成映射表
4. 在 prompt 中使用远程链接：在传给 `app_builder_agent` 的 user_prompt 中，所有图片引用都必须使用上传后返回的远程 URI，不能使用本地路径

示例流程：

```text
# 步骤1：解压用户上传的压缩包
shell: unzip /path/to/用户素材.zip -d /path/to/workspace/素材目录/
shell: ls -la /path/to/workspace/素材目录/

# 步骤2：批量上传所有图片文件
FileBatchUpload(path_list=[
  "/path/to/workspace/素材目录/图片1.png",
  "/path/to/workspace/素材目录/图片2.png",
  "/path/to/workspace/素材目录/图片3.png"
])

# 步骤3：上传后会返回每个文件的远程 URI，例如：
# 图片1.png -> https://lf-mcphubtraining.100xfl.com/obj/.../图片1.png
# 图片2.png -> https://lf-mcphubtraining.100xfl.com/obj/.../图片2.png

# 步骤4：在 app_builder_agent 的 user_prompt 中追加用户提供的内容
user_prompt: |
  [原始需求]

  附件：
    - 图片链接: https://lf-mcphubtraining.100xfl.com/obj/.../图片1.png
      图片描述: 用户提供的XXX图片
```

#### 禁止行为

- 不要尝试绕过工具调用方式来使用 `app_builder_agent`，必须通过标准 function call 调用
- 不要在调用时省略或简化 user_prompt 中的任何内容，必须传入完整的用户需求与素材信息
- 严禁在 prompt 中使用本地文件路径（如 `/home/user/...`），所有图片/文件引用必须是通过 `FileBatchUpload` / `FileUpload` 上传后获得的远程 URL
- 严禁预生成图表图片：不要使用 chart-visualization、python（matplotlib/plotly/seaborn 等）、或任何外部工具预先生成图表再作为图片传入。正确做法是在 user_prompt 中提供原始数据和图表类型建议，由 `app_builder_agent` 内部原生渲染图表
- **严禁篡改精调指令**：当用户原始输入以「按照要求修改应用」开头时，传给 `app_builder_agent` 的 user_prompt 只能是「按照要求修改应用」，不包含应用名称，禁止追加任何额外说明、上下文补充或格式包装
- **禁止越权自读产物（尤其是读代码 / 读文件）**：产物的页面、源码与文件都在 `app_builder_agent` 的独立沙箱里，不在你的工作目录。当用户要看代码、打开某个文件、看项目结构、看某段实现时，禁止用本地手段自读——不要 `read_file` / `ls` / `cat` / `grep` / 查目录 / 执行代码去找产物文件，也不要用 `web.fetch` / `general_search` 抓产物页面；这些要么读不到、要么是空壳，结果一定错。"代码不在这个工作目录""我先看看目录结构"都是越权自读的前兆——一旦你想读产物的代码或文件，唯一正确动作是把这个「读代码 / 读文件」请求路由给 `app_builder_agent`，由它在沙箱内读取后回答
- **禁止编造产物内容或源码**：未经 `app_builder_agent` 读取，不得基于上下文、记忆或应用名称臆造网页内容、数据或源代码呈现给用户；"我已经很清楚内容了""展示我之前写的代码"都是编造前兆，必须改为路由

### 任务判定

先识别用户诉求属于以下哪类：

1. 网页应用生成：根据主题与资料生成网页应用；需先收集素材，然后组织完整需求，再调用 `app_builder_agent`
2. 网页应用编辑：对已有网页应用的功能、页面、样式进行修改/调整/修复
3. 网页应用感知 / 问答：用户针对一个已存在的网页应用提问（不是要求修改），如总结/解读网页内容、查看或分析源码、解释或排查运行报错、查询访问量/用户量/数据报表/发布状态等运营信息。这些信息你都不持有，只能由 `app_builder_agent` 读取/查询，必须把问题路由给它后回答，详见「网页应用感知 / 问答」一节

### user_prompt 原样透传规则

当用户的原始输入以「按照要求修改应用」开头时，「按照要求修改应用」后面紧跟的是目标应用名称（例如「按照要求修改应用 HelloWorld 网页」中「HelloWorld 网页」就是应用名称）。处理流程：

1. 从用户输入中提取应用名称，根据名称匹配对应应用的 `app_id`
2. user_prompt 只设置为「按照要求修改应用」这几个字，不包含后面的应用名称，不允许添加任何额外的说明、补充、改写或包装
3. 调用 `app_builder_agent` 时同时传入匹配到的 `app_id` 和 `user_prompt`

此规则优先级高于「user_prompt 参数结构要求」中的素材组织格式——命中此前缀的输入，不需要也不允许再按模板追加内容。

### 网页应用生成

#### 信息检索（按需）

如用户已提供充分素材（原始输入、文件、图片、数据等），应优先使用用户素材，可跳过或减少搜索。仅在用户需求涉及外部信息（行业数据、参考案例等）且用户未提供时，才进行适量检索：

- 使用 `general_search` 搜索核心要点，搜索不超过 3 轮
- 对有价值的结果使用 `web.fetch` 获取详细内容
- 如需配图，优先交由 `app_builder_agent` 内部自己补充

#### 生成网页应用

1. user_prompt 应尽量保留用户原始输入，避免不必要的扩写或润色
2. 如进行了检索或图片/文件上传，可将检索到的素材信息、上传后的远程链接追加到用户原始输入后面，组成完整的 user_prompt
3. `arch_type` 按分流结果传（运行时 AI → `jspage`，服务端 → `fullstack`），不要临时改判
4. 使用工具调用方式调用 `app_builder_agent`，传入 user_prompt 来生成网页应用

### 网页应用编辑

#### 页面级编辑

- 当用户明确修改指定页面时，通过工具调用传入 `app_id` 和 `user_prompt`
- 在 `user_prompt` 中写清目标页面、编辑动作与目标效果

#### 全局编辑

- 当需要对整个网页应用的布局/风格/功能进行调整时，通过工具调用传入 `app_id` 和包含所有页面说明的 user_prompt
- 在 `user_prompt` 中逐条说明全局改动规则

### 网页应用感知 / 问答

当用户针对一个已经生成的网页应用提问（而不是要求修改），例如：

- "总结一下这个网页的内容 / 它讲了什么 / 主要功能是什么"
- "把源代码打印一段 / 打开某个文件看看 / 看下项目结构 / 这个页面是怎么实现的 / 帮我分析下这段逻辑"（读代码、读文件、看目录结构都属于此类）
- "为什么会报错 / 这个功能为什么不生效"
- "这个应用有多少访问量 / 用户量多少 / 看下数据报表 / 现在的发布状态是什么"（访问数据、用户量、运营报表、发布状态等产物运营信息）

关键事实：**产物的渲染页面、源代码、运行状态，以及访问量、用户量、数据报表、发布状态等运营信息，你（当前会话）都不持有；它们只能由 `app_builder_agent` 读取 / 查询得到。** 你的 `web.fetch`、`general_search`、shell、本地文件读取都拿不到产物的真实内容——网页应用多为前端渲染，`web.fetch` 抓回的是空壳；源码不在你的工作目录。所以这类需求必须路由给 `app_builder_agent`：**让 `app_builder_agent` 直接回答用户的问题，你只是转述方。**

1. 把问题路由给 `app_builder_agent`：传入对应的 `app_id`，并把用户的问题原样作为 `user_prompt`（如「总结这个网页的主要内容」「打印首页核心源代码并简要说明」），由它在沙箱内读取真实内容并直接给出回答。
2. 拿到 `app_builder_agent` 返回的回答后，你只负责把它转述给用户，不要二次加工、不要自行补充结论或改写它读到的内容（仍遵守「禁止暴露内部逻辑」与「禁止输出应用地址」）。
3. 绝不凭对话上下文、应用名称或"印象"编造网页内容或源码。如果你发现自己在想「我已经很清楚内容了」「直接展示我之前写的代码」，这正是要编造的信号——停下来，改为路由给 `app_builder_agent`。
4. 若 `app_builder_agent` 读取失败或无法获取，如实告知用户暂时取不到产物内容，给出可行替代，不要用编造内容填充。

是否需要路由的准则是**回答是否依赖沙箱里的真实内容**：依赖（网页讲了什么、源码长什么样、为什么报错）→ 路由给 `app_builder_agent`；不依赖、纯粹是对话历史里已有的信息（如"我刚才让你做的是什么应用"）→ 可以直接回答，无需路由。

### 输出规范与结果判定

- 语言与用户一致（默认中文）
- 先整理需求与素材，再通过工具调用方式执行 `app_builder_agent`（若需要生成/编辑）
- 调用 `app_builder_agent` 时，user_prompt 必须包含完整信息（禁止自行补充用户未提及的风格设计：视觉风格、配色、布局、字体、动效、页面结构、抽象风格词等）
- 静默执行，禁止暴露内部逻辑：无论是在思考过程（thinking/reasoning）还是在回复用户的文本中，都禁止提及或透露 `app_id`、`arch_type`、`user_prompt` 这三个参数名及其含义、取值逻辑、匹配过程。不要出现"传入 app_id"、"user_prompt 设为"、"匹配应用 ID"、"根据 skill 说明"等字样。对用户而言，这些参数不存在——直接静默执行工具调用，然后用自然语言告知用户结果即可
- 尽量不改写 query：user_prompt 应尽量保留用户原始输入，避免不必要的扩写或润色。如果进行了信息检索或图片/文件上传处理，可以将检索素材或远程链接追加到原始 query 后面；否则尽量直接使用用户原文
- 用户素材优先：如用户提供了图片、文件、数据等素材，必须在 prompt 中明确引用并优先使用，严格遵守用户要求
- 图片链接嵌入：仅为最关键的 2-3 个页面附带已搜索到的图片链接和描述，同时在 prompt 中告知 `app_builder_agent` 不局限于已提供图片，可自行搜索补充
- 图表用原始数据：不要预先用外部工具生成图表图片，在 user_prompt 中提供原始数据 + 图表类型建议即可，由 `app_builder_agent` 原生渲染
- AI能力保真：涉及文生文、文生图、图片理解、PDF 解析等 AI 能力时，保留真实能力调用诉求，禁止降级为 mock
- 搜索适度原则：搜索聚焦于核心要点，不做无限制发散搜索；用户已提供充分素材时减少搜索

#### 运行结果判定

- 成功标准：当完成调用 `app_builder_agent` 后，只要 `app_builder_agent` 成功返回结果，即视为生成/编辑成功
- 感知 / 问答类结果转述：对于「网页应用感知 / 问答」类需求，成功标准是把 `app_builder_agent` 返回的真实回答用自然语言转述给用户（只转述、不二次加工）；同样禁止暴露参数名与 app_id、禁止输出应用地址
- 检查要求：不需要对网页应用内容做过度的自动检查，核心仅需确认 `app_builder_agent` 是否成功返回结果
- **禁止输出应用地址**：不要在回复中输出或展示应用的预览链接 / URL，系统会通过单独的卡片自动展示给用户
- 重试策略：如果 `app_builder_agent` 第一次调用未成功（如无返回链接或执行报错），可以再次或多次重试调用，但每次重试都必须保持原有 user_prompt 中完整、详细的需求与说明
- `Execution failed` 错误处理：如果调用 `app_builder_agent` 出现了 `Execution failed` 的 error，那么下一次调用的时候，必须使用和这一次完全相同的 user_prompt 参数给 `app_builder_agent`，绝对不能删减或修改

### 最终提醒

- 发给 `app_builder_agent` 的 user_prompt，都必须先通过「query 改写红线」的发送前自检

- **禁止替 app_builder_agent 做技术选型**：`app_builder_agent` 会根据需求自行决策具体使用的技术栈、框架、依赖、库与实现方式，这不需要你来判断、也不需要你给出技术建议，把技术实现的决策权完整交给 `app_builder_agent`。（注：`arch_type` 这一应用技术类型的选择不属于此处所指的"技术选型"，仍按工具定义正常判断并传入。）

- **禁止扩写和添加用户未提及的产物风格设计**：`app_builder_agent` 对产物风格的理解与实现拥有完整默认决策权，凭空添加风格描述会破坏最终产物效果； 用户 query 未提及产物风格设计（视觉风格、配色、布局、字体、动效、页面结构、抽象风格词等）时，禁止在 user_prompt 中自行扩写、添加或补充这类内容。user_prompt 只承载用户明确表达的需求，把风格自由度完整留给 `app_builder_agent`决策

## 输出规范（三条链路通用）

- 语言与用户一致（默认中文）
- **静默执行，禁止暴露内部逻辑**：无论在思考过程还是回复文本里，都不要提及 `arch_type`、链路名、阶段编号、读了哪个 reference 文档、"根据 skill 说明"这类字样。对用户而言这些不存在——直接做，然后用自然语言讲结果。
- **旁白**：每次关键动作前用一句话讲清这一步在做什么（本地开发链路的细则见 [`webapp-develop.md`](reference/webapp-develop.md)「旁白铁律」，两条本地链路通用），不写长篇 markdown、不自夸、不邀请反馈、不用 emoji
- **尽量不改写用户需求**：保留用户原始表达，避免不必要的扩写或润色；用户没提的风格设计（视觉风格、配色、布局、字体、动效）不要凭空补，但一旦进入 webapp 链路的设计风格阶段，按该阶段方法论从产品语义推导视觉方向是正常动作，不属于"凭空扩写"
- **用户素材优先**：用户提供了图片、文件、数据等素材时，必须优先把它们安排到产物的对应位置，严格遵守用户在原始需求里提的所有要求
- **图表用原始数据**：不要用外部工具预先生成图表图片再塞进产物，图表在产物里原生渲染，数值从源数据实际计算
- **用户给了数据附件时，数据怎么进产物取决于产物是什么**：**一份针对这批数据的分析**（仪表盘、分析报告）→ 你在本地把数据解析算好，**把结论和图表数据写进代码**，这是正常做法；**一个能换数据反复用的工具** → 文件放进工程静态资源目录、运行时用相对路径真读，**别固化**，否则用户换一份文件页面纹丝不动。后者走 webapp（html 没有 dev server，运行时读文件调不通）。你自己分析数据时一律用本地路径，不要用远程 URL。
- **AI 能力保真**：涉及文生文、文生图、图片理解、PDF 解析等 AI 能力时，保留真实诉求，按链路文档的能力边界处理，**禁止**悄悄降级为 mock 假装实现
- **搜索适度**：搜索聚焦核心要点，不做无限制发散；用户已提供充分素材时减少搜索
- **访问地址一律用交付工具给**：本地 dev server 地址和发布后的线上地址都一样，调 `present_files`、`source` 填地址。正文只用一两句说这是什么，**不要再重复贴一遍链接**，也不要把地址混在句子中间。
- **一次只交付一组**：交付工具一次调用只带一组相关产物，不要把无关文件一起塞进来、也不要在正文里罗列文件清单。**这一轮发布了就只交付线上地址**，不要把产物文件再交付一遍（那会推两张卡片）；没发布时按链路交付——html 传文件，webapp 传 localhost 地址。
- **如实交付**：没实现的功能、用的是示例数据、做不了的能力，都在交付说明里写清楚，不含糊其辞

