Yayınlanma tarihi: 23 Haziran 2026
Her LanguageModel oturumunun sınırlı bir bağlam penceresi vardır. Sohbet büyüdükçe model, bağlamında tam mesaj geçmişini (her kullanıcı istemi ve her asistan yanıtı) biriktirir. Pencere dolduğunda tarayıcının otomatik taşma işleme özelliği devreye girer. Yeni isteme yer açmak için en eski mesaj çiftlerini (bir istem ve yanıt çifti) siler. Gelen istem o kadar büyükse ki tüm sohbet geçmişini kaldırmak bile yeterli olmuyorsa arama QuotaExceededError ile tamamen başarısız olur.
Oturum sıkıştırma, proaktif bir alternatiftir: Summarizer API ile görüşme geçmişini özetleyin, ardından bu özetleri initialPrompts olarak kullanarak yeni bir oturum başlatın. Tarayıcı, çalışma zamanı taşması işleme sırasında initialPrompts öğesini hiçbir zaman kaldırmaz. Bu nedenle, özetlerin kendileri create() çağrıldığında bağlam penceresine sığdığı sürece, sıkıştırılmış özet modelin bağlamına kalıcı olarak sabitlenir. Yeni oturum, orijinal jeton maliyetinin çok daha düşük bir kısmıyla aynı sohbet dizisini taşır.
Oturum sıkıştırma, uzun süren LanguageModel sohbetlerin sürekliliği kaybetmeden bağlam penceresinde kalmasını sağlar. Önemli adımlar şunlardır:
contextUsagedeğerinicontextWindowdeğerine göre izleyin ve kullanıcıya gösterin.- Erken uyarı olarak
contextoverflowetkinliğini dinleyin. - Language Detector API ile her mesajın dilini tespit edin, ardından dili dikkate alan bir Summarizer API örneğiyle mesajı özetleyin.
- Eski oturumu yok edin ve
initialPromptsile yeni bir oturum başlatın. - Hata kurtarma için
fullHistorykopyasını saklayın.
Bağlam kullanımını izleme
Prompt API, bir oturumun bağlamının ne kadar dolu olduğunu izlemek için iki özellik sunar:
session.contextUsage: Şu anda kullanılan jeton sayısı.session.contextWindow: Oturumun toplam jeton kapasitesi.
Bunu bir <progress> öğesinde yansıtarak kullanıcıların oturumun sınıra ne kadar yaklaştığını bir bakışta anlamasını sağlayın. value ve max değerlerini doğrudan jeton sayılarına ayarlayın. Tarayıcı, çubuğu otomatik olarak ölçeklendirir:
<progress id="token-bar" value="0" max="1"></progress>
<label for="token-bar" id="token-label">Context: — / — tokens</label>
function updateTokenDisplay(session) {
const usage = session.contextUsage;
const total = session.contextWindow;
tokenBar.value = usage;
tokenBar.max = total;
tokenLabel.textContent =
`${Math.round(usage)} / ${Math.round(total)} tokens ` +
`(${Math.round((usage / total) * 100)}%)`;
}
Çubuğun güncel kalması için her istem yanıtından sonra updateTokenDisplay() işlevini çağırın.
Bağlam taşmasını dinleme
Yeni bir istem, kalan bağlamı aştığında tarayıcının otomatik kurtarma işlemi başlar: Yeterli alan açılana kadar en eski istem ve yanıt çiftlerini tek tek kaldırır. contextoverflow etkinliği, bu çıkarma işlemi başladığı anda tetiklenir. Oturumu oluşturduktan hemen sonra bir işleyici kaydedin:
session.addEventListener('contextoverflow', () => {
showWarning('⚠ Context window nearly full. Consider compacting the session.');
});
Bu çıkarma davranışının iki önemli özelliği vardır:
initialPromptsçalışma zamanında çıkarılmaz. Tarayıcı, gelen isteme yer açmak için bunları kaldırmaz. AncakinitialPromptsöğesininLanguageModel.create()öğesine iletilen birleşik boyutu, bağlam penceresine sığamayacak kadar büyüksecreate(),QuotaExceededErrorile reddeder. Bu nedenle, sohbetin devam edebilmesi için sıkıştırmanın yeterince küçük olduğundan emin olun.- Tahliye işlemi sınırlıdır. Gelen istem o kadar büyükse önceki görüşmenin tamamını kaldırmak bile yeterli olmaz. Bu durumda
prompt()veyapromptStreaming()çağrısıQuotaExceededErrorile başarısız olur ve hiçbir şey kaldırılmaz.
İstem API'si belgelerinde bağlam taşması işleme hakkında daha fazla bilgi edinin.
Kullanıcıyı uyarmak, gönderme düğmesini devre dışı bırakmak veya tarayıcı, görüşme geçmişini sessizce silmeye başlamadan önce otomatik olarak sıkıştırmayı tetiklemek için contextoverflow etkinliğini kullanın.
Oturumu sıkıştırma
Sıkıştırma üç adımdan oluşur:
- Görüşme geçmişindeki her mesajı Özetleyici API ile özetleyin.
- Eski oturumu yok edin.
- Özetlerle doldurulmuş yeni bir oturum oluşturun
initialPrompts.
Geçmişi özetleme
Özetleyici API, tek tek sohbet mesajlarını sıkıştırmak için idealdir. Her mesajın önce Language Detector API ile dilini tespit edin. Böylece özetleyici doğru şekilde yapılandırılabilir:
async function detectLanguage(text, threshold = 0.7) {
const detector = await LanguageDetector.create();
const results = await detector.detect(text);
if (results.length > 0 && results[0].confidence >= threshold) {
return results[0].detectedLanguage;
}
return null; // confidence too low — caller falls back to navigator.language
}
0.7Güven eşiği, kesin olmayan algılamalar üzerinde işlem yapılmasını önler. Güven eşiğin altında olduğunda navigator.language'ya geri dönün.
Ardından, algılanan dil için yapılandırılmış bir özetleyici oluşturun. Daha küçük ve daha düşük gecikmeli model varyantını seçmek için preference: 'speed', daha hızlı model algılanan dili desteklemiyorsa preference: 'auto''ye geri dönmek için:
const summarizers = {}; // cache, keyed by `${format}:${lang}`
async function getSummarizer(format, lang) {
const key = `${format}:${lang}`;
if (summarizers[key]) return summarizers[key];
const baseOptions = {
type: 'tldr',
format, // 'markdown' or 'plain-text'
length: 'short',
expectedInputLanguages: [lang],
expectedContextLanguages: [lang],
outputLanguage: lang,
};
let options = { ...baseOptions, preference: 'speed' };
let avail = await Summarizer.availability(options);
if (avail === 'unavailable') {
options = { ...baseOptions, preference: 'auto' };
avail = await Summarizer.availability(options);
}
if (avail === 'unavailable') {
throw new Error('Summarizer API unavailable on this device.');
}
summarizers[key] = await Summarizer.create(options);
return summarizers[key];
}
format+lang çifti başına özetleyici önbelleğe alma, aynı dili paylaşan ardışık mesajlar olduğunda gereksiz create() çağrılarını önler.
format bağımsız değişkeni, mesajın içeriğinden türetilir. Düz metin için 'markdown' belirtmek istenmeyen biçimlendirmelere yol açabilir. Markdown için 'plain-text' belirtmek ise kod bloklarını ve vurguları kaldırır. İkisi arasındaki farkı küçük bir normal ifade gösterir:
function looksLikeMarkdown(text) {
return /(?:^#{1,6} |^[-*+] |\d+\. |\*\*|__|\[.+?\]\(|^> |^```)/m.test(text);
}
Dil ve biçim çözüldükten sonra her iletiyi özetleyin ve modelin bağımsız bir belgeyi değil, bir sohbet dönüşünü sıkıştırdığını anlaması için context dizesini iletin:
const compacted = [];
for (const msg of history) {
const lang = (await detectLanguage(msg.content)) ?? navigator.language;
const format = looksLikeMarkdown(msg.content) ? 'markdown' : 'plain-text';
const summarizer = await getSummarizer(format, lang);
const summary = await summarizer.summarize(msg.content.trim(), {
context:
`This is a ${msg.role} turn from a chat conversation. ` +
`Preserve its key meaning as concisely as possible.`,
});
// Only use the summary if it's actually shorter.
compacted.push({
role: msg.role,
content:
summary.trim().length < msg.content.length ? summary.trim() : msg.content,
});
}
Eski oturumu yok etme
Eski oturumun kaynaklarını serbest bırakın ve ardından yeni oturumu oluşturun:
session.destroy();
session = null;
Sıkıştırılmış geçmişle yeni bir oturum oluşturma
Yeni oturuma görüşme bağlamını eklemek için sıkıştırılmış mesajları initialPrompts olarak iletin:
// Collect every language the detector was confident about.
const sessionLangs =
confidentLangs.size > 0 ? [...confidentLangs] : [navigator.language];
session = await LanguageModel.create({
expectedInputs: [{ type: 'text', languages: sessionLangs }],
expectedOutputs: [{ type: 'text', languages: sessionLangs }],
initialPrompts: compacted,
});
// Re-register the overflow handler on the new session.
session.addEventListener('contextoverflow', () => {
/* ... */
});
Yeni oturum daha düşük bir contextUsage ile başlar. Sohbet kaldığı yerden devam eder: Model, önceki bağlam olarak özetleri kullandığından önceki konularla ilgili ek soruları yanıtlayabilir.
Hataları işleme
Eski oturum zaten yok edildikten sonra özetleme veya oturum oluşturma işlemi başarısız olursa kullanıcı sohbet etme özelliğini kaybeder. Hiçbir zaman sıkıştırma işlemiyle üzerine yazılmayan ayrı bir fullHistory dizisi tutun ve bunu kurtarma için yedek olarak kullanın:
const history = []; // current session's view, replaced on each compaction
const fullHistory = []; // every original message, never overwritten
// In the catch block:
if (!session) {
session = await LanguageModel.create({
initialPrompts: fullHistory.map(({ role, content }) => ({ role, content })),
});
session.addEventListener('contextoverflow', () => {
/* ... */
});
}
fullHistory işleminden kurtarma, bağlamı tekrar kapasiteye yaklaştırabilir ancak kullanıcı en azından tekrar çalışır duruma gelir ve hemen başka bir sıkıştırma işlemi deneyebilir.
İsteğe bağlı olarak bazı içeriklerin sıkıştırılmasını önleme
Bir iletinin her zaman bağlamda kalması gereken önemli kısımları varsa (ör. kod örnekleri) bunları ayrı olarak işleyin. Aşağıdaki örnekte, bir ileti alternatif düz yazı ve kod çiti segmentlerine ayrılıyor, ardından yalnızca düz yazı bölümleri özetlenirken kod segmentleri olduğu gibi bırakılıyor:
// Splits text into alternating prose and code-fence segments.
// Returns [{ type: 'prose'|'code', content: string }, …]
function splitByCodeFences(text) {
const parts = [];
const re = /^```[^\n]*\n[\s\S]*?^```[ \t]*$/gm;
let lastIndex = 0;
let match;
while ((match = re.exec(text)) !== null) {
if (match.index > lastIndex) {
parts.push({
type: 'prose',
content: text.slice(lastIndex, match.index),
});
}
parts.push({ type: 'code', content: match[0] });
lastIndex = match.index + match[0].length;
}
if (lastIndex < text.length) {
parts.push({ type: 'prose', content: text.slice(lastIndex) });
}
return parts;
}
Demoyu deneyin
Oturum sıkıştırma demosu, Prompt API ile sohbet etmenize ve oturumu istediğiniz zaman sıkıştırmanıza olanak tanır. Token çubuğu, bağlam kullanımını anlık olarak gösterir ve bağlam doldukça rengi değişir. Her sıkıştırmadan sonra, jeton sayılarının öncesi ve sonrası bir günlük girişine kaydedilir. Böylece, azalmayı doğrudan gözlemleyebilirsiniz.
Tam ve sıkıştırılmış ileti dizisi JSON'unu sayfanın alt kısmındaki daraltılabilir Hata ayıklama: İleti dizisi JSON'u bölümünde inceleyebilirsiniz.