← 返回博客

Open Design 源码解析:开源版 AI 设计引擎,从架构分析到 Docker 一键部署

当你发现一个工具能自动把”帮我做一个融资路演 PPT”变成一套带品牌配色的完整 HTML 幻灯片时,你知道这个行业又要变了。Open Design 就是这么一个东西——但它不是闭源的 SaaS,而是跑在你自己服务器上的开源项目。


一、Open Design 是什么

2026 年 4 月,Anthropic 发布了 Claude Design——一个让 LLM 直接输出设计制品(HTML / PDF / PPTX)而非纯文本对话的产品。它火了,但同时也引来了争议:闭源、仅限 Anthropic 模型、云端专用、无法自部署。

Open Design(GitHub: nexu-io/open-design,Apache-2.0 许可证)就是这个痛点的回应。它的定位很清晰:

  • 同样的 Artifact-first 工作流——输入一句话,输出设计稿,而不是长篇大论
  • 不捆绑任何 Agent——自动检测你本机上已安装的 16 种 Coding Agent CLI(Claude Code、Codex、Gemini CLI、Cursor Agent、Qwen Code 等),选一个就用
  • BYOK(Bring Your Own Key)——在每一层都可以用自己的 API Key
  • 本地优先,同时可部署——本地 pnpm tools-dev 一键启动,也可以 Docker 容器化部署到服务器
  • 129 套 Design System + 31 个 Skill——开箱即用的视觉规范和场景模板

简单说:它不造轮子,它把已有的轮子串成一辆车。


二、整体架构

Open Design 是一个 monorepo,基于 pnpm workspace 管理,核心由三个 App 和四个 Package 组成:

open-design/
├── apps/
│   ├── daemon/          # Node.js/Express 守护进程(核心大脑)
│   ├── web/             # Next.js 16 前端(用户界面)
│   └── desktop/         # Electron 桌面壳(可选)
├── packages/
│   ├── contracts/       # 应用层接口契约
│   ├── platform/        # 跨平台底层原语
│   ├── sidecar/         # 通用 sidecar 运行时
│   └── sidecar-proto/   # sidecar 协议定义
├── skills/              # 31 个场景 Skill(SKILL.md)
├── design-systems/      # 129 套设计规范(DESIGN.md)
├── prompt-templates/    # 93 个媒体生成模板
├── assets/frames/       # 设备框架(iPhone/MacBook 等)
└── deploy/              # Docker 部署配置

架构核心:Daemon

Daemon(守护进程)是整个系统的中枢,一个 Node.js/Express 服务,承担了以下职责:

职责说明
Agent 检测扫描系统 PATH,自动发现已安装的 Coding Agent CLI
Agent 编排将 Agent 子进程的输出解析为结构化事件流(SSE)
Skill 加载扫描 skills/ 目录下的 SKILL.md,解析 frontmatter
Design System 加载扫描 design-systems/ 目录下的 DESIGN.md
Prompt 组合三层拼接:基础系统提示 + Design System + Skill
Artifact 解析从 Agent 输出中提取 <artifact> 标签,解析 HTML
项目管理SQLite 持久化项目、对话、消息状态
媒体生成支持 gpt-image-2 / Seedance / HyperFrames
API 代理BYOK 模式下代理 Anthropic/OpenAI/Azure/Google 的 SSE 流

代码量上,server.ts 一个文件就超过 8000 行,agents.ts 有 1500+ 行,可见 Daemon 承载了绝大部分业务逻辑。

前端:Next.js Web 应用

前端是一个 Next.js 16 App Router 应用,主要模块:

  • App.tsx——调度 mode / skill / design system picker
  • providers/——Daemon 通信层 + BYOK API transport
  • prompts/——system / discovery / directions prompt 模板
  • artifacts/——流式 <artifact> 解析器
  • runtime/——iframe srcdoc 渲染、markdown、导出辅助
  • state/——localStorage + 持久化项目状态

