Metin maceralarını her zaman sevdim, ama parser'i deneyimin neredeyse her zaman en zayıf parçası buldum. Oyun take key'i anlar ama pick up the key'i anlamaz, ya da tam tersi, ve oyuncuyla dünya arasındaki ilişki parser tarafından yazılmış gibi hissettirir. baseline-engine, bu sürtünmeyi LLM'i yalnızca parser olarak kullanarak ve hikayeye hiç yazdırmayarak ortadan kaldırma denememdir.
Hikayenin baştan tamamen yapılandırıldığı – temiz koşullar ve etkilerle düğümler ve geçişler olarak – ve oyuncu girdi metninin bir LLM aracılığıyla bu düğümlerden birine eşlendiği bir interaktif kurgu motorudur. LLM içerik üretmez. Eşleştirir. Hikaye yazarının tanımladığı sonlu bir niyet kümesiyle sınırlandırılmıştır.
Dünya kendisi deterministiktir. Oyuncunun gördüğü, alabildiği, hangi kapıların açıldığı – tüm bunlar hikaye grafı tarafından belirlenir. LLM'in yaptığı şey şu soruyu yanıtlamaktır: bu oyuncu izin verilen eylemlerden hangisini kastediyor?
Bu ayrım, LLM'lerin hikaye anlatıcısı olarak en sancılı başarısızlık modlarını sizden uzak tutar. Var olmayan kapıları halüsine etmezler. Olmadığında anahtarın envanterde olduğunu iddia etmezler. Yirmi tur önce olan bir şeyle çelişmezler. Hikaye veridir, LLM girdiyi izin verilen geçişlere eşleyen bir fonksiyondur.
Bu aynı zamanda aynı hikayenin daha küçük, daha ucuz modellerle çalıştığı anlamına gelir. Tek görev cümleleri bir niyet listesine eşlemekse, 7B veya 8B bir model bunu iyi yapar. Birçok tur boyunca anlatıyı tutarlı tutmak başarısız oldukları yerdir.
Motor, yazarların odaları, geçişleri, olayları ve koşulları görsel olarak oluşturduğu bir düğüm editörü ile gelir. Her düğümün bir açıklaması, izin verilen oyuncu niyetlerinin bir listesi ve niyet başına etkilerin bir listesi vardır. Etkiler küçüktür: envanter mutasyonları, değişken atamaları, başka bir düğüme atlama.
LLM'in uğraştığı şey niyet listesidir. Açıktır, sıralıdır, çoğunlukla kısadır. Çalışma zamanında motor oyuncunun serbest girdisini alır ve modele sorar: bu niyetlerden hangisi en iyi uyuyor? Eşleşen biri varsa, etki uygulanır. Yoksa, oyun anlamadığını kibarca söyler ve yakın olasılıkları önerir.
Hikayeler düğüm seviyesinde dallanır, model seviyesinde değil. Oyuncunun anahtarı ya alıp ya da yok etmesini istiyorsam, bunlar iki açık geçiştir. Model, oyuncunun girdisinin hangisini kastettiğine karar verir, ama yok etmenin izin verilen bir eylem olup olmadığına karar vermez – buna hikaye yazarı karar verir.
Bu kısıtlayıcı görünür ama oyunu sahnelenebilir kılan tam da bu özelliktir. Beklenmeyen bir şey yazarak dünyayı kıran bir oyuncu, hikaye yazarının korkması gereken bir hata değildir. Yapabileceği beklenmedik bir şey yoktur. En fazla hiçbir şeye eşlenmeyen bir şey yazabilir, ve oyun nezaketle hayır der.
Model bazen yanlış olur. Bu olduğunda, oyuncu düzeltebilir: oyun bir "kastetimemdiğim buydu" affordance'ı ve yakın niyet listesi sunar. Düzeltme, mevcut hikaye scope'una giren orijinal girdi dizesine karşı önbelleğe alınır. Birisi sonraki sefer benzer bir şey yazdığında, önbellek LLM çağrısını kısa devre yapar ve doğrudan doğru niyete yönlendirir.
Bu aynı anda iki amaca hizmet eder. Bir gecikme optimizasyonudur, çünkü önbelleklenmiş girdiler model gidiş-dönüşünü atlar. Aynı zamanda bir kalite döngüsüdür: parser zaman içinde bu hikayede daha iyi olur – model öğrendiği için değil, düzeltmelerin kullanım ile büyüyen bir ifade-niyet sözlüğüne birikmesi nedeniyle. Önbellek sonunda insan bir yazarın eş anlamlılar yazarken yaptığı işi yapar, ama tahminlerle değil gerçek oyuncu davranışıyla.
Birden fazla AI arka uç, yerel öncelikli bir varsayılanla. OpenAI anahtarı isteyen bir oyun motoru göndermek istemedim. Motor dört tür arka uçla konuşur: Ollama (yerel, varsayılan, tercih ettiğim yol), OpenAI, Gemini, ve sadece bir model adıyla genel bir HTTP uç noktası olan bir "custom" yedek. Yerel yol en gurur duyduğum yoldur. Gemma gibi küçük bir instruction-tuned model, parser görevine fazlasıyla yeter: bir cümleyi avuç içi kadar niyet kümesine eşler, düz yazı yazmaz. Motoru çalıştırabilir, bir hikaye barındırabilir ve oyuncunun serbest girdisini kendi makinenizde kimseye ödeme yapmadan veya oyuncu metnini üçüncü tarafa göndermeden parse edebilirsiniz. En hızlı seçenek olmayacak ama çalışır, özeldir, ve ücretsizdir.
LLM'leri parser olarak kullanmak, LLM'leri yazar olarak kullanmaktan çok daha küçük ve daha güvenilir bir uygulamadır. Serbest bir cümleyi N seçenek arasından birine eşlemek, mevcut modellerin iyi yaptığı bir şeydir. Birçok tur boyunca tutarlı kurgu üretmek ise kötü yaptıkları şeydir. Sınırı bu çizginin doğru tarafına çekin ve sistem kullanılabilir hale gelir.
Oyuncu düzeltme döngüsü projenin en ilginç parçası olarak ortaya çıktı, ve neredeyse sonradan akla geldi. Orijinal spec sadece "oyuncuların farklı ifadelerle tekrar denemesine izin ver" idi. Düzeltmeyi girdi dizesine karşı önbelleğe almak, aynı hata için LLM maliyetini iki kez ödememeye çalışmaktan çıktı. Aynı zamanda parser'i zamanla daha akıllı yapmasının bir yan etkisi olması bonustu.
