软件团队花了几十年将确定性构建到工具链中。包管理器的锁文件。容器的固定基础镜像。编译产物的可重现构建。这一原则众所周知:相同的输入应该总是产生相同的输出,在任何机器上,在任何时间。
设计交付从未应用过这一原则。它默认是一个根本上依赖人的、因此是不确定的过程。设计师向开发者解释设计,开发者解读它。解读因人而异,因天而异,因 Zeplin 评论的清晰程度而异。你无法重放它,无法测试它,无法对它进行差异比较。
在 AI 编程 Agent 的时代,不确定性交付已成为一个头等工程问题。figmascope 用一个冻结的、可移植的上下文包来解决这个问题。
为什么当前工具对 Agent 来说是不确定的
Zeplin 和 Avocode 给你从 Figma 提取的数字——图层尺寸、颜色值、字体大小。但它们以可浏览的 UI 形式提供,而不是机器可读的产物。指向 Zeplin 的 Agent 必须导航 UI 才能找到值,这既脆弱、受速率限制,又取决于注释的写法。
Figma Dev Mode 走得更远:它直接从设计生成内联代码片段。但这些片段是无状态的——按需重新生成,没有版本控制。没有可以提交的包,没有可以差异比较的文件。如果设计师更新了设计,Dev Mode 视图会静默更新。你不知道底层设计相对于上次导出的内容是什么时候改变的。
截图是最坏的情况:纯像素数据,完全不确定地解析,每次产生不同的结构推断。
实时 MCP 连接——让 Agent 实时通过 API 访问 Figma 文件的工具——从定义上来说就是不确定的。文件在 Agent 读取时可能发生变化。Agent 早上 9 点的运行和下午 2 点的运行看到不同的输入。你无法重现早上 9 点的运行,因为来源已经改变了。
Agent 是概率系统。给它们提供不确定的输入不仅会产生差异——还会使系统无法测试。你无法判断糟糕的输出是由模型、提示词还是两次运行之间有人移动了一个图层造成的。
包作为编译单元
理解 figmascope 导出的正确心智模型是编译产物。就像编译器接受源代码并产生确定性二进制文件——相同的源代码、相同的标志、相同的二进制——figmascope 接受 Figma 文件状态并产生确定性包:相同的文件状态,每次相同的包。
包是一个冻结的快照。它捕获设计的特定版本,并序列化每个相关属性:空间布局、组件标识、Token 绑定、字符串内容、层级。一旦导出,包就是不可变的。Figma 文件可以改变;包不会。如果你想合并这些变化,你重新导出并获得一个新包。
这就是编译单元模型。设计文件是源代码。包是产物。Agent 消费产物,而不是源代码。
确定性交付的四个属性
可快照。交付产物必须代表特定时间点。不是"Figma 文件的当前状态"——而是一个命名的、有版本的导出。figmascope 包携带带有导出时间戳和包含内容指纹的 _meta.json。包是快照,不是实时视图。
可移植。产物必须是自包含的。不依赖外部服务、实时 API 或已登录的会话。figmascope 包是普通文件的 ZIP——JSON、Markdown、PNG。你可以复制它、发邮件、提交到 git、附加到 PR、交给初级开发者或编程 Agent,无需任何设置。
可检查。如果无法验证其中的内容,确定性产物毫无用处。包中的每个文件都是人类可读的。CONTEXT.md 是 Markdown。tokens.json 是类 W3C 的结构。逐屏 IR 是带有清晰字段名的 JSON。工程师可以打开包并准确审计 Agent 被告知了什么。这与"我粘贴了截图并获得了一些代码"在质量上完全不同。
可重现。给定相同的 Figma 文件状态,两次单独的导出应该产生功能等价的包。不是字节相同(时间戳不同),但语义相同:相同的节点结构、相同的 Token 值、相同的组件清单。如果你从未更改的文件导出两次,包在语义上有所不同,说明出了问题。这个属性让你可以验证导出流水线并捕获提取器本身的回归。
实践中的效果
设计师完成一个冲刺的屏幕设计。他们导出一个包。包被提交到仓库,与工单一起——或者附加到 Jira 问题,或者放在共享驱动器,取决于你的工作流。此时,交付产物已固定。Agent(或开发者)从包工作,而不是从实时 Figma 文件工作。
实现中途,设计师更新了三个屏幕。没问题:开发者的工作包不受影响。新屏幕获得新的导出。现在你有两个包,可以对它们进行差异比较:开发者开始使用的设计与当前设计之间有什么变化。这正是基于截图或实时连接的工作流无法实现的变化可见性。
在多 Agent 工作流中——一个 Agent 构建组件库,另一个构建屏幕布局,第三个编写测试——每个 Agent 获得相同的包作为真相来源。它们都从相同的冻结设计状态工作。它们的输出是可组合的,因为它们的输入是共享且固定的。这是真正可靠的多 Agent UI 生成的前提条件。
差异比较包
因为包是普通文件,它像代码一样差异比较。两次跨两个 Figma 版本对同一文件的导出给你一个 JSON 差异,精确告诉你发生了什么变化:
- 哪些节点被添加或删除
- 哪些 Token 绑定发生了变化
- 哪些字符串被更新
- 哪些组件变体被交换
- 哪些布局属性发生了变化(内边距、间距、方向)
这是当前任何交付工具都不存在的设计变化可见性。Figma 有自己的版本历史,但它是可视化的、面向设计师的。包差异是结构化的、面向开发者的:机器可读的变化数据,可以驱动自动化测试、更新变更日志或触发 CI 工作流。
设计交付的 CI/CD
一旦交付是确定性的,CI/CD 就自然而然地跟上了。你可以编写针对包运行的测试:"这个屏幕必须包含一个 Button/Primary 组件","这个 Token 必须被绑定且不是硬编码值","这个字符串必须有一个 stringRef 键"。这些是针对结构化数据的静态分析检查。它们在毫秒内运行,在流水线中运行。
你还可以对照给定的包验证代码生成 Agent 的输出。Agent 使用了 Token 还是硬编码了字面量?它生成了正确数量的重复组件实例吗?它使用了正确的间距值吗?当真相来源是结构化文件而非 PNG 时,这些问题都是可回答的。
MCP 对比
MCP 风格的 Figma 实时连接正在获得关注。其吸引力显而易见:Agent 始终看到最新设计,没有导出步骤,没有手动包管理。但实时连接以便利换取确定性——对于 AI Agent 来说,这种交换是不好的。
实时连接意味着:Agent 的上下文取决于它何时运行。如果设计师在白天工作,早上 9 点的运行和下午 2 点的运行看到不同的数据。你无法重现早期的运行。你无法针对固定输入进行测试。你无法审计 Agent 被告知了什么。如果生成的代码是错误的,你无法区分"模型做了一个糟糕的推断"和"Agent 运行期间设计发生了变化"。
正确的模型是:实时连接用于设计探索和迭代(重时效性),确定性包用于交付和生成(重可重现性)。它们不是竞争关系——它们在工作流的不同节点运行。
向初级开发者交付
使包对 AI Agent 有用的相同属性也使其对刚接触代码库的人类开发者有用。拿到包的初级开发者有:CONTEXT.md 中的完整规范、tokens.json 中的所有 Token 值、清单中列出的所有组件及其属性、所有字符串及其标识。他们不需要进入 Figma 文件,不需要 Figma 账户,不需要知道哪个屏幕是权威的。
包是一个完整的、自包含的工作单。与 Agent 接收到的相同。唯一的区别是人类阅读它,Agent 以编程方式处理它——但产物是相同的。
这种统一——相同的产物,人类或 Agent 消费者——就是重点。包是交付的单位。其他一切都是实现细节。
通过 Claude Code、Cursor 或 Aider 实践确定性交付。所有工具都从相同的 figmascope 导出开始。