3줄 요약

  1. OpenUI 팀은 ChatGPT 웹의 생성형 UI를 분석했다. 모델은 설명문과 화면 요소, 동작을 DIL이라는 형식으로 작성한다. 서버는 이를 실행 가능한 JavaScript와 데이터로 변환한다.
  2. 브라우저는 코드를 격리된 환경에서 실행하고 ChatGPT의 기존 컴포넌트로 화면을 표시한다. 슬라이더나 체크박스 조작은 모델을 다시 호출하지 않고 처리한다.
  3. 서버가 응답을 계속 재컴파일해도 사용자가 바꾼 값은 유지된다. 하지만 새로고침하면 값이 초기화되고, 후속 질문은 기존 화면을 수정하는 대신 새 화면을 생성한다.

무엇을 분석했나

Rabi Shanker Guha는 2026년 10월 8일, ChatGPT의 Intelligent UI를 역공학한 결과를 X에 공개했다. Intelligent UI는 답변에 슬라이더, 표, 차트, 지도와 입력 폼을 포함하고 사용자가 직접 조작할 수 있게 하는 기능이다. OpenAI의 공식 안내에서도 대화형 차트와 계산기, 시뮬레이션 등으로 정보를 탐색하는 사용법을 설명한다.1

Guha가 소개한 OpenUI 팀의 분석은 자신들의 ChatGPT 계정에서 수집한 대화 데이터, 응답이 전송되는 과정과 웹앱의 공개 JavaScript를 근거로 한다. GPT-6와 GPT-6 Thinking을 사용했으며, 서버 컴파일러도 입력과 출력의 짝을 토대로 재구현했다고 밝혔다.2

DIL을 작성하는 모델, 서버 컴파일러, 격리된 브라우저 실행 환경과 화면 렌더러의 관계

원문의 구현 구조 도식. 출처: Rabi Guha의 X 장문.

모델이 작성하는 형식

모델이 화면과 동작을 작성할 때 DIL이라는 형식을 사용했다고 분석팀은 설명한다. DIL은 설명문에 Markdown을 사용한다. 화면 요소에는 JSX와 비슷한 태그를, 상태와 계산에는 JavaScript를 사용한다. 상태는 사용자가 조작하면서 바뀌는 값이다. 작성자도 후속 답글에서 DIL이 어떤 말의 약어인지 아직 모른다고 했다.3

원문은 팀 요금 계산기를 예로 든다. 인원수 seats의 초기값은 8이다. 월 요금은 인원수에 29달러를 곱한 금액이다. 슬라이더는 1명부터 50명까지 선택할 수 있으며, 값이 바뀌면 요금도 갱신된다. 설명문과 제목을 작성하는 문법은 Markdown이고, 슬라이더와 제목을 표시하는 문법은 컴포넌트 태그다. 인원수를 저장하고 요금을 계산하는 부분은 JavaScript다.

이 형식을 사용하는 이유는 모델의 출력이 토큰 단위로 생성되기 때문이다. 모델이 이미 익숙한 표기법을 사용하면서도, 태그나 문장을 작성하는 도중에 실행 가능한 부분만 추출할 수 있어야 한다. DIL은 조건문, 반복문, 이벤트 처리 함수와 값을 문장에 삽입하는 표현도 제공한다.

서버가 변환하는 것

브라우저에서 실행할 수 있도록 DIL을 변환하는 작업은 서버가 맡는다. 서버는 JavaScript 프로그램과 JSON 데이터로 변환한 결과를 메시지의 model_dil_v2에 저장한다. JSON에는 화면에 표시할 고정 문구와 서버가 제공한 데이터가 포함된다.

이때 서버는 컴포넌트 태그를 함수 호출로 바꾸고, 설명문도 제목과 텍스트 컴포넌트로 변환한다. 문구는 별도 상수 테이블에 저장하므로 설명문만 추가되는 응답에서는 프로그램 전체를 변경할 필요가 없다.

컴파일 과정은 오류 처리와 입력 검증도 담당한다. 계산식에서 예외가 발생하면 해당 요소만 생략하고, 작성이 끝나지 않은 태그나 문장은 제외한다. 태그의 내용까지 작성된 요소라면, 컴파일러가 빠진 종료 태그를 추가해 완성한다. 컴포넌트에 없는 속성이나 형식이 틀린 값은 제거하고 진단 기록을 남긴다. 저자들은 아이콘의 fill 속성과 문자열로 작성한 gap="1"이 제거된 사례를 확인했다.

