Dipublikasikan: 23 Juni 2026
Setiap sesi LanguageModel memiliki jendela konteks
terbatas. Seiring berkembangnya percakapan, model mengumpulkan histori pesan lengkap
dalam konteksnya: setiap perintah pengguna dan setiap balasan asisten. Saat jendela terisi, penanganan overflow otomatis browser akan dimulai. Model ini akan menghapus pasangan pesan terlama, satu pasangan perintah dan respons dalam satu waktu, untuk mengosongkan ruang bagi perintah baru. Jika perintah masuk terlalu besar sehingga tidak muat meskipun seluruh histori percakapan dihapus, panggilan akan langsung gagal dengan QuotaExceededError.
Pemadatan sesi adalah alternatif proaktif: meringkas histori percakapan dengan Summarizer
API, lalu memulai ulang sesi baru menggunakan ringkasan tersebut sebagai initialPrompts. Browser tidak pernah mengeluarkan
initialPrompts selama penanganan overflow runtime, sehingga ringkasan yang dipadatkan
tetap tertambat secara permanen dalam konteks model, selama ringkasan
itu sendiri sesuai dengan jendela konteks saat create() dipanggil. Sesi
baru membawa rangkaian percakapan yang sama dengan sebagian kecil biaya token
asli.
Pemadatan sesi memberikan cara bagi percakapan LanguageModel berumur panjang untuk tetap berada dalam jendela konteks tanpa kehilangan kontinuitas. Langkah-langkah utamanya adalah:
- Pantau
contextUsagerelatif terhadapcontextWindowdan tampilkan kepada pengguna. - Dengarkan peristiwa
contextoverflowsebagai peringatan dini. - Deteksi bahasa setiap pesan dengan Language Detector API, lalu ringkas pesan tersebut dengan instance Summarizer API yang mendukung bahasa.
- Hancurkan sesi lama dan buat sesi baru dengan
initialPrompts. - Simpan salinan
fullHistoryuntuk pemulihan error.
Melacak penggunaan konteks
Prompt API mengekspos dua atribut untuk memantau seberapa penuh konteks sesi:
session.contextUsage: jumlah token yang saat ini digunakan.session.contextWindow: total kapasitas token sesi.
Tampilkan hal ini dalam elemen <progress> agar pengguna dapat langsung mengetahui seberapa dekat sesi dengan batasnya. Tetapkan value dan max langsung ke jumlah token; browser akan menskalakan batang secara otomatis:
<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)}%)`;
}
Panggil updateTokenDisplay() setelah setiap respons perintah agar status tetap
terkini.
Memantau luapan konteks
Jika perintah baru melebihi konteks yang tersisa, pemulihan otomatis
browser akan dimulai: browser akan menghapus pasangan perintah dan respons terlama satu per satu hingga
tersedia ruang yang cukup. Peristiwa contextoverflow diaktifkan saat pengusiran ini dimulai. Daftarkan handler segera setelah membuat sesi:
session.addEventListener('contextoverflow', () => {
showWarning('⚠ Context window nearly full. Consider compacting the session.');
});
Ada dua properti penting dari perilaku pengusiran ini:
initialPromptstidak dikeluarkan saat runtime. Browser tidak menghapusnya untuk menyediakan ruang bagi perintah yang masuk. Namun, jika ukuran gabunganinitialPromptsyang diteruskan keLanguageModel.create()itu sendiri terlalu besar agar sesuai dengan jendela konteks,create()akan menolak denganQuotaExceededError, jadi pastikan pemadatan cukup kecil untuk melanjutkan percakapan.- Pengusiran memiliki batasan. Jika perintah yang masuk terlalu besar sehingga menghapus seluruh percakapan sebelumnya tetap tidak cukup, panggilan
prompt()ataupromptStreaming()akan gagal denganQuotaExceededErrordan tidak ada yang dihapus.
Baca selengkapnya tentang penanganan overflow konteks dalam dokumentasi Prompt API.
Gunakan peristiwa contextoverflow untuk memperingatkan pengguna, menonaktifkan tombol kirim, atau memicu pemadatan secara otomatis sebelum browser mulai menghapus histori percakapan secara diam-diam.
Menciutkan sesi
Pemadatan memiliki tiga langkah:
- Ringkas setiap pesan dalam histori percakapan dengan Summarizer API.
- Hancurkan sesi lama.
- Buat sesi baru yang diisi dengan ringkasan sebagai
initialPrompts.
Meringkas histori
Summarizer API sangat cocok untuk memadatkan setiap pesan chat. Untuk setiap pesan, deteksi terlebih dahulu bahasanya dengan Language Detector API agar perangkum dapat dikonfigurasi dengan benar:
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
}
Nilai minimum keyakinan 0.7 menghindari tindakan pada deteksi yang tidak pasti. Jika
tingkat keyakinan di bawah nilai minimum, kembali ke navigator.language.
Selanjutnya, buat perangkum yang dikonfigurasi untuk bahasa yang terdeteksi. Lebih memilih
preference: 'speed' untuk memilih varian model yang lebih kecil dan memiliki latensi lebih rendah, dan
kembali ke preference: 'auto' jika model yang lebih cepat tidak mendukung
bahasa yang terdeteksi:
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];
}
Meng-cache perangkum per pasangan format+lang menghindari panggilan create() yang berlebihan
saat pesan berurutan menggunakan bahasa yang sama.
Argumen format berasal dari konten pesan itu sendiri. Menentukan
'markdown' untuk prosa biasa dapat menimbulkan pemformatan yang tidak diinginkan, dan menentukan
'plain-text' untuk Markdown akan menghapus pagar kode dan penekanan. Regular expression kecil
membedakan keduanya:
function looksLikeMarkdown(text) {
return /(?:^#{1,6} |^[-*+] |\d+\. |\*\*|__|\[.+?\]\(|^> |^```)/m.test(text);
}
Setelah bahasa dan format ditentukan, ringkas setiap pesan dan teruskan string context agar model memahami bahwa model sedang memadatkan giliran percakapan, bukan dokumen mandiri:
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,
});
}
Menghancurkan sesi lama
Lepaskan resource sesi lama sebelum membuat penggantinya:
session.destroy();
session = null;
Membuat sesi baru dengan histori yang dipadatkan
Teruskan pesan yang dipadatkan sebagai initialPrompts untuk memulai sesi baru dengan konteks percakapan:
// 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', () => {
/* ... */
});
Sesi baru dimulai pada contextUsage yang lebih rendah. Percakapan dilanjutkan dari tempat terakhir percakapan dihentikan: model memiliki ringkasan sebagai konteks sebelumnya, sehingga dapat menjawab pertanyaan lanjutan tentang topik sebelumnya.
Menangani error
Jika pembuatan ringkasan atau sesi gagal setelah sesi lama dihapus, pengguna akan kehilangan kemampuan untuk melakukan chat. Pertahankan array fullHistory terpisah yang tidak pernah ditimpa oleh pemadatan dan gunakan sebagai penggantian pemulihan:
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', () => {
/* ... */
});
}
Pemulihan dari fullHistory dapat menempatkan konteks di dekat kapasitas lagi, tetapi pengguna setidaknya kembali dalam status berfungsi dan dapat segera mencoba pemadatan lain.
Secara opsional, mencegah beberapa konten dipadatkan
Jika ada bagian penting dari pesan yang harus selalu tetap dalam konteks, misalnya contoh kode, proses secara terpisah. Contoh berikut membagi pesan menjadi segmen prosa dan pagar kode yang bergantian, lalu hanya meringkas bagian prosa sambil membiarkan segmen kode tetap utuh:
// 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;
}
Coba demo
Demo pemadatan sesi memungkinkan Anda melakukan chat dengan Prompt API dan memadatkan sesi kapan saja. Panel token menampilkan penggunaan konteks real-time dan berubah warna saat konteks terisi. Setelah setiap pemadatan, entri log mencatat jumlah token sebelum dan sesudah, sehingga Anda dapat langsung mengamati pengurangan tersebut.
Anda dapat memeriksa JSON percakapan lengkap dan ringkas di bagian Debug: JSON percakapan yang dapat diciutkan di bagian bawah halaman.