Model bahasa berbasis autoregresif (LLM) dirancang untuk memprediksi token berikutnya berdasarkan probabilitas statistik representasi teks, bukan mengeksekusi logika komputasi formal. Mengandalkan bobot internal model generatif untuk operasi matematika kompleks, agregasi finansial, atau evaluasi boolean bersarang sering berujung pada halusinasi numerik. Artikel ini membedah trade-off struktural antara pemrosesan langsung di dalam LLM versus mendelegasikannya ke dedicated code engine di backend, lengkap dengan pola implementasi router deterministik.

Problem Fundamental: Probabilitas vs Determinisme

LLM memproses angka sebagai pecahan token teks (subwords). Model tidak menyimpan representasi register aritmatika biner di memori. Ketika model menjawab kalkulasi panjang seperti 48291 * 8371, ia membangkitkan urutan token berdasarkan asosiasi pola pelatihan. Semakin panjang rantai perhitungan (Chain of Thought), semakin besar akumulasi galat (error compounding).

Sebaliknya, code engine seperti Python runtime atau WebAssembly (Wasm) beroperasi pada state machine deterministik dengan presisi IEEE-754 standar atau tipe data arbitrary-precision. Memisahkan natural language understanding (NLU) dari evaluasi komputasi adalah pola mendasar untuk sistem produksi yang membutuhkan auditabilitas.

Analisis Perbandingan: LLM Weights vs Code Engine

Keputusan arsitektur ini berdampak langsung pada metrik latensi, biaya operasional, dan keamanan sistem.

  • Akurasi Deterministik: LLM generatif memiliki batas reliabilitas pada kalkulasi multi-step atau operasi floating-point presisi tinggi. Code engine menjamin hasil identik untuk input yang identik (100% deterministik).
  • Latensi Eksekusi: Generasi token aritmatika LLM berlangsung lambat (terikat throughput inferensi token-per-detik). Code engine menyelesaikan kalkulasi dalam orde mikrodetik hingga milidetik. Namun, latensi total sistem gabungan mencakup overhead network hop dan inferensi routing awal.
  • Biaya Token: Perhitungan via CoT memakan banyak token output (tiap langkah penalaran bernilai uang). Delegasi ke code engine mereduksi token ke struktur pemanggilan fungsi (Function Calling / Tool Use) ringkas atau code block pendek.
  • Overhead Keamanan Sandbox: LLM murni tidak menjalankan instruksi pada level sistem operasi (zero sandbox overhead). Sebaliknya, code engine dinamis menuntut isolasi ketat (gVisor, nsjail, Firecracker, atau Wasm instance) guna mencegah Remote Code Execution (RCE) dan resource exhaustion.
  • Maintainability: Menguji prompt LLM untuk perhitungan numerik membutuhkan dataset evaluasi probabilistik yang rapuh terhadap perubahan versi model. Logika pada code engine dapat diverifikasi sepenuhnya menggunakan standard unit testing suite (misal: pytest).

Pola Arsitektur Hybrid: Router Backend

Pola arsitektur standar industri menempatkan routing layer di backend. Alur kerja terdiri dari tiga tahapan:

  1. Intent Extraction: LLM kelas ringan atau classifier berbasis schema mendeteksi apakah query membutuhkan kalkulasi matematis/logika formal, kemudian mengekstrak ekspresi ke format terstruktur.
  2. Safe Execution: Backend mengarahkan payload ke runner deterministik terisolasi (contoh: AST parser atau embedded Wasm/Python sandbox).
  3. Response Stitching: Hasil deterministik dikembalikan langsung ke pengguna atau diinjeksi kembali ke konteks model generatif untuk sintesis bahasa.

Implementasi: Router Deterministik Menggunakan Python AST

Berikut implementasi backend router tanpa overhead runtime penuh eksternal, memanfaatkan Python AST parsing untuk mengeksekusi ekspresi matematika dasar secara aman tanpa risiko eval() berbahaya.

import ast
import operator
from typing import Any, Union

