# Doubao App Builder

> 统一处理网页应用的生成、编辑，以及围绕已生成产物的问答。既负责把自然语言需求端到端转成可运行、可预览、可交付的网页应用产物，也负责在用户追问产物时基于真实产物作答。当用户要生成网站、H5、网页应用、管理后台、数据看板时使用。当用户要编辑已有网页应用、做功能新增、页面调整或 Bug 修复时使用。当用户提供 PRD、文档、截图或素材包并要求产出可预览网页应用时使用。当用户针对已生成的网页应用，要求总结或解读网页内容、查看或分析源码、解释或排查运行报错、查询访问量/用户量/数据报表/发布状态等运营信息时同样使用。

- Skill: `ahang1598/doubao-app-builder` (Agent Skill)
- Install (CLI): `npx skillmds add ahang1598/doubao-app-builder`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ahang1598/doubao-app-builder/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: ahang1598 (https://skillmd.com/u/ahang1598)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/ahang1598/doubao-app-builder

---


# doubao-app-builder

## 概述

面向网页应用生成、编辑与问答的工作流指引，统一用 `app_builder_agent` 工具完成应用的生成、改动，以及对已生成产物的读取问答。

## 概览

面向网页应用生成、编辑与问答的工作流指引，统一用 `app_builder_agent` 工具完成应用的生成、改动，以及对已生成产物的读取问答。
当用户出现以下任一意图时，调用本 skill：

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

## 应用技术类型约束（仅限新建应用场景）
- 用户query 明确指出应用技术栈类型(原型jspage/html/全栈fullstack)时，务必遵循用户原始速求；
- 用户query 未明确指定时：判定 `arch_type` 的核心标准只有一个：**用户是否需要长期保存和管理数据或文件**。默认使用 `jspage`，仅在用户明确需要数据存储时才使用 `fullstack`

### 直接使用 `fullstack`（无需询问）
当用户需求中**明确**出现以下任意情况时，直接选择 `fullstack`：

1. **需要保存业务数据**
2. **用户明确提到「全栈」「数据库」「后端 API」「前后端」等技术关键词**

示例（注意用户需求中出现了明确的存储相关动词/关键词）：

- "做一个合同管理系统，把审阅意见**保存到数据库**" → `fullstack`（明确说了"保存到数据库"）
- "开发一个报名系统，报名数据要**持久化存储**，运营能随时**导出**报名表" → `fullstack`（明确说了"持久化存储"和"导出"）
- "做一个工单系统，要有**后端 API**和**数据库**" → `fullstack`（明确提到技术关键词）

### 直接使用 `jspage`（无需询问）

当用户需求**不涉及**数据存储或文件存储时，直接选择 `jspage`。包括但不限于：

- 官网、营销页、产品介绍页、落地页
- 幻灯片、可视化报告、数据看板
- 应用原型、流程 Demo、可交互原型
- 文本对比、价格计算器、随机分组等工具
- AI 文案生成器、简历优化器、会议纪要生成器等调用 AI 生成结果的应用
- 用户明确表达「做个原型」「快速预览」「用模拟数据」等意图
- 3D/游戏场景 → 使用 `html`

示例：

- "创建一个销售管理系统原型，包含客户列表、销售阶段和跟进记录，使用模拟数据即可" → `jspage`（明确要做原型，只需模拟数据）

### 需要追问用户（禁止直接判定）

当用户说"做一个 XX 管理系统 / XX 平台 / XX 工具 / XX 应用"等**看似需要全栈但未明确提及数据存储**的需求时，**禁止直接调用 `app_builder_agent`，必须先通过对话文本询问用户，等用户回复后再继续**。

示例触发场景：

- "帮我做一个淘宝"
- "做一个 CRM 系统"
- "开发一个项目管理工具"
- "做一个 OA 系统"

**强制执行流程：**

1. **先对话询问，不调用任何工具**——直接用自然语言回复用户。示例回复：

   > 这个系统是否需要长期保存和管理数据或文件？
   >
   > 1. **需要保存数据**——我会构建包含前后端和数据库的全栈应用，支持数据持久化存储
   > 2. **先做一个原型看看效果**——快速生成可交互的前端页面，用模拟数据展示
   >
   > 你希望用哪种方式？

   这一步**只输出文本，不调用任何工具**，然后等待用户回复。

2. **用户回复后，根据选择确定 `arch_type` 并调用 `app_builder_agent`**：

   | 用户选择                           | `arch_type`      | 说明                             |
   | ---------------------------------- | ---------------- | -------------------------------- |
   | 需要保存数据 / 全栈 / 正式系统     | `fullstack`      | 生成包含前后端、数据库的完整应用 |
   | 原型 / 先看看效果 / 不需要保存数据 | `jspage`（默认） | 快速生成前端可交互原型           |


## 工具约束

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

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

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

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

`app_builder_agent` 是一个工具（function tool），必须以标准的工具调用（tool call / function call）方式来调用。其 schema 定义如下：

```json
{
  "type": "function",
  "function": {
    "name": "app_builder_agent",
    "description": "专业网页应用助手。负责网页应用的生成、编辑，以及对已生成应用的读取问答：根据用户自然语言、文档、截图、数据生成可交互网页应用，支持结合用户素材生成；对已有应用（传入 app_id）按页面或全局进行修改；对已有应用（传入 app_id）读取其页面内容、源码、运行状态，以及访问量、用户量、数据报表、发布状态等运营信息，回答用户关于该应用的总结、解读、分析、报错排查与运营数据查询类问题。产物的真实内容与运营数据只能由本工具获取，调用方无法自行得到，凡需基于这些信息作答都应调用本工具。发起本工具调用前，须先阅读并遵循 doubao-app-builder skill 的规则后再调用",
    "parameters": {
      "type": "object",
      "properties": {
        "app_id": {
          "description": "当需要编辑已有应用，或读取/问答已有应用（总结网页内容、查看分析源码、排查报错、查询运营数据）时，必须传入对应的应用 ID。若用户提供了形如 https://xxx/app/app_xxxxxx 的应用 URL，则其中 /app/ 后面的 app_xxxxxx 就是该应用的 app_id，可直接据此调用本工具",
          "type": "string"
        },
        "arch_type": {
          "description": "当需要创建应用时，必须传入对应的应用技术类型。默认选择 `jspage`; 如遇到 3D/游戏 场景，选择 `html`; 如明确需要数据库能力、文件数据持久化存储 等场景，选择 `fullstack`",
          "type": "string"
        },
        "user_prompt": {
          "description": "创建应用或编辑应用时的 Prompt。当用户原始输入以「按照要求修改应用」开头时，user_prompt 只传「按照要求修改应用」这几个字，不包含后面的应用名称，应用名称仅用于匹配 app_id",
          "type": "string"
        }
      },
      "required": ["user_prompt"]
    }
  }
}
```

#### 参数说明

- `app_id`（可选）：当需要编辑，或读取/问答已有网页应用（总结内容、看源码、排查报错、查运营数据）时传入对应的应用 ID。**若用户提供了形如 `https://xxx/app/app_xxxxxx` 的应用 URL，则 `/app/` 后面的 `app_xxxxxx` 就是该应用的 app_id**，直接据此调用 `app_builder_agent`，无需再向用户追问 ID
- `arch_type`（可选）：当需要创建应用时，必须传入对应的应用技术类型
- `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. 选择合适的应用技术类型，默认选择 `jspage`。如遇到 3D/游戏 场景，选择 `html`
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` 直接回答用户的问题，你（MOA）只是转述方。**

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