memarena 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- memarena-0.1.2/.gitignore +14 -0
- memarena-0.1.2/CHANGELOG.md +33 -0
- memarena-0.1.2/LICENSE +21 -0
- memarena-0.1.2/PKG-INFO +280 -0
- memarena-0.1.2/README.es.md +253 -0
- memarena-0.1.2/README.md +246 -0
- memarena-0.1.2/pyproject.toml +65 -0
- memarena-0.1.2/src/memarena/__init__.py +3 -0
- memarena-0.1.2/src/memarena/cli.py +318 -0
- memarena-0.1.2/src/memarena/data/demo/LICENSE-LongMemEval.txt +21 -0
- memarena-0.1.2/src/memarena/data/demo/dataset.json +8 -0
- memarena-0.1.2/src/memarena/data/demo/history.json +1879 -0
- memarena-0.1.2/src/memarena/data/demo/questions.json +360 -0
- memarena-0.1.2/src/memarena/data/demo/results.json +2638 -0
- memarena-0.1.2/src/memarena/errors.py +25 -0
- memarena-0.1.2/src/memarena/importers.py +173 -0
- memarena-0.1.2/src/memarena/judge.py +47 -0
- memarena-0.1.2/src/memarena/llm.py +252 -0
- memarena-0.1.2/src/memarena/longmemeval.py +107 -0
- memarena-0.1.2/src/memarena/metrics.py +48 -0
- memarena-0.1.2/src/memarena/models.py +141 -0
- memarena-0.1.2/src/memarena/prompts.py +80 -0
- memarena-0.1.2/src/memarena/qa.py +124 -0
- memarena-0.1.2/src/memarena/report.py +123 -0
- memarena-0.1.2/src/memarena/runner.py +202 -0
- memarena-0.1.2/src/memarena/systems/__init__.py +42 -0
- memarena-0.1.2/src/memarena/systems/base.py +71 -0
- memarena-0.1.2/src/memarena/systems/baselines.py +142 -0
- memarena-0.1.2/src/memarena/systems/letta_adapter.py +99 -0
- memarena-0.1.2/src/memarena/systems/mem0_adapter.py +209 -0
- memarena-0.1.2/src/memarena/systems/supermemory_adapter.py +63 -0
- memarena-0.1.2/src/memarena/viewer.py +115 -0
- memarena-0.1.2/src/memarena/viewer_dist/assets/index-C-JbZZPk.js +9 -0
- memarena-0.1.2/src/memarena/viewer_dist/assets/index-lrIwlJgU.css +1 -0
- memarena-0.1.2/src/memarena/viewer_dist/favicon.svg +1 -0
- memarena-0.1.2/src/memarena/viewer_dist/index.html +24 -0
- memarena-0.1.2/tests/__init__.py +0 -0
- memarena-0.1.2/tests/conftest.py +113 -0
- memarena-0.1.2/tests/fixtures/chatgpt_conversations.json +23 -0
- memarena-0.1.2/tests/fixtures/claude_conversations.json +11 -0
- memarena-0.1.2/tests/fixtures/generic.jsonl +4 -0
- memarena-0.1.2/tests/fixtures/longmemeval_mini.json +17 -0
- memarena-0.1.2/tests/test_adapters.py +111 -0
- memarena-0.1.2/tests/test_baselines.py +56 -0
- memarena-0.1.2/tests/test_cli_viewer.py +160 -0
- memarena-0.1.2/tests/test_importers.py +60 -0
- memarena-0.1.2/tests/test_llm.py +107 -0
- memarena-0.1.2/tests/test_qa.py +79 -0
- memarena-0.1.2/tests/test_runner.py +78 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.2 - 2026-11-03
|
|
4
|
+
|
|
5
|
+
- Include LongMemEval MIT notice with the bundled demo data
|
|
6
|
+
(`src/memarena/data/demo/LICENSE-LongMemEval.txt`, copied unmodified from xiaowu0162/LongMemEval) and cite it
|
|
7
|
+
in a "Third-party data" section of the README.
|
|
8
|
+
|
|
9
|
+
## 0.1.1 - 2026-11-03
|
|
10
|
+
|
|
11
|
+
- Terminal: `memarena demo` and `run` fit narrow terminals (80 columns, CI logs, pipes). Below 150 columns the
|
|
12
|
+
per-category accuracy moves to a second table; below 100 columns p50 and ingestion time are dropped.
|
|
13
|
+
- Viewer: the judge audit is stored as structured data and shown in the viewer's language (EN/ES).
|
|
14
|
+
- Viewer: system cards share one layout (kind chip under the name), so they line up.
|
|
15
|
+
- Viewer: answers render the bold/italic/code markdown models emit instead of showing raw asterisks; latency and
|
|
16
|
+
token counts sit on their own line in every answer card; the question field is labelled "Question"; Spanish
|
|
17
|
+
cards say "correctas".
|
|
18
|
+
- Viewer: deep links `#questions`, `#method` and `#q=<question id>` open a tab or expand a question.
|
|
19
|
+
|
|
20
|
+
## 0.1.0 - 2026-11-03
|
|
21
|
+
|
|
22
|
+
First release.
|
|
23
|
+
|
|
24
|
+
- Importers: ChatGPT export, Claude export (`conversations.json` or the `.zip`), generic JSONL.
|
|
25
|
+
- `memarena generate`: questions with gold answers and evidence pointers in LongMemEval's five categories
|
|
26
|
+
(single-session, multi-session, temporal, knowledge update, abstention), written as `pending` for review.
|
|
27
|
+
- `memarena run`: systems mem0 (OSS), Letta (REST API) and Supermemory (API), always next to three baselines:
|
|
28
|
+
full context, BM25 and embeddings. Same answer model and prompt for every system.
|
|
29
|
+
- Metrics: accuracy from an LLM judge (prompt published in `docs/judge-prompt.md`), retrieval latency p50/p95,
|
|
30
|
+
ingestion time, prompt tokens and cost, overall and per category.
|
|
31
|
+
- Viewer (React) bundled in the wheel: `memarena view`, question review and editing, static export for Pages.
|
|
32
|
+
- `memarena demo`: a recorded real run on a 20-question LongMemEval subset (MIT).
|
|
33
|
+
- `--max-cost` budget checked before every paid call, privacy warning before sending data to a cloud provider.
|
memarena-0.1.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Diego Pérez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
memarena-0.1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: memarena
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Benchmark memory layers on your own conversations, not on someone else's leaderboard.
|
|
5
|
+
Project-URL: Homepage, https://diegoperezg7.github.io/memarena/
|
|
6
|
+
Project-URL: Repository, https://github.com/diegoperezg7/memarena
|
|
7
|
+
Project-URL: Issues, https://github.com/diegoperezg7/memarena/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/diegoperezg7/memarena/blob/main/CHANGELOG.md
|
|
9
|
+
Author: Diego Pérez
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: agents,benchmark,evaluation,letta,llm,mem0,memory,rag
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: openai==3.42.1
|
|
24
|
+
Requires-Dist: rich==15.0.0
|
|
25
|
+
Requires-Dist: typer==0.27.3
|
|
26
|
+
Provides-Extra: letta
|
|
27
|
+
Requires-Dist: letta-client==1.12.1; extra == 'letta'
|
|
28
|
+
Provides-Extra: mem0
|
|
29
|
+
Requires-Dist: mem0ai==2.2.1; extra == 'mem0'
|
|
30
|
+
Requires-Dist: ollama==0.6.3; extra == 'mem0'
|
|
31
|
+
Provides-Extra: supermemory
|
|
32
|
+
Requires-Dist: supermemory==5.0.1; extra == 'supermemory'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="docs/assets/banner.svg" alt="memarena" width="760">
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<a href="https://github.com/diegoperezg7/memarena/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/diegoperezg7/memarena/actions/workflows/ci.yml/badge.svg"></a>
|
|
41
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-7945c5"></a>
|
|
42
|
+
<a href="https://github.com/diegoperezg7/memarena/releases"><img alt="Release" src="https://img.shields.io/github/v/release/diegoperezg7/memarena?color=7945c5"></a>
|
|
43
|
+
<a href="https://github.com/diegoperezg7/memarena/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/diegoperezg7/memarena?style=flat&color=7945c5"></a>
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
<p align="center"><b>Benchmark memory layers on your own conversations, not on someone else's leaderboard.</b></p>
|
|
47
|
+
|
|
48
|
+
<p align="center">English · <a href="README.es.md">Español</a> · <a href="https://diegoperezg7.github.io/memarena/">Live example viewer</a></p>
|
|
49
|
+
|
|
50
|
+
memarena turns your ChatGPT or Claude export into a memory test: it writes questions with gold answers
|
|
51
|
+
from your own history (you review them), feeds the history to each memory layer, asks every question and
|
|
52
|
+
grades the answers with a published LLM-judge prompt. Every run also includes the two things a memory layer
|
|
53
|
+
has to beat: **pasting the whole history** and **simple retrieval** (BM25 and embeddings).
|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
## Why
|
|
58
|
+
|
|
59
|
+
The public memory harnesses are each published by a memory vendor and are built around fixed datasets:
|
|
60
|
+
[supermemoryai/memorybench](https://github.com/supermemoryai/memorybench) (334 stars, Supermemory),
|
|
61
|
+
[vectorize-io/agent-memory-benchmark](https://github.com/vectorize-io/agent-memory-benchmark) (163, Vectorize) and
|
|
62
|
+
[mem0ai/memory-benchmarks](https://github.com/mem0ai/memory-benchmarks) (134, Mem0) (star counts checked 2026-11-03).
|
|
63
|
+
|
|
64
|
+
Vendor numbers do not agree with each other. Mem0's paper reports, on LoCoMo, a 26% relative improvement in
|
|
65
|
+
LLM-as-a-Judge over OpenAI's memory and 91% lower p95 latency with over 90% fewer tokens than full context
|
|
66
|
+
([arXiv 2504.19413](https://arxiv.org/abs/2504.19413)). Letta then reported 74.0% on LoCoMo with GPT-4o mini for a
|
|
67
|
+
plain filesystem agent, against the 68.5% Mem0 published for itself, adding that
|
|
68
|
+
"Mem0 did not respond to requests for clarification"
|
|
69
|
+
([Letta blog, 12 Aug 2025](https://www.letta.com/blog/benchmarking-ai-agent-memory)). Zep reports 94.8% on DMR vs
|
|
70
|
+
93.4% for MemGPT and up to 18.5% higher accuracy on LongMemEval ([arXiv 2501.13956](https://arxiv.org/abs/2501.13956)).
|
|
71
|
+
|
|
72
|
+
Whichever is right on LoCoMo, none of it tells you how a memory layer does on **your** conversations, with
|
|
73
|
+
**your** model, against the cheap option of pasting everything. memarena is vendor-neutral, runs on your
|
|
74
|
+
exports, and always puts full context, BM25 and embeddings in the same table.
|
|
75
|
+
|
|
76
|
+
## Quickstart
|
|
77
|
+
|
|
78
|
+
Recorded demo, no keys, no Docker, no model calls (under 2 minutes from a clean machine with `uv`):
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
uvx --from git+https://github.com/diegoperezg7/memarena@v0.1.2 memarena demo
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
or from a clone:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
git clone https://github.com/diegoperezg7/memarena && cd memarena && uv run memarena demo
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+

|
|
91
|
+
|
|
92
|
+
It prints the table below and opens the viewer on http://127.0.0.1:8765 (add `--no-view` to only print).
|
|
93
|
+
`uvx memarena` is coming to PyPI.
|
|
94
|
+
|
|
95
|
+
## Example output
|
|
96
|
+
|
|
97
|
+
This is a **recorded real run** (`memarena run`, 2026-11-03), shipped in the package and shown by `memarena demo`:
|
|
98
|
+
20 questions (4 per category) from [LongMemEval](https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned)
|
|
99
|
+
(MIT), with the evidence sessions of all 20 merged into **one** history of 28 sessions (~75k tokens), the way a
|
|
100
|
+
single user's export looks.
|
|
101
|
+
|
|
102
|
+
| System | Accuracy | Single | Multi | Temporal | Update | Abstain | Retrieval p50 / p95 | Ingest | Prompt tokens / q | Cost |
|
|
103
|
+
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
104
|
+
| **mem0** (memory layer) | **75%** | 50% | 50% | 75% | 100% | 100% | 49 / 134 ms | 21.6 min | 611 | $0.174 |
|
|
105
|
+
| bm25 (baseline) | 70% | 75% | 25% | 50% | 100% | 100% | 0.9 / 3.9 ms | 0.03 s | 4,180 | $0.008 |
|
|
106
|
+
| embeddings (baseline) | 55% | 50% | 50% | 25% | 50% | 100% | 105 / 233 ms | 34 s | 3,537 | $0.007 |
|
|
107
|
+
| full-context (baseline) | 50% | 0% | 0% | 75% | 75% | 100% | 0.5 / 1.2 ms | 0 s | 69,297 | $0.139 |
|
|
108
|
+
|
|
109
|
+
Setup: answer model `mistral/ministral-8b-latest` (same for every system), judge `mistral/codestral-latest`,
|
|
110
|
+
mem0 2.2.1 with `ministral-8b-latest` for fact extraction, embeddings `nomic-embed-text` on local Ollama, top 10
|
|
111
|
+
items per retriever. Hardware: Apple silicon laptop, 10 CPUs, 16 GB RAM; the local Ollama server was shared with
|
|
112
|
+
other jobs during the run, so the embedding latencies are pessimistic. 20 questions is a small sample: treat
|
|
113
|
+
differences of one or two questions as noise.
|
|
114
|
+
|
|
115
|
+
What this small run shows:
|
|
116
|
+
|
|
117
|
+
- **Pasting everything lost.** With ~69k prompt tokens per question, the 8B answer model said "I don't know" to
|
|
118
|
+
every single-session and multi-session question, while answering the same questions from retrieved snippets.
|
|
119
|
+
- **mem0 sent about 1% of the full-context prompt** (611 vs 69,297 tokens per question) and scored highest, but
|
|
120
|
+
its ingestion took 21.6 minutes and $0.17 of LLM calls for 165 turns (one extraction call per turn), against
|
|
121
|
+
0.03 s for BM25.
|
|
122
|
+
- **BM25 was 5 points behind mem0** at almost no cost. That gap is one question.
|
|
123
|
+
- **Judge audit.** I checked all 80 judge decisions by hand: 3 false positives, all temporal (one each for
|
|
124
|
+
full-context, bm25 and mem0, e.g. "about 1 week ago" accepted for "4 weeks"), and no false negatives. Corrected
|
|
125
|
+
accuracy: mem0 70%, bm25 65%, embeddings 55%, full-context 45%. The order does not change. The table shows the
|
|
126
|
+
judge's raw output, as the tool produced it.
|
|
127
|
+
- Total spent on this run: **$0.34** (Mistral API, priced from the token counts it returned).
|
|
128
|
+
|
|
129
|
+
Browse every answer, the judge's reasoning and what each system retrieved in the
|
|
130
|
+
[example viewer](https://diegoperezg7.github.io/memarena/).
|
|
131
|
+
|
|
132
|
+
## Use it on your own history
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# 1. Import your export (ChatGPT or Claude conversations.json, the export .zip, or JSONL)
|
|
136
|
+
uvx --from git+https://github.com/diegoperezg7/memarena@v0.1.2 memarena import conversations.json --out history.json
|
|
137
|
+
|
|
138
|
+
# 2. Generate questions with gold answers and evidence pointers (written as "pending")
|
|
139
|
+
memarena generate history.json --out questions.json # local Ollama by default
|
|
140
|
+
|
|
141
|
+
# 3. Review them: edit, approve or reject in the viewer (saved back to questions.json)
|
|
142
|
+
memarena view --questions questions.json --history history.json
|
|
143
|
+
|
|
144
|
+
# 4. Run the benchmark on the approved questions
|
|
145
|
+
memarena run history.json questions.json --systems full-context,bm25,embeddings,mem0
|
|
146
|
+
|
|
147
|
+
# 5. Look at the results, or export a static site
|
|
148
|
+
memarena view results.json
|
|
149
|
+
memarena export results.json --questions questions.json --out site
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
mem0, Letta and Supermemory are optional extras: run with
|
|
153
|
+
`uvx --from 'memarena[mem0] @ git+https://github.com/diegoperezg7/memarena@v0.1.2' memarena run ...`
|
|
154
|
+
(or `uv sync --extra mem0` in a clone).
|
|
155
|
+
|
|
156
|
+
**Privacy.** With `--provider ollama` and local systems nothing leaves your machine. With a cloud provider,
|
|
157
|
+
Supermemory or Letta Cloud, memarena lists where your conversations will go and asks before sending
|
|
158
|
+
(`--yes` skips the question). Generated questions must be reviewed: an unreviewed question set makes the
|
|
159
|
+
benchmark unreliable, so `run` only uses approved questions unless you pass `--include-pending`.
|
|
160
|
+
|
|
161
|
+
## How it works
|
|
162
|
+
|
|
163
|
+
```mermaid
|
|
164
|
+
flowchart LR
|
|
165
|
+
E["ChatGPT / Claude export<br/>or JSONL"] -->|memarena import| H[(history.json)]
|
|
166
|
+
H -->|memarena generate| Q[(questions.json<br/>pending)]
|
|
167
|
+
Q -->|review in viewer| QA[(questions.json<br/>approved)]
|
|
168
|
+
H --> I{ingest}
|
|
169
|
+
I --> FC[full context]
|
|
170
|
+
I --> BM[BM25]
|
|
171
|
+
I --> EM[embeddings]
|
|
172
|
+
I --> M0[mem0]
|
|
173
|
+
I --> LE[Letta]
|
|
174
|
+
I --> SM[Supermemory]
|
|
175
|
+
QA --> RQ{retrieve per question}
|
|
176
|
+
FC & BM & EM & M0 & LE & SM --> RQ
|
|
177
|
+
RQ -->|same answer model + prompt| A[answers]
|
|
178
|
+
A -->|LLM judge, published prompt| R[(results.json)]
|
|
179
|
+
R --> V[viewer / static site]
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- **Same answer model for everyone.** A system only decides what context reaches the answer model, so accuracy
|
|
183
|
+
differences come from memory, not prompting.
|
|
184
|
+
- **Questions** follow LongMemEval's categories: single-session, multi-session, temporal, knowledge update and
|
|
185
|
+
abstention (the answer is not in the history and the right reply is "I don't know").
|
|
186
|
+
- **Metrics**: accuracy from the LLM judge ([exact prompt](docs/judge-prompt.md)), retrieval latency p50/p95,
|
|
187
|
+
ingestion time, prompt tokens per question and cost, overall and per category.
|
|
188
|
+
- **Budget**: `--max-cost` (default 1 USD) is checked before every paid call; when it would be exceeded the run
|
|
189
|
+
stops and keeps partial results. Local models count as 0.
|
|
190
|
+
|
|
191
|
+
## Systems
|
|
192
|
+
|
|
193
|
+
| System | Kind | Runs | Status in v0.1 |
|
|
194
|
+
|---|---|---|---|
|
|
195
|
+
| `full-context` | baseline | anywhere | whole history pasted, newest kept if over `--max-context-tokens` |
|
|
196
|
+
| `bm25` | baseline | local, no deps | Okapi BM25 over user/assistant turn pairs |
|
|
197
|
+
| `embeddings` | baseline | Ollama or any OpenAI-compatible embeddings | cosine search over turn pairs |
|
|
198
|
+
| `mem0` | memory | local (mem0ai 2.2.1 OSS, Qdrant on disk) | live-tested (recorded demo); also smoke-tested with Ollama |
|
|
199
|
+
| `letta` | memory | Letta REST API (letta-client 1.12.1) | **not live-tested**: mock-tested only, see below |
|
|
200
|
+
| `supermemory` | memory | Supermemory API (supermemory 5.0.1), needs `SUPERMEMORY_API_KEY` | **not live-tested**: no key was available, mock-tested only |
|
|
201
|
+
|
|
202
|
+
Notes found while building the adapters:
|
|
203
|
+
|
|
204
|
+
- **mem0 and OpenRouter.** mem0 2.2.1's OpenAI-compatible client switches to OpenRouter whenever
|
|
205
|
+
`OPENROUTER_API_KEY` is set in the environment, ignoring the configured base URL. memarena hides that variable
|
|
206
|
+
from mem0 unless you chose OpenRouter, so your history goes only where you said. mem0's telemetry is turned off.
|
|
207
|
+
- **mem0 defaults.** memarena tests mem0's default install. Its BM25 keyword search and spaCy lemmatization need
|
|
208
|
+
the `mem0ai[nlp,extras]` extras, which v0.1 does not install, so mem0 runs with semantic search only.
|
|
209
|
+
- **Letta.** Since 0.34 the `letta/letta` Docker image and the `letta` PyPI package ship "Letta Code"; the old
|
|
210
|
+
self-hosted Python REST server is end-of-life (the image says so when you start it the old way). The adapter
|
|
211
|
+
uses the REST API through `letta-client`, so it needs Letta Cloud (`LETTA_API_KEY`) or a self-hosted server
|
|
212
|
+
that still exposes `/v1`. It writes each turn to the agent's archival memory and searches it; it does not drive
|
|
213
|
+
the agent loop.
|
|
214
|
+
|
|
215
|
+
## Configuration
|
|
216
|
+
|
|
217
|
+
| Option | Default | What it does |
|
|
218
|
+
|---|---|---|
|
|
219
|
+
| `--provider`, `--model` | `ollama`, `qwen3:4b` | answer model (also used by `generate`) |
|
|
220
|
+
| `--judge-provider`, `--judge-model` | same as answer model | judge |
|
|
221
|
+
| `--embed-provider`, `--embed-model` | `ollama`, `nomic-embed-text` | embeddings baseline and mem0's embedder |
|
|
222
|
+
| `--memory-provider`, `--memory-model` | `ollama`, `qwen3:4b` | LLM inside mem0 / Letta |
|
|
223
|
+
| `--systems` | `full-context,bm25,embeddings,mem0` | what to compare |
|
|
224
|
+
| `--top-k` | 10 | items each retriever returns |
|
|
225
|
+
| `--max-context-tokens` | 100000 | cap for the full-context baseline |
|
|
226
|
+
| `--max-cost` | 1.0 | USD budget, checked before every paid call |
|
|
227
|
+
| `--price in,out` | built-in table | override the USD-per-million-token price of the answer model |
|
|
228
|
+
|
|
229
|
+
Providers (one OpenAI-compatible client, keys only from environment variables, see [.env.example](.env.example)):
|
|
230
|
+
`ollama` (`OLLAMA_HOST`, default http://localhost:11434), `openai` (`OPENAI_API_KEY`), `openrouter`
|
|
231
|
+
(`OPENROUTER_API_KEY`), `mistral` (`MISTRAL_API_KEY`). Optional systems: `SUPERMEMORY_API_KEY`, `LETTA_API_KEY`,
|
|
232
|
+
`LETTA_BASE_URL`. memarena sends no telemetry.
|
|
233
|
+
|
|
234
|
+
**Ollama context window.** Ollama serves models with a small default window (4096 tokens for `qwen3:4b` here) and
|
|
235
|
+
its OpenAI-compatible `/v1` endpoint cannot change it per request, so long prompts are cut silently. Create a
|
|
236
|
+
variant with a bigger window once (it shares the weights, no extra disk) and point memarena at it:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
printf 'FROM qwen3:4b\nPARAMETER num_ctx 16384\n' > Modelfile && ollama create qwen3:4b-16k -f Modelfile
|
|
240
|
+
memarena run history.json questions.json --model qwen3:4b-16k --memory-model qwen3:4b-16k \
|
|
241
|
+
--max-context-tokens 12000 --num-ctx 16384
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Keep `--max-context-tokens` below the window (leave room for the question and the answer) so the full-context
|
|
245
|
+
baseline truncates visibly in the results instead of silently on the server, and keep `--num-ctx` equal to the
|
|
246
|
+
variant's window so mem0's calls do not force Ollama to reload the model. Local reasoning models such as qwen3
|
|
247
|
+
think before answering, which is slow on a laptop. The recorded demo did not use Ollama for chat: its answer model
|
|
248
|
+
(`ministral-8b-latest`, 128k window) received at most ~69.3k prompt tokens per question, so nothing was cut.
|
|
249
|
+
|
|
250
|
+
Reproduce the demo data and run:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
curl -LO https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_oracle.json
|
|
254
|
+
memarena longmemeval longmemeval_oracle.json --out-dir lme --per-category 4 --max-chars 16000
|
|
255
|
+
memarena run lme/history.json lme/questions.json --systems full-context,bm25,embeddings,mem0 \
|
|
256
|
+
--provider mistral --model ministral-8b-latest --judge-model codestral-latest \
|
|
257
|
+
--memory-provider mistral --memory-model ministral-8b-latest --yes --max-cost 2
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Roadmap
|
|
261
|
+
|
|
262
|
+
- More memory systems: Zep / Graphiti (need Neo4j or FalkorDB), cognee, MemOS.
|
|
263
|
+
- claude-mem is out of scope for now: it is a Claude Code session plugin, not an API to ingest conversations.
|
|
264
|
+
- Letta agent-loop mode (let the agent edit its own memory while reading the history).
|
|
265
|
+
- mem0 with its `nlp` and `extras` (hybrid search) as a separate configuration.
|
|
266
|
+
- Repeated runs with confidence intervals.
|
|
267
|
+
- LoCoMo is not bundled: its license (CC BY-NC 4.0) is not compatible with an MIT package.
|
|
268
|
+
|
|
269
|
+
## Third-party data
|
|
270
|
+
|
|
271
|
+
The recorded demo bundles a 20-question subset of LongMemEval
|
|
272
|
+
([xiaowu0162/longmemeval-cleaned](https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned), code at
|
|
273
|
+
[xiaowu0162/LongMemEval](https://github.com/xiaowu0162/LongMemEval)), MIT licensed, Copyright (c) 2024 Di Wu.
|
|
274
|
+
Its license notice ships next to the data, unmodified, in
|
|
275
|
+
[`src/memarena/data/demo/LICENSE-LongMemEval.txt`](src/memarena/data/demo/LICENSE-LongMemEval.txt)
|
|
276
|
+
(copied from the LongMemEval repository at commit `9e0b455`), and is included in the wheel and the sdist.
|
|
277
|
+
|
|
278
|
+
## License
|
|
279
|
+
|
|
280
|
+
[MIT](LICENSE) for memarena itself. The bundled demo data keeps its own MIT notice (see Third-party data).
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/banner.svg" alt="memarena" width="760">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://github.com/diegoperezg7/memarena/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/diegoperezg7/memarena/actions/workflows/ci.yml/badge.svg"></a>
|
|
7
|
+
<a href="LICENSE"><img alt="Licencia: MIT" src="https://img.shields.io/badge/license-MIT-7945c5"></a>
|
|
8
|
+
<a href="https://github.com/diegoperezg7/memarena/releases"><img alt="Release" src="https://img.shields.io/github/v/release/diegoperezg7/memarena?color=7945c5"></a>
|
|
9
|
+
<a href="https://github.com/diegoperezg7/memarena/stargazers"><img alt="Estrellas" src="https://img.shields.io/github/stars/diegoperezg7/memarena?style=flat&color=7945c5"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center"><b>Compara capas de memoria con tus propias conversaciones, no con el ranking de otro.</b></p>
|
|
13
|
+
|
|
14
|
+
<p align="center"><a href="README.md">English</a> · Español · <a href="https://diegoperezg7.github.io/memarena/">Visor de ejemplo</a></p>
|
|
15
|
+
|
|
16
|
+
memarena convierte tu exportación de ChatGPT o Claude en un test de memoria: escribe preguntas con su
|
|
17
|
+
respuesta correcta a partir de tu propio historial (las revisas tú), mete el historial en cada capa de memoria,
|
|
18
|
+
hace cada pregunta y puntúa las respuestas con un juez LLM cuyo prompt está publicado. Cada ejecución incluye
|
|
19
|
+
siempre lo que una capa de memoria tiene que superar: **pegar el historial entero** y **una recuperación simple**
|
|
20
|
+
(BM25 y embeddings).
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
## Por qué
|
|
25
|
+
|
|
26
|
+
Los arneses públicos de memoria los publica cada uno un fabricante de memoria y giran en torno a datasets fijos:
|
|
27
|
+
[supermemoryai/memorybench](https://github.com/supermemoryai/memorybench) (334 estrellas, Supermemory),
|
|
28
|
+
[vectorize-io/agent-memory-benchmark](https://github.com/vectorize-io/agent-memory-benchmark) (163, Vectorize) y
|
|
29
|
+
[mem0ai/memory-benchmarks](https://github.com/mem0ai/memory-benchmarks) (134, Mem0) (estrellas a 3 nov 2026).
|
|
30
|
+
|
|
31
|
+
Las cifras de los fabricantes no cuadran entre sí. El paper de Mem0 da, en LoCoMo, un 26 % de mejora relativa en
|
|
32
|
+
LLM-as-a-Judge frente a la memoria de OpenAI, y un 91 % menos de latencia p95 y más de un 90 % menos de tokens
|
|
33
|
+
que el contexto completo ([arXiv 2504.19413](https://arxiv.org/abs/2504.19413)). Letta publicó después un 74,0 %
|
|
34
|
+
en LoCoMo con GPT-4o mini para un agente con sistema de ficheros, frente al 68,5 % que Mem0 publicó para sí mismo,
|
|
35
|
+
y añadió «Mem0 did not respond to requests for clarification»
|
|
36
|
+
([blog de Letta, 12 ago 2025](https://www.letta.com/blog/benchmarking-ai-agent-memory)). Zep da un 94,8 % en DMR
|
|
37
|
+
frente al 93,4 % de MemGPT y hasta un 18,5 % más de acierto en LongMemEval
|
|
38
|
+
([arXiv 2501.13956](https://arxiv.org/abs/2501.13956)).
|
|
39
|
+
|
|
40
|
+
Tenga razón quien la tenga en LoCoMo, nada de eso dice cómo funciona una capa de memoria con **tus**
|
|
41
|
+
conversaciones, con **tu** modelo, frente a la opción barata de pegarlo todo. memarena es neutral, trabaja sobre
|
|
42
|
+
tus exportaciones y pone siempre contexto completo, BM25 y embeddings en la misma tabla.
|
|
43
|
+
|
|
44
|
+
## Inicio rápido
|
|
45
|
+
|
|
46
|
+
Demo grabada, sin claves, sin Docker y sin llamadas a modelos (menos de 2 minutos en una máquina limpia con `uv`):
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uvx --from git+https://github.com/diegoperezg7/memarena@v0.1.2 memarena demo
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
o desde un clon:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git clone https://github.com/diegoperezg7/memarena && cd memarena && uv run memarena demo
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+

|
|
59
|
+
|
|
60
|
+
Imprime la tabla de abajo y abre el visor en http://127.0.0.1:8765 (`--no-view` para solo imprimir).
|
|
61
|
+
`uvx memarena` llegará con la publicación en PyPI.
|
|
62
|
+
|
|
63
|
+
## Ejemplo de salida
|
|
64
|
+
|
|
65
|
+
Es una **ejecución real grabada** (`memarena run`, 3 nov 2026) que va dentro del paquete y que muestra
|
|
66
|
+
`memarena demo`: 20 preguntas (4 por categoría) de
|
|
67
|
+
[LongMemEval](https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned) (MIT), con las sesiones de evidencia
|
|
68
|
+
de las 20 juntas en **un solo** historial de 28 sesiones (~75k tokens), como sería la exportación de un usuario.
|
|
69
|
+
|
|
70
|
+
| Sistema | Acierto | Una sesión | Varias | Temporal | Actualización | Abstención | Recuperación p50 / p95 | Ingesta | Tokens de prompt / p | Coste |
|
|
71
|
+
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
72
|
+
| **mem0** (memoria) | **75 %** | 50 % | 50 % | 75 % | 100 % | 100 % | 49 / 134 ms | 21,6 min | 611 | 0,174 $ |
|
|
73
|
+
| bm25 (línea base) | 70 % | 75 % | 25 % | 50 % | 100 % | 100 % | 0,9 / 3,9 ms | 0,03 s | 4.180 | 0,008 $ |
|
|
74
|
+
| embeddings (línea base) | 55 % | 50 % | 50 % | 25 % | 50 % | 100 % | 105 / 233 ms | 34 s | 3.537 | 0,007 $ |
|
|
75
|
+
| full-context (línea base) | 50 % | 0 % | 0 % | 75 % | 75 % | 100 % | 0,5 / 1,2 ms | 0 s | 69.297 | 0,139 $ |
|
|
76
|
+
|
|
77
|
+
Configuración: modelo que responde `mistral/ministral-8b-latest` (el mismo para todos), juez
|
|
78
|
+
`mistral/codestral-latest`, mem0 2.2.1 con `ministral-8b-latest` para extraer hechos, embeddings
|
|
79
|
+
`nomic-embed-text` en Ollama local, 10 elementos por recuperador. Hardware: portátil Apple silicon, 10 CPUs,
|
|
80
|
+
16 GB de RAM; el servidor de Ollama estaba compartido con otros trabajos durante la ejecución, así que las
|
|
81
|
+
latencias de embeddings son pesimistas. 20 preguntas es una muestra pequeña: diferencias de una o dos preguntas
|
|
82
|
+
son ruido.
|
|
83
|
+
|
|
84
|
+
Lo que enseña esta ejecución pequeña:
|
|
85
|
+
|
|
86
|
+
- **Pegarlo todo perdió.** Con unos 69k tokens de prompt por pregunta, el modelo de 8B respondió «no lo sé» a todas
|
|
87
|
+
las preguntas de una y de varias sesiones, que sí respondía a partir de fragmentos recuperados.
|
|
88
|
+
- **mem0 envió alrededor del 1 % del prompt de contexto completo** (611 frente a 69.297 tokens por pregunta) y
|
|
89
|
+
sacó la nota más alta, pero su ingesta tardó 21,6 minutos y costó 0,17 $ en llamadas al LLM para 165 turnos (una
|
|
90
|
+
extracción por turno), frente a 0,03 s de BM25.
|
|
91
|
+
- **BM25 quedó a 5 puntos de mem0** casi sin coste. Esa diferencia es una pregunta.
|
|
92
|
+
- **Auditoría del juez.** Revisé a mano las 80 decisiones del juez: 3 falsos positivos, todos en temporal (uno en
|
|
93
|
+
full-context, otro en bm25 y otro en mem0; por ejemplo, aceptó «hace 1 semana» cuando eran «4 semanas») y ningún
|
|
94
|
+
falso negativo. Acierto corregido: mem0 70 %, bm25 65 %, embeddings 55 %, full-context 45 %. El orden no cambia.
|
|
95
|
+
La tabla muestra la salida tal cual del juez.
|
|
96
|
+
- Gasto total de esta ejecución: **0,34 $** (API de Mistral, calculado con los tokens que devolvió).
|
|
97
|
+
|
|
98
|
+
Cada respuesta, el razonamiento del juez y lo que recuperó cada sistema están en el
|
|
99
|
+
[visor de ejemplo](https://diegoperezg7.github.io/memarena/).
|
|
100
|
+
|
|
101
|
+
## Úsalo con tu historial
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# 1. Importa tu exportación (conversations.json de ChatGPT o Claude, el .zip, o JSONL)
|
|
105
|
+
uvx --from git+https://github.com/diegoperezg7/memarena@v0.1.2 memarena import conversations.json --out history.json
|
|
106
|
+
|
|
107
|
+
# 2. Genera preguntas con respuesta y punteros a la evidencia (quedan como "pending")
|
|
108
|
+
memarena generate history.json --out questions.json # Ollama local por defecto
|
|
109
|
+
|
|
110
|
+
# 3. Revísalas: edita, aprueba o rechaza en el visor (se guardan en questions.json)
|
|
111
|
+
memarena view --questions questions.json --history history.json
|
|
112
|
+
|
|
113
|
+
# 4. Ejecuta el benchmark con las preguntas aprobadas
|
|
114
|
+
memarena run history.json questions.json --systems full-context,bm25,embeddings,mem0
|
|
115
|
+
|
|
116
|
+
# 5. Mira los resultados o expórtalos como web estática
|
|
117
|
+
memarena view results.json
|
|
118
|
+
memarena export results.json --questions questions.json --out site
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
mem0, Letta y Supermemory son extras opcionales:
|
|
122
|
+
`uvx --from 'memarena[mem0] @ git+https://github.com/diegoperezg7/memarena@v0.1.2' memarena run ...`
|
|
123
|
+
(o `uv sync --extra mem0` en un clon).
|
|
124
|
+
|
|
125
|
+
**Privacidad.** Con `--provider ollama` y sistemas locales nada sale de tu máquina. Con un proveedor en la nube,
|
|
126
|
+
Supermemory o Letta Cloud, memarena dice adónde van a ir tus conversaciones y pregunta antes de enviarlas
|
|
127
|
+
(`--yes` se salta la pregunta). Las preguntas generadas hay que revisarlas: sin revisión el test no es fiable, así
|
|
128
|
+
que `run` solo usa las aprobadas salvo que pases `--include-pending`.
|
|
129
|
+
|
|
130
|
+
## Cómo funciona
|
|
131
|
+
|
|
132
|
+
```mermaid
|
|
133
|
+
flowchart LR
|
|
134
|
+
E["Exportación ChatGPT / Claude<br/>o JSONL"] -->|memarena import| H[(history.json)]
|
|
135
|
+
H -->|memarena generate| Q[(questions.json<br/>pendientes)]
|
|
136
|
+
Q -->|revisión en el visor| QA[(questions.json<br/>aprobadas)]
|
|
137
|
+
H --> I{ingesta}
|
|
138
|
+
I --> FC[contexto completo]
|
|
139
|
+
I --> BM[BM25]
|
|
140
|
+
I --> EM[embeddings]
|
|
141
|
+
I --> M0[mem0]
|
|
142
|
+
I --> LE[Letta]
|
|
143
|
+
I --> SM[Supermemory]
|
|
144
|
+
QA --> RQ{recuperación por pregunta}
|
|
145
|
+
FC & BM & EM & M0 & LE & SM --> RQ
|
|
146
|
+
RQ -->|mismo modelo y prompt| A[respuestas]
|
|
147
|
+
A -->|juez LLM, prompt publicado| R[(results.json)]
|
|
148
|
+
R --> V[visor / web estática]
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
- **El mismo modelo responde para todos.** Un sistema solo decide qué contexto llega al modelo, así que las
|
|
152
|
+
diferencias de acierto vienen de la memoria y no del prompt.
|
|
153
|
+
- **Las preguntas** siguen las categorías de LongMemEval: una sesión, varias sesiones, temporal, actualización
|
|
154
|
+
de conocimiento y abstención (la respuesta no está en el historial y lo correcto es decir «no lo sé»).
|
|
155
|
+
- **Métricas**: acierto según el juez LLM ([prompt exacto](docs/judge-prompt.md)), latencia de recuperación
|
|
156
|
+
p50/p95, tiempo de ingesta, tokens de prompt por pregunta y coste, en total y por categoría.
|
|
157
|
+
- **Presupuesto**: `--max-cost` (1 USD por defecto) se comprueba antes de cada llamada de pago; si se superaría,
|
|
158
|
+
la ejecución para y guarda los resultados parciales. Los modelos locales cuentan como 0.
|
|
159
|
+
|
|
160
|
+
## Sistemas
|
|
161
|
+
|
|
162
|
+
| Sistema | Tipo | Dónde corre | Estado en v0.1 |
|
|
163
|
+
|---|---|---|---|
|
|
164
|
+
| `full-context` | línea base | en cualquier sitio | historial entero; si no cabe en `--max-context-tokens`, se queda lo más reciente |
|
|
165
|
+
| `bm25` | línea base | local, sin dependencias | BM25 de Okapi sobre pares de turnos usuario/asistente |
|
|
166
|
+
| `embeddings` | línea base | Ollama o cualquier API de embeddings compatible con OpenAI | búsqueda por coseno sobre pares de turnos |
|
|
167
|
+
| `mem0` | memoria | local (mem0ai 2.2.1 OSS, Qdrant en disco) | probado en vivo (demo grabada); también probado con Ollama |
|
|
168
|
+
| `letta` | memoria | API REST de Letta (letta-client 1.12.1) | **sin probar en vivo**: solo con mocks, ver abajo |
|
|
169
|
+
| `supermemory` | memoria | API de Supermemory (supermemory 5.0.1), necesita `SUPERMEMORY_API_KEY` | **sin probar en vivo**: no había clave, solo con mocks |
|
|
170
|
+
|
|
171
|
+
Lo que salió al construir los adaptadores:
|
|
172
|
+
|
|
173
|
+
- **mem0 y OpenRouter.** El cliente compatible con OpenAI de mem0 2.2.1 se pasa a OpenRouter siempre que
|
|
174
|
+
`OPENROUTER_API_KEY` está en el entorno, ignorando la URL configurada. memarena le oculta esa variable a mem0
|
|
175
|
+
salvo que hayas elegido OpenRouter, para que tu historial vaya solo adonde dijiste. La telemetría de mem0 se
|
|
176
|
+
desactiva.
|
|
177
|
+
- **mem0 por defecto.** memarena prueba la instalación por defecto de mem0. Su búsqueda BM25 y la lematización
|
|
178
|
+
con spaCy necesitan los extras `mem0ai[nlp,extras]`, que la v0.1 no instala, así que mem0 usa solo búsqueda
|
|
179
|
+
semántica.
|
|
180
|
+
- **Letta.** Desde la 0.34 la imagen Docker `letta/letta` y el paquete `letta` de PyPI traen «Letta Code»; el
|
|
181
|
+
antiguo servidor REST en Python está retirado (la propia imagen lo dice al arrancarla como antes). El adaptador
|
|
182
|
+
usa la API REST con `letta-client`, así que necesita Letta Cloud (`LETTA_API_KEY`) o un servidor propio que
|
|
183
|
+
siga exponiendo `/v1`. Guarda cada turno en la memoria de archivo del agente y busca en ella; no ejecuta el
|
|
184
|
+
bucle del agente.
|
|
185
|
+
|
|
186
|
+
## Configuración
|
|
187
|
+
|
|
188
|
+
| Opción | Por defecto | Qué hace |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| `--provider`, `--model` | `ollama`, `qwen3:4b` | modelo que responde (también lo usa `generate`) |
|
|
191
|
+
| `--judge-provider`, `--judge-model` | el mismo que responde | juez |
|
|
192
|
+
| `--embed-provider`, `--embed-model` | `ollama`, `nomic-embed-text` | línea base de embeddings y embedder de mem0 |
|
|
193
|
+
| `--memory-provider`, `--memory-model` | `ollama`, `qwen3:4b` | LLM dentro de mem0 / Letta |
|
|
194
|
+
| `--systems` | `full-context,bm25,embeddings,mem0` | qué comparar |
|
|
195
|
+
| `--top-k` | 10 | elementos que devuelve cada recuperador |
|
|
196
|
+
| `--max-context-tokens` | 100000 | tope de la línea base de contexto completo |
|
|
197
|
+
| `--max-cost` | 1.0 | presupuesto en USD, comprobado antes de cada llamada de pago |
|
|
198
|
+
| `--price in,out` | tabla interna | precio en USD por millón de tokens del modelo que responde |
|
|
199
|
+
|
|
200
|
+
Proveedores (un solo cliente compatible con OpenAI, claves solo desde variables de entorno, ver
|
|
201
|
+
[.env.example](.env.example)): `ollama` (`OLLAMA_HOST`, por defecto http://localhost:11434), `openai`
|
|
202
|
+
(`OPENAI_API_KEY`), `openrouter` (`OPENROUTER_API_KEY`), `mistral` (`MISTRAL_API_KEY`). Sistemas opcionales:
|
|
203
|
+
`SUPERMEMORY_API_KEY`, `LETTA_API_KEY`, `LETTA_BASE_URL`. memarena no envía telemetría.
|
|
204
|
+
|
|
205
|
+
**Ventana de contexto de Ollama.** Ollama sirve los modelos con una ventana pequeña por defecto (4096 tokens para
|
|
206
|
+
`qwen3:4b` aquí) y su endpoint `/v1`, compatible con OpenAI, no deja cambiarla por petición, así que los prompts
|
|
207
|
+
largos se recortan en silencio. Crea una vez una variante con más ventana (comparte los pesos, no ocupa disco) y
|
|
208
|
+
usa esa:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
printf 'FROM qwen3:4b\nPARAMETER num_ctx 16384\n' > Modelfile && ollama create qwen3:4b-16k -f Modelfile
|
|
212
|
+
memarena run history.json questions.json --model qwen3:4b-16k --memory-model qwen3:4b-16k \
|
|
213
|
+
--max-context-tokens 12000 --num-ctx 16384
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Deja `--max-context-tokens` por debajo de la ventana (con margen para la pregunta y la respuesta) para que la
|
|
217
|
+
línea base de contexto completo recorte de forma visible en los resultados y no en silencio en el servidor, y deja
|
|
218
|
+
`--num-ctx` igual a la ventana de la variante para que las llamadas de mem0 no obliguen a Ollama a recargar el
|
|
219
|
+
modelo. Los modelos locales que razonan, como qwen3, piensan antes de responder y en un portátil van lentos. La
|
|
220
|
+
demo grabada no usó Ollama para el chat: su modelo (`ministral-8b-latest`, ventana de 128k) recibió como mucho
|
|
221
|
+
~69,3k tokens de prompt por pregunta, así que no se recortó nada.
|
|
222
|
+
|
|
223
|
+
Para reproducir los datos y la ejecución de la demo:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
curl -LO https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_oracle.json
|
|
227
|
+
memarena longmemeval longmemeval_oracle.json --out-dir lme --per-category 4 --max-chars 16000
|
|
228
|
+
memarena run lme/history.json lme/questions.json --systems full-context,bm25,embeddings,mem0 \
|
|
229
|
+
--provider mistral --model ministral-8b-latest --judge-model codestral-latest \
|
|
230
|
+
--memory-provider mistral --memory-model ministral-8b-latest --yes --max-cost 2
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Hoja de ruta
|
|
234
|
+
|
|
235
|
+
- Más sistemas de memoria: Zep / Graphiti (necesitan Neo4j o FalkorDB), cognee, MemOS.
|
|
236
|
+
- claude-mem queda fuera por ahora: es un plugin de sesiones de Claude Code, no una API para ingerir conversaciones.
|
|
237
|
+
- Modo agente de Letta (que el agente edite su propia memoria mientras lee el historial).
|
|
238
|
+
- mem0 con sus extras `nlp` y `extras` (búsqueda híbrida) como configuración aparte.
|
|
239
|
+
- Repeticiones con intervalos de confianza.
|
|
240
|
+
- LoCoMo no se incluye: su licencia (CC BY-NC 4.0) no es compatible con un paquete MIT.
|
|
241
|
+
|
|
242
|
+
## Datos de terceros
|
|
243
|
+
|
|
244
|
+
La demo grabada incluye un subconjunto de 20 preguntas de LongMemEval
|
|
245
|
+
([xiaowu0162/longmemeval-cleaned](https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned), código en
|
|
246
|
+
[xiaowu0162/LongMemEval](https://github.com/xiaowu0162/LongMemEval)), con licencia MIT, Copyright (c) 2024 Di Wu.
|
|
247
|
+
Su aviso de licencia va junto a los datos, sin modificar, en
|
|
248
|
+
[`src/memarena/data/demo/LICENSE-LongMemEval.txt`](src/memarena/data/demo/LICENSE-LongMemEval.txt)
|
|
249
|
+
(copiado del repositorio de LongMemEval en el commit `9e0b455`), y se incluye en el wheel y en el sdist.
|
|
250
|
+
|
|
251
|
+
## Licencia
|
|
252
|
+
|
|
253
|
+
[MIT](LICENSE) para memarena. Los datos de la demo mantienen su propio aviso MIT (ver Datos de terceros).
|