SmartArchitect:AI 驱动的设计平台,让想法秒变流程图
SmartArchitect 是一个 AI 驱动的可视化架构设计平台,通过自然语言对话快速将想法转化为流程图和架构图。核心功能包括: AI 对话生成:3 秒将描述转换为流程图 双画布系统:规范图与手绘风自由切换 图片智能识别:白板照片转可编辑流程图 多格式导出:支持 PPT、Slidev 等多种格式 多 AI 集成:可选 Gemini、GPT-4 等模型 技术栈采用 Next.js + FastA
SmartArchitect:AI 驱动的设计平台,让想法秒变流程图
一个用 AI 帮你理清思路的可视化工具 - 不是画图软件,是智能架构助手
GitHub: https://github.com/luguochang/SmartArchitect ⭐
在线体验: https://smart-architect.vercel.app/
🎬 功能演示
核心功能演示

SmartArchitect 完整功能展示:从对话生成到可视化编辑
特色功能详解
🏗️ 架构图生成 智能识别系统组件,自动生成技术架构图 |
✏️ Excalidraw 集成 手绘风格白板,支持自由创作和协作 |
📸 图片智能识别 上传白板照片,AI 自动转换为可编辑流程图 |
🎨 更多功能 • 多主题切换 |
🚀 快速开始
🌟 写在前面:为什么要做这个项目?
作为一名技术人,我在日常工作中经常遇到这样的场景:
场景一:技术方案评审
领导问:“这个系统怎么设计的?”
我:“嗯…就是先调用 API,然后…那个…中间有个消息队列…”
领导:“能画个图吗?”
我:“呃…我去找个白板…”(心里想:又要花半小时画图)
场景二:业务流程讨论
产品经理:“这个功能的流程是不是这样:用户点击按钮,然后…”
开发:“不对,中间还要校验权限…”
测试:“那异常情况呢?”
大家:“…”(各说各的,理解不一致)
场景三:学习新技术
看文档:“Kafka 的消息流转过程是…”
我:(看了半天文字,还是懵)
如果有个图就好了…但懒得画…
这些场景的共同痛点是什么?
- 💭 脑子里有想法,但表达不清楚 - 技术方案在脑海里很清晰,但用语言描述总是词不达意
- 🌀 业务流程复杂,理不清头绪 - 节点太多、分支太多,自己都搞不清楚
- 🤯 团队讨论时,理解不一致 - 每个人脑补的画面不一样,争论半天才发现不在一个频道
- 📝 记了一堆笔记,事后看不懂 - 当时记得很清楚,过几天再看就像天书
- 🎨 画图工具太复杂,学习成本高 - 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 的价值:
- 快速具象化 - 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 依赖
window、document等浏览器 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 不是一个"画图工具",而是一个"思维整理助手"。
核心价值:
- ✅ 降低门槛 - 说话就能画,不用学工具
- ✅ 快速迭代 - 想法边生成边完善,暴露盲区
- ✅ 统一认知 - 团队讨论时看同一张图,理解一致
技术亮点:
- 对话式 AI 生成(18+ 模板)
- 双画布系统(React Flow + Excalidraw)
- 流式响应(SSE 实时反馈)
- JSON 容错修复(创新算法)
- 多 AI Provider 支持(Gemini/OpenAI/Claude/SiliconFlow)
适用场景:
- 产品经理理清业务流程
- 技术人员设计系统方案
- 创业者梳理商业模式
- 运营人员设计活动流程
- 学生/教师理解算法逻辑
🎁 Star 这个项目的理由
- 🎨 真正实用:解决"想法说不清"的真实痛点
- 📚 学习价值:全栈 AI 项目的最佳实践
- 🚀 持续更新:Phase 6-9 正在开发
- 🤝 开源友好:MIT License,欢迎贡献
🙏 致谢
- React Flow - 强大的节点画布
- Excalidraw - 优雅的手绘白板
- FastAPI - 现代 Python 框架
- Next.js - 优秀的 React 框架
如果 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 与你一起成长
更多推荐



所有评论(0)