TechApril 2026

别让 Agent 直接把 Figma 翻译成页面:我用两个 Skill 做设计落地的完整工作流

Agent 编程能力越来越强,但直接把 Figma 喂给 Agent 生成页面,结果往往是局部看着对、全局不一致。我把解决方案封装成了两个 Skill:figma-to-spec 负责用 Figma MCP 读取设计结构并落成可审阅的 spec,token-to-theme 负责把 spec 里的视觉信号映射成项目的语义主题。前两步到位之后,日常页面开发自然就稳了。

2026-04-14作者:Scofield
FigmaFigma MCPVibe CodingAgentDesign to CodeDesign SystemTokens前端架构Skill
别让 Agent 直接把 Figma 翻译成页面:我用两个 Skill 做设计落地的完整工作流

Agent 很强,但直接喂 Figma 生成页面,结果经常跑偏

如果你已经在用 Cursor、Copilot、Claude Code 这类 Agent 编程工具写前端,大概率尝试过这件事:把一份 Figma 设计稿的截图或链接丢给 Agent,让它直接生成页面代码。

第一次看到结果的时候会觉得很惊喜——布局大致对了,颜色也接近,Agent 甚至帮你选了 Tailwind class。但做过几次之后你会发现问题:颜色值是 Agent 自己猜的,和设计稿只是"看起来差不多";不同页面之间的视觉语言并不统一,每个组件各自抄了一组局部值;响应式、hover 态、暗色模式这些设计稿没有显式给出的东西,Agent 要么直接忽略,要么按自己的理解补了一套,结果跟设计师的意图不一致。

局部看着对,全局不一致。这就是"让 Agent 直接从 Figma 生成页面"最典型的问题。

原因也很直接:Agent 在一次对话里能处理的上下文是有限的。你给它一个 section,它会尽力把这个 section 做好,但它看不到项目已有的主题层长什么样、其他页面用了哪些语义变量、以及你整个设计系统的一致性约束。它不是不够聪明,而是缺少全局输入。

我的做法:两个 Skill 打地基,后面日常开发自然就稳

所以我现在的做法是,不再让 Agent 直接从 Figma 跳到页面实现,而是在中间加两步,每一步都有明确的输入、输出和边界。而且这两步我已经封装成了两个可复用的 Skill,不用每次手写长 prompt。

第一步:调用 figma-to-spec,用 Figma MCP 做设计分析,落成 spec。 一句调用,Skill 内部会自动走 Figma MCP 工具读取设计结构数据,整理成一份可审阅的规格文档。

第二步:调用 token-to-theme,把 spec 里的 token candidate 映射成项目的主题层。 同样一句调用,Skill 会先检查项目现有的 CSS 变量和 Tailwind 配置,再把设计信号映射到已有的语义角色上。

这两步到位之后,Agent 日常写页面消费的就不再是一张模糊截图,而是结构明确的 spec 和语义化的 theme 变量。写出来的代码天然和项目整体一致。后面的页面开发就是正常的 Agent 日常开发了——输入质量变好了,不需要额外流程。

为什么要封装成 Skill

你可能会问:我自己写一段详细的 prompt 指导 Agent 做分析、做映射,效果不也一样吗?

不一样。这里面有大量的约束逻辑,如果每次靠手写 prompt 来保证,你会漏。

比如 figma-to-spec 这个 Skill 里内建了:scope 必须是 bounded 的(不能给整个 Figma 文件)、evidence 捕获有固定顺序(先 get_design_contextget_metadataget_screenshot,按信息密度降级)、不确定性必须显式标注(Agent 不能悄悄把猜测写成事实)、输出格式是固定的(有模板,下游可消费)。

token-to-theme 也一样:它有 auditmapapply 三个 mode,可以分步走——先看现状、再出映射方案、最后才真正改文件。而且它有"优先复用已有语义角色"的硬约束,不会让 Agent 自作主张发明 --header-bg--nav-text 这类碎片变量。

这些规则写一次、封装进 Skill、每次调用自动生效。你不需要记住它们,Skill 替你记住了。

为什么 Figma MCP 是前提

这套流程能跑起来的关键前提是 Figma MCP。

给 Agent 一张 Figma 截图,它只能做视觉层面的猜测——这块大概是灰色背景、那里大概是 16px 的字。但通过 Figma MCP,Agent 能拿到设计稿的真实结构数据:节点层级、组件实例关系、自动布局参数、样式定义和变量绑定。这是完全不同的两个信息层级。

