Local-First AI Agent Inference Optimization (Silex Engine) by Youssef El FajlaouiLocal-First AI Agent Inference Optimization (Silex Engine) by Youssef El Fajlaoui
Local-First AI Agent Inference Optimization (Silex Engine)
How to engineer low-latency autonomous agent systems on consumer hardware using prompt caching, grammar constraints, and local context optimization.
Running a single LLM inference query on a local machine is now relatively fast. If you run a quantized 8-billion parameter model on a modern Apple Silicon chip or a mid-range Nvidia GPU, you can expect 50+ tokens per second. For standard chat interfaces, this is more than fast enough.
But when you build an autonomous agent (like Kronos or Vyn), that single query is replaced by a continuous, multi-turn cognitive loop. A single user goal might trigger a cascade of agent steps: planning, tool selection, sandboxed execution, output parsing, verification, memory retrieval, and re-planning.
If each turn in the cognitive loop takes 3 to 5 seconds, an agent taking 10 steps will keep the user waiting for nearly a minute. This is the Cognitive Latency Cascade.
To make local-first agents practical, we had to systematically re-engineer the inference path. This post details the optimizations we implemented in the Silex Engine to run complex agentic loops locally with sub-second turn latency.
The Cognitive Latency Cascade
To understand why local agent loops are slow, we have to look at the anatomy of an agent step. In the Silex Engine, a single turn consists of:
Context Assembly: Loading the agent’s system prompt, conversation history, causal memory nodes, and available tool definitions.
Epistemic Update & Re-planning: Feeding the tool's outcome back into the context and asking the model if the goal is met or if a new action is required.
In a naive implementation, each step sends the entire updated context history to the local LLM engine. Because the context grows with every turn (as tool outputs and terminal logs accumulate), the time spent on Prefill (Prompt Processing) increases quadratically.
On consumer GPUs, the prefill phase is compute-bound. Processing a 12,000-token prompt can take several seconds, even if the model only generates a 50-token tool call.
We solved this using four core optimizations: Prompt Caching, Grammar-Constrained Sampling, Quantization Budgeting, and Local Vector Indexes.
1. Prompt Caching: Keeping Context Hot
The most dramatic latency reduction came from enabling Prompt Caching at the inference engine level (via llama.cpp / Ollama).
Normally, when you change even a single character at the end of an LLM prompt, the engine must re-evaluate the entire prompt from scratch. In an agent loop, the context is constantly changing as new tool results are appended.
However, 90% of the context remains identical from turn to turn: the system instructions, the tool definitions, and the older history. Only the latest tool observation changes.
By structuring our context template carefully, we can keep the static prefix cached in GPU memory:
In the Silex Engine config, we partition the context window to maximize cache hits. As long as the prefix remains unmodified, the engine only processes the new suffix tokens.
Here is how we configure the local inference client to request cache reuse:
Results: Prompt caching reduced our turn-to-turn prefill time from 4.2 seconds to 0.3 seconds on a standard RTX 4070 (12GB VRAM) for a 10,000-token context.
One of the biggest latency sinks in agent loops is retrying failed tool calls. If the agent attempts to output JSON but makes a syntax error (e.g., a missing comma or unescaped quote), the parser fails. The system must then send the error back to the LLM and ask it to regenerate the JSON.
This double-inference penalty wastes precious seconds.
Instead of parsing JSON after generation, we enforce JSON structure during generation. We use GBNF (GBNF-format grammars) to constrain the LLM's token sampling.
At each token selection step, the sampler sets the probability of invalid characters (like a letter when a number is expected, or a random string outside of the allowed tool keys) to zero. The model is physically incapable of outputting malformed JSON.
Here is a simplified GBNF grammar we inject when requesting a tool selection:
When we invoke the local model via the server, we pass this grammar payload:
By guaranteeing 100% syntactically correct tool calls, we eliminated JSON parser retry loops entirely. This reduced average agent step latency by 18% and made the execution loops completely predictable.
3. Quantization Budgeting: Q8 vs. Q4 Tradeoffs
Running local models requires choosing a quantization level (e.g., Q4_K_M, Q8_0, or FP16). The lower the quantization, the faster the prefill and generation speed, and the lower the VRAM requirement.
However, agent loops require high epistemic precision. A model that makes slight reasoning mistakes will select the wrong tool, fail to locate a bug, or loop indefinitely.
We benchmarked several Llama-3-8B and Mistral-7B quantization levels against a suite of 50 multi-turn coding and search tasks:
QuantizationVRAM footprintPrefill SpeedTask Success RateLoop Efficiency (Steps to completion)FP16~16.5 GB350 tok/s92%4.2 average stepsQ8_0~9.2 GB680 tok/s90%4.4 average stepsQ5_K_M~6.1 GB890 tok/s82%5.8 average stepsQ4_K_M~4.8 GB1120 tok/s64%8.1 average steps (high loop rates)
The Finding: While Q4 was incredibly fast, its task success rate dropped significantly because the model struggled to parse long compiler logs and chose redundant tools. It took more steps to solve a problem, meaning the total task duration was actually longer than using a slower, more precise model.
The Solution: We set the default local engine config for Silex to Q8_0 (8-bit quantization). It provides a near-perfect balance, retaining 98% of FP16's cognitive capability while running nearly twice as fast during prefill.
4. Local Causal Graphs and Memory Pruning
As an agent works, its context window fills up with past steps. In a long-running job, this can exceed the model's effective context limit, slowing down processing and causing the model to forget earlier facts.
Instead of keeping everything in the active context, the Silex Engine uses a local Causal Knowledge Graph backed by SQLite to store and organize memories offline.
Before each turn, we run a fast local graph search to retrieve only the nodes directly relevant to the current step. We prune the active context by replacing older, detailed tool logs with brief summaries.
For example, if the agent runs npm test and gets 200 lines of output, we store the full output in our local database, but represent it in the active context as a single summary node:
If the agent later needs to debug the specific test failure, it queries the database for the full log of that node. If not, the detailed logs stay out of the context window, keeping prompt prefill lightning-fast.
The Local Agent Experience
By combining prompt caching, grammar constraints, Q8 quantization, and active context pruning, we transformed the local agent experience.
Kronos and Vyn can now execute a multi-step workflow in sub-second increments per turn. The agent feels responsive and alive, providing real-time terminal traces to the operator without lagging or stuttering.
We believe that local-first AI is not just a privacy choice; it is an optimization choice. By optimizing the local inference path, we can build agents that are faster, more secure, and entirely under your control.
The code implementing these optimizations is open and built directly into the core of the Silex Engine. Run a local deployment, plug in your local Ollama instance, and experience the speed for yourself.