← 노트로 돌아가기

캔버스가 숨겨두었던 레이아웃 레이어

0.8.0 프리뷰에 달린 한 커뮤니티 답글이 에이전트 네이티브 디자인의 진짜 질문을 짚어냈다. 캔버스가 더 이상 작업 단위가 아니게 되면, 사용자는 레이아웃을 어떻게 계속 이해할 수 있을까?

캔버스가 숨겨두었던 레이아웃 레이어

유용한 커뮤니티 답글은 더 큰 버튼을 요구하지 않는다. 빠져 있는 레이어를 지목한다.

그것이 Open Design 0.8.0-preview 디스커션에서 일어난 일이다. 출시 스레드는 두 가지 전환을 주장했다. 캔버스를 일차적인 작업 단위로 취급하기를 멈추는 것, 그리고 에이전트를 일급(first-class) 디자인 작업자로 만드는 것이다. 한 답글은 그 방향에는 동의하면서도, 가장 어려운 지점을 짚었다. 캔버스가 사라지면, 사용자는 그것을 자신 있게 편집하기 전에 여전히 에이전트가 무엇을 만들었는지 이해할 방법이 필요하다는 것이다.

그 답글에 등장한 표현이 “Layout Understanding Layer(레이아웃 이해 레이어)”였다. 이는 안일한 답을 거부하기 때문에 좋은 이름이다. 에이전트 네이티브 디자인이 “스크린샷을 믿어라”를 의미할 수는 없다. 그것은 산출물에 대한 읽을 수 있는 모델을 필요로 한다. 섹션, 의도, 편집 가능한 부분, 안정적인 참조, 그리고 권장 편집 동작들 말이다. 이 글은 그 답글을 진지하게 받아들이려는 시도다 — 그런 레이어가 무엇을 담을 수 있는지, Open Design 안에서 어디에 위치해야 하는지, 그리고 왜 그것이 로드맵 약속이 아니라 기여 경로인지를 그려보려 한다.

캔버스는 디자이너에게 공간적 확신을 주었다

Figma의 캔버스는 단지 그리기 표면이 아니다. 그것은 설명 표면이기도 하다. 줌 아웃해서 페이지 계층을 보고, 프레임을 클릭하고, 제약 조건을 검사하고, 레이어 이름을 바꾸고, 작업의 한 조각이 어디서 끝나고 다른 조각이 어디서 시작되는지 이해할 수 있다.

캔버스가 사라질 때 실제로 잃는 것

그 이해는 사라지기 전까지는 과소평가하기 쉽다. 생성된 랜딩 페이지는 샌드박스 미리보기에서는 올바르게 보이면서도 여전히 지시하기 어려울 수 있다. 문제는 픽셀이 아니다 — 사람과 에이전트 사이에 공유된 어휘가 없다는 점이다.

“히어로를 더 자신감 있게 만들어”는 에이전트와 사람이 히어로가 무엇인지에 대해 합의했을 때만 유용하다. “가격 섹션을 더 빡빡하게 다듬어”는 산출물이 개정을 거쳐도 안정적인 섹션 정체성을 유지할 때만 작동한다. 그것이 없으면 모든 지시는 가리키기로 전락한다. 디자이너는 영역을 위치로 설명하고(“위에서 두 번째 블록”), 에이전트는 렌더링된 출력에서 추측하며, 다음 재생성은 조용히 모든 것의 번호를 다시 매긴다. 캔버스는 이 비용을 조용히 흡수해왔다. 캔버스는 당신을 위해 부분들에 이름을 붙여주었고, 작업하는 동안 그 이름들을 안정적으로 유지했으며, 설명하지 않고도 하나를 선택할 수 있게 해주었다.

단위가 틀렸더라도 그 명료함은 지킬 가치가 있다

