设计稿自己会说话:我用 Claude 给 Figma 做了个 AI 上下文插件
读完这篇文章,你会了解如何用 Figma Plugin API 提取设计稿的结构化信息,并通过 Claude 将其转化为开发者可读的自然语言描述。
背景:设计稿交付的信息断层
做前端的都经历过这种场景:设计师丢过来一个 Figma 链接,你打开一看------嗯,好看。然后呢?
- 这个间距是固定的还是响应式的?
- 这组卡片是横向滚动还是换行?
- 这个组件在不同状态下长什么样?
这些信息藏在设计师的脑子里,靠评审会口头传达,靠 Figma 批注零散记录。结果就是:开发凭感觉还原,设计反复走查,双方都在做低效沟通。
我想解决的问题很简单:让设计稿自己说话。自动从 Figma 节点中提取布局、样式、组件关系,然后用 AI 生成一段开发者能直接看懂的上下文描述。
方案设计
整体架构分三层:
核心流程:
- 用户在 Figma 中选中一个 Frame 或组件
- 插件递归遍历选中节点的子树,提取布局、样式、组件元信息
- 将提取结果组织成结构化 JSON
- 把 JSON 作为上下文发送给 Claude,让它生成面向开发者的描述
- 描述结果展示在插件面板中,支持复制
选择在插件端做信息提取而不是直接截图丢给多模态模型,原因有两个:一是结构化数据比截图更精确(像素级的间距、具体的 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',
max_tokens: 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": {
"FIGMA_TOKEN": "figd_your_token"
}
}
}
}
把这段配置加到你的 MCP 客户端配置文件中即可。不同客户端的配置路径:
| 客户端 | 配置路径 |
|---|---|
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.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 编辑器就能直接调用这些工具了:
get_node--- 获取 AI 友好格式的节点数据(比原始 JSON 节省 60%+ token)get_page_for_codegen--- 一次性获取完整的代码生成上下文get_node_css--- 直接输出 CSS 或 Tailwind 类名search_nodes--- 按名称/类型快速定位节点diff_nodes--- 对比节点差异,追踪设计变更
也支持全局安装或从源码构建,详见 GitHub README。
效果与总结
目前这个插件在团队内部使用,覆盖了日常 80% 的设计交付场景。几个数据:
- 平均每个 Frame 的描述生成时间:2-3 秒
- 设计走查中"这里是什么意思"类问题减少约 60%
- 开发者反馈最有用的信息:响应式策略和组件 props 映射
适用场景:设计系统成熟、组件化程度高的项目效果最好。如果设计稿本身就是一堆绝对定位的矩形,提取出来的结构信息价值有限。
后续规划:
- 支持批量处理整个页面的所有 Frame
- 接入设计系统 token 映射,直接输出 CSS 变量名
- 探索多模态方案作为补充(截图 + 结构数据一起给 Claude)
如果你也在做设计-开发协作相关的工具,欢迎交流。项目已开源:github.com/xiehuan123/...