Sim Studio:开源 AI Agent 工作流编排平台深度解析
posts posts 2026-05-01T20:07:04+08:00深入解析 Sim Studio 开源 AI Agent 工作流编排平台的架构设计,包括可视化编辑器原理、块扩展体系、执行引擎、Copilot 辅助功能与部署方式。技术笔记AI Agent, 工作流编排, ReactFlow, Next.js, Bun目标读者:已掌握 AI Agent 基础概念,想深入理解 AI Agent 工作流编排系统的开发者与架构师 核心问题:Sim 的架构设计是如何解决 AI Agent 编排中的核心挑战的?它的可视化编辑、跨服务集成与工作流执行引擎是如何协同工作的? 预计阅读时间:25–35 分钟
🎯 本节目标
完成本指南后,你将能够:
- 理解 Sim 作为 AI Agent 工作流编排平台的定位与架构设计
- 掌握 Sim 的可视化 Workflow Editor 核心原理(ReactFlow + 节点体系)
- 理解 Sim 的工具 / 块(Block)扩展体系与注册机制
- 了解工作流执行引擎(Executor)的设计思路
- 理解 Sim 如何通过 Copilot 将自然语言转换为工作流节点
- 独立完成 Sim 的本地部署与基础扩展开发
1. 背景与问题动机
构建一个可投入生产的 AI Agent 系统,远比"让大模型调用一次工具"复杂。真实场景需要:
- 多步骤编排:一个任务可能需要串行或并行执行多个 Agent,每个 Agent 调用不同的工具,结果影响后续节点的选择
- 状态管理:工作流中途可能需要暂停、恢复、或分支处理;每个块(Block)的输入输出需要被正确追踪
- 服务集成:Agent 需要与外部系统(Slack、Github、数据库、向量库)交互,这些集成需要统一的管理方式
- 可视化调试:非技术用户也需要理解、修改、共享工作流定义
- 安全隔离:Agent 执行的代码需要在隔离环境中运行,防止恶意操作影响宿主系统
用代码手写这些逻辑并非不可行,但维护成本极高,且难以可视化。用市面上的低代码平台,又往往缺乏 AI 原生支持,无法处理 LLM 调用、Prompt 链、工具调用等 AI 特有逻辑。
Sim 正是在这个交叉点上诞生:它是一个专为 AI Agent 工作流设计的开源可视化编排平台,让开发者既能通过图形界面快速构建工作流,又能通过代码深度定制每个节点的行为。
2. 整体架构概览
Sim 采用 Turborepo Monorepo 结构,代码分布在 apps/ 和 packages/ 两类包中:
apps/
├── sim/ # Next.js 主应用(前端 + API Routes + Workflow Editor)
└── realtime/ # Bun + Socket.IO 协作实时服务(多人同时编辑画布)
packages/
├── db/ # Drizzle ORM schema + PostgreSQL client(含 pgvector)
├── auth/ # Better Auth 共享认证模块
├── workflow-types/ # 纯类型定义(BlockState、Loop、Parallel 等)
├── workflow-persistence/ # 工作流加载 / 保存逻辑与子流程辅助函数
├── workflow-authz/ # 工作流权限验证(按 Workspace 级别)
├── executor/ # (位于 apps/sim/src/executor/)工作流执行引擎
├── tools/ # 工具定义与注册表
├── blocks/ # 块定义与注册表
├── providers/ # LLM Provider 集成
├── triggers/ # 触发器定义(定时、Webhook 等)
├── ts-sdk/ # TypeScript SDK,供外部程序调用 Sim API
├── python-sdk/ # Python SDK
├── realtime-protocol/ # Socket.IO 操作常量 + Zod schema
├── audit/ # 审计日志(recordAudit + AuditAction + AuditResourceType)
├── logger/ # 结构化日志(基于 createLogger)
├── security/ # 安全工具(safeCompare 等)
└── utils/ # 通用工具函数(ID 生成、sleep、错误处理等)2.1 架构设计原则
从 AGENTS.md 和 CLAUDE.md 中可以提炼出几条核心架构原则:
1. 依赖单向,禁止逆向
apps/* → packages/* 是单向的。packages/ 内部的包不得导入 apps/ 中的任何模块。这确保了核心业务逻辑的复用性,也使得包可以独立测试。
2. 关注点分离
apps/sim(Next.js)负责 UI、API Routes 和工作流编辑器的渲染;apps/realtime(Bun + Socket.IO)专门处理多人实时协作。两者之间通过共享的 workflow-types 和 realtime-protocol 包解耦。
3. 类型安全优先
整个代码库禁止使用 any。所有组件 Props、Store 状态、API 请求/响应都必须有明确的 TypeScript 接口。
4. 状态分层
- Zustand:全局 UI 状态(如工作流画布的当前选中节点、侧边栏展开状态)
- TanStack Query:服务端状态(工作流列表、用户信息、工具配置等)
useState:仅限组件内 UI 状态,不参与数据获取
3. 可视化 Workflow Editor:节点体系与扩展机制
Sim 的前端核心是一个基于 ReactFlow 的可视化工作流编辑器。用户通过拖拽节点(Block)、连接边(Edge)、配置参数来定义工作流。
3.1 块(Block)的三层结构
Sim 的节点扩展体系遵循一条严格路径:Tool → Block → Icon → (Trigger)。每一种外部服务接入 Sim,都需要依次完成这三层。
第一层:工具(Tool)
工具定义位于 apps/sim/src/tools/{service}/,每个服务一个目录:
tools/{service}/
├── index.ts # 统一导出
├── types.ts # 参数与响应类型
└── {action}.ts # 具体动作实现工具的结构化描述(以 ToolConfig<Params, Response> 为泛型)如下:
export const serviceTool: ToolConfig<Params, Response> = {
id: 'service_action',
name: 'Service Action',
description: '...',
version: '1.0.0',
oauth: { required: true, provider: 'service' },
params: { /* Zod schema */ },
request: { url: '/api/tools/service/action', method: 'POST', ... },
transformResponse: async (response) => { /* 标准化输出 */ },
outputs: { /* 定义输出字段 */ },
}所有工具在 tools/registry.ts 中注册。注册后即可被 Block 引用。
第二层:块(Block)
块是工作流编辑器中的视觉节点,定义在 apps/sim/src/blocks/blocks/{service}.ts。块引用工具并将工具参数映射为可视化配置表单:
export const ServiceBlock: BlockConfig = {
type: 'service',
name: 'Service',
description: '...',
category: 'tools', // 分类:agents / tools / logic / triggers
bgColor: '#hexcolor',
icon: ServiceIcon,
subBlocks: [
// 每个 subBlock 对应表单中的一个输入字段
{
id: 'field',
title: 'Label',
type: 'short-input', // short-input / file-upload / credential-select / ...
placeholder: '...',
required: true,
condition: { field: 'op', value: 'send' }, // 条件显示
dependsOn: ['credential'], // 依赖字段变化时清空
mode: 'basic', // basic | advanced | both | trigger
},
],
tools: {
access: ['service_action'], // 引用已注册的工具
config: {
tool: (p) => `service_${p.operation}`, // 动态工具名(序列化阶段执行)
params: (p) => ({ /* 类型转换在这里做 */ }), // 执行阶段参数
},
},
inputs: { /* ... */ },
outputs: { /* ... */ },
}关键设计细节:tools.config.tool 在序列化阶段执行(变量引用 <Block.output> 尚未解析),因此绝对不能在此处做类型转换(如 Number()),否则动态引用会被破坏。真正的类型转换放在 tools.config.params 中——它在执行阶段运行,此时变量已解析完毕。
块在 blocks/registry.ts 中按字母顺序注册。
第三层:图标(Icon)
图标定义在 apps/sim/src/components/icons.tsx,使用 SVG 组件形式:
export function ServiceIcon(props: SVGProps<SVGSVGElement>) {
return <svg {...props}>/* SVG from brand assets */</svg>
}3.2 表单条件逻辑
块的 subBlocks 支持复杂的条件显示逻辑:
// 单值匹配
condition: { field: 'op', value: 'send' }
// 多值匹配(OR)
condition: { field: 'op', value: ['send', 'reply'] }
// 取反
condition: { field: 'op', value: 'x', not: true }
// 复合条件
condition: {
field: 'op', value: 'x', not: true,
and: { field: 'type', value: 'dm', not: true }
}dependsOn 支持单字段或复合依赖:
dependsOn: ['credential'] // 单字段
dependsOn: { all: ['a'], any: ['b', 'c'] } // 复合依赖
3.3 多人实时协作
画布的实时协作由 apps/realtime(Bun + Socket.IO)处理。这个服务刻意不使用 Next.js、React、块 / 工具注册表、Provider SDK 或执行器——CI 通过 scripts/check-realtime-prune-graph.ts 强制执行这一边界。
packages/realtime-protocol 定义了 Socket.IO 操作常量与 Zod schema,确保前端编辑器与实时服务之间的通信格式统一。
4. 工作流执行引擎(Executor)
当工作流定义好后,执行引擎负责沿着节点图遍历、解析变量引用、调用工具、处理条件分支与循环。
4.1 类型系统
packages/workflow-types 定义了纯类型,包括:
BlockState:单个块的状态(输入、输出、错误信息)Loop:循环结构(items、iterator、maxIterations)Parallel:并行分支结构(branches、strategy: ‘all’ | ‘any’)- 等等
这些类型不包含任何运行时逻辑,可以在 executor 之外的其他包(如 persistence、authz)安全引用。
4.2 持久化与加载
packages/workflow-persistence 处理工作流的原始加载与保存。加载后的工作流图由 executor 遍历执行。
4.3 权限验证
packages/workflow-authz 提供 authorizeWorkflowByWorkspacePermission 函数,在执行工作流前验证调用者是否有权限访问对应的工作空间。
4.4 代码执行隔离
Sim 支持两种代码执行模式:
- 远程执行(E2B):将用户代码发送到云端的隔离沙箱执行,适用于需要较强算力的场景
- 本地隔离执行(isolated-vm):使用
isolated-vm库在 Node.js 进程内创建 V8 隔离环境,适用于轻量级代码片段
两种模式都保证用户代码不会直接影响宿主进程。
5. Copilot:从自然语言到工作流节点
Copilot 是 Sim 的 AI 辅助功能,它能将用户的自然语言描述转换为工作流节点配置。这个功能由 Sim 官方托管服务提供(https://sim.ai 上的 Copilot API Key)。
对于自托管实例,使用 Copilot 需要:
- 在
https://sim.ai → Settings → Copilot生成一个 Copilot API Key - 将其设置为自托管环境变量
COPILOT_API_KEY
Copilot 的实现深度依赖于工作流类型系统(workflow-types)和块注册体系——它需要理解有哪些节点类型、每个节点的参数结构,才能准确地将自然语言映射为配置。
6. 向量知识库与 RAG
Sim 原生支持向量数据库集成。用户可以上传文档到向量库,Agent 在执行工作流时可以基于检索增强生成(RAG)模式,从私有内容中获取答案。
这使得 Sim 适合构建需要结合企业私有知识的工作流应用,例如客服机器人、内部知识问答系统等。
7. 技术栈总结
| 层级 | 技术选型 | 作用 |
|---|---|---|
| 前端框架 | Next.js(App Router) | 主应用、API Routes、页面渲染 |
| 运行时 | Bun | 比 Node.js 更快的包管理与执行 |
| 数据库 | PostgreSQL + Drizzle ORM + pgvector | 结构化存储 + 向量检索 |
| 认证 | Better Auth | 跨服务的统一认证方案 |
| UI 组件 | Shadcn + Tailwind CSS | 一致的设计语言 |
| 状态管理 | Zustand + TanStack Query | 全局 UI 状态 + 服务端数据获取 |
| 可视化编辑器 | ReactFlow | 工作流画布渲染 |
| 流式渲染 | Streamdown | Markdown 流式输出(AI 生成内容) |
| 实时协作 | Socket.IO(Bun) | 多人同时编辑画布 |
| 后台任务 | Trigger.dev | 定时任务、工作流异步步骤 |
| 代码执行 | E2B(远程沙箱)+ isolated-vm(本地隔离) | 安全地运行用户代码 |
| 文档 | Fumadocs | 技术文档站 |
| Monorepo | Turborepo | 构建缓存与任务编排 |
8. 部署方式详解
8.1 最快方式:npx 一键启动
npx simstudio
# 访问 http://localhost:3000背后执行的是 Docker 拉取与启动(需要 Docker 已运行)。
8.2 Docker Compose 生产部署
git clone https://github.com/simstudioai/sim.git && cd sim
docker compose -f docker-compose.prod.yml up -d支持本地模型(Ollama / vLLM),使用 docker-compose.ollama.yml 并加上 --profile setup。
8.3 手动开发部署
前置:Node.js v20+、Bun、PostgreSQL 12+(已安装 pgvector)
# 1. 安装依赖
git clone https://github.com/simstudioai/sim.git && cd sim
bun install
# 2. 配置环境变量
cp apps/sim/.env.example apps/sim/.env
# 生成加密密钥(三个随机密钥替换占位符)
perl -i -pe "s/your_encryption_key/$(openssl rand -hex 32)/" apps/sim/.env
perl -i -pe "s/your_internal_api_secret/$(openssl rand -hex 32)/" apps/sim/.env
perl -i -pe "s/your_api_encryption_key/$(openssl rand -hex 32)/" apps/sim/.env
# 3. 启动数据库
docker run --name simstudio-db \
-e POSTGRES_PASSWORD=your_password \
-e POSTGRES_DB=simstudio \
-p 5432:5432 -d pgvector/pgvector:pg17
# 4. 运行数据库迁移
cd packages/db && bun run db:migrate
# 5. 启动开发服务
bun run dev:full
# 等价于分别运行:bun run dev(Next.js)+ cd apps/sim && bun run dev:sockets(实时服务)9. 扩展开发示例:添加一个新的服务集成
假设我们要为 Notion 添加一个集成。需要依次完成:
步骤 1:创建工具
在 tools/notion/ 下创建文件,定义 notion_tool 的参数 schema 与请求逻辑。
步骤 2:注册工具
在 tools/registry.ts 中导入并注册该工具。
步骤 3:添加图标
在 components/icons.tsx 中添加 NotionIcon SVG 组件。
步骤 4:创建块
在 blocks/blocks/notion.ts 中定义块配置,引用 notion_tool,定义表单字段(SubBlocks)。
步骤 5:注册块
在 blocks/registry.ts 中按字母顺序插入该块。
步骤 6(可选):创建触发器
如果 Notion 有 webhook 事件,则在 triggers/notion/ 下创建触发器,并在 triggers/registry.ts 中注册。
10. 设计原则与经验总结
从 Sim 的架构中可以提炼出以下可复用的设计经验:
1. 工具 → 块 → 图标 → 触发器的线性扩展路径 这种流程强制每引入一个新服务时都走完完整的链路,确保一致性和可发现性。不会发生"块有了但图标没有"或"工具注册了但无法在编辑器中使用"的混乱。
2. 执行时机分离(序列化 vs 执行期)
tools.config.tool 在变量引用尚未解析时执行,只负责确定工具名称;tools.config.params 在执行期运行,负责类型转换和参数组装。这个分离避免了变量引用的破坏。
3. 包边界强制隔离
apps/realtime 故意不使用 Next.js、React、块注册表等重型依赖,CI 脚本验证这一点。如果违反,CI 失败。这防止了服务间隐式耦合膨胀。
4. 纯类型包作为契约
workflow-types 不含任何运行时逻辑,只有类型定义。这使得 executor、persistence、authz 等包可以各自独立引用,而不用担心循环依赖或执行环境差异。
5. 审计日志的统一记录
@sim/audit 包提供 recordAudit 函数、AuditAction 和 AuditResourceType 常量,所有敏感操作都通过统一入口记录,便于安全审计与合规追溯。
11. 常见问题
Q1:Sim 和 LangGraph、AutoGen 等框架有什么区别?
Sim 强调可视化编排与开箱即用的集成。LangGraph/AutoGen 是代码优先的编排库,适合开发者深度定制;Sim 则同时面向需要可视化编辑的非技术用户,以及需要深度扩展的开发者。
Q2:自托管版本和云端版本功能一致吗?
大部分功能一致。云端版本额外包含 Sim 官方托管的 Copilot 服务(需要 COPILOT_API_KEY)。其他功能(如工作流编辑、工具集成、Trigger.dev 定时任务等)在自托管版本中均可使用。
Q3:Sim 支持哪些 LLM?
Sim 通过 providers/ 包集成了多种 LLM Provider,具体支持列表需参考官方文档(https://docs.sim.ai)。
Q4:如何在 Sim 中处理分支逻辑?
Sim 支持 Parallel(并行分支)和条件分支块(logic 类 Block)。工作流执行引擎会按照图拓扑顺序遍历,遇到并行块时会等待所有分支完成后再继续。
Q5:工作流出错后如何处理?
执行引擎会记录每个 Block 的执行状态(BlockState),包括错误信息。用户可以从失败节点重新触发工作流,或者使用错误处理块(Error Handler Block)定义异常情况下的备选路径。
12. 下一步
| 推荐内容 | 难度 | 说明 |
|---|---|---|
| Sim 官方文档 | ⭐ | 完整的安装配置与使用指南 |
| Sim GitHub 仓库 | ⭐⭐ | 源码阅读,参与贡献 |
| ReactFlow 官方文档 | ⭐⭐ | 深入理解工作流编辑器底层技术 |
| Drizzle ORM 文档 | ⭐⭐ | 理解 Sim 数据库 schema 设计 |
| Better Auth 文档 | ⭐⭐ | 理解 Sim 的认证架构 |
文档元信息 难度:⭐⭐⭐⭐ | 类型:专家设计 | 更新日期:2026-05-01 | 预计阅读时间:30 分钟