docs: add MemLens-256K results to the multimodal memory blog (#639)

* docs: report multimodal memory results on MemLens-256K

* docs: simplify MemLens results with LLM-Judge charts

* docs: disclose MemLens evaluation settings and evidence

* docs: streamline MemLens evaluation report

* docs: clarify integrated benchmark reproduction results

* docs: pin MemLens reproduction experiment commit

* docs: reference public MemLens evaluation commit

* test(docs): validate exact evaluation link destinations

* test(docs): simplify evaluation link checks

* test(docs): verify Judge settings and visible chart scores

---------

Co-authored-by: jinli.yl <jinli.yl@alibaba-inc.com>
This commit is contained in:
WQS 2026-10-21 16:31:47 +08:00 • committed by GitHub
parent 831fa82669
commit beda564def
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 398 additions and 0 deletions

View file

@ -79,6 +79,18 @@ Image resources then participate in the existing retrieval workflow. A later sea
Auto Resource supports PNG, JPG/JPEG, WebP, GIF, BMP, TIFF, and HEIC. Larger images may be resized or converted for the model request; the original resource files remain unchanged. HEIC requires the optional `reme-ai[image-heif]` package.
## Performance: Multimodal Long-History QA on MemLens-256K {#memlens-256k-results}
On MemLens-256K, ReMe Image achieved LLM-Judge scores of **53.44%** with Qwen3.6-35B-A3B and **72.49%** with Qwen3.8-Max, exceeding Full Context Image by **6.35** and **6.88** percentage points, respectively.
![MemLens-256K LLM-Judge with Qwen3.6-35B-A3B: Full Context Image 47.09%, ReMe Text 41.27%, ReMe Image 53.44%, OpenViking 37.04%, Mem0 38.62%.](../figure/memlens-256k-qwen36-judge.svg)
![MemLens-256K LLM-Judge with Qwen3.8-Max: Full Context Image 65.61%, ReMe Text 52.91%, ReMe Image 72.49%, OpenViking 42.33%, Mem0 51.32%.](../figure/memlens-256k-qwen38-judge.svg)
The comparison uses the official LLM-Judge protocol to evaluate each complete system. Six cases triggered model-provider content moderation in at least one method, so all methods use the same filtered set of **189/195** cases.
ReMe can retrieve original conversations, and Image can reopen source images; OpenViking retrieval in this evaluation is restricted to memory. See the [evaluation notes](./memlens_256k_evaluation.md) for experimental settings, exclusions and the reproduction comparison.
## Getting Started
Both paths require a vision model that supports image input and tool calling, along with a compatible AgentScope wrapper and formatter. The selected wrapper's `as_llm` binding determines which model is used. See [Configuration](./configuration.md) for credential setup.

View file

@ -0,0 +1,68 @@
# MemLens-256K Evaluation Notes
This report describes the experimental settings, data selection and results of the MemLens-256K evaluation in the [multimodal memory article](./blog_20261009.md#memlens-256k-results).
## Results and Evaluation Set {#results}
The evaluation uses the 195 questions in the official [MemLens](https://huggingface.co/datasets/xiyuRenBill/MEMLENS) `agent_subset_195.json`, each with its complete 256K history. After excluding the six questions listed below, all methods are evaluated on the same 189 questions. The official category/subtype-specific LLM-Judge protocol assigns each answer a score of 0 or 1; the reported percentage is `100 × correct / 189`.
| Model | Method | Judge correct / 189 | LLM-Judge (%) |
| --- | --- | ---: | ---: |
| Qwen3.6-35B-A3B | Full Context Image | 89 / 189 | 47.09 |
| Qwen3.6-35B-A3B | ReMe Text | 78 / 189 | 41.27 |
| Qwen3.6-35B-A3B | ReMe Image | 101 / 189 | 53.44 |
| Qwen3.6-35B-A3B | OpenViking | 70 / 189 | 37.04 |
| Qwen3.6-35B-A3B | Mem0 | 73 / 189 | 38.62 |
| Qwen3.8-Max | Full Context Image | 124 / 189 | 65.61 |
| Qwen3.8-Max | ReMe Text | 100 / 189 | 52.91 |
| Qwen3.8-Max | ReMe Image | 137 / 189 | 72.49 |
| Qwen3.8-Max | OpenViking | 80 / 189 | 42.33 |
| Qwen3.8-Max | Mem0 | 97 / 189 | 51.32 |
ReMe Image scores **53.44%** and **72.49%** on the two models, exceeding Full Context Image by **6.35** and **6.88** percentage points, respectively.
## Method and Judge Settings {#evaluation-settings}
| Method | Memory input and answer-time data access |
| --- | --- |
| Full Context Image | The answer model receives the complete conversation text and original images directly. |
| ReMe Text | Builds memory from the original conversation text. The answer Agent uses BM25 to search daily notes, digest notes and original sessions, then reads relevant text. |
| ReMe Image | Builds memory from the original conversation text and images. Retrieval covers the same sources as Text, with `read_image` available to reopen saved original images. |
| OpenViking | Uses native image descriptions and memory processing. Answer-time retrieval is restricted to memory with the default top 10. |
| Mem0 | Builds memory through Mem0 2.0.4's native vision interface. Answer-time retrieval uses FAISS to select the top 20 memories. |
Each method is evaluated with Qwen3.6-35B-A3B and Qwen3.8-Max as the candidate models. ReMe Image and Mem0 both use original images. ReMe's memory and answer context limits are 200,000 and 400,000 tokens, with temperature 0 and thinking enabled. Memory/compression and answer output budgets are 65,536 and 16,384 tokens. Each question uses an independent answer Agent with at most 30 iterations and native context compression. The `read_image` adapter accesses saved attachments with a 50 MiB read limit and a 4,096-image retention limit.
Full Context, OpenViking and Mem0 also use temperature 0, thinking enabled and a 16,384-token output budget for answering. Mem0's memory stage uses its native settings: a 2,000-token output budget, temperature 0.1 and top_p 0.1. The OpenViking evaluation adapter includes a JSON parsing correction and explicit error reporting for image-processing failures.
Scoring follows the [official MemLens protocol](https://github.com/xrenaf/MEMLENS/tree/77f3ab9a52fa2d6a17978e2dffe80438a4ecced2). All methods use **Qwen3.8-Max** as Judge, with temperature **0**, thinking **disabled** and a **256-token** output budget. The Judge runs independently of candidate memory applications; reference answers and question-type labels are used only for scoring.
## Common Content-Moderation Filter {#content-moderation-filter}
The method/question combinations below triggered content moderation when calling the Qwen model service. Taking the union of affected questions across all methods and both models gives six questions. We exclude this same set from every method and model, leaving **189/195** questions for evaluation.
In the table, A3B denotes Qwen3.6-35B-A3B and Max denotes Qwen3.8-Max.
| Question ID | Method / model that triggered moderation | Stage |
| --- | --- | --- |
| `q_028cb832` | OpenViking / Max | Memory construction |
| `q_1d99a36c` | OpenViking / A3B | Memory construction |
| `q_3b01c02a` | ReMe Text and Image / A3B; OpenViking / A3B and Max; Mem0 / A3B | Memory construction |
| `q_564a657b` | ReMe Image / Max | Answering |
| `q_600a79aa` | ReMe Image / Max | Memory construction |
| `q_c9f8e24d` | ReMe Text / Max | Answering |
## Independent Reproduction Results {#independent-reproduction}
We organized and integrated the MemLens benchmark code into ReMe, then independently reran ReMe Image using the same data inputs and scoring settings. See the [run instructions](https://github.com/agentscope-ai/ReMe/blob/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8/benchmark/memlens/README.md), [method configuration](https://github.com/agentscope-ai/ReMe/blob/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8/plugins/memlens/src/reme_memlens/benchmark.yaml), [Judge configuration](https://github.com/agentscope-ai/ReMe/blob/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8/plugins/memlens-judge/src/judge_memlens/plugin.yaml) and [Judge scoring rules](https://github.com/agentscope-ai/ReMe/blob/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8/plugins/memlens-judge/src/judge_memlens/protocol.py) for the implementation and settings.
The corresponding public evaluation code is available in [PR #640](https://github.com/agentscope-ai/ReMe/pull/640) at commit [962d5cd](https://github.com/agentscope-ai/ReMe/commit/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8).
After applying the same six-question filter, one A3B question and two Max questions remain incomplete because conversation-history processing failed. The table compares the 188 and 187 questions completed in both experiments, respectively.
| Model | Paired questions | Original ReMe Image correct | Independent reproduction correct | Original → reproduction LLM-Judge (%) |
| --- | ---: | ---: | ---: | ---: |
| Qwen3.6-35B-A3B | 188 | 100 | 96 | 53.19 → 51.06 |
| Qwen3.8-Max | 187 | 135 | 134 | 72.19 → 71.66 |
On these matched questions, the reproduced LLM-Judge scores for Qwen3.6-35B-A3B and Qwen3.8-Max are 2.13 and 0.53 percentage points lower than the original results, respectively. Overall, performance remains broadly consistent with the original experiment.

View file

@ -276,6 +276,8 @@ BEAM covers ten categories of tasks, including contradiction resolution, event o
ReMe also uses $\pi$-Bench to evaluate the potential of multi-session reasoning to improve agent proactivity. The PROC score in $\pi$-Bench evaluates capabilities including directly fulfilling hidden intent, guiding targeted clarification, recovering cross-session preferences, reusing cross-session conventions, inferring cross-task dependencies, and advancing underspecified requests. Across five user personas, ReMe Agent achieved an average PROC score of 0.580, outperforming NanoBot by 2.4% under the same test-model configuration. See the [$\pi$-Bench paper](https://arxiv.org/abs/2605.14678) for details about the benchmark.
On **MemLens-256K**, ReMe Image achieved LLM-Judge scores of **53.44% / 72.49%** with Qwen3.6-35B-A3B / Qwen3.8-Max, exceeding Full Context Image by **6.35 / 6.88** percentage points. All methods use the same **189/195** cases after filtering six cases that triggered model-provider content moderation. See the [multimodal memory evaluation](./blog_20261009.md#memlens-256k-results) for the five-method comparison.
## Who Is ReMe For?
### People Who Use Agents Directly

View file

@ -0,0 +1,56 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="520" viewBox="0 0 1000 520" role="img" aria-labelledby="title desc">
<title id="title">MemLens-256K: Qwen3.6-35B-A3B</title>
<desc id="desc">LLM-Judge scores on the same 189 of 195 cases. Full Context Image: 47.09%; ReMe Text: 41.27%; ReMe Image: 53.44%; OpenViking: 37.04%; Mem0: 38.62%. Six cases with provider content-moderation evidence are excluded across all methods.</desc>
<style>
text { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #263344; }
.title { font-size: 26px; font-weight: 650; }
.subtitle, .tick { font-size: 16px; fill: #64748b; }
.label { font-size: 18px; }
.value { font-size: 21px; font-weight: 600; font-variant-numeric: tabular-nums; }
.highlight { fill: #2563eb; font-weight: 700; }
.grid { stroke: #e2e8f0; stroke-width: 1; stroke-dasharray: 3 5; }
.baseline { fill: #cbd5e1; stroke: #94a3b8; }
.reme { fill: #2563eb; stroke: #1d4ed8; }
</style>
<rect x="1" y="1" width="998" height="518" rx="12" fill="#ffffff" stroke="#e2e8f0"/>
<text class="title" x="36" y="46">Qwen3.6-35B-A3B</text>
<text class="subtitle" x="36" y="76">MemLens-256K · LLM-Judge (%) ↑</text>
<line class="grid" x1="100" y1="416" x2="940" y2="416"/>
<text class="tick" x="82" y="422" text-anchor="end">0%</text>
<line class="grid" x1="100" y1="356" x2="940" y2="356"/>
<text class="tick" x="82" y="362" text-anchor="end">20%</text>
<line class="grid" x1="100" y1="296" x2="940" y2="296"/>
<text class="tick" x="82" y="302" text-anchor="end">40%</text>
<line class="grid" x1="100" y1="236" x2="940" y2="236"/>
<text class="tick" x="82" y="242" text-anchor="end">60%</text>
<line class="grid" x1="100" y1="176" x2="940" y2="176"/>
<text class="tick" x="82" y="182" text-anchor="end">80%</text>
<line class="grid" x1="100" y1="116" x2="940" y2="116"/>
<text class="tick" x="82" y="122" text-anchor="end">100%</text>
<line x1="100" y1="416" x2="940" y2="416" stroke="#94a3b8"/>
<g data-method="Full Context Image" data-score="47.09">
<rect class="baseline" x="144" y="274.73" width="104" height="141.27"/>
<text class="value" x="196" y="262.73" text-anchor="middle">47.09%</text>
<text class="label" x="196" y="450" text-anchor="middle"><tspan x="196">Full Context</tspan><tspan x="196" dy="23">Image</tspan></text>
</g>
<g data-method="ReMe Text" data-score="41.27">
<rect class="baseline" x="308" y="292.19" width="104" height="123.81"/>
<text class="value" x="360" y="280.19" text-anchor="middle">41.27%</text>
<text class="label" x="360" y="450" text-anchor="middle">ReMe Text</text>
</g>
<g data-method="ReMe Image" data-score="53.44">
<rect class="reme" x="472" y="255.68" width="104" height="160.32"/>
<text class="value highlight" x="524" y="243.68" text-anchor="middle">53.44%</text>
<text class="label highlight" x="524" y="450" text-anchor="middle">ReMe Image</text>
</g>
<g data-method="OpenViking" data-score="37.04">
<rect class="baseline" x="636" y="304.88" width="104" height="111.12"/>
<text class="value" x="688" y="292.88" text-anchor="middle">37.04%</text>
<text class="label" x="688" y="450" text-anchor="middle">OpenViking</text>
</g>
<g data-method="Mem0" data-score="38.62">
<rect class="baseline" x="800" y="300.14" width="104" height="115.86"/>
<text class="value" x="852" y="288.14" text-anchor="middle">38.62%</text>
<text class="label" x="852" y="450" text-anchor="middle">Mem0</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -0,0 +1,56 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="520" viewBox="0 0 1000 520" role="img" aria-labelledby="title desc">
<title id="title">MemLens-256K: Qwen3.8-Max</title>
<desc id="desc">LLM-Judge scores on the same 189 of 195 cases. Full Context Image: 65.61%; ReMe Text: 52.91%; ReMe Image: 72.49%; OpenViking: 42.33%; Mem0: 51.32%. Six cases with provider content-moderation evidence are excluded across all methods.</desc>
<style>
text { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #263344; }
.title { font-size: 26px; font-weight: 650; }
.subtitle, .tick { font-size: 16px; fill: #64748b; }
.label { font-size: 18px; }
.value { font-size: 21px; font-weight: 600; font-variant-numeric: tabular-nums; }
.highlight { fill: #2563eb; font-weight: 700; }
.grid { stroke: #e2e8f0; stroke-width: 1; stroke-dasharray: 3 5; }
.baseline { fill: #cbd5e1; stroke: #94a3b8; }
.reme { fill: #2563eb; stroke: #1d4ed8; }
</style>
<rect x="1" y="1" width="998" height="518" rx="12" fill="#ffffff" stroke="#e2e8f0"/>
<text class="title" x="36" y="46">Qwen3.8-Max</text>
<text class="subtitle" x="36" y="76">MemLens-256K · LLM-Judge (%) ↑</text>
<line class="grid" x1="100" y1="416" x2="940" y2="416"/>
<text class="tick" x="82" y="422" text-anchor="end">0%</text>
<line class="grid" x1="100" y1="356" x2="940" y2="356"/>
<text class="tick" x="82" y="362" text-anchor="end">20%</text>
<line class="grid" x1="100" y1="296" x2="940" y2="296"/>
<text class="tick" x="82" y="302" text-anchor="end">40%</text>
<line class="grid" x1="100" y1="236" x2="940" y2="236"/>
<text class="tick" x="82" y="242" text-anchor="end">60%</text>
<line class="grid" x1="100" y1="176" x2="940" y2="176"/>
<text class="tick" x="82" y="182" text-anchor="end">80%</text>
<line class="grid" x1="100" y1="116" x2="940" y2="116"/>
<text class="tick" x="82" y="122" text-anchor="end">100%</text>
<line x1="100" y1="416" x2="940" y2="416" stroke="#94a3b8"/>
<g data-method="Full Context Image" data-score="65.61">
<rect class="baseline" x="144" y="219.17" width="104" height="196.83"/>
<text class="value" x="196" y="207.17" text-anchor="middle">65.61%</text>
<text class="label" x="196" y="450" text-anchor="middle"><tspan x="196">Full Context</tspan><tspan x="196" dy="23">Image</tspan></text>
</g>
<g data-method="ReMe Text" data-score="52.91">
<rect class="baseline" x="308" y="257.27" width="104" height="158.73"/>
<text class="value" x="360" y="245.27" text-anchor="middle">52.91%</text>
<text class="label" x="360" y="450" text-anchor="middle">ReMe Text</text>
</g>
<g data-method="ReMe Image" data-score="72.49">
<rect class="reme" x="472" y="198.53" width="104" height="217.47"/>
<text class="value highlight" x="524" y="186.53" text-anchor="middle">72.49%</text>
<text class="label highlight" x="524" y="450" text-anchor="middle">ReMe Image</text>
</g>
<g data-method="OpenViking" data-score="42.33">
<rect class="baseline" x="636" y="289.01" width="104" height="126.99"/>
<text class="value" x="688" y="277.01" text-anchor="middle">42.33%</text>
<text class="label" x="688" y="450" text-anchor="middle">OpenViking</text>
</g>
<g data-method="Mem0" data-score="51.32">
<rect class="baseline" x="800" y="262.04" width="104" height="153.96"/>
<text class="value" x="852" y="250.04" text-anchor="middle">51.32%</text>
<text class="label" x="852" y="450" text-anchor="middle">Mem0</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -78,6 +78,18 @@ source_resource: "[[resource/2026-10-09/system-overview.png]]"
Auto Resource 支持 PNG、JPG/JPEG、WebP、GIF、BMP、TIFF 和 HEIC。较大的图片会在模型请求中按需缩小或转换格式,原始资源文件保持不变。HEIC 需要额外安装 `reme-ai[image-heif]`。
## Performance:MemLens-256K 多模态长历史问答 {#memlens-256k-results}
在 MemLens-256K 上,ReMe Image 的 LLM-Judge 得分在 Qwen3.6-35B-A3B 和 Qwen3.8-Max 下分别达到 **53.44%** 和 **72.49%**,比 Full Context Image 高 **6.35** 和 **6.88** 个百分点。
![Qwen3.6-35B-A3B 的 MemLens-256K LLM-Judge 对比:Full Context Image 47.09%,ReMe Text 41.27%,ReMe Image 53.44%,OpenViking 37.04%,Mem0 38.62%。](../figure/memlens-256k-qwen36-judge.svg)
![Qwen3.8-Max 的 MemLens-256K LLM-Judge 对比:Full Context Image 65.61%,ReMe Text 52.91%,ReMe Image 72.49%,OpenViking 42.33%,Mem0 51.32%。](../figure/memlens-256k-qwen38-judge.svg)
评测使用官方 LLM-Judge 协议,比较各方法完整系统的表现。6 个 case 在至少一种方法中触发了模型服务商的内容安全审核,因此对所有方法统一过滤,汇报其余 **189/195** 个 case 的结果。
ReMe 可以检索原始会话,Image 还可重新读取原图;本次 OpenViking 的检索范围限定为 memory。实验设置、过滤清单和复现对比见[详细评测说明](./memlens_256k_evaluation.md)。
## 如何开始使用
两个入口都需要支持图片和工具调用的视觉模型,以及兼容的 AgentScope wrapper 和 formatter。模型由所选 wrapper 的 `as_llm` 绑定决定。凭证配置见[基础配置](./configuration.md)。

View file

@ -0,0 +1,68 @@
# MemLens-256K 评测说明
本文介绍[多模态记忆文章](./blog_20261009.md#memlens-256k-results)中 MemLens-256K 评测的实验设置、数据筛选和结果。
## 结果与统计范围 {#results}
评测使用 [MemLens](https://huggingface.co/datasets/xiyuRenBill/MEMLENS) 官方 `agent_subset_195.json` 中的 195 个问题,每题使用对应的完整 256K 历史。按下文说明过滤六个问题后,所有方法在相同的 189 题上评测。LLM-Judge 按官方类别/子类别评分协议为每题给出 0 或 1 分,得分为 `100 × 正确数 / 189`。
| 模型 | 方法 | Judge 正确数 / 189 | LLM-Judge (%) |
| --- | --- | ---: | ---: |
| Qwen3.6-35B-A3B | Full Context Image | 89 / 189 | 47.09 |
| Qwen3.6-35B-A3B | ReMe Text | 78 / 189 | 41.27 |
| Qwen3.6-35B-A3B | ReMe Image | 101 / 189 | 53.44 |
| Qwen3.6-35B-A3B | OpenViking | 70 / 189 | 37.04 |
| Qwen3.6-35B-A3B | Mem0 | 73 / 189 | 38.62 |
| Qwen3.8-Max | Full Context Image | 124 / 189 | 65.61 |
| Qwen3.8-Max | ReMe Text | 100 / 189 | 52.91 |
| Qwen3.8-Max | ReMe Image | 137 / 189 | 72.49 |
| Qwen3.8-Max | OpenViking | 80 / 189 | 42.33 |
| Qwen3.8-Max | Mem0 | 97 / 189 | 51.32 |
ReMe Image 在两个模型上的得分分别为 **53.44%** 和 **72.49%**,比 Full Context Image 高 **6.35** 和 **6.88** 个百分点。
## 方法与 Judge 设置 {#evaluation-settings}
| 方法 | 记忆输入与回答阶段的数据访问范围 |
| --- | --- |
| Full Context Image | 回答模型直接读取完整历史文字与原图。 |
| ReMe Text | 使用原始会话文字生成记忆;回答 Agent 通过 BM25 检索 daily、digest 和原始 session,并读取相关文本。 |
| ReMe Image | 使用原始会话文字和图片生成记忆;检索范围与 Text 相同,并可通过 `read_image` 重新读取保存的原图。 |
| OpenViking | 使用原生图片描述和记忆流程;回答阶段检索限定为 memory,采用默认 top 10。 |
| Mem0 | 使用 Mem0 2.0.4 原生视觉入口生成记忆;回答阶段通过 FAISS 检索 top 20 记忆。 |
各方法分别使用 Qwen3.6-35B-A3B 和 Qwen3.8-Max 作为待测模型。ReMe Image 与 Mem0 均直接使用原图。ReMe 的记忆和回答上下文上限分别为 200,000 / 400,000 tokens,temperature 为 0,开启 thinking;记忆/压缩与回答输出预算分别为 65,536 / 16,384 tokens。每题使用独立回答 Agent,最多运行 30 轮,并采用原生上下文压缩。Image 的 `read_image` 支持读取保存的附件,读取上限为 50 MiB,图片保留上限为 4,096 张。
Full Context、OpenViking 和 Mem0 的回答阶段同样使用 temperature 0、thinking 开启、输出预算 16,384 tokens。Mem0 记忆阶段采用原生设置:输出预算 2,000 tokens,temperature 和 top_p 均为 0.1。OpenViking 的评测适配包含 JSON 解析修正,以及图片处理失败时的显式报错。
评分采用 [MemLens 官方协议](https://github.com/xrenaf/MEMLENS/tree/77f3ab9a52fa2d6a17978e2dffe80438a4ecced2),所有方法统一使用 **Qwen3.8-Max** 作为 Judge,temperature 为 **0**、thinking **关闭**、输出预算为 **256 tokens**。Judge 与待测方法的记忆应用独立运行;参考答案及题型标签仅用于评分。
## 统一内容审核过滤 {#content-moderation-filter}
调用 Qwen 模型服务时,下表中的方法在处理相应问题时触发了内容安全审核(绿网协议)。我们对各方法、两个模型触发审核的问题取并集,共得到六题,并在所有方法和两个模型中统一过滤,最终统计相同的 **189/195** 题。
表中 A3B 指 Qwen3.6-35B-A3B,Max 指 Qwen3.8-Max。
| 问题 ID | 触发内容审核的方法 / 模型 | 阶段 |
| --- | --- | --- |
| `q_028cb832` | OpenViking / Max | 记忆构建 |
| `q_1d99a36c` | OpenViking / A3B | 记忆构建 |
| `q_3b01c02a` | ReMe Text、Image / A3B;OpenViking / A3B、Max;Mem0 / A3B | 记忆构建 |
| `q_564a657b` | ReMe Image / Max | 回答 |
| `q_600a79aa` | ReMe Image / Max | 记忆构建 |
| `q_c9f8e24d` | ReMe Text / Max | 回答 |
## 独立复现结果 {#independent-reproduction}
我们将 MemLens benchmark 代码整理并集成到 ReMe 项目中,在相同的数据输入和评分设置下,对 ReMe Image 进行了独立复现。运行方式见[评测说明](https://github.com/agentscope-ai/ReMe/blob/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8/benchmark/memlens/README.md),具体参数见[方法配置](https://github.com/agentscope-ai/ReMe/blob/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8/plugins/memlens/src/reme_memlens/benchmark.yaml)、[Judge 配置](https://github.com/agentscope-ai/ReMe/blob/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8/plugins/memlens-judge/src/judge_memlens/plugin.yaml)和[Judge 评分规则](https://github.com/agentscope-ai/ReMe/blob/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8/plugins/memlens-judge/src/judge_memlens/protocol.py)。
独立复现对应的公开评测代码见 [PR #640](https://github.com/agentscope-ai/ReMe/pull/640),commit 为 [962d5cd](https://github.com/agentscope-ai/ReMe/commit/962d5cd8401c1d2be17f3bb95f8ac9c185672cd8)。
应用相同的六题过滤后,复现实验中 A3B 有 1 题、Max 有 2 题因会话历史处理失败未得到完整结果。下表分别在两次实验均完成的 188 题和 187 题上进行配对比较。
| 模型 | 配对题数 | 原实验正确数 | 独立复现正确数 | 原实验 → 独立复现 LLM-Judge (%) |
| --- | ---: | ---: | ---: | ---: |
| Qwen3.6-35B-A3B | 188 | 100 | 96 | 53.19 → 51.06 |
| Qwen3.8-Max | 187 | 135 | 134 | 72.19 → 71.66 |
在上述配对题目上,Qwen3.6-35B-A3B 和 Qwen3.8-Max 的独立复现 LLM-Judge 得分分别比原实验低 2.13 和 0.53 个百分点,整体性能与原实验基本保持一致。

View file

@ -292,6 +292,8 @@ cases / 400 题上取得 66.1%,在 1M 设置下的 35 cases / 700 题上取得
Agent 在 5 种用户角色(User Persona)上平均取得 0.580 的 PROC 分数,超出相同测试模型配置的 NanoBot
2.4%。关于该基准的详细介绍见 [$\pi$-Bench 论文](https://arxiv.org/abs/2605.14678)。
在 **MemLens-256K** 上,ReMe Image 的 LLM-Judge 在 Qwen3.6-35B-A3B / Qwen3.8-Max 下达到 **53.44% / 72.49%**,比 Full Context Image 高 **6.35 / 6.88** 个百分点。统一过滤 6 个触发模型服务商内容安全审核的 case 后,汇报 **189/195** 个 case;五种方法的对比见[多模态记忆评测](./blog_20261009.md#memlens-256k-results)。
## ReMe 能帮谁?
### 直接使用 Agent 的人

View file

@ -0,0 +1,122 @@
import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import path from "node:path";
import test from "node:test";
import { fileURLToPath } from "node:url";
const siteDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const generatedDir = path.join(siteDir, ".generated/site");
const docsDir = path.resolve(siteDir, "../docs");
const methods = ["Full Context Image", "ReMe Text", "ReMe Image", "OpenViking", "Mem0"];
// Published binary verdict counts, not raw benchmark outputs or a second chart generator.
const models = [
{ name: "Qwen3.6-35B-A3B", figure: "qwen36", correct: [89, 78, 101, 70, 73] },
{ name: "Qwen3.8-Max", figure: "qwen38", correct: [124, 100, 137, 80, 97] },
];
const excluded = ["q_028cb832", "q_1d99a36c", "q_3b01c02a", "q_564a657b", "q_600a79aa", "q_c9f8e24d"];
const publicRevision = "962d5cd8401c1d2be17f3bb95f8ac9c185672cd8";
const reproductionLinks = [
...[
"benchmark/memlens/README.md",
"plugins/memlens/src/reme_memlens/benchmark.yaml",
"plugins/memlens-judge/src/judge_memlens/plugin.yaml",
"plugins/memlens-judge/src/judge_memlens/protocol.py",
].map((file) => `https://github.com/agentscope-ai/ReMe/blob/${publicRevision}/${file}`),
"https://github.com/agentscope-ai/ReMe/pull/640",
`https://github.com/agentscope-ai/ReMe/commit/${publicRevision}`,
];
test("MemLens chart labels and geometry match the published scores", async () => {
for (const model of models) {
const svg = await readFile(path.join(docsDir, "figure", `memlens-256k-${model.figure}-judge.svg`), "utf8");
const bars = [...svg.matchAll(/<g data-method="([^"]+)" data-score="([\d.]+)">\s*<rect[^>]*y="([\d.]+)"[^>]*height="([\d.]+)"[^>]*\/>\s*<text[^>]*>([\d.]+)%<\/text>/g)];
assert.equal(bars.length, methods.length);
for (const [index, method] of methods.entries()) {
const score = (100 * model.correct[index] / 189).toFixed(2);
assert.equal(bars[index][1], method);
assert.equal(bars[index][2], score);
assert.equal(bars[index][5], score, `${model.name}/${method}: visible score`);
assert.ok(Math.abs(Number(bars[index][4]) - Number(score) * 3) < 0.001);
assert.ok(Math.abs(Number(bars[index][3]) + Number(bars[index][4]) - 416) < 0.001);
}
}
});
test("MemLens bilingual notes and blogs match the published scores", async () => {
for (const language of ["en", "zh"]) {
const blog = await readFile(path.join(generatedDir, language, "blog_20261009.md"), "utf8");
const notes = await readFile(path.join(generatedDir, language, "memlens_256k_evaluation.md"), "utf8");
const rows = notes.split("\n").filter((line) => /^\| Qwen.*\| \d+ \/ 189 \|/.test(line));
assert.equal(rows.length, 10);
for (const model of models) {
for (const [index, method] of methods.entries()) {
const correct = model.correct[index];
const score = (100 * correct / 189).toFixed(2);
assert.ok(rows.includes(`| ${model.name} | ${method} | ${correct} / 189 | ${score} |`));
assert.ok(blog.includes(`${method} ${score}%`), `${language}: alt text for ${model.name}/${method}`);
}
const gain = (100 * (model.correct[2] - model.correct[0]) / 189).toFixed(2);
assert.ok(blog.includes(`**${gain}**`));
assert.ok(notes.includes(`**${gain}**`));
}
}
});
test("MemLens notes disclose moderation filters, paired results and Judge settings", async () => {
const triggers = {
zh: [
["OpenViking / Max", "记忆构建"],
["OpenViking / A3B", "记忆构建"],
["ReMe Text、Image / A3B;OpenViking / A3B、Max;Mem0 / A3B", "记忆构建"],
["ReMe Image / Max", "回答"],
["ReMe Image / Max", "记忆构建"],
["ReMe Text / Max", "回答"],
],
en: [
["OpenViking / Max", "Memory construction"],
["OpenViking / A3B", "Memory construction"],
["ReMe Text and Image / A3B; OpenViking / A3B and Max; Mem0 / A3B", "Memory construction"],
["ReMe Image / Max", "Answering"],
["ReMe Image / Max", "Memory construction"],
["ReMe Text / Max", "Answering"],
],
};
for (const language of ["en", "zh"]) {
const notes = await readFile(path.join(generatedDir, language, "memlens_256k_evaluation.md"), "utf8");
const filter = notes.split("{#content-moderation-filter}")[1].split("{#independent-reproduction}")[0];
assert.deepEqual([...new Set(filter.match(/q_[0-9a-f]{8}/g))].sort(), excluded);
const rows = filter.split("\n").filter((line) => line.startsWith("| `q_"));
assert.deepEqual(rows, excluded.map((id, index) => {
const [method, stage] = triggers[language][index];
return `| \`${id}\` | ${method} | ${stage} |`;
}));
assert.match(filter, /189\/195/);
assert.ok(notes.includes("| Qwen3.6-35B-A3B | 188 | 100 | 96 | 53.19 → 51.06 |"));
assert.ok(notes.includes("| Qwen3.8-Max | 187 | 135 | 134 | 72.19 → 71.66 |"));
const judge = notes.split("\n\n").find((paragraph) => /(?:as|作为) Judge/.test(paragraph));
assert.ok(judge, `${language}: Judge settings must be documented`);
assert.match(judge, /\*\*Qwen3\.8-Max\*\*/);
assert.match(judge, /temperature (?:为 )?\*\*0\*\*/);
assert.match(judge, /thinking \*\*(?:disabled|关闭)\*\*/);
assert.match(judge, /\*\*256(?:-token| tokens)\*\*/);
assert.match(notes, /memory-only|restricted to memory|限定为 memory/);
}
});
test("MemLens notes pin the public evaluation revision without private audit details", async () => {
for (const language of ["en", "zh"]) {
const blog = await readFile(path.join(generatedDir, language, "blog_20261009.md"), "utf8");
const notes = await readFile(path.join(generatedDir, language, "memlens_256k_evaluation.md"), "utf8");
assert.match(blog, /\]\(\.\/memlens_256k_evaluation\.md\)/);
assert.match(notes, /\]\(\.\/blog_20261009\.md#memlens-256k-results\)/);
assert.doesNotMatch(notes, /\/mnt\/|\/Users\/|docs\/_build|file:\/\//);
const reproduction = notes.split("{#independent-reproduction}")[1];
const targets = [...reproduction.matchAll(/\]\(([^)\r\n]+)\)/g)].map(([, target]) => target);
assert.deepEqual(targets.sort(), [...reproductionLinks].sort());
const prose = notes.replace(/\]\([^)]+\)/g, "]");
assert.doesNotMatch(prose, /\b[a-f0-9]{40,64}\b/);
for (const anchor of ["results", "evaluation-settings", "content-moderation-filter", "independent-reproduction"]) {
assert.ok(notes.includes(`{#${anchor}}`));
}
}
});