YouMind
Oturum aç

ChatGPT Intelligent UI'yi tersine mühendislikle inceledik. İşte gerçekte nasıl çalışıyor

@rabi_guha
İNGILIZCE08 Eki 2026
206K
2.0K
146
66
3.5K

TL;DR

Bu makale, ChatGPT'nin yeni piyasaya sürülen Intelligent UI'sinin arkasındaki teknik mimariyi detaylandırarak özel çıkarım dili (DIL), JavaScript ve JSON'a sunucu tarafı derleme ve yalıtılmış worker'lar aracılığıyla güvenli istemci tarafı yürütme kullanımını açıklıyor.

ChatGPT nihayet Generative UI'ı duyurdu ve bir gecede bu alanın adını Intelligent UI olarak değiştirdi. Biz de bunu nasıl hayata geçirdiklerini incelemek zorundaydık.

https://x.com/OpenAI/status/2107894997538525580

Bu yazı, OpenAI'ın amiral gemisi Intelligent UI'ı Web ve Mobil'de yerel (native) olarak nasıl katmanlara ayırdığını, hangi formatları kullandığını ve nasıl render ettiğini derinlemesine inceleyen bir analizdir.

Yapı taşları

ChatGPT'nin uygulaması iş yükünü model, arka uç sunucusu ve istemci arasında paylaştırıyor:

  • Çıkarım formatı: Model arayüzü, Markdown'ı JSX benzeri etiketler ve JavaScript ile harmanlayan DIL dilinde yazar.
  • Sunucu taraflı derleme: Sunucu her kısmi yanıtı bir JavaScript programına ve metin ile verilerden oluşan bir JSON belgesine dönüştürür.
  • İstemci çalışma zamanı: Yalıtılmış (sandboxed) bir çalışma zamanı programı yürütür ve UI işlemlerini üretir.
  • Render etme: ChatGPT bu işlemleri kendi yerel bileşenlerine uygular.
  • Tasarım sistemi ve katalog: Modelin kullanımına sunulan bileşenler, özellikler ve tasarım token'ları.
Rabi Shanker Guha - inline image

ChatGPT Intelligent UI Mimari Diyagramı

Çıkarım formatı

Modelin ürettiği şey budur. ChatGPT'de buna OpenAI'ın DIL adını verdiği bir dil deniyor: düz metin için Markdown, bileşenler için JSX benzeri etiketler, durum ve mantık için ise JavaScript kullanılıyor. Küçük bir yanıtın tüm katmanlardan nasıl geçtiğine birlikte bakalım:

text
1## Ekip planı tahmini
2Ekibiniz için **aylık fiyatı** görmek üzere kaydırıcıyı sürükleyin.
3{@body const [seats,setSeats] = DIL.useState(8)}
4{@body const price = seats*29}
5<box border padding={3} gap={2}>
6 <slider min={1} max={50} value={seats} onChange={setSeats}/>
7 <title size="xl">${price}/ay</title>
8</box>

Başlık ve paragraf sıradan Markdown'dır. Etiketler ise ChatGPT'nin kataloğundaki bileşenlerdir. İki {@body …} satırı JavaScript'tir: ilki seats adında bir durum (state) tanımlar, ikincisi ise bundan price değerini türetir. Kaydırıcı seats değerine bağlıdır, dolayısıyla onu hareket ettirmek fiyatı günceller.

Model arayüzü token token yazdığı için özel bir formata ihtiyaç vardır.

  • Güvenilir bir şekilde yazılması kolay olmalıdır, bu yüzden modelin zaten çok iyi bildiği gösterimlerden inşa edilmiştir.
  • Yarım yazılmışken bile kullanılabilir kalmalıdır. İfadeler kendi satırlarında durur ve açık kalan herhangi bir öğe otomatik olarak kapatılabilir. Bu sayede sunucu, kısmi bir yanıtı son tamamlanmış yapısında kesebilir ve yine de derleyebilir.

Sunucu taraflı derleme

İstemci, modelin çıktısını asla yazıldığı haliyle çalıştırmaz. OpenAI'ın sunucusu bunu bir JavaScript programına ve bir JSON belgesine derler; bunlar mesajla birlikte (model_dil_v2 olarak) saklanır. Yanıt şu şekilde derlenir (okunabilirlik için biçimlendirilmiştir):

