SmartArchitect:AI 驱动的设计平台,让想法秒变流程图

一个用 AI 帮你理清思路的可视化工具 - 不是画图软件,是智能架构助手

GitHub: https://github.com/luguochang/SmartArchitect
在线体验: https://smart-architect.vercel.app/


🎬 功能演示

核心功能演示

在这里插入图片描述

SmartArchitect 完整功能展示:从对话生成到可视化编辑


特色功能详解

🏗️ 架构图生成

智能识别系统组件,自动生成技术架构图

✏️ Excalidraw 集成

手绘风格白板,支持自由创作和协作

📸 图片智能识别

上传白板照片,AI 自动转换为可编辑流程图

🎨 更多功能

• 多主题切换
• 代码同步编辑
• 多格式导出
• RAG 知识库


🚀 快速开始

🌟 写在前面:为什么要做这个项目?

作为一名技术人,我在日常工作中经常遇到这样的场景:

场景一:技术方案评审
领导问:“这个系统怎么设计的?”
我:“嗯…就是先调用 API,然后…那个…中间有个消息队列…”
领导:“能画个图吗?”
我:“呃…我去找个白板…”(心里想:又要花半小时画图)

场景二:业务流程讨论
产品经理:“这个功能的流程是不是这样:用户点击按钮,然后…”
开发:“不对,中间还要校验权限…”
测试:“那异常情况呢?”
大家:“…”(各说各的,理解不一致)

场景三:学习新技术
看文档:“Kafka 的消息流转过程是…”
我:(看了半天文字,还是懵)
如果有个图就好了…但懒得画…

这些场景的共同痛点是什么?

  1. 💭 脑子里有想法,但表达不清楚 - 技术方案在脑海里很清晰,但用语言描述总是词不达意
  2. 🌀 业务流程复杂,理不清头绪 - 节点太多、分支太多,自己都搞不清楚
  3. 🤯 团队讨论时,理解不一致 - 每个人脑补的画面不一样,争论半天才发现不在一个频道
  4. 📝 记了一堆笔记,事后看不懂 - 当时记得很清楚,过几天再看就像天书
  5. 🎨 画图工具太复杂,学习成本高 - ProcessOn、Visio、Axure…每个工具都要学半天

我需要的不是一个"画图工具",而是一个"智能架构助手"。

于是,SmartArchitect 诞生了:

用自然语言描述想法AI 3 秒生成流程图边看边调整思路越来越清晰

核心理念

  • 不是"画得好不好看",而是**“想得清不清楚”**
  • 不是"工具多强大",而是**“能不能快速落地想法”**
  • 不是"功能多丰富",而是**“能不能真正解决问题”**

🎯 SmartArchitect 是什么?

一句话介绍

SmartArchitect 是一个 AI 驱动的可视化架构设计平台,通过自然语言对话的方式,帮助你快速将脑海中的想法转化为清晰的流程图和架构图。

核心特性一览

特性 说明 传统工具对比
🤖 AI 对话生成 说话就能画,3 秒生成流程图 传统工具需要手动拖拽,10-30 分钟
🎨 双画布系统 Flow Canvas(规范图)+ Excalidraw(手绘风) 传统工具只有一种模式
📸 图片识别 白板照片秒变可编辑流程图 传统工具无法识别图片
🔄 代码同步 可视化 ↔ Mermaid 代码双向同步 传统工具只能手动画
🌈 12+ 主题 适配演示、开发、文档等多种场景 传统工具主题单一
📤 多格式导出 PPT、Slidev、演讲稿一键生成 传统工具导出格式有限
🔌 多 AI 集成 Gemini、GPT-4、Claude、SiliconFlow 任选 传统工具无 AI 能力
💾 增量生成 在现有架构基础上持续优化 传统工具每次从零开始

技术栈

