Lanjut ke konten
Samkarsa Logbook

v1.0.0-011 : [DRAFT] Optimasi System Prompt — Native Separation & Ollama Modelfile

Memisahkan system prompt hardcode dari user input menggunakan field API yang tepat (systemInstruction untuk Gemini, system untuk Ollama) dan membuat Ollama Custom Modelfile agar system prompt nol token saat runtime di jalur Ollama.

MCP,Jualan2mnt baca

Setiap request ke LLM saat ini menggabungkan system prompt statis (hardcode ratusan baris) dengan user input dinamis menjadi satu string fullPrompt yang dikirim sekaligus ke model. Pola ini boros token karena system prompt tidak pernah berubah:

System Prompt Ukuran Estimasi Token Terbuang
transactionParser.ts ~9 KB ~2.275 token / request
ocrTool.ts ~10 KB ~2.500 token / request
pricingParser.ts ~2,4 KB ~600 token / request
vibeOrchestrator.ts ~2 KB ~500 token / request

Selain itu, log monitoring di mcp_request_logs menyimpan fullPrompt sehingga isi teks transaksi user tenggelam dan terpotong di tengah ratusan baris system prompt.


Prinsip: Alih-alih menggabungkan menjadi satu string, kirim system prompt dan user input melalui field terpisah yang sudah didukung natively oleh Gemini SDK dan Ollama API.

Gemini — pindah system prompt ke getGenerativeModel:

// SEBELUM (bermasalah):
const fullPrompt = `${systemPrompt}\n\nUser: ${prompt}`;
const model = genAI.getGenerativeModel({ model: modelName });
await model.generateContent(fullPrompt); // dikirim campur jadi satu
// SESUDAH (bersih):
const model = genAI.getGenerativeModel({
model: modelName,
...(systemPrompt ? { systemInstruction: systemPrompt } : {})
});
await model.generateContent(prompt); // hanya user input

Ollama — gunakan field system yang sudah ada di API:

// SEBELUM:
{ model: modelName, prompt: fullPrompt, stream: false }
// SESUDAH:
{ model: modelName, system: systemPrompt || '', prompt: prompt, stream: false }

Dampak langsung Tier 1:

  • ✅ Log monitoring bersih — hanya menyimpan teks transaksi user
  • ✅ Arsitektur lebih benar secara semantik
  • ✅ Model memproses system instruction lebih akurat
  • ⚠️ Token dihitung tetap sama di Gemini (belum ada penghematan biaya nyata)

Prinsip: Membuat model turunan di VPS Ollama yang sudah “hafal” system prompt via Modelfile. Saat runtime, tidak ada system prompt yang dikirim.

#!/bin/bash
cat > /tmp/Modelfile.accounting << 'MODELEOF'
FROM qwen2.5:3b
SYSTEM """
[isi penuh parseTransactionSystemPrompt]
"""
PARAMETER num_ctx 8192
PARAMETER temperature 0.1
MODELEOF
docker exec ollama ollama create blonjo-accounting -f /tmp/Modelfile.accounting

OLLAMA_ACCOUNTING_MODEL=blonjo-accounting

const accountingModel = process.env.OLLAMA_ACCOUNTING_MODEL;
if (accountingModel && ollamaAlive) {
// 0 token system — sudah baked ke model
return await AiProviderService.generateText(userInput, undefined, 'accounting_bot');
} else {
// Fallback Tier 1: Gemini dengan systemInstruction
return await AiProviderService.generateText(userInput, parseTransactionSystemPrompt, 'accounting_bot');
}

Skenario Token Input Sekarang Token Input Setelah
Parse via Gemini (Tier 1) ~2.325 tok ~2.325 tok (arsitektur bersih)
Parse via Ollama (Tier 1) ~2.325 tok ~2.325 tok (arsitektur bersih)
Parse via Ollama (Tier 2) ~2.325 tok ~50 tok 🎉
Log monitoring Terpotong ❌ Input user bersih ✅

Request Transaksi: "beli gula 2kg 20rb"
├─► Gemini (Tier 1)
│ systemInstruction = parseTransactionSystemPrompt [~2.275 tok]
│ generateContent("beli gula 2kg 20rb") [~10 tok]
│ Log: "beli gula 2kg 20rb" ✅
└─► Ollama blonjo-accounting (Tier 2)
system = (sudah baked ke model, 0 token dikirim)
prompt = "beli gula 2kg 20rb" [~10 tok]
Log: "beli gula 2kg 20rb" ✅

  • Gemini Free Tier: Token masih dihitung di Tier 1. Penghematan nyata di Gemini hanya via Context Caching (butuh billing aktif).
  • Model drift Tier 2: Jika parseTransactionSystemPrompt diupdate di kode tapi model VPS tidak diperbarui → Ollama masih pakai prompt lama. Perlu SOP update.
  • ocrTool adalah model vision (multimodal) — tidak bisa di-bake ke Ollama text model → cukup Tier 1.
  • Kompatibilitas: systemInstruction sudah didukung di @google/generative-ai v0.3.0+.

  1. Tier 1 saja atau Tier 1 + Tier 2?
  2. Selain transactionParser, apakah pricingParser dan vibeOrchestrator juga perlu model baked?