GNL 0.17: erken aşamada ve hızlı ilerliyor — API'ler sürümden sürüme değişebilirBize katıl

GNL
Dokümanlar menüsü
Studio@gnldev/lab

Lab

Bir ajan neden öyle yaptı ve değiştirilirse ne yapardı — çalıştırmaları parçaları çıkarılmış olarak yeniden oynatılarak ölçülür. Deneysel: API'si değişecek.

Deneysel
@gnldev/lab deneyseldir ve Studio'nun Lab sekmesi de bunu söyler. API'si GNL'in geri kalanından hızlı değişir: 0.16'dan önce birkaç kez değişti ve yine değişecek; her değişiklik ne yapılacağıyla birlikte changelog'dadır. Teşhisi ölçülmüştür, ama dar bir alanda — rakamların ne olmadığı aşağıda "Sınırlar" altında.

Ne işe yarar#

Bir ajan beklemediğiniz bir şey yaptı ve bir prompt cümle yığınıdır: hangisi o çağrıyı doğurdu? Lab bunu, ajanı parçaları çıkarılmış olarak yeniden çalıştırıp neyin değiştiğini sayarak cevaplar; bir parçanın payı onun Shapley değeridir. Burada hiçbir şey ajanınızı değiştirmez. Sonuç okuduğunuz bir şeydir ve ardından kendi kodunuzda yaptığınız bir değişikliktir.

Lab, @gnldev/experiment (yeniden oynatma, maskeleme, denemeler ve aritmetik) üzerine kuruludur; @gnldev/optimizer da aynısını kullanır, ikisi birbirine ihtiyaç duymaz.

Nereden gelir#

Lab, Apache-2.0 lisanslı açık kaynaktır; diğer paketler gibi herkese açık depoda ve npm'dedir — ücretli katmanın parçası değildir. Peer olarak @gnldev/durable ve ai 7 ister.

kurulum
npm i @gnldev/lab @gnldev/durable ai

Altı soru, altı fonksiyon#

Her fonksiyon farklı bir şey oynatır ve neyi oynattığı, bir tool'un çalışıp çalışmayacağını belirler:

  • Bu çağrıyı ne doğurdu? explainRun, kayıtlı bir çalıştırmayı parçalarından her biri çıkarılarak yeniden oynatır — prompt bölümleri, önceki mesajlar, tool sonuçları. Hiçbir tool çalışmaz. Herhangi bir paydan önce, kaydın modelin genelde yaptığı şey olup olmadığını (representative) ve sonucun parçalara hiç bağlı olup olmadığını (dependsOnParts) söyler; her pay noise taşır. 2^parça × deneme model çağrısı yapar.
  • Hangi kelimeler karar verdi? toolChoiceProbability ile wordShares, bir sağlayıcının logprobs'undan, her kelime grubunun sıradaki çağrının belirli bir tool olma olasılığını ne kadar oynattığını okur. OpenAI'nin API'si bir tool çağrısında olasılık vermez (ölçüldü); bu yüzden sampledToolChoice her alt kümeyi birkaç kez sorar ve her pay, şansın onu ne kadar oynatabileceğini söyler. Tüm bir çalıştırmayı değil, bir kararı, sıradakini açıklar.
  • Bu prompt bölümü çıkarılabilir mi? checkPrune, yeni prompt'ları bölümle ve bölümsüz gerçekten oynatır; yanında gürültü tabanı ve önemli olması gereken bir kontrol bölümü vardır. Tool'lar çalışır — oynatılacak kayıt yok — bu yüzden ona sahtelerini verin.
  • Yeni bir ajan hangi parçalara ihtiyaç duyar? bestForm, bir ajanın bileşenlerinin her alt kümesini sahte tool'lu bir senaryo setinde dener; senaryolar bir program tarafından denetlenir, hakem model yoktur; en iyisi kadar iyi yapan en ucuz formu söyler. Sizin yerinize hiçbir şey seçmez: seçilen bileşenleri ajanın koduna siz yazarsınız.
  • Bu çalıştırma değiştirilmiş olsa ne yapardı? runCapsule, kayıtlı bir çalıştırmayı kopyalar ve farklı bir system prompt, başka tool'lar ya da geçmişi veya belleği olmadan yeniden oynatır. Hiçbir tool çalışmaz ve hiçbir şey yazılmaz. Kaydın hiç yapmadığı bir çağrı, sizin yazdığınız answers'tan cevaplanır ya da bekleyen olarak listelenir. Değişiklik, çalıştırmanın olduğu hâliyle aynı sayıda oynatılmasına karşı okunur, böylece fark şansla karıştırılmaz.
  • Bir thread'in bu turu neden yanlış gitti? threadPlan bir thread'in turlarını okur ve hiçbir model çağırmaz; diagnoseTurn expect ister — doğru bir cevabın ne yaptığı — ve onsuz başlamayı reddeder. guess ile önce bir model, suçlu olması en olası bir ya da iki parçayı söyler ve yalnızca onlar, değiştirilmemiş turun yanında oynatılır; neden yalnızca oynatmalarla söylenir, tahminle asla.