前端 (Next.js 14 全栈)

  • ⚛️ React 19 + TypeScript 5.7
  • 🎯 React Flow 11(节点式画布)
  • ✏️ Excalidraw 0.18(手绘白板)
  • 🎨 Tailwind CSS 3.4(现代样式)
  • 📝 Monaco Editor(代码编辑器)
  • 🔄 Zustand(状态管理)

后端 (FastAPI 高性能 API)

  • 🚀 FastAPI 0.115 + Python 3.12
  • 🤖 多 AI 模型集成(Gemini/OpenAI/Claude/SiliconFlow)
  • 📊 Pydantic(数据验证)
  • 🔍 ChromaDB(向量数据库,RAG 知识库)
  • 📝 python-pptx(PPT 导出)
  • ⚡ Uvicorn(ASGI 服务器)

部署架构

  • ☁️ Vercel(前端全球 CDN)
  • 🔧 Render(后端 API 服务)
  • 🆓 完全免费部署($0/月)

🎯 真实场景:这个工具怎么帮你理清思路?

场景 1:产品经理理清业务流程

传统做法的痛点:

  • 打开 Axure/墨刀,纠结用什么形状,什么连线
  • 画了半天,发现流程不对,又要重新画
  • 花 2 小时画图,核心业务逻辑还没想清楚

用 ArchBoard 的体验:

你: "设计一个电商秒杀流程,用户点击秒杀按钮..."

AI: [3秒生成基础流程]
    用户点击 → 检查库存 → 扣减库存 → 创建订单 → 跳转支付

你: "等等,库存扣减要加锁,防止超卖"

AI: [立即调整]
    检查库存 → Redis分布式锁 → 扣减库存 → 创建订单

你: "支付失败要恢复库存"

AI: [补充异常流程]
    支付失败 → 释放锁 → 恢复库存 → 返回失败

结果:10 分钟,流程图 + 边界情况都想清楚了。


场景 2:技术人员设计系统方案

传统做法的痛点:

  • 写 Word 文档描述,干巴巴的,别人看不懂
  • 开评审会,各说各的,没有统一视图
  • 评审完了,还是不清楚怎么做

用 ArchBoard 的体验:

你: "设计一个短视频推荐系统,包含数据采集、特征提取、召回、排序"

AI: [生成初版架构]
    [数据采集] → [特征工程] → [召回服务] → [排序服务] → [用户端]

你: "召回服务拆成 3 个:热度召回、协同过滤、内容召回"

AI: [调整架构]
                    ┌─ 热度召回 ─┐
    特征工程 → ├─ 协同过滤 ─┤ → 排序融合 → 用户端
                    └─ 内容召回 ─┘

你: "加上实时数据流,用 Kafka + Flink"

AI: [补充实时链路]
    用户行为 → Kafka → Flink实时计算 → Redis → 召回服务

结果:方案清晰可见,评审时直接对着图讨论,效率提升 5 倍。


场景 3:算法学习 - 理解复杂逻辑

传统做法的痛点:

  • 看代码,一头雾水
  • 看文字描述,太抽象
  • 死记硬背,容易忘

用 ArchBoard 的体验:

你: "快速排序算法的执行流程"

AI: [生成算法流程]
    选择基准值 → 分区(小于/大于)→ 递归左右子数组 → 合并

你: "详细展示分区的过程"

AI: [展开细节]
    遍历数组 → 比较元素 → 小于基准移左 → 大于基准移右 → 交换位置

结果:算法逻辑一目了然,理解深刻。


💡 核心价值:为什么 ArchBoard 不一样?

1. 降低门槛 - 说话就能画,不用学工具

传统画图工具

  • 学习成本高:要记住快捷键、形状库、连线方式
  • 操作繁琐:拖形状 → 对齐 → 连线 → 调整位置 → 美化
  • 思维中断:本来想的是业务逻辑,结果被工具打断

ArchBoard

  • 零学习成本:会打字就会用
  • 对话式交互:像和朋友聊天一样描述想法
  • 专注思考:AI 负责画,你负责想

技术实现