javascript
1function __dilSafe(evaluate, failureValue) {
2 try { return evaluate(); } catch { return failureValue; }
3}
4
5DIL.render(__dil.jsx(() => {
6 const __dilConstants = DIL.useConstants();
7 const __dilModelDataBindings = DIL.useAppData((appData) => appData.opGenui?.modelDataBindings ?? {});
8 const [seats, setSeats] = DIL.useState(8, { key: "seats" });
9 const price = __dilSafe(() => seats * 29, undefined);
10 return __dil.jsx(__dil.Fragment, null,
11 __dil.jsx("title", { size: "lg" }, __dilConstants["0"]),
12 __dil.jsx("text", null, __dilConstants["1"], __dil.jsx("bold", null, __dilConstants["2"]), __dilConstants["3"]),
13 __dil.jsx("box", { border: true, padding: 3, gap: 2 },
14 __dilSafe(() => __dil.jsx("slider", { min: 1, max: 50, value: seats, onChange: setSeats }), null),
15 __dil.jsx("title", { size: "xl" }, __dilConstants["4"], __dilSafe(() => price, null), __dilConstants["5"])));
16}, { key: "body:2" }));
json
1{
2 "constants": {
3 "0": "Ekip planı tahmini",
4 "1": "Şunu görmek için kaydırıcıyı sürükleyin: ",
5 "2": "aylık fiyat",
6 "3": " ekibiniz için.",
7 "4": "$",
8 "5": "/ay"
9 },
10 "appData": { "opGenui": { "componentResults": {}, "modelDataBindings": {} } }
11}

Markdown, bileşenlerle aynı ağaç yapısına derlenir. Başlık bir title'a, paragraf içinde kalın yazı barındıran bir text'e dönüşür ve kelimeleri constants tablosuna taşınır.

Derleme işlemi, aksi takdirde her istemcinin tekrarlamak zorunda kalacağı işleri üstlenir:

  • Sade fonksiyon çağrıları. İşaretleme dili (markup), __dil.jsx çağrılarına dönüşür; böylece bir JavaScript çalışma zamanı, DIL için ayrı bir ayrıştırıcıya (parser) ihtiyaç duymadan programı değerlendirebilir.
  • Hata izolasyonu. İfadeler __dilSafe içine sarılır, böylece hata fırlatan bir ifade tüm render işlemini iptal etmek yerine yalnızca tek bir öğeyi devre dışı bırakır.
  • Ayrı bir tabloda metin. Statik metinler constants tablosuna taşınır; böylece yanıt akarken büyüyen metin programı değil veriyi değiştirir.
  • Kararlı durum anahtarları. Her durum parçası bir anahtar alır ({ key: "seats" }), bu sayede değeri her yeniden derlemede korunur.
  • Onarım ve doğrulama. Eksik ifadeler ve etiketler atılır, kapatılmamış öğeler kapatılır ve kataloğa karşı doğrulamayı geçemeyen özellikler kaldırılarak tanılama (diagnostic) olarak kaydedilir.

JSON belgesi, metin sabitlerini ve görsel arama sonuçları gibi sunucunun yanıt için çözümlediği tüm verileri tutar (bkz. Veri).

İstemci çalışma zamanı

İstemci, derlenmiş programı ve JSON belgesini alır. Görevi, programı çalıştıran bir çalışma zamanı (runtime) ile sonucu çizen bir render edici (renderer) arasında bölünmüştür.

Program model tarafından yazılan bir kod olduğu için doğrudan ChatGPT sayfasında çalıştırılmaz. ChatGPT, allow-scripts ve default-src 'none' içerik güvenlik politikasıyla yalıtılmış gizli bir iframe (runner.html) yükler ve bu da bir Web Worker başlatır.

  • Kilitleme (Lockdown). Worker, bir programı değerlendirmeden önce global kapsamından ağ erişimini, zamanlayıcıları, mesajlaşmayı ve dinamik kod çalıştırmayı kaldırır, kalan globalleri ise dondurur.
  • Değerlendirme. Ardından programı new Function ile değerlendirir. Çalışma zamanı nesneleri (DIL, __dil, GenUI) ve kataloğun bileşik bileşenleri parametre olarak aktarılır.
  • Bekçi (Watchdog). Belirli bir zaman aşımı süresi içinde yanıt vermeyen bir program karantinaya alınır ve worker yeniden başlatılır.

