Agent lokal jalan lancar sepuluh turn, lalu mulai ngulang-ngulang jawaban, lupa instruksi awal, atau jawab seolah separuh percakapan sebelumnya gak pernah ada. Modelnya yang sering disalahin. Padahal biasanya masalahnya di context window: Ollama cuma alokasi beberapa ribu token, percakapan tumbuh melewati batas itu, dan history-nya dipotong sebelum sampai ke model.
Kebingungannya datang dari dua angka berbeda yang dua-duanya kelihatan seperti "context length". ollama show nampilin maksimum yang dilatih ke model, seringnya 32k atau lebih. ollama ps nampilin yang beneran dialokasikan server di mesin ini, yang bisa cuma 4k. Selisih dua angka itulah tempat agent lokal kehilangan ingatan.
Panduan ini buat nutup selisih itu: baca alokasi asli, kunci budget per model, kecilin KV cache, dan buktiin tiap perubahan pakai angka dari hardware kamu sendiri.
Yang perlu disiapin
- Ollama terpasang dan jalan (
ollama --version) - Satu model yang support tool, misalnya
qwen3:8b curldan Python 3- VRAM atau RAM yang cukup buat context yang mau kamu pakai
Langkah 1: Cek context yang beneran kamu dapat
Pull model, kirim satu request biar ke-load, lalu lihat apa yang dilakukan server:
ollama pull qwen3:8b
ollama run qwen3:8b "say hi" > /dev/null
ollama ps
Outputnya punya kolom CONTEXT dan PROCESSOR. Ini contoh dari dokumentasi Ollama, angka di mesin kamu bakal beda:
NAME ID SIZE PROCESSOR CONTEXT UNTIL
gemma4:latest c6eb396dbd59 9.6 GB 100% GPU 131072 2 minutes from now
CONTEXT itu alokasinya. PROCESSOR nunjukin apakah model dan cache-nya muat di GPU. Sekarang bandingin sama kartu model:
ollama show qwen3:8b
Perintah itu nampilin context length yang dipakai waktu model dilatih. Itu batas atas, bukan janji. Server milih angkanya sendiri berdasarkan VRAM yang tersedia. Menurut dokumentasi Ollama, default-nya bertingkat: di bawah 24 GiB VRAM dapat 4k, 24 sampai 48 GiB dapat 32k, dan 48 GiB ke atas dapat 256k. FAQ-nya masih nulis 4096 sebagai default, jadi dua halaman itu gak kompak. Percaya ollama ps aja, karena itu yang nggambarin proses yang sedang jalan.
Data yang sama bisa diambil lewat HTTP:
curl -s http://localhost:11434/api/ps | python3 -m json.tool
Tiap model yang ke-load melaporkan context_length, size, dan size_vram. Kalau size_vram lebih kecil dari size, sebagian model ada di RAM sistem dan generasinya bakal lambat banget.
Langkah 2: Naikin default server
Di Linux yang pakai service systemd, edit drop-in-nya, jangan file unit aslinya:
sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_CONTEXT_LENGTH=32768"
sudo systemctl daemon-reload
sudo systemctl restart ollama
Kirim satu request, lalu cek /api/ps lagi. context_length harusnya 32768. Kalau masih 4096, environment variable-nya gak sampai ke proses:
systemctl show ollama -p Environment
Di macOS, aplikasinya baca variabel dari launchd. Set dulu, lalu tutup dan buka lagi Ollama:
launchctl setenv OLLAMA_CONTEXT_LENGTH 32768
Angka ini global. Model autocomplete 1B kamu juga kena, dan KV cache model itu di 32k adalah VRAM yang gak perlu kamu buang. Karena itu ada langkah berikutnya.
Langkah 3: Kunci budget per model
Modelfile bikin tiap model bawa default-nya sendiri, jadi setelan server yang dipakai bareng gak bisa diam-diam nurunin agent coding kamu.
FROM qwen3:8b
PARAMETER num_ctx 32768
PARAMETER temperature 0.7
PARAMETER repeat_penalty 1.05
SYSTEM """You are a coding assistant. Answer with patches, not essays."""
ollama create qwen3-agent -f Modelfile
ollama run qwen3-agent "list three uses of a ring buffer"
ollama ps
ollama ps sekarang harusnya nunjukin 32768 buat model turunan itu. Isi Modelfile-nya selalu bisa dicek:
ollama show --modelfile qwen3-agent | head -20
Pisahin model sesuai kerjaannya. Model chat di 8k, model coding di 32k, model embedding yang context budget-nya gak perlu dipikirin. Satu angka global maksa semua workload masuk ke amplop yang sama.
Satu catatan: client yang ngirim options.num_ctx eksplisit di /api/chat atau /api/generate bakal menang atas Modelfile. Kalau framework agent kamu set nilainya sendiri, Modelfile-nya cuma hiasan. Cek request yang dia kirim sebelum nyalahin server.
Langkah 4: Kecilin cache, bukan context-nya
Ukuran KV cache tumbuh seiring panjang context. Flash attention plus cache terkuantisasi adalah cara paling murah buat mempertahankan context panjang tanpa beli GPU baru. Dua-duanya environment variable di level server:
sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
sudo systemctl daemon-reload
sudo systemctl restart ollama
journalctl -u ollama -n 50 --no-pager | grep -iE "flash attention|kv_cache_type"
Log-nya harus nyebut flash attention dan tipe cache-nya. Kalau gak ada, setelannya gak kepasang.
Menurut dokumentasi, q8_0 makan memori sekitar setengah dari f16 dengan kehilangan presisi yang sangat kecil, dan q4_0 sekitar seperempat dengan kehilangan yang mulai kelihatan di context panjang. Cache terkuantisasi butuh flash attention; tanpa itu Ollama balik ke f16. Setelan ini juga global buat semua model yang di-load server, jadi kamu gak bisa campur tipe cache dalam satu proses.
Dampaknya ke kualitas tergantung model. Dokumentasi nyebut model dengan GQA tinggi, Qwen2 salah satunya, lebih sensitif ke kuantisasi cache. Kalau kamu mau q4_0 buat nambah headroom, jalankan prompt eval kamu di dua setelan itu sebelum dipakai serius.
Langkah 5: Hitung matematika paralelismenya
Request paralel mengalikan alokasi context. Dokumentasi kasih contohnya langsung: context 2K dengan 4 request paralel jadi context 8K, plus memori yang mengikuti. Kebutuhan memori skala dengan OLLAMA_NUM_PARALLEL kali OLLAMA_CONTEXT_LENGTH.
Jadi context 32k dengan empat slot paralel berarti 128k cache yang harus dialokasikan. Di kartu 12 GB itu biasanya berakhir jadi split CPU, dan split CPU lebih lambat daripada antrean.
Buat agent lokal single user:
[Service]
Environment="OLLAMA_CONTEXT_LENGTH=32768"
Environment="OLLAMA_NUM_PARALLEL=1"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Kalau satu mesin dipakai beberapa orang, naikin OLLAMA_NUM_PARALLEL ke 2 atau 4 setelah cek sisa memori. Request di luar kapasitas antre sampai OLLAMA_MAX_QUEUE (default 512), lalu API balikin 503, yang setidaknya error jujur daripada timeout.
Langkah 6: Berhenti bayar biaya load
Model di-unload setelah 5 menit idle secara default. Agent yang jalan tiap 15 menit bayar harga load di setiap run, dan harganya kelihatan di load_duration tiap response.
[Service]
Environment="OLLAMA_KEEP_ALIVE=30m"
Bisa juga diatur per request, dan itu menang atas default server:
curl http://localhost:11434/api/generate -d '{"model": "qwen3-agent", "keep_alive": "30m"}'
curl http://localhost:11434/api/generate -d '{"model": "qwen3-agent", "keep_alive": -1}'
Prompt kosong bikin model ke-preload. Nilai negatif bikin model tetap di memori sampai kamu lepas sendiri:
ollama stop qwen3-agent
Keep-alive panjang bagus di workstation dan jelek di host GPU bersama yang dipakai job lain. Pilih per mesin, bukan per tutorial.
Langkah 7: Ukur pakai API, bukan pakai feeling
Tiap response dari /api/generate bawa load_duration, prompt_eval_count, prompt_eval_duration, eval_count, dan eval_duration, semuanya dalam nanodetik. Itu cukup buat ngitung tiga angka yang penting: waktu load, kecepatan prefill, dan kecepatan decode.
# bench.py
import json
import sys
import urllib.request
model = sys.argv[1] if len(sys.argv) > 1 else "qwen3-agent"
payload = {
"model": model,
"prompt": "Explain the CAP theorem in three sentences.",
"stream": False,
}
req = urllib.request.Request(
"http://localhost:11434/api/generate",
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"},
)
d = json.load(urllib.request.urlopen(req))
print(f"load {d['load_duration'] / 1e9:6.2f} s")
print(f"prefill {d['prompt_eval_count'] / (d['prompt_eval_duration'] / 1e9):6.1f} tok/s")
print(f"decode {d['eval_count'] / (d['eval_duration'] / 1e9):6.1f} tok/s")
print(f"total {d['total_duration'] / 1e9:6.2f} s")
Jalankan, ubah satu variabel, jalankan lagi. Kecepatan decode itu yang kamu rasain waktu baca jawaban. Kecepatan prefill itu yang dirasain agent kamu waktu dia nyodorin 20k token output tool ke prompt.
Buat nemuin plafon praktis, kirim prompt panjang dan pantau prefill:
# long_context.py
import json
import urllib.request
filler = "Latency is a distribution, not a number. " * 3000
payload = {
"model": "qwen3-agent",
"prompt": filler + "
In one sentence: what is the main idea above?",
"stream": False,
}
req = urllib.request.Request(
"http://localhost:11434/api/generate",
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"},
)
d = json.load(urllib.request.urlopen(req))
print(d["prompt_eval_count"], "prompt tokens")
print(round(d["prompt_eval_count"] / (d["prompt_eval_duration"] / 1e9), 1), "prefill tok/s")
Jaga filler-nya tetap di bawah num_ctx kamu. Kalau prefill jatuh di 24k padahal kartu modelnya ngiklankan 128k, 24k itu plafon asli di kartu tersebut, dan sehebat apa pun prompt engineering-nya gak bakal ngubah itu.
Kalau ada yang aneh
- Context masih 4096 setelah diubah: service belum di-restart, atau variabelnya masuk ke file unit bukan ke drop-in. Cek
systemctl show ollama -p Environment. PROCESSORnunjukin split CPU/GPU: bobot plus cache-nya gak muat. Turuninnum_ctx, ganti cache keq8_0, atau pakai kuantisasi yang lebih kecil.- Jawaban berhenti di tengah kalimat: itu
num_predict, bukan context. Bandingineval_countsama limit yang kamu set. - API balikin 503: antreannya penuh. Tambah paralelisme cuma kalau memori cukup, kalau nggak ya serialisasi kerjanya.
- Kualitas turun setelah pindah ke
q4_0: wajar di beberapa model. Balik keq8_0dan pertahankan context-nya.
Loop yang layak dipertahankan
Baca context_length dari /api/ps. Kunci angkanya di Modelfile buat tiap jenis pekerjaan. Kuantisasi cache sebelum beli hardware. Jaga model tetap hangat di mesin yang sanggup. Lalu ukur load, prefill, dan decode setelah tiap perubahan.
Tiga angka dan satu file config per model jauh lebih berguna daripada nebak-nebak kenapa agent lupa instruksi ketiga lagi.
Referensi
- Default context length dan
ollama ps: https://docs.ollama.com/context-length - FAQ: flash attention, tipe KV cache, keep alive, konkurensi: https://docs.ollama.com/faq
- Referensi Modelfile: https://docs.ollama.com/modelfile
- Endpoint daftar model yang jalan (
/api/ps): https://docs.ollama.com/api/ps