Đây là quy trình đã trở thành mặc định trong mọi nhóm design-to-code hiện nay: xuất frame từ Figma, dán PNG vào Claude hoặc Cursor, gõ "build this", rồi lặp từ output hallucinated. Nó hoạt động vừa đủ để có cảm giác hiệu quả. Nhưng không đủ tốt để đưa lên production.

Đây không phải vấn đề năng lực mô hình. Đây là vấn đề đầu vào. Ảnh chụp màn hình là cách biểu diễn tệ nhất có thể của thiết kế Figma để LLM suy luận — và đó gần như là thứ mà mọi nhóm đều dùng đầu tiên. Bundle ngữ cảnh của figmascope là giải pháp thay thế có cấu trúc.

Hệ thống phân cấp đã biến mất

File Figma là một cây. Frame chứa các nhóm auto-layout, trong đó chứa các component instance, trong đó chứa các layer text và fill. Cây đó mã hóa ý định layout: hàng này là flex container, card này là padded box, ba item này là sibling với gap 16px giữa chúng.

Ảnh chụp màn hình làm phẳng cây đó thành lưới pixel. LLM thấy hình dạng và màu sắc. Nó không thấy cấu trúc layout — nó suy luận. Và suy luận bị mất mát theo cả hai hướng: mô hình có thể tái tạo cấu trúc trông đúng về mặt trực quan nhưng sai về mặt ngữ nghĩa (div có chiều rộng cố định thay vì flex child, absolute positioning thay vì auto-layout), hoặc nó có thể thấy sự mơ hồ cấu trúc và chọn tùy tiện.

Bạn không thể biết từ PNG liệu một hàng ngang các item được triển khai bằng display: flex, CSS Grid, HStack tùy chỉnh, hay ba div positioned tuyệt đối. Chúng trông giống hệt nhau về mặt trực quan. LLM chọn một. Lựa chọn thay đổi giữa các lần chạy.

Ngữ nghĩa không tồn tại qua quá trình raster hóa

LLM có thể thấy rằng hình chữ nhật với góc bo tròn chứa một số text và icon. Những gì nó không thể thấy:

Ngữ nghĩa trong Figma nằm trong layer tree: tên component, thuộc tính variant, loại node. Component Button/Primary/Large được định kiểu rõ ràng. Trong ảnh chụp màn hình, nó là hình chữ nhật bo góc với shadow và label. Mô hình đoán "đây có lẽ là button" đúng phần lớn thời gian — rồi đoán "đây có lẽ là variant primary" dựa trên màu sắc, có thể hoặc không khớp với tên thực tế của design system.

Những lỗi nhỏ cộng dồn. Ghost button được render thành outlined button. Tooltip được render thành modal trigger. Trạng thái disabled được render thành active. Mỗi cái này cách nguồn sự thật một bước suy luận ảnh chụp màn hình.

Hệ thống spacing không phân giải thành số

Nhìn vào ảnh chụp màn hình của card với padding. Padding là bao nhiêu? Bạn không thể biết nếu không đo pixel, biết tỷ lệ canvas, biết độ phân giải xuất, và tính toán. LLM tính toán sai — nó ước tính, làm tròn, và không có cách nào biết design system của bạn dùng grid cơ sở 8px hay 4px hay thứ gì khác.

Vì vậy nó đoán. Nó tạo ra padding: 12px khi thiết kế nói 16. Nó tạo ra gap: 8px khi thiết kế nói 12. Những con số này trông hợp lý khi tách biệt nhưng sai — và nếu design system của bạn dùng spacing tokens như spacing.md hay Spacing/400, LLM không biết về chúng chút nào. Nó hardcode các literal sẽ trôi dạt khỏi hệ thống ngay khi có gì đó thay đổi.

LLM không hallucinate. Nó đang làm chính xác những gì bạn sẽ làm khi chỉ có ảnh chụp màn hình: đoán. Bạn chỉ ngạc nhiên khi những đoán đó sai vì bạn có thể thấy câu trả lời đúng trong file Figma suốt thời gian đó.