Çalışma zamanı, React tarzında küçük bir uzlaştırıcıdır (reconciler). Bileşeni render eder ve hook durumlarını anahtarlanmış yuvalarda tutar. Sonrasında ortaya çıkan ağacı bir öncekiyle karşılaştırır ve farkları bir işlem listesi olarak kodlar. Kendisi hiçbir şey çizmez.

Aşağıdaki açıklayıcı örnek, ilk render işleminden elde edilen işlemleri göstermektedir; her satır bir düğüme karşılık gelir. Her öğenin özellik adlarını listeleyen girdiler çıkarılmıştır:

text
1CREATE #1 title SET size = "lg" PLACE under root at 0
2CREATE #2 text "Ekip planı tahmini" PLACE under #1 at 0
3CREATE #3 text PLACE under root at 1
4CREATE #4 text "Şunu görmek için kaydırıcıyı sürükleyin: " PLACE under #3 at 0
5CREATE #5 bold PLACE under #3 at 1
6CREATE #6 text "aylık fiyat" PLACE under #5 at 0
7CREATE #7 text " ekibiniz için." PLACE under #3 at 2
8CREATE #8 box SET border = true, padding = 3, gap = 2 PLACE under root at 2
9CREATE #9 slider SET min = 1, max = 50, value = 8, onChange = fn#1 PLACE under #8 at 0
10CREATE #10 title SET size = "xl" PLACE under #8 at 1
11CREATE #11 text "$" PLACE under #10 at 0
12CREATE #12 text "232" PLACE under #10 at 1
13CREATE #13 text "/ay" PLACE under #10 at 2

Fonksiyonlar worker'dan asla çıkmaz; kaydırıcının işleyicisi yalnızca bir tanımlayıcı (fn#1) olarak gönderilir. Ağ üzerinden iletilirken işlemler, dizelerin ayrı bir tabloda tutulduğu ikili bir tamsayı dizisi olarak kodlanır.

Render etme

ChatGPT sayfası, işlemleri kendi bileşen ağacına uygular. Her CREATE, ChatGPT'nin tasarım sisteminden yerel bir bileşeni somutlaştırır ve sayfa, değişiklikleri geldikçe animasyonlarla işler. Sayfa yalnızca bilinen bileşen türleri için işlemleri kabul eder, bu nedenle model çıktısı rastgele bir işaretleme veya stil ekleyemez. İstisnalar, bazı özelliklerin kabul ettiği ham CSS değerleri (bkz. Tasarım sistemi ve katalog) ve bir iframe içinde çalışan AppBlock uygulamalarıdır (bkz. Acil çıkış kapısı).

Etkileşim ise ters yönde işler. Kullanıcı kaydırıcıyı 9'a çektiğinde, sayfa işleyicinin tanımlayıcısını ve argümanlarını worker'a gönderir. Worker setSeats(9) çağrısını yapar, yeniden render eder ve güncelleme işlemlerini döndürür. Bu süreçte modele hiçbir çağrı yapılmaz.

Tasarım sistemi ve katalog

Katalog, modelin neleri talep edebileceğini belirler. Buna ihtiyaç vardır çünkü model bir arayüzü ham yerleşim ve stil kurallarından sıfırdan inşa etmez. ChatGPT'nin nasıl çizeceğini zaten bildiği bileşenler arasından seçim yapar ve onları padding={3} gibi tasarım token'larıyla stillendirir. Piksel genişlikleri ve hex renk kodları gibi ham CSS değerleri bazı özellikler için kabul edilir, ancak tasarım token'ları tercih edilir. Bunun sonucunda:

  • Üretilen arayüzler her platformda ChatGPT'nin geri kalanıyla uyumlu görünür.
  • Derleyicinin çıktıyı kontrol edebileceği bir şeması olur. Bir bileşende var olmayan bir özellik veya yanlış türde bir değişmez değer (literal), derleme sırasında kaldırılır ve tanılama olarak kaydedilir.

Yakaladığımız bir yanıtta derleyici iki özelliği kaldırdı: bir simgedeki fill (bir unknown_prop tanısı) ve bir kutudaki gap="1" (bir invalid_literal tanısı).

