Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/rust-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ jobs:
libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev \
"$WEBKIT_DEV_PKG"

# OCR 端到端测试需要真实的 tesseract + chi_sim 语言包(缺失时该测试会自动跳过)。
- name: Install tesseract for OCR end-to-end test (Linux)
if: runner.os == 'Linux'
run: sudo apt-get install -y tesseract-ocr tesseract-ocr-chi-sim

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,14 @@ Graph, conversation memory, and project memory are explanation/context layers by
- Graph extraction and entity-relationship API: working; graph visualization UI is limited.
- Cross-language retrieval (Chinese query → English document): basic coverage; bilingual query expansion not complete.
- Source preview and Markdown export.
- OCR (standalone images / text-layer-free scanned PDFs / DOCX embedded images; runs at **index time** via tesseract + `chi_sim`): available, configurable from Settings → Models or `POST /api/settings/ocr-path`; but **entity names are easily misread** (measured: `苍岭` → `苑岭/苔岭`), and mixed PDFs, `ppt`/`xlsx` embedded images, and `CCITTFaxDecode`/`JPXDecode` remain out of scope. Re-index is required for already-indexed files after changing the path.

### 📐 Designed / Not Yet Implemented

- LLM-judge evaluation loop for answer quality (current metrics cover retrieval only; no objective answer score).
- Rate limiting for admin endpoints (brute-force protection), request-id/trace for retrieval pipeline.
- OpenAPI / Swagger spec for memori-server.
- API key storage via OS keychain (currently plain text in settings.json).
- OCR (image and scanned-document files are not currently indexable).
- Memory heat score, conflict resolver, lifecycle classifier.
- 50k-scale load test (P50/P95 at scale not yet validated).
- Multi-tenant isolation (currently all OIDC users share one vault).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ document routing -> chunk retrieval -> RRF/gating -> evidence/citation
- 图谱抽取与实体关系 API:已实现,图谱可视化 UI 仍有限。
- 跨语言检索(中文问→英文文档):基础覆盖,query 双语扩展未完整。
- Source preview 与 Markdown export。
- OCR(独立图片 / 无文本层扫描件 PDF / DOCX 内嵌图,**索引期** tesseract + `chi_sim`):已接入,桌面「设置 → 模型」与服务端 `POST /api/settings/ocr-path` 均可配置路径;但**实体名容易被误读**(实测 `苍岭` → `苑岭/苔岭`),且混合型 PDF、`ppt`/`xlsx` 内嵌图、`CCITTFaxDecode`/`JPXDecode` 仍是边界;改配置后需重建索引才会对已入库文件生效。
- 50k 规模压测:harness 与验证已完成(顺序/并发 P50/P95/P99,争用系数 1.91× 达标 <2×,数据与结论见 `docs/qa/PERF_SCALE_50K.md`);但 50k 下**单查询绝对延迟仍高**(顺序 P50 ≈ 9.8s,`doc_recall` 占约 81%),文档级召回优化还在路上。

### 📐 设计中/待实现
Expand All @@ -279,7 +280,6 @@ document routing -> chunk retrieval -> RRF/gating -> evidence/citation
- 管理接口限流(防暴力登录/admin)、检索链路 request-id/trace。
- OpenAPI / Swagger spec(memori-server)。
- API key 接 OS keychain(当前明文存 settings.json)。
- OCR(图片/扫描件目前不可检索)。
- Memory heat score、conflict resolver、lifecycle classifier。
- 多租户隔离(当前 OIDC 登录后共享同一库)。

Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ This directory is organized by document purpose. Keep new files in the matching
- [Release notes v0.4.0](./release/RELEASE_NOTES_v0.4.0.md)
- [Release notes v1.0.0](./release/RELEASE_NOTES_v1.0.0.md)
- [Release notes v1.0.2](./release/RELEASE_NOTES_v1.0.2.md)
- [Release notes v1.5.0](./release/RELEASE_NOTES_v1.5.0.md)
- [Release notes v1.5.2](./release/RELEASE_NOTES_v1.5.2.md)