在开发模式下,Next.js 会通过 rewrites 将 /api/* 请求代理到相邻的 Express 进程,无需配置 CORS。


三、源码核心机制拆解

1. Agent 自动检测

Open Design 最聪明的设计之一是:它不自己当 Agent,而是用你本机上已有的。

apps/daemon/src/agents.ts(1500+ 行)中,实现了以下检测逻辑:

// 每个 Agent CLI 都有独立的配置条目:
// - listModels: 可选的模型列表获取命令
// - fallbackModels: 静态模型列表
// - buildArgs: 构建 CLI 启动参数
// - streamFormat: 输出流格式(claude-stream-json / acp-json-rpc / plain 等)
// - agentCapabilities: 能力标志映射

支持的 16 种 Coding Agent:

类别Agent
主流 CLIClaude Code · Codex CLI · Gemini CLI · Cursor Agent · OpenCode
国产Qwen Code · Qoder CLI · Kimi CLI
ACP 协议Hermes · Devin for Terminal · Pi · Kiro · Kilo · Mistral Vibe · DeepSeek TUI
其他GitHub Copilot CLI

每种 Agent 都有独立的 buildArgs 函数来构造启动参数,以及 streamFormat 来定义输出解析方式。比如 Claude Code 用 --output-format stream-json 输出行分隔的 JSON 事件流,Daemon 解析后通过 SSE 推给前端。

如果没检测到任何 CLI,还可以切换到 BYOK API 模式——直接调用 Anthropic / OpenAI / Azure / Google 的 API,Daemon 内置了代理层来归一化不同厂商的 SSE 格式。

2. Skill 驱动的工作流

Skill 是 Open Design 的”场景模板”,每个 Skill 就是一个 SKILL.md 文件:

skills/
├── web-prototype/         # 通用原型(默认 skill)
├── saas-landing/          # 营销落地页
├── dashboard/             # 数据仪表盘
├── mobile-app/            # 移动端应用
├── guizang-ppt/           # 杂志风 PPT(默认 deck skill)
├── magazine-poster/       # 杂志海报
├── dating-web/            # 交友应用
├── sprite-animation/      # 精灵动画
├── motion-frames/         # 动态帧
└── ...(共 31 个)

apps/daemon/src/skills.ts(500+ 行)负责扫描、加载和解析这些 Skill 文件。每个 SKILL.md 包含 YAML frontmatter:

---
name: web-prototype
description: Build a single-screen web prototype
od:
  mode: prototype
  scenario: design
---

加载器解析 frontmatter 后提取 name、description、mode、scenario 等元信息,连同 body 正文一起返回给前端。

3. Design System:129 套视觉规范

Design System 是 Open Design 的另一大亮点。每个 Design System 也是一个 Markdown 文件(DESIGN.md),遵循 9 段式 schema:

design-systems/
├── neutral-modern/        # 中性现代(默认)
├── warm-editorial/        # 温暖编辑风
├── linear/                # Linear 风格
├── stripe/                # Stripe 风格
├── apple/                 # Apple 风格
├── xiaohongshu/           # 小红书风格
├── ...(共 129 套)

这些来自三个来源:

  • 2 套手工编写 starter(Neutral Modern + Warm Editorial)
  • 70 套产品级系统(来自 awesome-design-md
  • 57 套 design skill(来自 awesome-design-skills

4. Prompt 三层组合机制

每次发送请求时,Daemon 从三层构建 system prompt:

BASE_SYSTEM_PROMPT     ← 输出契约:<artifact> 包裹,不用 code fence
  + DESIGN.md 正文     ← 色板 / 字体 / 布局规范
    + SKILL.md 正文    ← 工作流与输出规则

切换 Skill 或 Design System 后,下一次发送自动使用新的组合。这种组合式的 Prompt 工程让同一个 Agent 能扮演不同的角色——从网页设计师到 PPT 制作员,到数据可视化专家。

5. Artifact 流式渲染

Agent 的输出通过 <artifact> 标签包裹:

<artifact>
  <!DOCTYPE html>
  <html>
    <head>...</head>
    <body>...</body>
  </html>
</artifact>

前端的 artifact 解析器从 SSE 流中实时提取 <artifact> 内容,渲染到沙箱 iframe 中。用户可以编辑文件、导出为 HTML / PDF / PPTX / ZIP / Markdown 五种格式。


四、Docker 部署实践

Open Design 提供了完善的 Docker 部署方案,基于 Alpine 镜像,单容器即可运行。

环境要求

项目说明
系统Linux(x86_64 或 ARM64)
Dockerv28+
Docker Composev5+
内存最低 384MB(实测空闲 18-22 MiB)
CPU单核即可

1. Docker 镜像构建

官方提供了多阶段构建的 Dockerfile:

# 第一阶段:构建
FROM node:24-alpine AS build
RUN apk add --no-cache python3 make g++
WORKDIR /app
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
RUN corepack enable && corepack prepare pnpm@10.33.2 --activate \
    && pnpm install --frozen-lockfile
COPY apps ./apps
COPY packages ./packages
COPY tools ./tools
COPY skills ./skills
COPY design-systems ./design-systems
RUN pnpm --filter @open-design/daemon build \
    && pnpm --filter @open-design/web build \
    && pnpm --filter @open-design/daemon deploy --legacy --prod /app/deploy/daemon

# 第二阶段:运行
FROM node:24-alpine
RUN apk add --no-cache tini \
    && addgroup -S -g 1001 open-design \
    && adduser -S -D -H -u 1001 -G open-design open-design
WORKDIR /app
COPY --from=build --chown=open-design:open-design /app/deploy/daemon ./apps/daemon
COPY --from=build --chown=open-design:open-design /app/apps/web/out ./apps/web/out
COPY --chown=open-design:open-design skills ./skills
COPY --chown=open-design:open-design design-systems ./design-systems
COPY --chown=open-design:open-design craft ./craft
COPY --chown=open-design:open-design prompt-templates ./prompt-templates
COPY --chown=open-design:open-design assets/frames ./assets/frames
ENV NODE_ENV=production
ENV OD_BIND_HOST=0.0.0.0
ENV OD_PORT=7456
EXPOSE 7456
USER open-design
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "apps/daemon/dist/cli.js", "--no-open"]

关键设计点:

  • 多阶段构建——构建层包含完整的 pnpm 依赖,运行层只保留产物,镜像体积小
  • 非 root 用户——创建 open-design 用户(uid 1001)运行服务
  • tini init——使用 tini 作为 PID 1,正确处理信号
  • 只读根文件系统——配合 read_only: true + tmpfs,提高安全性

2. Docker Compose 配置

官方 docker-compose.yml 开箱即用:

name: open-design

services:
  open-design:
    container_name: open-design
    image: docker.io/vanjayak/open-design:latest
    restart: always
    environment:
      NODE_ENV: production
      NODE_OPTIONS: --max-old-space-size=192
      OD_BIND_HOST: 0.0.0.0
      OD_PORT: 7456
      OD_WEB_PORT: 7456
    ports:
      - "7456:7456"
    volumes:
      - open_design_data:/app/.od
    read_only: true
    tmpfs:
      - /tmp
    security_opt:
      - no-new-privileges:true
    mem_limit: 384m
    pids_limit: 256
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:7456/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s

volumes:
  open_design_data:

安全加固做得很到位:

  • read_only: true——容器根文件系统只读
  • tmpfs: /tmp——临时目录挂载到内存
  • no-new-privileges: true——禁止提权
  • mem_limit: 384m——内存上限
  • pids_limit: 256——进程数上限
  • healthcheck——健康检查每 30 秒一次

3. 环境变量配置

通过 .env 文件配置:

# Docker Hub 镜像
OPEN_DESIGN_IMAGE=docker.io/vanjayak/open-design:latest

# 服务端口(建议通过反向代理暴露,不要直接开在公网上)
OPEN_DESIGN_PORT=7456

# 允许的浏览器 Origin(配置域名或反代地址时使用)
OPEN_DESIGN_ALLOWED_ORIGINS=https://your-domain.com

# 容器内存限制
OPEN_DESIGN_MEM_LIMIT=384m

# Node.js 堆内存上限
NODE_OPTIONS=--max-old-space-size=192

4. 启动服务

cd deploy
docker compose up -d

首次启动后,访问 http://<服务器地址>:7456 即可看到 Open Design 的 Web 界面。

5. Nginx 反向代理(推荐)

出于安全考虑,建议不要直接暴露 Daemon 端口,而是通过 Nginx 反代:

server {
    listen 443 ssl;
    server_name your-domain.com;

    location /api/ {
        proxy_pass http://127.0.0.1:7456;

        # SSE 必须关闭 buffering 和 gzip
        proxy_buffering off;
        gzip off;

        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

关键坑点:SSE(Server-Sent Events)路由必须关闭 nginx 的 gzipproxy_buffering,否则浏览器会在 80-90 秒后报错 ERR_INCOMPLETE_CHUNKED_ENCODING。因为 gzip 会缓冲分块的 SSE 响应,即使服务端已经发送了 X-Accel-Buffering: no

6. 运行状态验证

# 查看容器状态
docker ps --filter name=open-design

# 健康检查
curl http://127.0.0.1:7456/api/health

# 查看版本
curl http://127.0.0.1:7456/api/version

# 查看日志
docker logs open-design

五、实际体验与评价

优点

  1. 架构清晰——Daemon 做重活,前端只负责 UI,职责分离干净
  2. 不造轮子——复用已有的 16 种 Coding Agent CLI,生态兼容性强
  3. Skill / Design System 机制可扩展——丢一个新的 SKILL.md 到目录里就能用,门槛极低
  4. Docker 部署友好——多阶段构建、安全加固、健康检查一应俱全
  5. 资源占用极低——空闲时仅 18-22 MiB 内存,384MB 上限绰绰有余

值得注意的点

  1. 需要 Node 24——.nvmrc 强制要求 Node.js 24.x,这是一个较新的版本
  2. pnpm 版本锁定——packageManager 固定为 pnpm@10.33.2,版本不匹配可能出问题
  3. 无用户认证——API 对非浏览器客户端未做认证,公网部署必须加反代或鉴权
  4. Agent CLI 需要在 PATH 上——容器内默认没有安装任何 Coding Agent CLI,需要通过 BYOK API 模式使用,或自行构建包含 CLI 的自定义镜像
  5. Electron 桌面版——仅支持 macOS(Apple Silicon)和 Windows(x64),Linux 下建议用 Web 模式

六、总结

Open Design 做的事情其实可以一句话概括:把 Coding Agent CLI 变成设计引擎。

它的价值不在于创造了某个全新的技术范式,而在于做了一个很好的”编排层”——把已有的 Agent 能力、设计系统、场景模板,通过一套清晰的 Prompt 组合机制和流式 Artifact 管线串联起来,让非设计师也能产出专业级的设计稿。

对于想在自己的服务器上跑一套 AI 设计工具、又不想被单一厂商绑定的场景来说,这是一个值得关注的开源项目。


项目地址:nexu-io/open-design 在线体验:open-design.ai