About
设计稿自己会说话:我用 Claude 给 Figma 做了个 AI 上下文插件 读完这篇文章,你会了解如何用 Figma Plugin API 提取设计稿的结构化信息,并通过 Claude 将其转化为开发者可读的自然语言描述。 背景:设计稿交付的信息断层 做前端的都经历过这种场景:设计师丢过来一个 Figma 链接,你打开一看——嗯,好看。然后呢? 这个间距是固定的还是响应式的? 这组卡片是横向滚动还是换行? 这个组件在不同状态下长什么样? 这些信息藏在设计师的脑子里,靠评审会口头传达,靠 Figma 批注零散记录。结果就是:开发凭感觉还原,设计反复走查,双方都在做低效沟通。 我想解决的问题很简单:让设计稿自己说话。自动从 Figma 节点中提取布局、样式、组件关系,然后用 AI 生成一段开发者能直接看懂的上下文描述。 方案设计 整体架构分三层: mermaid graph LR A[Figma Plugin UI] --> B[Plugin Main Thread] B --> C[节点树遍历 & 信息提取] C --> D[结构化 JSON] D --> E[Claude API] E --> F[自然语言描述] F --> A 核心流程: 1. 用户在 Figma 中选中一个 Frame 或组件 2. 插件递归遍历选中节点的子树,提取布局、样式、组件元信息 3. 将提取结果组织成结构化 JSON 4. 把 JSON 作为上下文发送给 Claude,让它生成面向开发者的描述 5. 描述结果展示在插件面板中,支持复制 选择在插件端做信息提取而不是直接截图丢给多模态模型,原因有两个:一是结构化数据比截图更精确(像素级的间距、具体的 token 名称这些截图看不出来);二是 token 消耗可控,一个中等复杂度的页面提取出来大概 2-3K tokens,远比图片便宜。 实现:节点树遍历与信息提取 Figma Plugin API 的节点树结构和 DOM 类似,每个节点有 type、布局属性、样式属性。核心是一个递归遍历函数,针对不同节点类型提取不同信息: typescript interface NodeContext { type: string; name: string; layout?: LayoutInfo; style?: StyleInfo; children?: NodeContext[]; componentMeta?: ComponentMeta; } function extractNodeContext(node: SceneNode, depth = 0): NodeContext | null { if (!node.visible || depth > 8) return null; const context: NodeContext = { type: node.type, name: node.name, }; if ('layoutMode' in node && node.layoutMode !== 'NONE') { context.layout = { direction: node.layoutMode, gap: node.itemSpacing, padding: { top: node.paddingTop, right: node.paddingRight, bottom: node.paddingBottom, left: node.paddingLeft, }, sizing: { width: node.primaryAxisSizingMode, height: node.counterAxisSizingMode, }, }; } if ('fills' in node || 'strokes' in node) { context.style = extractStyleInfo(node); } if (node.type === 'INSTANCE') { context.componentMeta = { componentName: node.mainComponent?.name ?? 'unknown', overrides: getOverrideProperties(node), }; } if ('children' in node) { context.children = node.children .map(child => extractNodeContext(child, depth + 1)) .filter(Boolean) as NodeContext[]; } return context; } 几个关键决策: 深度限制设为 8 层。Figma 设计稿嵌套可以非常深(尤其是用了 Auto Layout 嵌套的复杂布局),但超过 8 层的细节对开发者理解整体结构帮助不大,反而会让 token 爆炸。 跳过不可见节点。隐藏图层通常是设计师的草稿或废弃方案,没必要描述。 组件实例只记录 override。如果一个 Instance 没有任何覆盖属性,说明它和主组件完全一致,只需要引用组件名即可。 实现:Prompt 工程与 Claude 调用 拿到结构化 JSON 后,需要让 Claude 理解这些数据并生成有用的描述。直接把整棵 JSON 树丢进去效果不好——Claude 会逐字翻译 JSON 字段,产出一堆"该节点的 layoutMode 为 VERTICAL"这种废话。 最终的 prompt 策略是角色 + 约束 + 示例: typescript function buildPrompt(context: NodeContext): string { return 你是一个资深前端开发者的助手。下面是从 Figma 设计稿中提取的结构化信息。 请基于这些信息,生成一段面向前端开发者的上下文描述,帮助他们理解: 1. 整体布局结构和响应式策略 2. 关键组件的用途和状态 3. 需要注意的间距、对齐、层级关系 4. 与设计系统组件的对应关系(如果有) 要求: 用开发者熟悉的术语(flex、grid、gap、padding) 指出哪些值是固定的、哪些应该是响应式的 如果发现设计系统组件,说明组件名和传入的 props 不要逐字翻译 JSON,要提炼有价值的信息 控制在 300 字以内 设计稿结构数据: ${JSON.stringify(context, null, 2)}; } 调用 Claude API 时用的是 claude-sonnet-4-6,在速度和质量之间取了平衡。对于一个中等复杂度的 Frame,响应时间大概 2-3 秒,可以接受。 typescript async function generateDescription(context: NodeContext): Promise<string> { const response = await anthropic.messages.create({ model: 'claude-sonnet-4-6-20250514', maxtokens: 1024, messages: [{ role: 'user', content: buildPrompt(context) }], }); return response.content[0].type === 'text' ? response.content[0].text : ''; } 踩坑与优化 坑 1:大页面 token 超限 一个完整的落地页可能有上百个节点,提取出来的 JSON 轻松超过 10K tokens。解决方案是分块处理:先对顶层子节点做一次概览描述,再允许用户点击具体区域获取详细描述。这样每次请求控制在 3K tokens 以内。 坑 2:Figma Plugin 的 sandbox 限制 Figma 插件的 main thread 跑在 sandbox 里,不能直接发网络请求。需要通过 figma.ui.postMessage 把数据传给 UI 层(一个 iframe),由 UI 层调用 Claude API。这个通信模型一开始让我绕了弯路——在 main thread 里写了半天 fetch 才发现根本跑不通。 typescript // main thread: 提取完数据后发给 UI figma.ui.postMessage({ type: 'context-ready', payload: context }); // UI thread: 收到数据后调用 API window.onmessage = async (event) => { if (event.data.pluginMessage.type === 'context-ready') { const description = await generateDescription(event.data.pluginMessage.payload); // 展示结果... } }; 坑 3:描述质量不稳定 早期版本生成的描述时好时坏,有时候会输出"这是一个漂亮的设计"这种没用的话。加了 few-shot 示例后明显改善——在 prompt 里放了两个好的描述样本,Claude 就能稳定输出结构化、有信息量的内容。 快速上手 项目已发布到 npm,推荐用 npx 直接使用,无需安装: json { "mcpServers": { "figma": { "command": "npx", "args": ["-y", "figma-ai-context"], "env": { "FIGMATOKEN": "figdyourtoken" } } } } 把这段配置加到你的 MCP 客户端配置文件中即可。不同客户端的配置路径: | 客户端 | 配置路径 | |--------|----------| | Claude Desktop | ~/Library/Application Support/Claude/claudedesktopconfig.json (macOS) | | Claude Code | .claude/settings.json 中的 mcpServers 字段 | | Cursor | Settings → MCP → Add Server | | VS Code (Copilot) | .vscode/mcp.json | 获取 Figma Token:登录 Figma → Settings → Personal Access Tokens → 创建新 token,复制 figd 开头的字符串。 配置完成后,你的 AI 编辑器就能直接调用这些工具了: getnode — 获取 AI 友好格式的节点数据(比原始 JSON 节省 60%+ token) getpageforcodegen — 一次性获取完整的代码生成上下文 getnodecss — 直接输出 CSS 或 Tailwind 类名 searchnodes — 按名称/类型快速定位节点 diffnodes — 对比节点差异,追踪设计变更 也支持全局安装或从源码构建,详见 GitHub README。 效果与总结 目前这个插件在团队内部使用,覆盖了日常 80% 的设计交付场景。几个数据: 平均每个 Frame 的描述生成时间:2-3 秒 设计走查中"这里是什么意思"类问题减少约 60% 开发者反馈最有用的信息:响应式策略和组件 props 映射 适用场景:设计系统成熟、组件化程度高的项目效果最好。如果设计稿本身就是一堆绝对定位的矩形,提取出来的结构信息价值有限。 后续规划: 支持批量处理整个页面的所有 Frame 接入设计系统 token 映射,直接输出 CSS 变量名 探索多模态方案作为补充(截图 + 结构数据一起给 Claude) 如果你也在做设计-开发协作相关的工具,欢迎交流。项目已开源:github.com/xiehuan123/figma-ai-context
Discuss this product