SOLAR is a learning-augmented cache-replacement policy for the experience memory of LLM agents. It treats an agent's retrieval buffer as an online semantic cache and decides, on the fly, when to modify the cache (regret-gated admission) and what to evict (Bayesian, posterior-guided selection). SOLAR needs no offline training and no extra LLM calls, adding <1 ms of overhead per step.
This repository contains the reference implementation of SOLAR, the classic cache-replacement baselines we compare against (FIFO, LRU, LFU, ARC), the on-policy evaluation pipeline on LoCoMo and DialSim, and the synthetic-workload / theory-verification experiments from the paper.
Method name mapping (paper ↔ code).
Paper name Code name ( --method)Config Description SOLAR solarsolar.jsonFull framework: regret-gated timing + posterior-guided eviction SOLAR-A solar_asolar_a.jsonAdmission only (regret-gated timing + heuristic eviction) SOLAR-E solar_esolar_e.jsonEviction only (always admit + Thompson-sampling eviction) FIFO fifofifo.jsonFirst-in-first-out baseline LRU lrulru.jsonLeast-recently-used baseline LFU lfulfu.jsonLeast-frequently-used baseline ARC arcarc.jsonAdaptive Replacement Cache baseline Embedder embedder_messageembedder.jsonUnlimited-capacity reference (no eviction)
configs/
datasets/ # Dataset grouping configs (each / domain / task)
memory_systems/ # Per-method hyper-parameter configs (solar.json = SOLAR, ...)
raw/
Locomo/ # LoCoMo raw conversations (corpus source)
DialSim/ # DialSim raw dialogues (corpus source)
run_scripts/
run_experience_eval.py # Main on-policy evaluation entry (LoCoMo / DialSim)
run_adversarial.py # Cycling-workload adversarial verification
src/
agent/ # Cache-policy agents (solar, solar_a, solar_e, fifo, lru, lfu, arc, embedder)
solver/ # Solver wrappers + SolverFactory
dataset/ # Locomo / DialSim dataset loaders
llms/ # OpenAI-compatible LLM / embedder clients
utils.py
synthetic_workloads/ # Synthetic data generators + controlled experiments
theory/ # Theoretical verification (competitive ratio, regret, adversarial)
conda create -n solar python=3.10
conda activate solar
pip install -r requirements.txtSOLAR calls an OpenAI-compatible chat endpoint for two purposes: (1) the agent's response generation and (2) LLM-as-judge scoring of those responses. Any provider that speaks the OpenAI API format works — the official OpenAI API, Azure OpenAI, or a locally served model (e.g. vLLM / Ollama with an OpenAI-compatible server).
Copy the template and fill in your own credentials:
cp .env.example .envThen edit .env:
# Judge / evaluation model (LLM-as-judge scoring)
EVALUATE_BASE_URL="https://api.openai.com/v1"
EVALUATE_MODEL="gpt-4o-mini"
EVALUATE_API_KEY="sk-..." # <-- your key here
# Generation model (used by the memory agent)
OPENAI_BASE_URL="https://api.openai.com/v1"
OPENAI_API_KEY="sk-..." # <-- your key here-
Official OpenAI: set
*_BASE_URLtohttps://api.openai.com/v1and use a key starting withsk-. -
Local model (vLLM/Ollama): point
*_BASE_URLat your server, e.g.http://localhost:8000/v1; the key can be any non-empty placeholder. To serve a model with vLLM:vllm serve Qwen/Qwen3-8B --port 8000 --chat-template qwen3_nonthinking.jinja
The default embedder is sentence-transformers/all-MiniLM-L6-v2 (384-dim), downloaded automatically from HuggingFace on first run. You can change it in configs/memory_systems/*.json.
We evaluate on two datasets from the MemoryBench-Full benchmark: LoCoMo and DialSim. MemoryBench is a third-party benchmark and is not redistributed in this repository; only the raw conversation corpora needed as input live under raw/. The QA splits are pulled automatically:
- QA splits are downloaded at runtime from HuggingFace
THUIR/MemoryBench-Full. Each session provides atrainsplit (used as a warm-up stream to accumulate experience; not scored) and atestsplit (the reported F1). No manual download is needed — thedatasetslibrary fetches it on first use. Pass--use-mb-liteto use the smallerTHUIR/MemoryBenchfor quick smoke tests. - Corpora (the raw multi-session conversations) are read locally from
raw/Locomo/locomo10.jsonandraw/DialSim/. These are included for convenience. If you need to refresh them, obtain the original LoCoMo and DialSim releases from their respective sources and place them underraw/in the same layout.
On first run the HuggingFace cache and embedder weights are downloaded automatically; subsequent runs are offline-capable.
The protocol preloads the conversation corpus (shared by all methods), warms up each policy on the train split to fill the cache, then reports F1 on the held-out test split.
# Run SOLAR on a single LoCoMo session
python run_scripts/run_experience_eval.py --method solar --datasets Locomo-0
# Compare all methods on one session at capacity K=50
python run_scripts/run_experience_eval.py --all --datasets Locomo-0 --capacity 50
# Full sweep: all methods over capacities and seeds, all LoCoMo sessions
python run_scripts/run_experience_eval.py --all \
--datasets Locomo-0 Locomo-1 Locomo-2 Locomo-3 Locomo-4 \
Locomo-5 Locomo-6 Locomo-7 Locomo-8 Locomo-9 \
--capacity-sweep 10 20 50 100 --seed-sweep 42 1337 2024
# Cross-dataset validation on DialSim
python run_scripts/run_experience_eval.py --all --all-dialsim \
--capacity-sweep 10 20 50 100 --seed-sweep 42 1337 2024Useful flags:
| Flag | Meaning |
|---|---|
--method NAME / --methods N1 N2 |
run one / several methods (see mapping table) |
--all |
run all 8 methods |
--datasets ... / --all-dialsim |
choose LoCoMo sessions / all DialSim shows |
--capacity K / --capacity-sweep ... |
cache size(s) K |
--seed K / --seed-sweep ... |
random seed(s); use ≥3 seeds for reportable numbers |
--lambda-cost FLOAT |
switching cost λ for SOLAR's admission threshold |
--use-mb-lite |
smaller QA split for fast smoke tests |
--output PATH |
results directory |
Key hyper-parameters for SOLAR live in configs/memory_systems/solar.json (e.g. lambda_cost, capacity, threshold_mode, novelty_weight).
# Cycling-workload adversarial verification (FIFO thrashing, Theorem on FIFO regret)
python run_scripts/run_adversarial.pyThe synthetic_workloads/ directory contains the generators and controlled experiments (cycling workload, working-set sweep / phase transition, retrieval-noise U-curve); see synthetic_workload_spec.md for the full specification. The theory/ directory holds the numerical verification of the competitive-ratio and regret bounds.
If you find SOLAR useful, please cite our paper. (BibTeX to be added upon publication.)
See LICENSE.