0%

从 Figma 到编码 Agent:设计上下文的结构化、缓存与校验

将设计稿交给编码 Agent,需要先解决设计数据从哪里来。官方集成提供了现成入口;直接调用设计平台 API,则把数据获取和请求调度的控制权留在自己的工具中。

选择从成本约束开始:如果需求集中在读取节点、导出截图和资产,已有 API 权限与额度能够覆盖这些操作,就有机会在不增加设计平台订阅支出的情况下完成设计获取。接下来需要衡量的是,为此承担多少集成和维护工作。

本文以 Figma 为例,讨论一种将设计获取与页面实现分开的架构:通过可调度的 API 获取层准备本地上下文包,再由多模态 Agent 完成实现与验证。这里的获取层指承担数据获取与请求调度的模块,CLI 是本地调用入口;工具则包含获取层、包管理和校验等模块。成本、请求复用、凭据分配和输入质量共同决定这层工具的边界。

TL;DR

直接接 API 的收益来自两个方面:在已有权限和额度内控制新增费用,以及自行决定请求如何合并、缓存、分配和重试。相应代价是维护获取层与数据契约。

确定性 CLI 负责获取、归一化、缓存和结构校验,多模态 Agent 负责理解设计、结合现有工程实现页面,并在真实浏览器中验证。两者通过本地上下文包交接。

这套划分让输入失败有明确的状态和恢复路径,也保留了几个必要边界:包完整不代表选对了设计范围,缓存命中不代表远端设计没有变化,视觉通过也不代表业务行为通过。

已有 Figma MCP,为什么选择直接接 API

官方 Figma MCP 提供设计上下文、截图等工具,并能结合 Code Connect 提供设计组件对应的代码实现信息。对于已经具备合适套餐和席位、需要这些集成能力的场景,直接使用官方工具可以减少自建维护。

当需求集中在设计读取时,可以把成本拆成平台访问、编码 Agent 和工具维护三部分。API 方案主要改变第一部分,并增加第三部分;它不会消除模型调用费用。在已有权限和额度足够的场景下,设计获取可以接近零新增费用,但这是一种有条件的成本结构。

MCP 本身是连接协议,费用和访问条件由具体服务决定。Figma 官方 MCP 提供有限额度的访问REST API 的限流规则也与套餐、席位和端点等因素有关,入口选择取决于这些条件能否覆盖实际工作量。

决策维度 官方集成 自建 API 获取层
使用成本 使用现有套餐、席位与服务额度 利用已有 API 额度,承担工具维护投入
数据组织 使用集成提供的上下文 自定上下文包和校验规则
请求策略 使用现成工具,再配套外围流程 控制缓存、批处理、凭据选择和重试
组件关联 可利用 Code Connect 等集成 按需求决定是否承担额外关联工作
演进责任 跟随官方服务 维护接口适配和格式兼容

直接接 API 的价值在于把获取策略变成可以设计的工程模块。缓存减少请求量,调度管理可用额度,本地包支持跨会话复用。这些机制同样可以放在 MCP 调用之外;差异在于选择哪一层承担这些责任,以及相应的维护投入是否与收益匹配。

先明确工具要解决哪一段问题

设计稿进入代码仓库之前,需要回答三个问题:拿到了什么、这些内容是否足够、它们对应哪个实现目标。

拿到了什么,可以通过截图、节点结构和资产清单记录下来。内容是否足够,需要检查文件和引用关系,也需要结合目标看图判断。对应哪个实现目标,则依赖目标仓库、页面或路由,以及已有项目的业务约束。

三类信息的来源不同。设计平台能够提供节点与导出结果,却不能替项目决定路由和接口;CLI 能检查文件,却不能仅凭文件存在判断一个弹窗是否包含了全部内容;Agent 能理解图片,但下载失败、缓存替换这些操作没有必要每次重新组织。

