AML Memory MVP
August 6, 2026 · View on GitHub
A reproducible, evidence-only memory system for the Textual Memory / Academic Methods track of the 2026 Agent Memory Challenge. Version 0.3 adds typo-tolerant semantic retrieval, conversation-neighbor expansion, verbatim evidence windows, and bounded output while keeping the deployment surface intentionally small.
The service implements the current synchronous Add and Search contract. It stores every source message with strict user_id isolation, indexes English and CJK text with SQLite FTS5 plus character n-grams, and returns ranked source evidence. It deliberately does not generate final answers.
Design goals
- Contract correctness before leaderboard optimization.
- Original source evidence in every Search result.
- Exact
user_idisolation with no cross-sample state. - Idempotent Add requests.
- Reproducible Docker deployment with no external database.
- Optional, auditable
gpt-4o-miniindexing cues for the current Full-run rule.
Architecture
Add messages
├─ optional per-message gpt-4o-mini index cues (no answer generation)
├─ deterministic English/CJK lexical features
└─ SQLite records + FTS5 index, partitioned by user_id
Search query
├─ optional gpt-4o-mini facets, query expansion, and time intent
├─ Porter FTS5 BM25 with English typo fragments and CJK n-grams
├─ generic concept and adjacent-turn candidate expansion
├─ informative-term, option, date/number, and correction scoring
├─ incremental MMR for complementary multi-hop evidence
└─ top_k timestamped, bounded, verbatim conversation windows
API
The evaluator may configure either the short paths or aliases:
GET /healthPOST /addorPOST /v1/memory/addPOST /searchorPOST /v1/memory/search
Add
{
"request_id": "eval:run:dataset:sample:chunk-0",
"messages": [
{
"role": "user",
"timestamp": 1704067200000,
"content": "memory text"
}
],
"user_id": "eval:run:dataset:sample",
"session_id": "eval:run:session:0"
}
The response is sent only after every message is persisted and immediately searchable:
{
"success": true,
"request_id": "eval:run:dataset:sample:chunk-0",
"user_id": "eval:run:dataset:sample",
"session_id": "eval:run:session:0"
}
Search
{
"query": "Which answer best matches the memory?",
"options": ["A. First", "B. Second"],
"user_id": "eval:run:dataset:sample",
"top_k": 100
}
{
"data": [
{
"id": "mem_...",
"content": "[user | 2026-07-01T12:00:00Z] original source evidence",
"score": 0.91,
"created_at": "2026-07-01T12:00:00Z"
}
]
}
Run with Docker
Local deterministic mode, with no model credential:
docker build -t aml-memory-mvp:0.3.0 .
docker run --rm -p 8000:8000 \
-e AML_LLM_MODE=off \
-v aml-memory-data:/data \
aml-memory-mvp:0.3.0
Resilient formal-evaluation mode. It uses gpt-4o-mini when a runtime
credential is injected and otherwise falls back to the deterministic retriever:
docker run --rm -p 8000:8000 \
-e AML_LLM_MODE=best_effort \
-e OPENAI_MODEL=gpt-4o-mini \
-e OPENAI_API_KEY \
-v aml-memory-data:/data \
aml-memory-mvp:0.3.0
Do not put credentials in the image, repository, URL, screenshots, or logs.
Run without Docker
Python 3.10 or later is required.
python -m venv .venv
. .venv/bin/activate
pip install -r requirements-dev.txt
AML_LLM_MODE=off uvicorn app.main:app --host 0.0.0.0 --port 8000
In another terminal:
python scripts/smoke.py
pytest
Configuration
| Variable | Default | Purpose |
|---|---|---|
AML_DATABASE_PATH | data/memory.db | SQLite database path |
AML_LLM_MODE | off | off, best_effort, or required |
AML_API_KEY | empty | Optional Add/Search authentication |
OPENAI_API_KEY | empty | Runtime-only model credential |
OPENAI_MODEL | gpt-4o-mini | Model locked for current Full rule |
OPENAI_BASE_URL | OpenAI v1 | Compatible API base URL |
AML_CANDIDATE_LIMIT | 400 | Retrieval candidates before reranking |
AML_MAX_OUTPUT_CHARS | 240000 | Evidence-output safety budget for the shared Answer context |
The model path makes at most one bounded JSON call per Add request and one per Search request. Search analysis is capped at 256 output tokens; Add indexing is capped dynamically between 256 and 1024 tokens according to batch size. For the challenge run, use a dedicated OpenAI API project with a monthly budget no higher than USD 50. The application does not embed credentials or silently switch to another model.
When AML_API_KEY is set, both Authorization: Bearer, Authorization: Token, and X-Api-Key are accepted. /health stays public.
Reproducibility
GitHub Actions runs unit tests and a Docker-level Add/Search smoke test on every push. The system uses a single worker by default because SQLite coordinates all concurrent requests through WAL and a 60-second busy timeout. The evaluator may still call the service concurrently.
Optional retrieval-only development checks can be run against separately downloaded public datasets. They use evidence/session annotations only, never answer labels, and the datasets are not packaged with the service:
python scripts/eval_locomo_retrieval.py /path/to/locomo10.json
python scripts/eval_longmemeval_retrieval.py /path/to/longmemeval_s_cleaned.json --per-type 5
For a formal submission, bind the score to the public Git commit and the image tag 0.3.0. Do not change that version after a Full run is accepted.
Originality and disclosure
This submission is original glue and retrieval code created for the 2026 Agent Memory Challenge. It does not copy an existing memory-system repository or reproduce a paper implementation. It uses standard information-retrieval techniques:
- SQLite FTS5 BM25 candidate retrieval;
- deterministic Unicode normalization, Porter stemming, typo fragments, and CJK character n-grams;
- general concept expansion and source-order-safe adjacent-turn retrieval;
- informative-term coverage, exact date/number anchors, and option-aware scoring;
- latest/earliest/sequence intent with correction-aware temporal governance;
- incremental maximal-marginal-relevance selection for complementary multi-hop evidence;
- bounded verbatim conversation windows with stable source identifiers;
- optional per-message indexing cues and query facets that are never returned as answers.
See DISCLOSURE.md for the complete statement and SUBMISSION.md for the prepared submission material.
Data handling
Evaluation memories are stored only in the configured SQLite database. Delete the database or Docker volume within 30 days after the run, unless the organizer gives written permission to retain it longer.
License
MIT