## Archive

Expand Down
2 changes: 1 addition & 1 deletion docs/planning/IMPROVEMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ README 仍可能让外部读者高估成熟度(叙事盖过实测)。
2. **长文深埋事实**(`V101/V102` 0/2):Parent Document Expansion(高分 chunk 拉同文档上下文,上限 8000 字符)。
3. **跨语言 V119**:中文问→英文邮件埋点例外漏召——双语 query 扩展 / 别名映射。
4. **B 类诱饵代号拒答残留**(`V086/V087/V092`):需语义级代号核验,有误伤 answer 风险,谨慎。
5. **OCR**:图片/扫描件 0/4 不可检索——大功能,接 tesseract 或视觉模型
5. ~~**OCR**:图片/扫描件不可检索~~ —— **已落地**(tesseract + chi_sim,**索引期** OCR:独立图片 / 无文本层扫描件 PDF / DOCX 内嵌图;桌面「设置 → 模型」与服务端 `POST /api/settings/ocr-path` 均可配置路径)。剩余边界(混合型 PDF、ppt/xlsx 内嵌图、CCITTFax/JPXDecode、OCR 实体名误读)见 `RETRIEVAL_BASELINE_V2.md`「OCR 接入与边界」;该文档里 `V103–V108` 的 0/4 结论是**无 OCR 时期**的实测,需在装有 tesseract 的环境重跑才会反映新能力
6. **作答层评测盲区**:harness 只用 top-k 当代理,不给 LLM 答案文本判分——接 LLM-judge 闭环事实正确性/忠实度。

---
Expand Down
6 changes: 3 additions & 3 deletions docs/planning/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Overall Progress: 工程硬化批 (E1–E8 + 审计安全/CI/前端速赢) 全
| 文档 | H1(E8) README 成熟度徽标 ✅/🚧/📐 | `17e5987` |
| 卫生 | I1 email-memory-source 计划文档加 `.gitignore`(决定不入库) | `46ae244` |
| 检索主线 | 解析扩到 9 格式 + v2 困难基准(548 文档/126 题)+ 英文/跨语言 + 拒答硬化 | `25654ec`/`22064fc`/`154372f`/`9c5f77f` |
| 检索主线 | **Q6 OCR 接入**:独立图片 / 无文本层扫描件 PDF / DOCX 内嵌图(tesseract + chi_sim,**索引期**抽取;ask 与文件预览不跑 OCR) | 本 PR(collab) |

→ **审计里所有"低风险、可量化、可一轮闭环"的项已全部清完。**

Expand All @@ -47,7 +48,6 @@ Overall Progress: 工程硬化批 (E1–E8 + 审计安全/CI/前端速赢) 全
| **Q2** 长文深埋事实 0/2(doc rank1 但 chunk rank2-4 被拒) | 🔴 | Parent-Document Expansion(同文档 chunk 合并),与 Q1 同属 gating/证据构建轮,需一起验 | 质量轮 |
| **Q4** 跨语言漏召(中文问→英文埋点例外) | 🟡 | 需双语 query 扩展 + 不污染单语盘面,须 live 验证 | 质量轮 |
| **Q5** 诱饵代号拒答泄露(V086/V087/V092) | 🟡 | 需语义级核验,有误伤正常代号风险,须谨慎迭代 | 质量轮(谨慎) |
| **Q6** OCR:图片/扫描件 0/4 不可检索 | 🟡 | 需集成 OCR 引擎 + 图像预处理 + 端到端索引,多日大功能 | 大功能(多轮) |
| **E9/G3** 多租户 / 多资料库隔离(DB/索引/审计三层) | 🟢 | 需先定租户模型(产品决策),不是纯工程 | 待需求确认 |
| **E10/G4** 增量索引进度推送(SSE/WebSocket) | 🟢 | 独立功能,需前后端协同设计 | 独立功能 |
| **E11** shell-service 共享层(收敛 desktop/server 重复流程) | 🟢 | 大重构,收益是可维护性而非功能,低优先 | 重构(低优先) |
Expand All @@ -57,7 +57,7 @@ Overall Progress: 工程硬化批 (E1–E8 + 审计安全/CI/前端速赢) 全
### 推荐推进顺序