이것이 #DeFigma 주장에서 신중해야 하는 부분이다. 캔버스는 에이전트 네이티브 시스템에는 잘못된 작업 단위일 수 있다 — 그것은 파일을 작성하는 에이전트가 아니라 사각형을 드래그하는 사람을 전제하기 때문이다 — 하지만 사람들이 캔버스에서 얻었던 명료함은 여전히 가치 있다. “캔버스를 버린다”와 “캔버스가 제공하던 이해를 버린다”를 같은 결정으로 취급하는 것이 실수일 것이다. 그 둘은 같지 않다. Open Design은 그 명료함을 던져버릴 게 아니라 산출물 모델 안으로 옮겨야 한다. 레이아웃 레이어는 그 이전(relocation)을 가리키는 이름이다.

Open Design은 이미 올바른 기본 요소를 갖추고 있다

이 제안이 Open Design에 들어맞는 이유는, 이 프로젝트가 이미 명시적인 계약(contract)을 중심으로 구축되어 있기 때문이다. 스킬은 SKILL.md 파일이다. 디자인 시스템은 DESIGN.md 파일이다. 플러그인은 open-design.json 사이드카를 추가한다. 시스템 안의 어떤 것도 리버스 엔지니어링해야 하는 바이너리 덩어리가 아니다. 계약은 텍스트이고, 텍스트는 에이전트와 사람 모두 읽을 수 있는 것이다. 그 메커니즘은 스킬 31개, 시스템 72개: Open Design 라이브러리는 어떻게 작동하는가에서 다루며, 제품 차원의 주장은 우리가 Open Design을 제품이 아니라 스킬 레이어로 만든 이유에 있다.

레이아웃 레이어는 같은 패턴을 따라야 한다. 에이전트가 읽을 수 있는 텍스트, UI가 렌더링할 수 있는 상태, 그리고 다른 에이전트가 재사용할 수 있는 메타데이터여야 한다. 이 세 가지를 한꺼번에 만족시키지 못한다면, 그것은 잘못된 형태다.

레포 관점에서 보면, 이는 세 가지 표면을 가리킨다:

표면담아야 할 것
산출물 매니페스트섹션, 컴포넌트, 에셋, 생성된 파일에 대한 안정적인 ID
플러그인 스냅샷어떤 스킬, 디자인 시스템, 입력, 파이프라인 단계가 산출물을 만들었는지
리뷰 UI / 헤드리스 출력레이아웃 맵, 편집 가능한 측면, 그리고 권장 편집 의도

중요한 제약: 이 레이어는 또 하나의 독점 캔버스가 되어서는 안 된다. 피해야 할 실패 모드는 새 이름으로 Figma의 씬 그래프를 다시 만드는 것이다 — Open Design UI만 렌더링할 수 있고 앱을 떠나는 순간 죽어버리는, 풍부하지만 앱 전용인 구조 말이다. 레이아웃 레이어는 대신 파일과 함께 이동하는 평범한 산출물 맵이어야 하며, 그래야 기여자가 텍스트 편집기에서 그것을 읽을 수 있고 다른 에이전트가 SDK 없이도 그것을 소비할 수 있다.

빈 캔버스 위로 와이어프레임 레이아웃 골격이 선택 가능한 자체 레이어로 떠오르는 모습, 거의 흰색에 가까운 에디토리얼 바탕 위 녹색 프레임 안에
레이아웃 레이어는 캔버스가 암묵적으로 유지하던 구조다 — 에이전트와 사람이 둘 다 읽을 수 있는 곳으로 끄집어낸 것이다.

레이아웃 레이어의 실용적인 형태

에이전트 네이티브 디자인을 덜 불투명하게 느끼게 해줄 가장 작은 버전은 다음과 같다:

  1. 생성된 각 산출물은 안정적인 시맨틱 ID를 갖는다: hero, proof-strip, pricing, faq, final-cta.
  2. 각 ID는 의도 문장을 담는다: “상단 섹션”이 아니라 “제품의 약속을 한 화면에서 설명한다”.
  3. 각 섹션은 편집 가능한 측면을 나열한다: 카피, 밀도, 레이아웃, 색상, 미디어, 모션, 데이터 소스.
  4. 생성된 각 파일은 그것을 만든 섹션 ID로 다시 연결된다.
  5. 각 리뷰 패스는 권장 편집 의도를 내보낸다: “히어로 헤드라인을 줄여라”, “가격 카드의 대비를 높여라”, “고객 후기 블록을 나눠라”.
  6. UI는 이를 내비게이터로 렌더링하고, 헤드리스 사용자는 같은 구조를 JSON 또는 Markdown으로 받는다.