因此,工具的目标收敛为:为 Agent 准备一份来源明确、内容可检查、失败可解释的设计输入。页面应该采用什么组件、如何适配现有布局、哪些行为必须保留,仍放在目标项目中判断。

将范围收敛到输入准备,可以避免工具同时承担完整代码生成平台的复杂度。输入检查可以跨页面复用,页面实现则依赖各自的组件和业务约束,因此两者分开处理。

用本地上下文包划分职责

从责任分配看,有三种可选方式。

方式 适用之处 需要承担的问题
Agent 直接获取设计并实现 一次性探索,流程短 获取、重试、输入检查依赖每次执行过程
工具获取设计并直接生成页面 输出范围固定、生成规则明确 工具需要承担组件选择、框架适配和业务集成
工具准备上下文包,Agent 实现 输入处理需要复用,目标工程存在差异 需要维护包格式,以及工具与 Agent 之间的约定

这里选择第三种职责划分。CLI 接收设计节点,下载资源,转换为统一结构;Agent 读取结果,再在目标仓库里工作。

flowchart TD
    A["Figma 选定节点"] --> B["CLI:获取、归一化、校验"]
    B --> C["本地上下文包"]
    C --> D["Agent:查看截图、确认范围"]
    E["目标项目与受保护业务行为"] --> F["页面实现"]
    D --> F
    F --> G["真实浏览器:视觉比较与业务验证"]
    G --> H["人工验收"]

这里有意保留了一次明确的交接。输入准备结束后,可以检查包的内容、重新运行校验,也可以在后续任务中复用同一份本地输入。页面实现失败时,排查起点也更清晰:先判断输入是否正确,再看实现是否偏离。

本地流程可以采用 CLI 和文件系统作为载体,无需额外常驻服务。对本地编码流程来说,这减少了服务启动、连接状态和部署方面的维护。代价是状态主要保存在本机;跨机器共享、多人同步和缓存清理需要另行处理。

将多凭据放进请求调度层

直接接 API 的另一个考虑,是请求不必固定绑定一把 key。获取层可以接收多组凭据,将具体凭据的选择从业务操作中抽离。上层只表达“获取这个节点和关联资产”,下层负责决定由哪个可用凭据执行、是否等待,以及何时重试。

多凭据调度需要先识别额度归属。key 是认证材料,额度池是容量边界,两者未必一一对应。例如,按 Figma 的额度计量规则,personal access token 按用户和套餐计量,同一用户生成多把 token 不会得到多份独立额度;plan access token 则按 token 和套餐计量。调度器应依据上游规则归组,避免把共享额度误认为可用的新容量。

flowchart TD
    A["节点与资产获取任务"] --> B{"有效缓存是否命中"}
    B -->|是| C["复用本地上下文"]
    B -->|否| D["请求合并与等待队列"]
    D --> E["按访问权限筛选凭据"]
    E --> F["按额度池与冷却状态调度"]
    F --> G["设计平台 API"]
    G -->|成功| H["校验并保存上下文"]
    G -->|限流| I["记录冷却时间与重试预算"]
    I --> D

在权限和额度均可用的候选集合中,可以采用不同的分配策略。

策略 选择理由 需要处理的代价
随机或轮询 凭据容量接近,调度逻辑简单 不能保证负载均衡,需要排除冷却中的额度池
按文档分片 同一文档保持相对稳定的访问路径 热点文档可能集中,需要允许重新分配
按容量加权 不同额度池的容量存在差异 需要维护容量估计和运行状态

选择策略之前先过滤权限,能够避免一次随机分配把任务交给无权读取该文件的凭据。缓存隔离也应沿用相同的访问边界,不能因为某个凭据获取过数据,就让其他调用者自动获得读取资格。

遇到 429 时,应按上游返回的 Retry-After 冷却相应额度池。存在具有访问权限、额度独立且仍可用的其他候选时,可以重新调度;候选全部不可用时进入等待,并受最大等待时间和重试次数约束。认证失败、权限不足和临时网络错误需要分别处理,避免把所有错误都变成无休止的换 key 重试。