1. **质量轮(Q1+Q2 优先,Q4/Q5 同轮)** — 价值最高,Q3 judge 基础设施已就绪;红线"reject 不退",每改一次 gating 跑 `--judge` 全量验"答案对↑ 且 拒答对不↓"。
2. **Q6 OCR** — 覆盖面,独立大功能可单独成轮
2. **Q6 后续**:`V103–V108` 那 4 道图片/扫描题需在装有 tesseract 的环境**重跑**,才能把新能力写进基线数字;混合型 PDF、ppt/xlsx 内嵌图、CCITTFax/JPXDecode 仍是已知边界(见 `RETRIEVAL_BASELINE_V2.md`「OCR 接入与边界」)
3. **E9/E10/E11、P4 HNSW** — 需产品决策或规模到了再做。

## 2026-06-05 Live Regression Update
Expand Down Expand Up @@ -551,7 +551,7 @@ GPT 修复计划(泛化去噪 + 覆盖率门控,无实体硬编码):
- 产品化:OpenAPI 可用;管理接口限流;一条 request-id 串起整链路;有 50k 规模 P50/P95 数据与扩展决策。
- 文档:README 能力状态可一眼分清"已验证 vs 设计中"。

**不在本阶段**(记录留档,后续单独成轮):A 类 gating 误拒放行、长文 Parent-Doc 扩展、跨语言 V119 双语扩展、OCR、作答层 LLM-judge 评测——详见 `RETRIEVAL_BASELINE_V2.md` 与 IMPROVEMENTS.md 末节。
**不在本阶段**(记录留档,后续单独成轮):A 类 gating 误拒放行、长文 Parent-Doc 扩展、跨语言 V119 双语扩展、作答层 LLM-judge 评测——详见 `RETRIEVAL_BASELINE_V2.md` 与 IMPROVEMENTS.md 末节。(**OCR 已落地**,见上方"已做"表;剩余边界见 `RETRIEVAL_BASELINE_V2.md`「OCR 接入与边界」。)