요금 계산기의 인원수를 저장할 때는 seats처럼 이름이 일정한 키를 사용한다. 같은 응답을 다시 컴파일해도 실행 환경은 이 키로 기존 값을 찾을 수 있다. 따라서 사용자가 이미 조작한 슬라이더 값이 유지된다.

브라우저의 실행과 화면 표시

분석에서 확인한 웹 실행 환경은 숨겨진 iframe과 Web Worker를 사용한다. iframe은 다른 실행 환경을 포함하는 문서 요소이고, Worker는 페이지의 화면 처리와 별도로 JavaScript를 실행하는 기능이다. 모델이 생성한 프로그램에서는 네트워크 접근, 타이머와 메시지 전송 등의 기능 사용을 제한한다. 프로그램이 정해진 시간 안에 응답하지 않으면 해당 프로그램을 격리하고 Worker를 재시작한다.

Worker는 프로그램을 실행해 이전 화면 구조와 새 구조의 차이를 계산한다. 그 결과를 요소 생성, 속성 변경, 배치 등의 명령으로 전송한다. 실제 화면은 ChatGPT 페이지가 자신의 컴포넌트를 사용해 표시한다. 클릭 처리 함수도 함수 전체를 보내지 않고 식별자로 전달한다.

요금 계산기에서 인원수를 8명에서 9명으로 바꾸면 페이지가 조작 정보와 함수 식별자를 Worker에 전달한다. Worker는 인원수를 9로 저장하고 월 요금을 261달러로 계산한 뒤, 필요한 화면 변경을 반환한다. 슬라이더 조작에 따른 요금 계산은 브라우저에서 처리하므로, 값을 바꿀 때마다 모델에 다시 요청할 필요가 없다.

원문에 따르면 클라이언트 코드에는 약 70종의 컴포넌트가 정의되어 있다. 저자들은 수집한 응답에서 39종을 관찰했다. 화면 요소를 얼마나 띄우고 어떤 색상과 크기로 표시할지는 디자인 토큰에 등록된 공통 값을 사용해 지정한다. 일부 속성은 픽셀 너비나 색상 코드도 허용한다. 이미지와 상품을 표시하는 복합 컴포넌트는 OpenAI가 미리 작성한 것을 사용했다.4

반려견 조끼 디자인 선택 화면, 저녁 식사 메뉴와 인원 조절 화면, 차트와 시나리오 조절 화면

원문에 제시된 ChatGPT 화면 사례. 출처: Rabi Guha의 X 장문.

응답이 생성되는 동안

서버는 원시 DIL, 컴파일된 프로그램과 데이터를 포함하는 메시지에 변경분을 전송한다. 분석팀이 확인한 서버는 수백 밀리초마다 그때까지 생성한 전체 내용을 다시 컴파일했다. 구조가 바뀌면 프로그램 전체를 교체한다. 문구만 추가되면 상수 테이블을 갱신한다. 태그가 아직 완성되지 않았다면 텍스트만 전송한다.

상세 원문의 한 측정 사례는 6,341자 응답이 18.7초 동안 84번 갱신됐다고 기록한다. 새 텍스트가 포함된 갱신은 76번이었다. 그중 52번은 프로그램 전체를 전송했고, 14번은 문구만 갱신했다. 나머지 10번은 미완성 태그 때문에 화면이 바뀌지 않았다. 다른 8번은 메시지 생성, 이미지 결과 전달과 완료 처리였다. 약 275KB의 변경 데이터 중 83%가 반복 전송한 코드였다.5

Worker는 새 프로그램을 기존 상태로 실행한다. 실행이나 렌더링에 실패하면 마지막으로 정상 동작한 프로그램을 유지한다. 화면에는 텍스트, 행, 차트와 높이 변화에 서로 다른 애니메이션을 적용한다.

데이터와 후속 질문

상세 원문에서는 모델이 이미지 URL이나 상품 가격을 직접 다시 작성하지 않는 방식도 설명한다. 이미지 컴포넌트는 검색어를 요청하고 서버가 검색 결과를 전달한다. 상품 가격은 도구 결과의 식별자와 필드 이름으로 참조하며, 서버가 해당 필드의 값을 공급한다. 이렇게 서버가 값을 제공하면 모델이 데이터를 다시 작성할 때 생길 수 있는 복사 오류를 줄일 수 있다. 날씨 수치처럼 모델이 직접 작성한 데이터도 관찰됐다.