Quan hệ token biến mất

Designer của bạn đặt background đó thành #7F5CFE. Trong Figma, hex đó được gắn với biến: color/brand/primary. Gắn kết đó có ý nghĩa — nó có nghĩa màu tham gia vào theming, dark mode hoán đổi nó, nếu màu brand thay đổi bạn cập nhật một biến và mọi instance cập nhật.

Trong ảnh chụp màn hình: nó màu tím. LLM tạo ra background-color: #7F5CFE. Quan hệ token đã biến mất. Codebase của bạn giờ có hardcoded hex không bao giờ theo dõi design system. Nhân điều này với mọi component trong màn hình.

Điều tương tự áp dụng cho typography scale, border radius, và định nghĩa shadow. Mỗi giá trị trong file Figma được duy trì tốt có khả năng là token có tên. Mỗi giá trị trong ảnh chụp màn hình chỉ là một con số.

Tái sử dụng component không nhìn thấy được

Màn hình được tạo tốt tái sử dụng component. Bốn product card là bốn instance của cùng một component ProductCard. Avatar trong nav và avatar trong comment thread đều là instance của Avatar/Medium. Điều này quan trọng với code: bạn muốn một React component, không phải bốn biến thể tự làm sẽ phân kỳ.

Từ ảnh chụp màn hình, LLM thấy bốn hình chữ nhật trông giống nhau. Nó có thể tạo ra một component có thể tái sử dụng — hoặc nó có thể tạo ra bốn block JSX gần như giống hệt nhau vì nó không nhận ra chúng là cùng một thứ. Không có tín hiệu nào trong hình ảnh để cho biết cái nào đúng.

IR mà figmascope xuất mang componentId trên mỗi instance node. Agent biết: bốn node này đều là ProductCard. Tạo một lần, render bốn lần với props khác nhau. Đó là output bạn muốn. Đó là output bạn không thể có được từ pixel.

Nhận dạng chuỗi bị mất

Bạn có nút "Continue" trên ba màn hình khác nhau. Ba instance đó có phải cùng một chuỗi không, hay một designer đã viết chúng độc lập? Trong file Figma có cấu trúc tốt, chúng tham chiếu cùng một string key. Điều đó có nghĩa là một mục i18n, một thay đổi lan truyền khắp nơi.

Trong ba ảnh chụp màn hình: ba lần LLM tạo ra chuỗi hardcoded. Nếu bạn đang xây dựng ứng dụng quốc tế hóa, giờ bạn có ba chuỗi cần tìm và thay thế thay vì một chuỗi để tra cứu. Chuyện nhỏ. Cộng dồn qua codebase thực tế.

Tại sao LLM hallucinate: nó tái suy ra cấu trúc mỗi lần

Mô hình không có bộ nhớ về các lần chạy trước. Mỗi lần bạn dán cùng ảnh chụp màn hình, nó tái tạo cấu trúc từ đầu. Việc tái tạo mang tính xác suất — nghĩa là cùng ảnh chụp màn hình + cùng prompt + cùng mô hình có thể tạo ra output khác nhau có thể đo được trong các lần chạy khác nhau. Cùng thiết kế, code khác nhau. Tên component khác nhau, pattern className khác nhau, lựa chọn layout khác nhau.

Đây không phải lỗi mô hình. Đây là hành vi mong đợi của mô hình xác suất với ràng buộc không đủ. Ảnh chụp màn hình cung cấp ràng buộc không đủ. Mô hình lấp đầy khoảng trống. Khoảng trống được lấp khác nhau mỗi lần.

Bạn có thể khắc phục một phần bằng prompt dài, chi tiết hơn — "dùng Tailwind, dùng grid 8px, dùng những tên component này..." — nhưng khi đó bạn đã tự chỉ định cấu trúc lẽ ra phải có trong file thiết kế. Bạn đang làm công việc trích xuất mà công cụ nên làm.