Katalog üç bölümden oluşur:

  • Yerel bileşenler. ChatGPT'nin istemci kodundaki bileşen kayıt defterinde yaklaşık 70 bileşen tanımlanmıştır; yakaladığımız yanıtlarda bunların 39'u görülmektedir.
  • Boşluk, köşe yuvarlaklığı, renk ve boyut için tasarım token'ları.
  • Görsel ve ürün bileşenleri gibi, OpenAI tarafından DIL ile yazılıp sandbox'a önceden derlenmiş olarak gönderilen bileşik bileşenler. Yakaladığımız verilerde model bu bileşenleri kullandı ancak asla kendisininkini tanımlamadı.

Akış (Streaming)

Metni akışa almak basittir: her yeni token ekranda halihazırda bulunan metnin sonuna eklenir. Ancak bir arayüzü akışa almak üç nedenden dolayı daha zordur:

  • Çıktı genellikle henüz çalıştırılabilir değildir. Çoğu an itibarıyla eksik bir programdır; bir etiket veya ifade hala açıktır ve yazıldığı haliyle çalıştırılamaz.
  • Arayüz büyürken çalışmaya devam etmelidir. Kullanıcının halihazırda etkileşime girdiği bileşenler durumlarını korumalıdır.
  • Bazı içerikler ayrı gelir. Görseller gibi veriler metinden değil, sunucudan gelir.

Sunucu Taraflı Akış

Sona eklenen token'lardan oluşan düz bir akış bunu ifade edemez. Bunun yerine ChatGPT; ham metni, derlenmiş programı ve verilerini yan yana tutan yapılandırılmış bir mesaja yamalar (patch) akışı gönderir.

Yanıt tarayıcıya bir sunucu tarafından gönderilen olay akışı (POST /backend-api/f/conversation) üzerinden ulaşır. Her olay, oluşturulmakta olan mesaja yapılan JSON-Patch tarzı bir güncellemedir. Tek bir olay genellikle hem ham DIL metnini hem de onun derlenmiş formunu birlikte günceller. Aşağıda, yakalanan bir yanıttan kısaltılmış bir güncelleme örneği yer almaktadır:

json
1{"o": "patch", "v": [
2 {"p": "/message/content/parts/0", "o": "append", "v": " Arkadaşlarla Pazar kuzu rostosu — bol yemek, …"},
3 {"p": "/message/metadata/model_dil_v2/code", "o": "replace", "v": "DIL.render(__dil.jsx(()=>{…"},
4 {"p": "/message/metadata/model_dil_v2/constants", "o": "append", "v": {"0": "İşte arkadaşlarınızla güzel bir Pazar kuzu rostosu için bir plan — …"}},
5 {"p": "/message/metadata/model_dil_v2/constants", "o": "append", "v": {"1": "Madem sen"}},
6 {"p": "/message/metadata/model_dil_v2/fallbackMarkdown", "o": "append", "v": " Arkadaşlarla Pazar kuzu rostosu — …"}
7]}

Sunucu artımlı (incremental) derleme yapmaz. Büyük olasılıkla modelin her yeni çıktı parçasıyla birlikte, birkaç yüz milisaniyede bir, modelin o ana kadar yazdığı her şeyi yeniden derler ve sonucu gönderir. Derleme, henüz hiçbir etiket görünmeden ilk token ile başlar.

Derleyicinin şunlarla ilgilenmesi gerekir:

  • Yarım yazılmış bir yanıtı derlemek
  • Metni güncellemek
  • UI'ı güncellemek

Zaman çizelgesi kabaca şöyle görünür:

Rabi Shanker Guha - inline image

GIF

İstemci Taraflı Akış

Sayfa her yeni güncellemeyi yalıtılmış worker'a iletir. Worker bunu değerlendirir, mevcut durumla yeniden render eder ve güncelleme işlemlerini sayfaya gönderir. Durumlar, derleme sırasında eklenen anahtarlar sayesinde yeniden derlemelerde değerlerini korur. Yeni bir program değerlendirilemez veya render edilemezse, worker en son çalışan programı muhafaza eder.

Ardından sayfa her değişikliği animasyonla işler:

  • metin 0,7 saniye içinde belirginleşir;
  • yeni satırlar ve ızgara öğeleri 0,42 saniye içinde kayarak girer;
  • grafikler 1,8 saniye içinde çizilir;
  • kapsayıcı yükseklikleri aniden atlamak yerine yumuşak bir geçişle değişir.

