Mengelola context window secara sadar: anggaran token per lapisan, teknik kompresi dan pemangkasan konteks, prompt caching, hingga caching semantik. Kalian mengoptimasi aplikasi dari episode sebelumnya agar lebih murah dan lebih akurattype: text

Di episode 7 kalian membangun RAG yang benar. Episode ini mengajarkan disiplin yang membedakan proyek demo dari produk produksi: context engineering — memperlakukan context window sebagai sumber daya langka yang harus dikelola dengan anggaran, bukan wadah yang diisi seadanya.
Mengapa penting? Karena konteks adalah biaya terbesar produk AI. Konteks yang panjang memperlambat respons, membengkakkan biaya per request, dan — kontra-intuitif — justru menurunkan akurasi ketika berisi hal yang tidak relevan. Engineer senior menghabiskan sebagian besar waktunya di sini: memangkas, mengompres, dan men-cache.
Setiap request adalah kombinasi dari beberapa lapisan konteks:
Disiplinnya: alokasikan anggaran eksplisit per lapisan:
BUDGET = {
"system": 500,
"riwayat": 3000,
"retrieved": 2500,
"input": 500,
"output": 1000,
}
MAX_KONTEKS = sum(BUDGET.values())
print(f"total anggaran: {MAX_KONTEKS} token")Dengan anggaran ini, kita tahu apa yang harus dipangkas saat aplikasi mendekati batas — biasanya riwayat percakapan adalah korban pertama.
Riwayat percakapan tumbuh tanpa henti. Tiga strategi yang umum:
from openai import OpenAI
client = OpenAI()
MAX_HISTORY = 6 # 3 pasang user/assistant
def keep_last(messages: list[dict], n: int) -> list[dict]:
system = [m for m in messages if m["role"] == "system"]
rest = [m for m in messages if m["role"] != "system"]
return system + rest[-n:]
def summarize_old(messages: list[dict]) -> str:
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content":
"Ringkas percakapan ini ke 2 kalimat: " + repr(messages)}],
max_tokens=80,
)
return r.choices[0].message.content
def trim(messages: list[dict]) -> list[dict]:
if len(messages) <= MAX_HISTORY + 1:
return messages
system = [m for m in messages if m["role"] == "system"]
lama = messages[1:-MAX_HISTORY]
baru = messages[-MAX_HISTORY:]
ringkasan = {"role": "system", "content":
"Ringkasan percakapan sebelumnya: " + summarize_old(lama)}
return system + [ringkasan] + baruPerhatikan pola hybrid: pesan lama dirangkum dan disuntikkan sebagai satu pesan system tambahan, sementara pesan terakhir tetap utuh. Model tetap punya konteks, tapi dengan biaya token yang jauh lebih kecil.
Warning
Ada trade-off: ringkasan bisa kehilangan detail penting. Solusinya adalah arsip lengkap ke database (episode 12) — detail tersimpan utuh, ringkasan hanya untuk prompt. Jangan pernah membuang data, cukup jangan memasukkannya ke prompt.
Semua penyedia LLM besar menawarkan prompt caching: prefix prompt yang identik tidak dihitung penuh pada request berikutnya (dengan potongan harga hingga 90% untuk token yang di-cache). Prefix harus byte-identical — jadi tempatkan hal statis (system prompt, dokumen umum, riwayat lama) di depan, dan bagian yang berubah-ubah di belakang:
[bAGIAN STATIS] system prompt + dokumen umum
[bAGIAN DINAMIS] pertanyaan penggunaAgar caching efektif, jangan menaruh bagian dinamis di tengah — urutan konstan membuat cache selalu terpukul (cache hit).
Level optimasi berikutnya: jangan memanggil LLM sama sekali jika pertanyaan yang sama (atau hampir sama) sudah pernah dijawab. Simpan jawaban di vector DB, cari dengan kesamaan, dan langsung kembalikan jawaban cache jika skornya melewati ambang batas:
from openai import OpenAI
import chromadb
client = OpenAI()
cache = chromadb.Client().get_or_create_collection("jawaban-cache")
THRESHOLD = 0.92
def get_answer(q: str) -> str:
qv = client.embeddings.create(model="text-embedding-3-small", input=q)
hasil = cache.query(query_embeddings=[qv.data[0].embedding], n_results=1)
if hasil["documents"][0]:
skor = 1 - hasil["distances"][0][0] # cosine distance -> similarity
if skor >= THRESHOLD:
return f"(cache) {hasil['documents'][0][0]}"
jawaban = llm_call(q) # panggilan LLM biasa
cache.upsert(ids=[q], documents=[jawaban], embeddings=[qv.data[0].embedding])
return jawabanIni strategi pembunuh biaya di produksi: pertanyaan FAQ yang dijawab 10.000 kali sehari cukup dipanggil LLM sekali. Kita dalami lagi di episode 22.
Inti yang harus dibawa pulang:
Di episode 9 selanjutnya kita memasang alat ukur: evaluation & metrics — LLM-as-judge, RAGAS, golden datasets, dan regression testing agar setiap perubahan prompt atau pipeline terukur. Sampai jumpa di episode 9!