İkisi kodda#

kayıtlı bir çalıştırmayı açıkla
import { explainRun, explainRunSize } from '@gnldev/lab';
import { retryingFetch } from '@gnldev/experiment';
import { SqliteStorage } from '@gnldev/durable/sqlite';
import { createOpenAI } from '@ai-sdk/openai';

const storage = new SqliteStorage('runs.db');
const model = createOpenAI({ fetch: retryingFetch() }).chat('gpt-4.1-mini');
declare const tools: Parameters<typeof explainRun>[0]['tools']; // the agent's own definitions; execute never runs

console.log(explainRunSize(4, 3), 'replays'); // know the bill before you ask
const r = await explainRun({
  journal: storage.runs, runId: 'order-42', model, tools,
  systemSections: { rules: 'Always look the order up first.', policy: 'Damaged: replace. Refund only if asked.' },
  messages: { greeting: [0, 1], orderNumber: [2, 3] }, // positions in the run's input; the last message stays
  toolResults: { lookup: 'searchOrders' },               // the result is hidden, the call stays
  trials: 3,
});
if (!r.representative.ok) console.log('this recording is not what the model usually does — shares are weak');
if (!r.dependsOnParts) console.log('the outcome is the same with every part and with none — read signs, not %');
for (const s of r.shares) console.log(s.part, s.share.toFixed(2), '±', s.noise.toFixed(2));
kayıtlı bir çalıştırmayı değiştirilmiş hâliyle, olduğu hâlinin yanında oynat
import { runCapsule } from '@gnldev/lab';
import { SqliteStorage } from '@gnldev/durable/sqlite';
import type { LanguageModel, ToolSet } from 'ai';

declare const model: LanguageModel;
declare const tools: ToolSet; // the agent's definitions, changed as you want; execute never runs
const storage = new SqliteStorage('runs.db');

const r = await runCapsule({
  journal: storage.runs, runId: 'order-42', model, tools,
  system: 'Help with orders. If it came broken, refund it.',
  answers: [{ toolName: 'refund', args: { orderId: '42' }, output: { refunded: 250 } }],
  unchanged: { tools }, // also play the run as it was, as many times
});
console.log(r.sameAsRecorded.value, r.pending, r.difference);

Studio'da#

Studio'ya lab'ı verirseniz bir Lab sekmesi gösterir. Sekme kendi çalıştırma listesini göstermez: tamamlanmış bir çalıştırmayı Inspector'da açar ve Open in Lab ile gönderirsiniz (thread için, thread defterinden). Üç sekmesi var — Improve, New agent ve Scenarios. Improve, bir çalıştırmayı ya da thread'i tek bir yazılı beklentiye karşı tek ekrana koyar: şeritte turlar, turun açıklaması, teşhisi ve capsule'ü. Seçenek verilmezse route'lar 501 cevaplar ve sekme gizlenir.

Lab sekmesi
import { createStudioApp } from '@gnldev/studio';
import { studioLab } from '@gnldev/lab';
import { toJournal, type CreateGnlConfig } from '@gnldev/durable';
import { SqliteStorage } from '@gnldev/durable/sqlite';
import { openai } from '@ai-sdk/openai';

declare const config: CreateGnlConfig; // the config createGnl is given
const storage = new SqliteStorage('runs.db');

const studio = createStudioApp({
  reader: toJournal(storage),
  apiBase: '/studio',
  lab: studioLab({ config, models: { 'gpt-4.1-mini': openai('gpt-4.1-mini') } }),
});

Planı görmeden hiçbir şey harcanmaz. Her Lab çağrısı önce oynatma sayısını, token'ları, fiyatı ve sağlayıcıyı gösterir ve hiçbir tool'un çalışmadığını, hiçbir kaydın değişmediğini söyler; çağrı, neyin istendiğiyle denetim kaydına girer (sayılar ve adlar, yazdığınız metin asla). Uzun bir çağrı ne kadar ilerlediğini bir Stop düğmesiyle gösterir; sağlayıcı 429 cevapladığında bir seferde bir çağrıya yavaşlar ve beklediğini söyler. Lab yalnızca kendisine verdiğiniz bir ajanın çalıştırmasını sunar ve ajanın kendi tool'ları onda asla çalışmaz: yalnızca senaryoların sahte tool'ları çalışır.