// 前端:用户输入自然语言
const userInput = "设计一个用户注册流程,包含手机验证码";

// 后端:AI 理解意图并生成结构化数据
const response = await fetch('/api/chat-generator/generate', {
  method: 'POST',
  body: JSON.stringify({
    user_input: userInput,
    diagram_type: "flow",  // 流程图类型
    provider: "gemini"      // 使用 Gemini AI
  })
});

// 返回:节点和边的数据结构
{
  "nodes": [
    { "id": "1", "label": "进入注册页", "type": "start-event" },
    { "id": "2", "label": "输入手机号", "type": "task" },
    { "id": "3", "label": "发送验证码", "type": "task" },
    { "id": "4", "label": "验证通过", "type": "decision" },
    { "id": "5", "label": "创建账号", "type": "task" },
    { "id": "6", "label": "注册成功", "type": "end-event" }
  ],
  "edges": [
    { "source": "1", "target": "2" },
    { "source": "2", "target": "3" },
    ...
  ]
}

2. 快速迭代 - 想法边生成边完善

关键洞察

很多时候,我们说不清想法,不是因为表达能力差,而是想法本身还不够清晰

ArchBoard 的价值

  1. 快速具象化 - 3 分钟把模糊想法变成图
  2. 暴露盲区 - 看到流程图后发现:这里没考虑到,那里有问题
  3. 持续优化 - 对话式调整,想法越来越完善

迭代策略

第 1 轮:快速生成基础版
"画一个用户登录流程"

第 2 轮:补充核心逻辑
"加上手机验证码登录"

第 3 轮:完善异常处理
"验证码输错 3 次锁定账号"

第 4 轮:优化体验细节
"添加自动登录(记住密码 7 天)"

第 5 轮:美化布局
"把节点对齐一下,布局更清晰"

技术实现 - 流式响应

# backend/app/api/chat_generator.py
@router.post("/chat-generator/generate-stream")
async def generate_stream(request: ChatGenerationRequest):
    """流式生成,实时反馈进度"""
    async def event_stream():
        # 1. 告知开始
        yield "data: [START] 开始生成流程图...\n\n"

        # 2. 调用 AI
        yield "data: [CALL] 正在调用 AI 分析...\n\n"

        # 3. 流式返回 Token
        async for token in service.generate_with_streaming(request.user_input):
            yield f"data: [TOKEN] {token}\n\n"

        # 4. 完成
        yield "data: [END] 生成完成\n\n"

    return StreamingResponse(event_stream(), media_type="text/event-stream")

前端接收流式数据