举个例子,截图里你看到的是"一行灰色文字",而通过 get_design_context 拿到的是:这是一个 Text 节点,使用了名为 Body/Small 的文字样式,填充色绑定了 color/text-secondary 这个变量,它的父容器是一个 Auto Layout frame,间距为 8px。这些结构化信息是 Agent 做出准确判断的基础——有了它,Agent 才能区分"这里用的是次级文字色"还是"这里碰巧写了一个灰色"。

figma-to-spec Skill 内部正是基于这些 Figma MCP 工具做分析的。它会按固定顺序调用 get_design_contextget_metadataget_screenshot,同时拿到结构数据和视觉参考,再基于这些一手证据做分析。这就是"用 Skill 做设计分析"和"给 Agent 一张截图让它看图抄作业"之间最核心的区别。

实操:用 figma-to-spec 分析一个 section

我用这个博客的 Blog Header 做例子,完整走一遍。

我实际的调用方式

Use figma-to-spec to analyze this Blog Header section.
Figma URL: https://www.figma.com/design/xxxxx/Blog?node-id=123-456
Scope: this single frame only.
Mode: section-spec.
Target stack: Next.js + Tailwind + shadcn/ui.

就这么多。一个 Figma 链接、一个 scope、一个 mode、一个 target stack。

Skill 帮你保证了什么

你不需要告诉 Agent "先用 get_design_context 再用 get_metadata 再用 get_screenshot"——Skill 内部有固定的 evidence 捕获流程,按信息密度从高到低自动走。

你不需要提醒 Agent "不确定的地方要标出来"——Skill 要求所有推断必须和直接观察分离,不确定性有专门的 Uncertainty 区域。

你不需要担心 Agent 偷偷分析了整个 Figma 文件——Skill 有 scope 约束,如果输入过宽,它会先缩窄到 bounded set 再开始分析。

你不需要每次指定输出格式——Skill 有固定的输出契约和模板,design_analysis.mdpage_spec.md 的结构是确定的。

它产出什么

Agent 通过 Figma MCP 拿到的不是一张模糊截图,而是具体到每个节点的布局方式、文字样式绑定、颜色变量引用、Auto Layout 参数。基于这些一手数据,它整理出一份结构化的 spec:

Section purpose:Blog Header 用来建立站点身份、提供主导航,它是全局性的,不是某一篇文章的专属 UI。

Pattern 和 primitive:导航链接列表、站点标题文字块、副标题区域、浅色分隔线——这些是可复用的 primitive。

Token candidate:背景色(极浅灰)、标题字号和字重、导航链接颜色及 active 态颜色、分隔线颜色、内边距节奏。这些还只是候选信号,不是最终变量名。

Uncertainty:导航 hover 态没有在设计稿中给出、移动端折叠菜单行为未知、深色模式配色未知。

这份 spec 最大的价值是把设计判断从"Agent 的内部推理"变成了"你可以审阅的外部文档"。你看完之后可以说"hover 态就用 primary 色"或者"mobile 下导航折叠成 hamburger",然后这些决策也被记录进 spec。Agent 不再是在黑盒里做判断,而是先把判断摊开来让你确认。

一个 section 做完,再选下一个 section 调用同一个 Skill。每个 section 的 spec 质量都是独立保证的。

为什么 spec 还不够:raw token 不能直接进组件

到这一步,你手上已经有了一份比 Figma 截图稳定得多的中间文档。但如果直接拿这份 spec 让 Agent 写页面,还是会出问题。

spec 里的 token candidate 仍然是设计侧的信号,它们还没有和你项目里实际存在的主题系统建立关系。