Sınırlar — rakamların ne olmadığı#

Bir thread teşhisi, tek bir modelle, yerleştirilmiş hatalar üzerinde ölçüldü. Ajanların thread'lerine kırk hata yerleştirildi (bayat bir working memory, pencereden düşmüş bir tur, yanlış bir tool sonucu, zayıf bir kural) ve Studio'nun kendi route'ları üzerinden gpt-6-luna ile teşhis edildi: doğru neden 39'da söylendi, yanlış neden hiçbirinde; 40.sı kararsız kaldı. Girdisinde yanlış bir şey olmayan, her biri bir kez başarısız olmaya zorlanan 15 turda hiçbirinde neden söylenmedi. Yalnızca elenme — guess'ten önceki teşhis — aynı 40'ın 15'ini söyledi.

Hatalar bulunmak için yerleştirildi: yanıltıcı olgu metnin içinde, okurun gördüğü yerde. Yanıltıcı bir anımsanmış mesaj hiç yerleştirilemedi, çünkü model hiçbirini izlemedi. Tek modeldir. 55'te sıfır yanlış neden, oranı en çok yaklaşık %6,5'e koyar. Etiket, okurun görmediği hatalarla ve birden fazla modelle kalkar.

Logprobs vermeyen bir sağlayıcıda hangi kelimelerin karar verdiği örneklenir: az denemeyle payların çoğu şansın içindedir. Ve Lab bir hüküm makinesi değildir — sonuç, gürültüsü yanında okuduğunuz bir şeydir.

API#

fnexplainRun

Kayıtlı bir çalıştırmanın çağrılarını ne doğurdu: parçalar sırayla çıkarılıp yeniden oynatılır, hiçbir tool çalışmaz. Gürültülü paylar, representative ve dependsOnParts döndürür.

fnexplainRunSize

Bir açıklamanın kaç yeniden oynatma alacağı, sormadan önce faturayı bilesiniz diye.

fnwordShares

Verdiğiniz bir değerde her kelime grubunun payı (en çok 12); toolChoiceProbability ya da sampledToolChoice ile, sıradaki çağrının belirli bir tool olma olasılığında.

fntoolChoiceProbability

Sıradaki çağrının bir tool olma olasılığı, OpenAI uyumlu bir sağlayıcının logprobs'undan okunur; alt küme başına bir çağrı. Logprobs vermeyen sağlayıcı sıfır değil hatadır.

fnsampledToolChoice

Aynı değer, her alt kümeyi birkaç kez (varsayılan 5) sorarak, varyansıyla, AI SDK'nın ulaştığı her model için.

fncheckPrune

Bir prompt bölümü çıkarılabilir mi: yeni prompt'lar gerçekten oynatılır, gürültü tabanı ve bir kontrol bölümü yanında. Tool'lar çalışır — sahtelerini verin.

fnbestForm

Yeni bir ajanın bileşenlerinin her alt kümesi, sahte tool'lu bir senaryo setinde; en iyisi kadar geçen en ucuz form, hiçbiri bir oynatmayı geçmediyse yok.

fnrunCapsule

Kayıtlı bir çalıştırma kopyalanıp değiştirilmiş hâliyle (system prompt, tool'lar, geçmiş, bellek), olduğu hâlinin yanında yeniden oynatılır. Hiçbir tool çalışmaz, hiçbir şey yazılmaz.

fnthreadPlan

Bir thread'in turları, sayfa sayfa: her biri nasıl bitti, girdisi nereden geldi, neler test edilebilir ve teşhisin maliyeti. Hiçbir model çağırmaz.

fndiagnoseTurn

Bir thread'in turu neden yanlış gitti, yazdığınız bir beklentiye karşı: önce isteğe bağlı bir tahmin, sonra değiştirilmemiş turun yanında oynatmalar.

fnstudioLab

Studio'nun Lab sekmesinin çağırdığı nesneyi kurar; config ve bir açıklamanın kullanabileceği modellerle birlikte createStudioApp'e lab seçeneği olarak verilir.

İlgili
Lab'ın altındaki yeniden oynatma, maliyet optimizer'ının daha ucuz bir modeli denemek için kullandığıyla aynıdır; Lab'ın kendisi Studio Inspector'dan açılır.