# Whitelist operator aritmatika yang diizinkan
ALLOWED_OPERATORS = {
    ast.Add: operator.add,
    ast.Sub: operator.sub,
    ast.Mult: operator.mul,
    ast.Div: operator.truediv,
    ast.Pow: operator.pow,
    ast.USub: operator.neg,
}

class SafeEvaluator(ast.NodeVisitor):
    def visit_BinOp(self, node: ast.BinOp) -> Union[int, float]:
        op_type = type(node.op)
        if op_type not in ALLOWED_OPERATORS:
            raise ValueError(f"Operator tidak didukung: {op_type.__name__}")
        return ALLOWED_OPERATORS[op_type](self.visit(node.left), self.visit(node.right))

    def visit_UnaryOp(self, node: ast.UnaryOp) -> Union[int, float]:
        op_type = type(node.op)
        if op_type not in ALLOWED_OPERATORS:
            raise ValueError(f"Operator unary tidak didukung: {op_type.__name__}")
        return ALLOWED_OPERATORS[op_type](self.visit(node.operand))

    def visit_Constant(self, node: ast.Constant) -> Union[int, float]:
        if not isinstance(node.value, (int, float)):
            raise ValueError(f"Tipe literal tidak valid: {type(node.value)}")
        return node.value

    def generic_visit(self, node: ast.AST) -> Any:
        raise ValueError(f"Node AST tidak diizinkan: {type(node).__name__}")

def run_deterministic_math(expression: str) -> float:
    # ponytail: AST whitelisting cukup untuk aritmatika dasar. Upgrade ke Wasm/nsjail untuk Python scripting lengkap.
    parsed_ast = ast.parse(expression, mode='eval')
    evaluator = SafeEvaluator()
    return evaluator.visit(parsed_ast.body)

def route_request(payload: dict) -> dict:
    """
    Router layer: membedakan pemrosesan teks murni vs instruksi komputasi numerik.
    """
    mode = payload.get("type")
    expression = payload.get("expression", "")

    if mode == "deterministic_computation":
        try:
            result = run_deterministic_math(expression)
            return {"status": "success", "result": result, "engine": "ast_engine"}
        except Exception as e:
            return {"status": "error", "message": str(e), "engine": "ast_engine"}
    
    # Fallback ke inference loop LLM generatif
    return {"status": "delegated", "engine": "llm_generative"}

# Runnable self-check
if __name__ == "__main__":
    valid_query = {"type": "deterministic_computation", "expression": "(25 * 4) + (100 / 5)"}
    assert route_request(valid_query)["result"] == 120.0
    
    attack_query = {"type": "deterministic_computation", "expression": "__import__('os').system('ls')"}
    assert route_request(attack_query)["status"] == "error"

Isolasi Eksekusi: Sandbox Wasm dan OS-Level Containers

Jika query membutuhkan eksekusi kode tingkat lanjut (seperti runtime Python interaktif dengan NumPy atau Pandas, bukan sekadar ekspresi aritmatika tunggal), mekanisme AST di atas tidak lagi memadai. Arsitektur harus beralih ke level sandbox engine:

  • WebAssembly (Wasm): Menggunakan engine seperti Wasmtime atau Wasmer. Wasm menyediakan isolasi memori berbasis instruksi linear (fault-isolation boundary) dengan cold-start overhead sangat rendah (orde sub-milidetik). Sangat ideal untuk eksekusi logika komputasi murni tanpa dependensi sistem operasi langsung.
  • MicroVMs / Kernel Isolation: Menggunakan solusi seperti Firecracker atau Docker yang dibungkus runtime gVisor (runsc). Pendekatan ini membatasi pemanggilan syscall Linux rentan, cocok jika pipeline komputasi menuntut dependensi library C/C++ native kompleks.

Strategi Integrasi

Gunakan LLM generatif secara eksklusif untuk parsing bahasa alami, restrukturisasi output, dan sintesis kontekstual. Tempatkan kalkulasi matematis, evaluasi conditional deterministik, dan pemrosesan data tabular ke dalam engine terdedikasi di balik router API. Arsitektur hybrid ini menurunkan latensi, mengeliminasi biaya token penalaran yang tidak perlu, dan memastikan integritas data kalkulasi pada sistem produksi.