设计稿自己会说话:我用 Claude 给 Figma 做了个 AI 上下文插件

设计稿自己会说话:我用 Claude 给 Figma 做了个 AI 上下文插件

读完这篇文章,你会了解如何用 Figma Plugin API 提取设计稿的结构化信息,并通过 Claude 将其转化为开发者可读的自然语言描述。

背景:设计稿交付的信息断层

做前端的都经历过这种场景:设计师丢过来一个 Figma 链接,你打开一看------嗯,好看。然后呢?

  • 这个间距是固定的还是响应式的?
  • 这组卡片是横向滚动还是换行?
  • 这个组件在不同状态下长什么样?

这些信息藏在设计师的脑子里,靠评审会口头传达,靠 Figma 批注零散记录。结果就是:开发凭感觉还原,设计反复走查,双方都在做低效沟通。

我想解决的问题很简单:让设计稿自己说话。自动从 Figma 节点中提取布局、样式、组件关系,然后用 AI 生成一段开发者能直接看懂的上下文描述。

方案设计

整体架构分三层:

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',
    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/...

相关推荐
豹哥学前端1 小时前
浏览器console里的双中括号 `[[ ]]`
前端·javascript·ecmascript 6
菜泡泡@1 小时前
npm 安装pnpm之后运行pnpm -v查询报错
前端·npm·node.js
贫民窟的勇敢爷们1 小时前
React跨平台能力,打破前端开发的平台边界
前端·react.js·前端框架
你很易烊千玺2 小时前
JS 数组所有变态遍历・完整案例 + 场景 + 对比
javascript·数组
lifejump2 小时前
Dede(织梦)CMS渗透测试(all)
前端·网络·安全·web安全
扬帆破浪2 小时前
sidecar崩溃后前端怎么续命 重启策略与状态保留
前端·人工智能·架构·开源·知识图谱
光影少年2 小时前
前端算法题
前端·javascript·算法
Lee川2 小时前
从输入框到智能匹配:一文读懂搜索功能的完整实现
前端·后端
朝阳393 小时前
React【面试】
前端·react.js·面试