## Change Log
计划级变更日志已不再单独维护(原 `docs/planning/PLAN_CHANGELOG.md` 已随仓库整理移除),历史变更请查 git 提交记录。
Expand Down
18 changes: 14 additions & 4 deletions docs/qa/RETRIEVAL_BASELINE_V2.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,12 @@ bench:`cargo run -p memori-core --example graph_bench -- <files>`(对每个

## 长文 / 图片 / 扫描件 的真实处理结论(专门样本实测)
- **长文(3 万字)**:索引/分块正常(切成 ~35 个 ≤1000 字块),检索能把长文**召回到 doc rank 1**;但埋在深处的事实其片段只排到 rank 2–4,两道长文题(`V101/V102`)最终被 **gating 判拒**——长文通过"埋点深 + gating 保守"双重打击降低可答率。图谱构建则极贵(见上)。
- **图片内容**`extract_*` 只取文本,**图片一律忽略、全链路无 OCR**。实测:
- **图片内容**(⚠️ 下面 4 条是**接入 OCR 之前**的实测,数字保留作对照):当时 `extract_*` 只取文本,**图片一律忽略、全链路无 OCR**。实测:
- 图说明/正文里的事实(`V103/V104`)→ 正常作答 ✓。
- 事实只画在图里(`V105` 晨曦回滚阈值、`V108` 白川预算图)→ 片段 rank=None,作答被拒;纯图 docx(`V106` 暮山)→ 文档都召不回。
- **扫描件 PDF**(`V107` 苍岭)→ lopdf 抽 0 字,文档完全不可见。
- 即这 4 道"图片/扫描"题 **0/4 可答**——坐实"图片/扫描内容不可检索"的能力缺口(如需可检索须接 OCR,单列大功能)。
- 即这 4 道"图片/扫描"题 **0/4 可答**——坐实**当时**"图片/扫描内容不可检索"的能力缺口。
- **后续已补齐**:现已接入索引期 OCR(tesseract + chi_sim,见本文件「OCR 接入与边界」)。上面这 4 题需在装有 tesseract(且带 `chi_sim` 语言包)的环境**重跑**,才会反映新能力。

## 索引护栏(本轮新增)
`memori-core/src/indexing.rs`:
Expand All @@ -147,7 +148,7 @@ bench:`cargo run -p memori-core --example graph_bench -- <files>`(对每个
## 失败分析(改进杠杆,非套件 bug)
- **A. 答案题被误拒(检索正确、gating 过保守)**:`多格式抽取` 仅 1/6 作答、`长文检索` 0/2、`xlsx` 1 题——文档/片段命中 rank 1–2 但 gating 打分 < 阈值 55 走 `score_below_threshold`。集中在"单事实/低词法覆盖"证据,与 v1 同源(可由 coverage / rerank 置信度放行路径再调)。
- **B. 拒答题被泄露作答(困难语料触发误放行)**:诱饵代号 / 不存在属性 / PII 越权触发 `identifier_grounded_release` / `rerank_confident_release` / 复合查询 `compound_partial_release`(gate=0 绕过)。**本轮已修 PII/注入/越权类(见文末"拒答安全硬化");诱饵代号类经查证为语料蓄意设计(诱饵码埋进带"无关"声明的干扰文档),需语义级核验,留待。**
- **C. 图片/扫描(B 类预期 miss)**: bug,是无 OCR 的能力边界,已用 4 道题固定记录。
- **C. 图片/扫描(B 类预期 miss)**:当时非 bug,是无 OCR 的能力边界,已用 4 道题固定记录。**现已接入索引期 OCR**;该边界只剩这些情况:未安装/未配置 tesseract、混合型 PDF(有文本层 + 扫描页)、`ppt`/`xlsx` 内嵌图、`CCITTFaxDecode`/`JPXDecode` 编码的图片(详见「OCR 接入与边界」)

## 重排模型 A/B(本轮,同 embed/同语料/同代码,仅换 :18004 重排服务)
- **bge-reranker-v2-m3(现默认)**:Top-1 文档 69.6% / Top-3 文档 91.3% / Top-1 chunk 75.0% / Top-5 chunk 95.7% / chunk MRR 0.8301 / 拒答 83.3% / 平均检索 ≈1.5s。平滑 logit(−7.5~8.0),与现有"裸分 min-max 融合 + gating 阈值"调校天然兼容。
Expand Down Expand Up @@ -180,6 +181,15 @@ bench:`cargo run -p memori-core --example graph_bench -- <files>`(对每个
### 关于 top1 文档 0.696(非 bug,已用 `top_documents` 诊断坐实)
给 harness 加了 `top_documents` 字段(每题最终证据去重后的有序文档路径)。据此查实:**20 道 top1-miss 里 19 道,排第 1 的都是目标的"同项目兄弟文档"**(检索每次都准确锁定项目,只是没挑中套件指定的那个体裁)。根因是套件"直问-散文事实/改写"题**故意含糊**(只点项目名/代号、不点具体事实,答案关键词不在 query 里),rerank 无法在同项目 7 份文档间区分。**这是 v2 相对 v1 的刻意难度,不是融合/排序 bug;top3 0.913 / top5 片段 0.957 / MRR 0.830 说明召回与答案 chunk 入选均正常。** 把 top1-文档硬拉到 v1 的 ~0.875 只能靠"让 query 重新点名具体事实"=把 v2 退化回 v1 的易,违背 v2 初衷。

## OCR 接入与边界(本 PR 落地)

- **能力**:索引期对三类来源做 OCR(tesseract + `chi_sim`)——独立图片(`png`/`jpg`/`jpeg`)、**无文本层**的扫描件 PDF、DOCX 内嵌图(`word/media/*`)。识别文本与正文一起入库,之后走正常分块/检索。
- **不做 OCR 的时机**:ask 期构造引用摘要、桌面端文件预览都**不触发 OCR**;OCR 只在索引期发生(避免同步阻塞回答链路与 UI)。
- **配置路径**:环境变量 `MEMORI_OCR_TESSERACT_PATH`(最高优先)> `settings.json` 的 `ocr_tesseract_path` > PATH 自动探测。桌面端入口在「设置 → 模型」;服务端入口 `POST /api/settings/ocr-path`(operator 角色)。
- **改配置后需要重建索引**:路径变更或首次安装 tesseract 后,**已入库**的图片与扫描件不会自动重跑 OCR,需触发重建。
- **实测**(本机 tesseract + `chi_sim`,样本 `Memory_Test_V2/special_005_扫描件_苍岭_对账.pdf`):每页解码出 1 张图、单页约 0.8s,能识别出「…项目的对账窗口为每月 8 号…」等正文;但**实体名会被误读**(`苍岭` → `苑岭/苔岭`)。结论:OCR 文本可用于**召回辅助**,不宜当作精确匹配/精确引用口径。
- **已知边界**:混合型 PDF(有文本层 + 扫描页)不对扫描页 OCR;`ppt`/`xlsx` 内嵌图未接入;`CCITTFaxDecode`(G4 传真压缩,黑白扫描件常见)与 `JPXDecode`(JPEG2000)暂不支持;单图解码后像素上限 128 MB;位深只接受 8 bit/通道(其余跳过,避免把解码噪声写进知识库)。
- **自动化验证**:`memori-core` 有真实扫描件的 OCR 端到端测试(`scanned_pdf_is_indexed_through_ocr_when_available`,**无 tesseract 时自动跳过**);CI 的 Linux job 安装 `tesseract-ocr` + `tesseract-ocr-chi-sim`,保证该测试真实执行。
## 作答层 LLM-judge 基线(2026-08-24 新增)

此前"答案题正确"只用 top-k 命中当代理(见上表注),**从不看答案文本**。`--judge` 档补齐该闭环:对应答题走真实问答管线生成答案,再由 chat 模型对照 `target_clues` 判 correct/partial/incorrect(correct=1、partial=0.5、incorrect=0),逐题理由写入报告。judge 实现见 `memori-core/src/answer_judge.rs`,harness 入口 `--judge`。
Expand Down Expand Up @@ -217,6 +227,6 @@ judge 判分成功率 106/106(应答题全部产出判定,零失败)。平
1. gating 对"单事实低词法覆盖"证据的放行(A 类)。
2. 诱饵代号 / 不存在属性的拒答硬化(B 类残留,需语义级代号核验,见上节)。
3. 长文:分块/gating 对深埋事实的处理(长文题 0/2)。
4. OCR:图片/扫描件可检索(C 类,大功能,需接 tesseract 或视觉模型)
4. ~~OCR:图片/扫描件可检索~~ —— **已落地**(tesseract,索引期;见上面「OCR 接入与边界」)。剩余:在装有 tesseract 的环境重跑 `V103–V108`,把新能力写进基线数字
5. 重排已切到 bge-reranker-v2-m3(见上节 A/B)。若日后要上 Qwen3-Reranker,需先为其近二值分数重调融合权重 + 重标定 gating 阈值,再复测。
6. 作答层:在满配环境重跑 `--judge` 建官方作答层基线(本机受限数字仅作下限参考)。
Loading
Loading