Acil çıkış kapısı: AppBlock, iframe içinde bir uygulama

Rabi Shanker Guha - inline image

ChatGPT tarafından oluşturulan satır içi uygulama

Bazı istekler, Web Audio ile ses sentezleyen bir davul makinesi gibi yerel bileşenlerin tasarlanmadığı şeyler gerektirir. Bunlar için model bir AppBlock yazabilir: HTML, CSS ve JavaScript'ten oluşan, yanıta gömülü bağımsız bir web uygulaması. Aşağıda kısaltılmış bir örneğin başlangıcı yer alıyor:

text
1<AppBlock title="Davul Laboratuvarı" icon="app-chatgpt" variant="inline" app_block_id="drum-lab-01">
2<div id="dl" class="w-full min-w-0 space-y-4 text-base">
3 <style>
4 #dl{color:var(--viz-text)}#dl button{touch-action:manipulation}#dl .panel{background:var(--viz-panel);border:1px solid var(--viz-border);border-radius:15px}…
5 </style>
6 …
7 <button id="dl-play" class="btn" style="background:var(--viz-text);color:var(--viz-card);min-width:100px">▶ Oynat</button>
8 …
9</div>
10<script>
11(function(){
12const root=document.getElementById('dl');if(root.dataset.init)return;root.dataset.init="yes";
13…
14function audioInit(){if(!audio){const C=window.AudioContext||window.webkitAudioContext; if(!C)return false;audio=new C();…
15…
16})();
17</script>
18</AppBlock>

AppBlock'lar, Intelligent UI bileşenlerinden farklı şekilde render edilir.

Her şeyi bir araya getirmek

Bir prompt yazıyorsunuz. Model arayüzü yazmaya başlıyor, sunucu bunu ChatGPT'nin çalıştırabileceği bir şeye dönüştürüyor ve sayfa yanıt aktıkça onu parça parça inşa ediyor. Arayüz hazır olduğunda, bir kaydırıcıyı hareket ettirmek veya bir onay kutusunu işaretlemek, modeli tekrar sormadan arayüzü yerel olarak güncelliyor.

Modele özgü bir dil, sunucu taraflı bir derleme adımı, yerel render ediciler ve temeli sağlam bir tasarım sistemi tüm bunları mümkün kılıyor. Her parça kritik bir rol üstleniyor ve birlikte dünya çapındaki milyarlarca kullanıcıya yapay zeka odaklı arayüzlerin yeni neslini sunuyor. Yaşamak için ne güzel bir zaman!

Rabi Shanker Guha - inline image

ChatGPT Intelligent UI ekran görüntüleri

Metodoloji

Tüm gözlemler kendi ChatGPT hesaplarımızdan, ChatGPT web uygulamasının ürettiği ağ trafiğinden ve chatgpt.com adresinin herkese açık olarak sunduğu JavaScript kodlarından elde edilmiştir. Bu gözlemler Ekim 2026'da GPT-6 ve GPT-6 Thinking kullanılarak yapılmıştır.

Analiz Codex ve Claude desteğiyle gerçekleştirilmiştir. Codex ile yazılmış, görselleştirmeler Claude tarafından yapılmıştır.

(Daha detaylı versiyonu şu adrestedir: https://www.openui.com/blog/how-chatgpt-intelligent-ui-works

Tek tıkla kaydet

YouMind ile viral makaleleri AI derin okumayla incele

Kaynağı kaydedin, odaklı sorular sorun, argümanı özetleyin ve viral bir makaleyi tek bir AI çalışma alanında yeniden kullanılabilir notlara dönüştürün.

YouMind'ı keşfet
Üreticiler için

Markdown'ınızı temiz bir 𝕏 makalesine dönüştürün

Kendi uzun yazılarınızı yayımlarken görselleri, tabloları ve kod bloklarını 𝕏 için biçimlendirmek zahmetlidir. YouMind, eksiksiz bir Markdown taslağını temiz ve hemen paylaşılabilir bir 𝕏 makalesine dönüştürür.

Markdown'dan 𝕏'e deneyin

Çözülecek daha fazla kalıp

Son viral makaleler

Daha fazla viral makale keşfet