const response = await fetch('/api/chat-generator/generate-stream', {
  method: 'POST',
  body: JSON.stringify({ user_input })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  // 解析 SSE 格式:data: [STATUS] message

  // 实时显示进度
  setProgress(message);
}

用户体验

  • 不是干等,而是看到 AI 一步步生成
  • 像看别人思考的过程,更有参与感

3. 双画布系统 - 规范图 + 自由画

Flow Canvas - 结构化流程图

基于 React Flow(节点式画布),带来革命性体验:

🔗 真正的节点互联

  • 传统工具:拖方框 + 画线,只是"画"在一起,没有关联
  • ArchBoard:拖拽节点时连线自动跟随,删除节点时相关连线自动清理
  • 结果:流程图始终保持一致性

技术实现

// frontend/components/ArchitectCanvas.tsx
import ReactFlow, {
  Node,
  Edge,
  applyNodeChanges,
  applyEdgeChanges
} from 'reactflow';

const ArchitectCanvas = () => {
  const [nodes, setNodes] = useState<Node[]>([]);
  const [edges, setEdges] = useState<Edge[]>([]);

  // 节点变化时自动更新连线
  const onNodesChange = useCallback((changes) => {
    setNodes((nds) => applyNodeChanges(changes, nds));

    // 同步到 Mermaid 代码
    updateMermaidCode(nodes, edges);
  }, []);

  // 连线变化时自动验证
  const onEdgesChange = useCallback((changes) => {
    setEdges((eds) => applyEdgeChanges(changes, eds));
  }, []);

  return (
    <ReactFlow
      nodes={nodes}
      edges={edges}
      onNodesChange={onNodesChange}
      onEdgesChange={onEdgesChange}
      fitView
    />
  );
};

⚡ 实时响应式更新

  • 传统工具:修改位置后需要手动调整每条线
  • ArchBoard:基于 React 虚拟 DOM,节点移动时连线自动重绘
  • 结果:随意调整布局,图不会乱

🎯 程序化控制能力

  • 传统工具:每个元素都是独立的"画出来的形状"
  • ArchBoard:节点和连线是可编程的数据结构
  • 结果:流程图可以像代码一样管理,支持 Git 版本控制

代码 ↔ 可视化双向同步

// Mermaid 代码 → 流程图
const updateFromMermaid = async (code: string) => {
  // 调用后端解析 Mermaid
  const response = await fetch('/api/mermaid/parse', {
    method: 'POST',
    body: JSON.stringify({ code })
  });

  const { nodes, edges } = await response.json();

  // 更新画布
  setNodes(nodes);
  setEdges(edges);

  // 自动布局
  const layouted = getLayoutedElements(nodes, edges, 'TB');
  setNodes(layouted.nodes);
  setEdges(layouted.edges);
};

// 流程图 → Mermaid 代码
const updateFromCanvas = async (nodes, edges) => {
  const response = await fetch('/api/graph/to-mermaid', {
    method: 'POST',
    body: JSON.stringify({ nodes, edges })
  });

  const { code } = await response.json();

  // 更新代码编辑器
  setMermaidCode(code);
};

🚀 性能优化

  • 传统工具:元素多了就卡(全量渲染)
  • ArchBoard:虚拟化技术,只渲染可视区域
  • 结果:即使 100+ 节点,依然流畅
Excalidraw - 手绘风白板

适合头脑风暴、Workshop、快速草图:

技术难点 - SSR 适配

// Excalidraw 依赖浏览器 API,Next.js SSR 会报错
// 解决方案:动态导入 + 禁用 SSR

import dynamic from 'next/dynamic';

const Excalidraw = dynamic(
  async () => (await import("@excalidraw/excalidraw")).Excalidraw,
  {
    ssr: false,  // 关键:禁用服务器端渲染
    loading: () => <div>Loading Excalidraw...</div>
  }
);

export function ExcalidrawBoard() {
  const [mounted, setMounted] = useState(false);

  // 确保只在客户端渲染
  useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) {
    return <div>Loading...</div>;
  }

  return (
    <div style={{ height: "100vh" }}>
      <Excalidraw />
    </div>
  );
}

AI 生成 Excalidraw 场景

# backend/app/api/excalidraw.py
@router.post("/excalidraw/generate")
async def generate_excalidraw_scene(request: ExcalidrawGenerateRequest):
    """AI 生成 Excalidraw 场景"""

    # 构造 Prompt
    prompt = f"""
    根据以下描述生成 Excalidraw 场景的 JSON 格式:

    用户描述:{request.prompt}

    要求:
    1. 返回包含 elements 数组的 JSON
    2. 每个元素包含 id, type, x, y, width, height 等属性
    3. type 可以是: rectangle, ellipse, arrow, text 等
    4. 确保 JSON 格式正确(重要!)
    """

    # 调用 AI
    service = create_excalidraw_service()
    scene = await service.generate_scene(
        prompt=request.prompt,
        provider=request.provider,
        width=request.width,
        height=request.height
    )

    return ExcalidrawGenerateResponse(scene=scene, success=True)

创新点 - JSON 修复机制

问题:AI 生成的 JSON 可能不完整(网络中断、Token 限制)