Vấn đề tái tạo

Các nhóm dùng ảnh chụp màn hình để bàn giao design-to-code gặp phải cùng một vấn đề: output không thể tái tạo. Hai developer, cùng ảnh chụp màn hình Figma, độc lập prompt Claude — họ nhận được cấu trúc component khác nhau, pattern className khác nhau, quyết định lồng nhau khác nhau. Giờ bạn có hai codebase trông giống nhau về mặt trực quan nhưng không nhất quán về kiến trúc.

Điều này làm code review khó hơn. Làm refactoring khó hơn. Làm audit tuân thủ design system không thể. Bạn không thể diff "agent đã tạo ra gì từ thiết kế này" nếu câu trả lời thay đổi mỗi lần chạy.

Ngữ cảnh có cấu trúc giải quyết khả năng tái tạo vì nó cố định đầu vào. Bundle đầu vào xác định — cùng JSON với cùng node ID, tên component, giá trị token, và quan hệ không gian — sẽ tạo ra output nhất quán hơn nhiều qua các lần chạy, agent và developer. Không hoàn toàn xác định: mô hình vẫn mang tính xác suất. Nhưng phương sai giảm mạnh khi cấu trúc được chỉ định thay vì suy luận.

Những gì ảnh chụp màn hình cho bạn so với những gì IR cho bạn

Lấy một product card: hình ảnh, tiêu đề, phụ đề, giá, nút "Add to cart". Đây là những gì mỗi đầu vào cung cấp cho agent:

Đầu vào ảnh chụp màn hình: Hình chữ nhật với hình ảnh ở trên, hai dòng text, một con số, và một nút. Màu sắc được suy luận. Padding được ước tính. Đây là component hay one-off thì không biết. Variant nút được suy luận từ màu sắc. Hệ thống spacing không biết.

Đầu vào IR: Node kind FRAME, tên ProductCard, component ID liên kết đến định nghĩa component. Auto-layout với hướng dọc, gap 16px, padding ngang 16px, padding dọc 12px. Node con: IMAGE (lấp đầy chiều rộng, chiều cao cố định), TEXT với stringRef.key: "product.title" và style typography/heading.sm, TEXT với stringRef.key: "product.subtitle" và style typography/body.md, TEXT với fill color/price, INSTANCE của Button/Primary/Medium. Background fill color/surface.card. Border radius radius/card.

IR cho agent một bản đặc tả. Ảnh chụp màn hình cho nó một gợi ý.

Khung nhìn: đây là vấn đề tài liệu

Chúng ta đã giải quyết chính xác vấn đề này cho source code hàng thập kỷ trước. Bạn không đưa cho agent ảnh chụp màn hình của codebase và yêu cầu nó suy luận về kiến trúc. Bạn đưa cho nó code — biểu diễn có cấu trúc, có thể phân tích, có ngữ nghĩa có ý nghĩa. Abstract syntax tree, không phải ảnh của editor.

Thiết kế Figma là dữ liệu có cấu trúc. Chúng có cấu trúc cây được định nghĩa rõ ràng với các node có kiểu và giá trị có tên. Figma API expose cấu trúc này hoàn toàn. Lý do duy nhất quy trình ảnh chụp màn hình vẫn tồn tại là việc trích xuất cấu trúc và định dạng nó thành ngữ cảnh có ma sát.

Giảm ma sát đó là điều figmascope làm. Bạn dán URL Figma, quá trình xuất chạy trong trình duyệt của bạn, và bạn nhận được ZIP với ngữ cảnh có cấu trúc: CONTEXT.md, tokens.json, per-screen IR, component inventory, strings manifest. Mọi thứ agent cần, không có gì suy luận từ pixel.

Giữ ảnh chụp màn hình để xác nhận trực quan — bundle bao gồm PNG 2x chính xác cho mục đích đó. Dùng cấu trúc cho mọi thứ khác. Xem thực tế: quy trình Cursor, quy trình Claude Code, hoặc quy trình Aider.