这一设计将限流影响收敛到获取层:页面实现无需知道凭据如何分配,也无需处理冷却与重试。多凭据利用可用容量,缓存和批处理减少所需容量,两者配合才能稳定降低远端请求压力。多进程共享凭据时,还需要共享额度池状态,否则各进程分别控制并发,合计请求仍可能超过上游限制。

凭据由运行环境或秘密管理设施注入,上下文包只保留来源和结果,运行日志通过不包含密钥的内部标识定位请求。这样可以调整调度策略,而不把认证材料传播到 Agent 上下文和业务仓库。

截图、结构和资产分别提供什么

上下文包的核心内容很少:一张设计截图、一份归一化节点数据、一组本地资产,以及描述这些文件的 manifest。

截图提供整体视觉依据。层次、留白、对齐和颜色关系,最终都要回到图片上判断。节点数据补充图片难以准确表达的信息,例如文字、几何尺寸和组件关系。资产则保留需要直接使用的图标与图片,减少实现时重新猜测或绘制的空间。

manifest 记录来源节点、导出参数、文件位置、资产映射和诊断信息,让这些内容形成一份可以检查的输入。

这里接受了一定冗余。截图和结构可能描述同一个元素,归一化数据之外还保留清理敏感字段后的平台原始数据。它们服务于不同目的:常规读取使用统一结构;遇到转换差异时,可以回查来源数据。Agent 也不需要一次读完所有内容,可以先看截图,再定向读取相关节点和资产。

归一化还有一个边界:统一结构不可能完整表达所有平台特性。可以通过来源适配层隔离平台字段,使核心包格式保持稳定。适配层负责解释各平台语义,无法无损转换的部分保留来源信息,避免把不相同的概念强行映射为同一字段。

完整性校验之后,还要确认设计范围

一个背景矩形可以是合法节点,也可以正常导出截图。假设目标是实现一个支付弹窗,但链接只选中了背景矩形,那么请求成功、文件可读、JSON 合法都无法证明输入满足任务要求。

包状态可以分为三类:

状态 含义与处理
complete 通过当前包校验,可以进入设计范围确认
partial 存在缺失或诊断信息,保留结果供检查与恢复
invalid 核心结构或必需文件不满足要求,不能作为有效输入

这里需要区分“结果允许保存”和“允许继续完整复刻”。非关键资产失败时,CLI 可以保留 partial 包,便于诊断;完整复刻流程仍要求输入达到 complete,并确认截图范围正确。

结构检查可以采用较窄的启发式规则:根节点属于基础图形,没有子节点、有效文字和可导出资产时,标记为设计范围可疑。它用于发现明显可疑的输入,不负责判断所有设计是否完整。一个有文字但缺少主体内容的节点,仍然可能通过结构检查。

因此,Agent 必须在实现前查看截图,将其与用户描述的目标对照。发现主要内容缺失,就重新确认来源节点。工具不会静默向上寻找父节点,因为父节点也可能包含多个页面、旧版本或无关区域,扩大范围同样是在改变任务输入。

这种处理会增加一次人工沟通,但减少了输入未确认时的实现投入。尤其当根因是选错节点时,重复下载同一个链接没有修复作用。

缓存解决复用,刷新解决新鲜度

设计截图和资产适合保存在本地。持续调整同一个页面时,可以复用已有输入,也避免把页面实现绑定在每一次远端访问上。

容易混淆的是缓存标识的含义。一种缓存键设计是对来源平台、文档 ID、节点 ID、导出格式和缩放参数生成 fingerprint。它标识同一组获取参数,没有包含远端内容版本。

例如,生成 fingerprint 的输入可以是下面这组参数,标识均为示意值:

1
2
3
4
5
6
7
{
"provider": "figma",
"documentId": "example-document",
"nodeId": "1:2",
"format": "png",
"scale": 2
}