{
  "elements": [
    {"id": "1", "type": "rectangle", "x": 100, "y": 100
  // 后续被截断

解决方案:追踪括号栈,自动闭合

# backend/app/services/excalidraw_generator.py
def repair_json(json_str: str) -> str:
    """自动修复不完整的 JSON"""
    stack = []
    is_string = False
    is_escaped = False

    for char in json_str:
        if is_string:
            if char == '\\':
                is_escaped = not is_escaped
            elif char == '"' and not is_escaped:
                is_string = False
            else:
                is_escaped = False
        else:
            if char == '"':
                is_string = True
            elif char == '{':
                stack.append('}')
            elif char == '[':
                stack.append(']')
            elif char == '}':
                if stack and stack[-1] == '}':
                    stack.pop()
            elif char == ']':
                if stack and stack[-1] == ']':
                    stack.pop()

    # 补全缺失的闭合符号
    completion = ""
    while stack:
        completion += stack.pop()

    return json_str + completion

测试用例

# 测试 1: 缺少对象闭合
input1 = '{"name": "test", "items": [1, 2, 3'
output1 = repair_json(input1)
# 输出: {"name": "test", "items": [1, 2, 3]}

# 测试 2: 嵌套结构不完整
input2 = '{"data": {"nested": {"value": 123'
output2 = repair_json(input2)
# 输出: {"data": {"nested": {"value": 123}}}

容错机制 - 自动降级

# AI 生成失败时,自动返回 Mock 场景
try:
    scene = await service.generate_scene(prompt, ...)
except Exception as e:
    logger.error(f"AI generation failed: {e}")

    # 返回预设的示例场景
    mock_scene = service._mock_scene()

    return ExcalidrawGenerateResponse(
        scene=mock_scene,
        success=False,
        message=f"Using mock fallback: {str(e)}"
    )

4. 多 AI Provider 支持 - 灵活切换

支持的 AI 模型

  • Google Gemini(推荐)- 免费额度大,速度快
  • OpenAI GPT-4 - 理解最准确,适合复杂场景
  • Claude 3.5 - 逻辑最清晰,适合技术方案
  • SiliconFlow - 国内访问快,无需梯子
  • 自定义模型 - 接入你自己的 API

统一抽象层

# backend/app/services/ai_vision.py
class AIVisionService:
    def __init__(self, provider: str, api_key: str, model_name: str):
        self.provider = provider
        self.api_key = api_key
        self.model_name = model_name

    async def analyze_image(self, image_data: str, prompt: str):
        """统一接口,内部根据 provider 分发"""
        if self.provider == "gemini":
            return await self._call_gemini(image_data, prompt)
        elif self.provider == "openai":
            return await self._call_openai(image_data, prompt)
        elif self.provider == "claude":
            return await self._call_claude(image_data, prompt)
        elif self.provider == "siliconflow":
            return await self._call_siliconflow(image_data, prompt)
        elif self.provider == "custom":
            return await self._call_custom(image_data, prompt)

    async def _call_gemini(self, image_data, prompt):
        """调用 Gemini API"""
        client = genai.GenerativeModel(self.model_name)

        # 处理图片
        image = self._decode_image(image_data)

        # 调用 API
        response = await client.generate_content([prompt, image])

        return response.text

    async def _call_openai(self, image_data, prompt):
        """调用 OpenAI Vision API"""
        client = openai.AsyncOpenAI(api_key=self.api_key)

        response = await client.chat.completions.create(
            model=self.model_name,
            messages=[{
                "role": "user",
                "content": [
                    {"type": "text", "text": prompt},
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": f"data:image/jpeg;base64,{image_data}"
                        }
                    }
                ]
            }]
        )

        return response.choices[0].message.content

特殊适配 - ikuncode.cc 中转站

问题:某些中转服务阻止 SDK 请求(403 Forbidden)

解决方案:检测到中转站时使用原始 HTTP 请求

# backend/app/services/chat_generator.py
async def _call_claude_with_custom_base(self, prompt: str, base_url: str):
    """绕过 SDK 限制,直接使用 HTTP"""

    # 检测中转站
    if "ikuncode.cc" in base_url.lower():
        logger.info("Detected ikuncode.cc, using raw HTTP")

        headers = {
            "x-api-key": self.api_key,
            "anthropic-version": "2023-06-01",
            "content-type": "application/json"
        }

        payload = {
            "model": self.model_name,
            "max_tokens": 4096,
            "messages": [{"role": "user", "content": prompt}],
            "stream": True
        }

        # 使用 httpx 直接请求
        async with httpx.AsyncClient(timeout=120.0) as client:
            async with client.stream("POST", f"{base_url}/messages",
                                    headers=headers, json=payload) as response:
                response.raise_for_status()

                buffer = ""
                async for chunk in response.aiter_bytes():
                    text = chunk.decode('utf-8')
                    for line in text.split('\n'):
                        if line.startswith('data: '):
                            data = json.loads(line[6:])
                            if data['type'] == 'content_block_delta':
                                buffer += data['delta']['text']

                return buffer
    else:
        # 使用官方 SDK
        client = anthropic.AsyncAnthropic(
            api_key=self.api_key,
            base_url=base_url
        )
        response = await client.messages.create(...)
        return response.content[0].text

兼容的中转站

  • ikuncode.cc
  • api2d.com
  • closeai.biz
  • 自定义 API 端点

🛠️ 技术架构详解

整体架构

┌─────────────────────────────────────────────────────────────┐
│                     Frontend (Next.js 14)                    │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │ React Flow   │  │ Excalidraw   │  │ Monaco Editor│      │
│  │   Canvas     │  │   Canvas     │  │  (Mermaid)   │      │
│  └──────────────┘  └──────────────┘  └──────────────┘      │
│         ↓                  ↓                  ↓              │
│  ┌─────────────────────────────────────────────────┐        │
│  │         Zustand State Management                │        │
│  └─────────────────────────────────────────────────┘        │
└─────────────────────────────────────────────────────────────┘
                              ↕ REST API / SSE
┌─────────────────────────────────────────────────────────────┐
│                     Backend (FastAPI)                        │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐   │
│  │ Vision   │  │   Chat   │  │ Mermaid  │  │ Excalidraw│   │
│  │ Service  │  │Generator │  │  Parser  │  │ Generator │   │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘   │
│         ↓             ↓             ↓             ↓         │
│  ┌─────────────────────────────────────────────────┐       │
│  │        Multi-Provider AI Abstraction Layer      │       │
│  │   (Gemini / OpenAI / Claude / SiliconFlow)      │       │
│  └─────────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────────┘

技术栈

前端

  • Next.js 14 (App Router) + React 19
  • React Flow 11(流程图画布)
  • Excalidraw 0.18(手绘白板)
  • Monaco Editor(代码编辑器)
  • Zustand 4.5(状态管理)
  • Tailwind CSS 3.4(样式)
  • Lucide Icons(图标库)

后端

  • FastAPI 0.115(Python 框架)
  • Pydantic(数据验证)
  • Uvicorn(ASGI 服务器)
  • httpx(异步 HTTP 客户端)

AI 集成

  • Google Generative AI SDK
  • OpenAI Python SDK
  • Anthropic Claude SDK
  • 自定义 HTTP 适配器

🐛 开发过程中遇到的难题与解决方案

难题 1:React Flow 圆形节点被方框包围

问题现象

  • BPMN 的 start-event(圆形)节点外面有方形容器
  • 即使设置 border-radius: 50%,外层仍是方形

原因:React Flow 的默认样式

.react-flow__node {
  border: 2px solid #1a192b;
  background: white;
  padding: 10px;
  border-radius: 3px;
}

解决方案:CSS 覆盖 + 玻璃形态学设计

/* frontend/globals.css */

/* 1. 让节点容器完全透明 */
.react-flow__node {
  border: none !important;
  background: transparent !important;
  padding: 0 !important;
}

/* 2. 圆形节点特殊处理 */
.react-flow__node:has(.glass-node.rounded-full) {
  border-radius: 9999px !important;
  box-shadow: none !important;
  background: transparent !important;
}

/* 3. 玻璃态效果 */
.glass-node {
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.3);
}