매니페스트가 실제로 어떻게 생겼을지

이것을 글로 적어두는 핵심은 그 구조가 평범하다는 점이다 — 바로 그 때문에 그것이 비공개 트릭이 아니라 공개 계약이 될 수 있다. 생성된 랜딩 페이지의 매니페스트는 다음과 같을 수 있다:

{
  "artifact": "landing/index.html",
  "producedBy": { "skill": "magazine-poster", "system": "linear", "stage": "compose" },
  "sections": [
    {
      "id": "hero",
      "intent": "Explain the product promise in one screen",
      "editable": ["copy", "density", "media"],
      "files": ["landing/index.html#hero", "landing/hero.css"]
    },
    {
      "id": "pricing",
      "intent": "Let a visitor self-select a plan without scrolling back",
      "editable": ["copy", "layout", "data-source"],
      "files": ["landing/index.html#pricing", "landing/pricing.json"]
    }
  ],
  "suggestedEdits": [
    { "target": "hero", "intent": "shorten headline to one line" },
    { "target": "pricing", "intent": "drop from three plans to two" }
  ]
}

이 키들 중 어느 것도 특이하지 않다. sections는 리스트이고, editable은 열거형이며, files는 역참조다. 가치는 스키마의 영리함에 있는 것이 아니다 — ID가 재생성을 거쳐도 살아남는다는 사실에 있다. 그래서 에이전트가 두 번 다시 작성해도 같은 pricing 블록은 여전히 pricing이다.

그것만으로도 디자이너가 “pricing을 세 개 플랜에서 두 개로 바꿔”라고 말할 수 있게 하기에 충분하고, 코드 에이전트가 픽셀에서 추측하지 않고 올바른 파일을 패치하게 하기에 충분하다. 지시는 섹션 ID로 해석되고, 섹션 ID는 파일 집합으로 해석되며, 편집은 의도된 곳에 안착한다.

이것이 기능 요청이 아니라 기여 경로인 이유

그것은 또한 커뮤니티에 깔끔한 기여 경로를 제공한다. 기여자는 여기서 돕기 위해 제품을 재설계할 필요가 없다. 한 산출물 유형에 대한 매니페스트를 내보내는 스킬, 편집 의도를 제안하는 리뷰 아톰, 다른 스킬이 읽을 수 있는 필드를 추가하는 매니페스트 확장, 또는 재생성을 거쳐도 섹션 ID가 안정적으로 유지되는지 단언하는 테스트 케이스를 작성할 수 있다. 이들 각각은 하나의 출력을 덜 불투명하게 만드는 작고 머지 가능한 변경이다 — 그리고 이 레이어는 평범한 텍스트이므로, 덱과 모바일 화면을 작업하는 두 기여자는 공유 바이너리 포맷을 조율할 필요가 없다. 레이아웃 레이어는 앱 안에 묻힌 비공개 기능이 아니라 공개 계약이 된다.

다음에 할 일

이런 종류의 문제에 작업하고 싶다면, 하나의 산출물을 검사하기 쉽게 만드는 작은 스킬이나 플러그인을 기여하라. 구체적인 출력에서 시작하라: 랜딩 페이지, 덱, 또는 모바일 화면. 안정적인 섹션 ID를 추가하고, 편집 가능한 측면을 설명하고, 산출물과 함께 JSON 또는 Markdown으로 내보내고, 리뷰어가 검사 가능한 레이어가 만드는 차이를 볼 수 있도록 before/after 산출물과 함께 PR을 열어라.

이것은 여전히 출시된 기능이 아니라 방향이다 — 지금 그것에 이름을 붙이는 가치는, 기본 요소가 이미 존재하기 때문에 그 작업이 재작성이 아니라 추가적이라는 데 있다.

스킬을 기여하라.

관련 읽을거리


← 노트로 돌아가기 GitHub · 소스 ↗