对参数做稳定序列化后再计算哈希,可以得到缓存标识。这里没有设计版本或内容摘要字段;导出参数发生变化会改变标识,远端内容变化则不会自动反映进来。

因此,同一个链接命中缓存,只能说明本地存在通过校验、参数匹配的包。设计内容发生变化而节点 ID 不变时,这个 fingerprint 不会自动改变。

可以选择显式刷新:新任务或已知设计更新时重新获取;确认设计来源未变化的持续任务可以复用。这样保留了离线复用能力,也把新鲜度判断的责任暴露出来。若业务要求每次自动追踪最新版,就需要增加远端版本检查,并接受相应的请求、延迟和失败处理。

刷新本身还涉及旧数据保护。一种做法是先在同级临时目录准备新包,校验后再切换到正式目录;替换过程中保留旧目录备份,捕获到发布失败时尝试恢复。

这样可以避免下载到一半直接破坏旧包,但这套目录操作不等于完整的事务系统。多步重命名之间存在切换窗口,也不能据此声称已经解决并发读写或进程崩溃恢复。若需要并发读取或崩溃恢复,可以进一步采用不可变版本目录、指针切换和恢复记录;这些机制也会增加状态管理成本,应由实际要求驱动。

工具状态与项目代码分开存放

截图、原始 JSON、缓存和浏览器证据有自己的生命周期。它们可能体积较大,也会随着设计变化而重复生成。如果默认放进业务工作树,每个目标项目都要处理忽略规则、临时文件和误提交问题。

状态和缓存可以放在工作树外,通过稳定的工作空间标识关联目标仓库。标识设计需要考虑路径变化,避免一次目录改名就让原有缓存和任务状态失去关联。

这个决策减少了工具对业务仓库的侵入,同时也带来可发现性成本:查看和清理文件时,需要通过 CLI 找到实际路径。另一台机器重新克隆仓库,也不会自动获得这台机器的本地状态。

这里区分的是文件用途。设计来源包和验证证据由工具管理;页面运行确实需要的图片,则仍应进入目标项目约定的资产目录,并接受正常代码审查。

页面验收需要两组证据

上下文准备完成,只是实现的起点。

迁移已有页面时,还需要明确哪些业务行为受保护,例如路由、API 调用、状态流转、表单校验和错误提示。设计截图通常不包含这些约束,它们必须从任务说明和既有实现中获得。

验收因此分成两组证据:视觉比较关注布局、字号、间距和资产使用;业务验证关注操作之后是否仍发生正确的请求、状态变化和错误处理。静态截图无法证明提交行为正确,接口请求成功也不能证明页面符合设计。

由多模态 Agent 对照原稿与真实应用截图,按需要迭代,再运行相关业务验证。CLI 只提供输入与状态支持,不输出视觉评分,也不负责最终验收判断。

这仍然存在主观性。图片比较的结论受视口、字体、页面状态和判断标准影响,所以需要保存具体证据,并保留人工验收。验收应保留差异项及其依据,单一的“还原度百分比”很难表达业务行为和视觉差异。

这层工具适用于什么范围

当同一设计需要多轮实现、任务经常跨会话继续、已有页面还带着业务约束时,本地上下文包能提供一个稳定的检查起点。排查时可以分别处理来源、输入质量、实现和验收,减少不同阶段之间的猜测。

如果只是根据一张截图做一次性原型,维护包格式、workspace 和状态可能比任务本身还重。引入这层工具的前提,是输入处理已经成为重复工作,或者错误输入的代价足够高。

这套职责划分提供了可检查的输入格式、明确的失败状态和工具分工。缓存新鲜度仍需要显式管理,设计范围仍需要看图确认,跨机器协作也不在本地状态方案的承诺之内。保留这些边界,后续才容易判断新增能力应该进入 CLI、Agent 工作流程,还是独立的协作系统。