.glass-node.rounded-full {
  width: 60px;
  height: 60px;
  border-radius: 50%;
}

效果:现代化的玻璃形态学设计,美观且专业。


难题 2:Mermaid 代码与画布循环更新

问题

  • Monaco Editor 修改代码 → 画布更新 → 触发代码更新 → 无限循环

解决方案:使用 useRef 追踪更新状态

const isUpdatingFromCode = useRef(false);
const isUpdatingFromCanvas = useRef(false);

// 从代码更新画布
const syncToCanvas = async (code: string) => {
  if (isUpdatingFromCanvas.current) return;  // 防止循环

  isUpdatingFromCode.current = true;

  // 调用后端解析
  const { nodes, edges } = await parseMermaid(code);

  // 更新画布
  setNodes(nodes);
  setEdges(edges);

  setTimeout(() => {
    isUpdatingFromCode.current = false;
  }, 100);
};

// 从画布更新代码
const syncToMermaid = async (nodes, edges) => {
  if (isUpdatingFromCode.current) return;  // 防止循环

  isUpdatingFromCanvas.current = true;

  // 调用后端生成代码
  const { code } = await generateMermaid(nodes, edges);

  // 更新编辑器
  setMermaidCode(code);

  setTimeout(() => {
    isUpdatingFromCanvas.current = false;
  }, 100);
};