슬라이더를 조작하는 것과 모델에 다시 질문하는 것은 구분된다. 후속 질문은 GenUI.issueNewTurn으로 현재 상태를 포함한 새 메시지를 보낸다. 예를 들어 반려견 조끼 디자인 화면에서는 선택한 스타일, 색상과 기능을 문장으로 만든다. 버튼을 누르면 그 문장이 새 사용자 메시지로 저장된다. 폼 제출도 같은 방식으로 처리한다.

저자들이 관찰한 제약도 이 구분과 관련 있다. 모델은 사용자가 화면에서 바꾼 상태를 직접 읽지 못하며, 새 메시지로 전달된 내용만 받는다. 후속 질문은 새 프로그램을 포함한 답변을 생성한다. 페이지를 새로고침하면 사용자가 변경한 상태가 사라졌다.

저자들은 가격 위젯을 한 번 클릭했을 때 명령이 158개 생성됐지만, 실제 변경은 4개뿐이었던 사례도 보고했다. 차트 지표를 바꾸자 매출이 6,930달러에서 256,410달러로 바뀐 계산 오류도 있었다. 정적 Markdown 대체 응답에서는 상태로 계산한 값과 반복문이 생성한 내용이 빠졌다. 이미지 검색이 요청과 다른 결과를 반환하고, 수집한 화면들이 고정 열 개수와 픽셀 너비를 사용한 점도 기록했다.5

별도 웹앱을 만드는 경우

기존 컴포넌트로 표현하기 어려운 요청에는 AppBlock을 사용한다. 원문의 드럼 머신은 Web Audio로 소리를 합성해야 하므로, 모델이 HTML, CSS와 JavaScript를 포함한 웹앱을 작성했다. 서버 컴파일러는 이 내용을 일반 컴포넌트처럼 변환하지 않고 표시용 참조만 생성한다. 클라이언트가 원시 응답의 앱 소스를 읽어 별도 도메인의 iframe에서 실행한다.

앱의 서체와 기본 간격에는 공통 스타일을 적용하고, 밝은 테마와 어두운 테마는 제공된 색상 변수로 맞춘다. iframe 크기도 앱 내용에 맞춰 조정한다. 앱의 내부 상태는 자체 JavaScript 변수가 관리하며, 저자들이 수집한 사례에서는 ChatGPT를 다시 호출하지 않았다.

템포와 음량, 패턴과 연주 패드를 조작하는 Drum Lab 웹앱

AppBlock으로 생성한 Drum Lab. 출처: Rabi Guha의 X 장문.

Guha의 최초 게시물은 모델이 원시 코드를 쓰지 않는다고 요약했다. 장문과 후속 답글은 DIL에 JavaScript가 포함되며 AppBlock에서는 웹앱 코드도 작성한다고 설명한다. 정확한 구분은 실행과 화면 표시 방식에 있다. 일반 컴포넌트 응답은 서버 컴파일과 격리된 실행 환경을 거치고, AppBlock은 별도 iframe에서 자체 화면을 표시한다.

출처

Rabi Shanker Guha, 「We reverse engineered ChatGPT Intelligent UI. Here’s how it actually works」, 2026년 10월 8일.


  1. OpenAI, Visualizations. 공식 문서는 사용법을 설명한다. 이 글의 DIL과 컴파일러에 관한 구현 설명은 OpenUI 팀의 분석을 요약했다. ↩︎

  2. 저자들은 대화를 내보내고 전송 데이터를 재생했다. 브라우저 검사, 공개 클라이언트 코드 분석과 기능별 프롬프트 실험도 수행했다. 재구현한 컴파일러의 출력이 수집한 중간 응답과 최종 응답에서 바이트 단위로 일치했다고 보고했다. 본 다이제스트에서는 그 실험을 재실행하지 않았다. ↩︎

  3. Guha의 DIL 약어에 관한 답글, 원시 코드 생성에 관한 답글. Guha는 10월 10일 OpenUI 비교 답글에서 OpenUI Lang을 클라이언트에서 중간 JSON으로 변환한다고 밝혔다. 모델이 생성하는 JavaScript는 OpenUI 1.5에 추가할 예정이라고 했다. ↩︎

  4. 분석 대상은 웹앱이다. 저자들은 실행 환경이 React Native의 JavaScript 엔진인 Hermes 관련 전역값도 허용한다고 설명했다. 이를 근거로 모바일에서도 같은 실행 환경을 사용할 가능성을 제시했다. 모바일 구현은 직접 조사하지 않았다. ↩︎

  5. 측정 수치, 데이터 참조, 후속 질문과 제약은 OpenUI 상세 원문에 수록돼 있다. 수치는 저자들이 수집한 개별 응답의 측정값이다. ↩︎ ↩︎