比如 spec 里写了"背景色接近白色或极浅灰",这个观察是准确的,但它告诉 Agent 的是"设计里用了什么",而不是"代码里应该消费什么"。你的项目里可能已经有 --background 这个 CSS 变量,Tailwind 里有 bg-background 这个 class,但如果 Agent 没有感知到这层映射关系,它很可能会直接写一个 bg-[#fafafa] 出来——局部正确,但绕过了整个主题系统。

三个月后你想换主题,发现这个颜色不在 CSS 变量里,而是散落在组件的 arbitrary value 里,根本无法统一修改。这就是 raw token 直接进入组件的代价。

所以 spec 和页面开发之间,还需要一步:把设计信号映射成项目的语义主题。这正是第二个 Skill 做的事。

实操:用 token-to-theme 做主题映射

先 audit,再 map,最后 apply

token-to-theme 有三个 mode,可以分步走。我通常不会上来就让它改文件,而是先让它看:

Use token-to-theme in audit mode.
Token source: docs/design/blog-header/design_analysis.md
Target stack: Next.js + Tailwind + shadcn/ui.

audit mode 只读不写。Agent 会扫描项目的 globals.css、Tailwind 配置,告诉你:项目现有哪些语义角色、用的是什么格式(HSL channels、hex、OKLCH)、spec 里的 token candidate 哪些已经有对应、哪些缺失。

看完 audit 结果没问题,再跑 map mode:

Use token-to-theme in map mode.
Token source: docs/design/blog-header/design_analysis.md

这一步产出一份 theme_mapping.md,记录每个 token candidate 最终映射到哪个语义角色:

  • 背景色 → --background(已存在,直接复用)
  • 主文字色 → --foreground(已存在)
  • 导航链接色 → --muted-foreground(已存在,次级文字)
  • active 态链接色 → --foreground(复用主文字色,靠字重区分)
  • 分隔线色 → --border(已存在)
  • 字号和内边距 → 映射到 Tailwind 现有的 scale

这个案例里,现有的 theme 角色全部够用,不需要新增变量。这恰恰是最理想的结果——说明项目的语义体系已经能覆盖这个 section 的视觉需求,Agent 只需要复用,不需要发明。

确认映射方案后,再跑 apply mode 让它真正改文件。如果有需要新增的语义变量,它只动 theme 层(CSS 变量声明、Tailwind theme 配置),不动业务组件。

Skill 帮你保证了什么

和 figma-to-spec 一样,token-to-theme 内建了一些你不用操心的约束:

优先复用已有角色。Skill 有硬约束:如果项目已经有 --background--foreground 这些语义角色,必须优先映射上去,不能另起一套 --header-bg--nav-text

只动 theme 层。安全编辑区域被明确限定在 token 变量声明、semantic 变量声明和 Tailwind theme 配置里。不会动业务组件。

保留项目已有格式。项目用 HSL channels 就继续 HSL channels,用 hex 就继续 hex,不会为了"规范"强行迁移格式。

handoff 契约。Skill 的产出是稳定的——后续无论你是自己写页面还是让 Agent 写,消费的都是同一套语义变量。

两个 Skill 跑完之后:日常开发自然就稳了

当 spec 和 theme mapping 都稳定之后,后续的页面开发就是正常的 Agent 日常开发。不需要额外流程。

区别只在于 Agent 消费的输入变了。以前是"看这个 Figma 截图,帮我写个 header",现在是:

"根据 Blog Header 的 spec,使用项目已有的 semantic theme 变量实现这个组件。背景用 bg-background,主文字用 text-foreground,导航链接用 text-muted-foreground,分隔线用 border-border。"

写出来的代码天然就和项目的其他部分一致,因为所有组件消费的都是同一套语义接口。将来换主题或切暗色模式,只需要改 CSS 变量层,所有消费了 semantic role 的组件会自动跟着变。

这就是全局一致性的来源:不是靠 Agent 在每次生成页面时都自觉保持一致,而是靠前两步把输入本身变得一致。

完整链路走读:从一个 Figma section 到可用代码

把前面的内容串起来,一个 section 从设计稿到代码的完整路径是这样的:

1 → 调用 figma-to-spec

Use figma-to-spec. Figma URL: xxx. Scope: Blog Header. Mode: section-spec.

产出:design_analysis.md,包含 section purpose、pattern、token candidate、uncertainty。

2 → 审阅 spec,补充决策

你看完 spec,补充 Agent 标记为 uncertain 的地方:"hover 态用 --primary"、"mobile 下折叠成 hamburger"。这些决策被记录进 spec。

3 → 调用 token-to-theme(audit → map → apply)

Use token-to-theme in audit mode. Token source: design_analysis.md.

确认现状后:

Use token-to-theme in map mode.

审阅 theme_mapping.md,确认映射方案。然后:

Use token-to-theme in apply mode.

theme 层更新完成。

4 → 日常开发

拿着 spec + 语义主题让 Agent 写页面。这一步跟你平时让 Agent 写代码没区别,只是输入质量好了。

一个 section 就是这四步。做完这个 section,选下一个 section 再走一遍。整个项目的设计落地就是重复这个循环。

这套工作流真正解决的是什么

回过头看,这两个 Skill 解决的不是"怎么写页面"的问题,而是"怎么让 Agent 在全局层面把控设计落地"的问题。

没有 spec 层,Agent 每次拿到的都是一个局部设计截图,它没办法知道这个 section 和其他 section 之间有什么视觉关系。每次对话都是一个孤岛,全局一致性全靠人肉维护。

没有 theme mapping,Agent 会自己猜颜色值,或者把设计稿里的局部值直接写进组件。结果是项目里散落着几十个看似不同、实际上应该统一的颜色,主题根本无法集中维护。

有了这两层之后,Agent 的每一次页面实现都在消费同一个稳定输入。spec 告诉它"这里应该有什么",theme 告诉它"应该用项目里的哪个变量"。Agent 的能力被用在它最擅长的地方——快速实现结构和逻辑——而不是被迫同时做理解、映射和实现三件事。

而封装成 Skill 的价值在于,你不需要每次都记住所有约束。scope 边界、evidence 顺序、uncertainty 标注、优先复用已有角色、只动 theme 层——这些规则 Skill 替你执行,你只需要提供 Figma 链接和确认产出。

最容易踩的坑

这套流程在实际使用中有几个高频错误,分享出来帮你避坑。

直接给 Agent 整份 Figma 文件。scope 太大,Agent 会试图一次性处理所有 frame,推断数量爆炸,spec 里混合着事实和猜测,下游完全无法区分。每次只给一个 bounded section,做完一个再做下一个。figma-to-spec Skill 在 scope 过宽时会自动缩窄,但最好从你这一端就给明确。

跳过 Figma MCP,只给截图。截图只有视觉信息,Agent 拿到的是像素层面的猜测。通过 Figma MCP 拿到的是结构数据——节点层级、样式绑定、变量引用——两者的分析质量完全不在一个层级。

spec 没审就直接跑 token-to-theme。spec 的 uncertainty 区域是给你决策的机会。如果你跳过审阅直接进 theme mapping,那些不确定性会被 Agent 在后续步骤里悄悄补上——你失去了干预窗口。

token-to-theme 直接跑 apply,跳过 audit 和 map。能跑通但不推荐。audit 让你看清项目 theme 现状,map 让你在改动之前确认映射方案。跳过这两步就像不看路直接跑,大概率不会翻车,但翻了之后回溯成本高。

Theme mapping 的时候另起一套新变量。如果项目已经有 --background--foreground 这些语义角色,Agent 有时候会"更精确"地创建 --header-bg--nav-text 这类局部变量。token-to-theme Skill 有硬约束防止这件事,但如果你手动写 prompt 做映射而不是用 Skill,这个坑很容易踩。

什么时候适合这套流程

这套工作流不是所有项目都需要的。

适合的场景:页面超过 3 个、设计还会迭代、需要主题一致性、可能要支持暗色模式、多人协作或者你自己六个月后还要维护。简单说就是"这个项目不是一次性的"。

不适合的场景:一次性活动页、临时 demo、只有一个页面且不会再改、或者整个项目的视觉复杂度低到不需要 theme 系统。这种情况下,直接让 Agent 看截图生成页面完全合理。

一个简单的判断标准:如果你预期同一套视觉规则会被用在两个以上的地方,那 spec + theme mapping 就是值得的。如果这真的是一次性的,直接干就好。

结尾:Vibe Coding 的关键不是让 Agent 更快,而是让它更稳

Agent 会越来越强,Figma MCP 能拿到的设计数据也会越来越丰富。但这不意味着你应该把所有事情都压缩成一步让 Agent 直接做完。

我在实际使用中发现的最重要的一个判断是:Agent 的速度不是瓶颈,全局一致性才是。它可以在几秒钟内帮你写完一个组件,但如果每次写组件的输入都是一个孤立的截图,全局的一致性就只能靠你自己反复检查和修正来维护。

把前置工作封装成 Skill,本质上是在用 Agent 做全局把控,而且让这种全局把控变得可复现。第一次配好之后,后面每个 section 都是同一套流程、同一套约束、同一套输出标准。不会因为你某次忘了写某个 prompt 细节,质量就降级。

这才是 Vibe Coding 真正该追求的方向:不是让 Agent 更快地生成页面,而是让它在更稳定的输入上工作,让全局一致性成为默认状态而不是额外负担。


这两个 Skill 我已经发布,可以直接拿来用:

  • figma-to-spec — 用 Figma MCP 分析设计,产出结构化 spec
  • token-to-theme — 把 token candidate 映射成项目的语义主题

安装后一句话调用即可,所有约束自动生效。