关键:使用 100ms 延迟确保状态更新完成。


难题 3:Excalidraw SSR 报错

错误信息

Error: Hydration failed because the initial UI does not match what was rendered on the server.

原因

  • Excalidraw 依赖 windowdocument 等浏览器 API
  • Next.js SSR 阶段这些 API 不存在

解决方案:动态导入 + 禁用 SSR

import dynamic from 'next/dynamic';

const Excalidraw = dynamic(
  async () => (await import("@excalidraw/excalidraw")).Excalidraw,
  { ssr: false }  // 关键
);

export function ExcalidrawBoard() {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) return <div>Loading...</div>;

  return <Excalidraw />;
}

难题 4:AI 返回的 JSON 格式不正确

问题

  • 网络中断、Token 限制导致 JSON 不完整
  • 直接 JSON.parse() 会报错

示例

{
  "elements": [
    {"id": "1", "type": "rectangle"
  // 后续被截断

解决方案:JSON 修复算法

def repair_json(json_str: str) -> str:
    stack = []
    is_string = False

    for char in json_str:
        if char == '"' and not is_string:
            is_string = True
        elif char == '"' and is_string:
            is_string = False
        elif not is_string:
            if char == '{':
                stack.append('}')
            elif char == '[':
                stack.append(']')
            elif char in ('}', ']'):
                if stack and stack[-1] == char:
                    stack.pop()

    # 补全缺失的括号
    completion = ""
    while stack:
        completion += stack.pop()

    return json_str + completion

应用

try:
    data = json.loads(ai_response)
except json.JSONDecodeError:
    # 尝试修复
    repaired = repair_json(ai_response)
    data = json.loads(repaired)

🚀 性能优化实战

优化 1:React Flow 渲染性能

问题:节点数超过 50 个时拖拽卡顿

优化方案

// 1. React.memo 避免不必要的重渲染
export const ApiNode = memo(({ data }: NodeProps) => {
  return (
    <div className="glass-node">
      <Globe size={24} />
      <div>{data.label}</div>
    </div>
  );
});

// 2. 节流更新
const onNodesChange = useCallback(
  throttle((changes: NodeChange[]) => {
    setNodes((nds) => applyNodeChanges(changes, nds));
  }, 16),  // ~60fps
  []
);

// 3. 虚拟化(超过 100 个节点)
<ReactFlow
  nodes={nodes}
  edges={edges}
  nodesDraggable={nodes.length < 100}
  zoomOnScroll={nodes.length < 100}
/>

效果

  • 50 个节点: 60fps(无明显提升)
  • 100 个节点: 20fps → 45fps
  • 200 个节点: 5fps → 30fps

优化 2:AI 请求缓存

问题:多次请求相同内容浪费 API 额度

解决方案:LRU 缓存

import hashlib

class AIVisionService:
    def __init__(self):
        self.cache = {}  # {hash: result}

    async def analyze_image(self, image_data: str, prompt: str):
        # 生成缓存 key
        cache_key = hashlib.md5(
            (image_data[:100] + prompt).encode()
        ).hexdigest()

        # 检查缓存
        if cache_key in self.cache:
            logger.info(f"Cache hit: {cache_key}")
            return self.cache[cache_key]

        # 调用 AI
        result = await self._call_ai(image_data, prompt)

        # 存入缓存(最多 100 个)
        if len(self.cache) > 100:
            self.cache.pop(next(iter(self.cache)))

        self.cache[cache_key] = result
        return result

优化 3:前端资源优化

优化前

  • 首屏加载: 3.2s
  • 主包大小: 2.5MB

优化措施

// 1. 动态导入(代码分割)
const ExcalidrawBoard = dynamic(() => import('./ExcalidrawBoard'), {
  ssr: false,
  loading: () => <Skeleton />
});

// 2. 图片懒加载
<Image
  src="/logo.png"
  alt="Logo"
  loading="lazy"
  placeholder="blur"
/>

// 3. 字体优化
// next.config.js
module.exports = {
  optimizeFonts: true,
  images: {
    formats: ['image/avif', 'image/webp']
  }
}

优化后

  • 首屏加载: 1.8s(↓ 44%)
  • 主包大小: 1.2MB(↓ 52%)
  • Lighthouse 得分: 78 → 92

📈 未来规划

Phase 6: 协作功能

  • 实时多人编辑(WebSocket + CRDT)
  • 评论与批注系统
  • 版本历史与回滚

Phase 7: AI 能力增强

  • 流程优化建议(AI 指出问题)
  • 自动补全缺失步骤
  • 风险点提示

Phase 8: 知识库

  • 保存常用模板
  • 团队模板库
  • 智能推荐相似流程

Phase 9: 导出增强

  • 高清 PNG/SVG
  • PDF 多页导出
  • PowerPoint 演示文稿

🌟 总结

ArchBoard 不是一个"画图工具",而是一个"思维整理助手"。

核心价值

  1. 降低门槛 - 说话就能画,不用学工具
  2. 快速迭代 - 想法边生成边完善,暴露盲区
  3. 统一认知 - 团队讨论时看同一张图,理解一致

技术亮点

  1. 对话式 AI 生成(18+ 模板)
  2. 双画布系统(React Flow + Excalidraw)
  3. 流式响应(SSE 实时反馈)
  4. JSON 容错修复(创新算法)
  5. 多 AI Provider 支持(Gemini/OpenAI/Claude/SiliconFlow)

适用场景

  • 产品经理理清业务流程
  • 技术人员设计系统方案
  • 创业者梳理商业模式
  • 运营人员设计活动流程
  • 学生/教师理解算法逻辑

🎁 Star 这个项目的理由

  • 🎨 真正实用:解决"想法说不清"的真实痛点
  • 📚 学习价值:全栈 AI 项目的最佳实践
  • 🚀 持续更新:Phase 6-9 正在开发
  • 🤝 开源友好:MIT License,欢迎贡献

🙏 致谢


如果 ArchBoard 帮你理清了思路,请给个 ⭐ Star 支持一下!

# 克隆项目
git clone https://github.com/luguochang/SmartArchitect.git

# 启动(一键脚本)
cd ArchBoard
./start-dev.sh  # Linux/Mac
start-dev.bat   # Windows

# 访问应用
http://localhost:3000

让想法清晰,让沟通高效 - ArchBoard 与你一起成长

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