📝 Technical Review & Optimization Suggestions
Hi @Cocoblood9527,概括:
Diving into the LocalMemOS codebase and am genuinely impressed by the architecture. The use of a Rust core with bitemporal data modeling (valid_from/valid_to), idempotent upserts, and evidence-based traceability is excellent. The engineering quality is very high.
While reviewing the implementation, I identified a few areas where we could potentially improve performance, search quality, and MCP integration. I've categorized these based on impact for your consideration:
🔴 P0: Critical Improvements (High Impact)
1. Missing MCP Tool Schemas
Currently, MCP tools are registered without JSON Schemas (e.g., server.tool("memory_upsert_fact", upsert as any)). This prevents Claude Desktop/Cursor from providing parameter hints and causes issues with automatic tool calling.
- Suggestion: Define explicit JSON Schemas for all tools in
packages/mcp/src/tools.ts.
2. FTS5 Index Cleanup
In store.rs, the upsert_fts_row function inserts new entries but never deletes old ones when a fact is updated or retired. This leads to "index bloat," where search results include stale/retired facts.
- Suggestion: In
close_current_fact, add a DELETE FROM facts_fts WHERE fact_id = ? to keep the search index clean.
3. HTTP Concurrency Bottleneck
The AppState uses a global Mutex for the MemoryStore. Since recall and list are read-only operations, they are currently blocking each other.
- Suggestion: Switch from
std::sync::Mutex to tokio::sync::RwLock to allow concurrent read operations.
🟡 P1: Important Optimizations
1. Missing Database Indexes
The facts table lacks composite indexes for the core lookup query (namespace, scope_id, entity, attribute). This will cause full table scans as the dataset grows.
- Suggestion: Add a composite index on
(namespace, scope_id, entity, attribute, valid_to).
2. Python SDK Semantic Gap
The Python recall method is missing the as_of parameter, which is available in the Rust core. This prevents users from performing historical point-in-time queries via the Python SDK.
3. FTS Stopword List
The current STOPWORDS list is quite minimal.
- Suggestion: Consider expanding the list or integrating a standard NLP stopword set to improve search relevance.
🟢 P2: Maintenance & DX
- ID Generation: The
ID_COUNTER (AtomicU64) resets on process restart. Consider switching to ULID or UUID v4 to ensure global uniqueness across restarts.
- Documentation: It would be helpful to explicitly note in the README that the project currently targets macOS/Linux, and
include_history is reserved for future use to avoid user confusion.
Summary
This is an outstanding project with a very solid foundation. These suggestions are just my observations while studying the code. I am happy to open PRs for some of these (especially the MCP Schema and Indexing) if you think they align with your roadmap!
Keep up the great work!
LocalMemOS 深度技术审查报告(基于真实源码)
⚠️ 重要说明:前两次分析基于 README 描述,存在大量错误假设。本报告基于对仓库全部源码的实际阅读,结论完全重建。
一、项目真实架构(纠正前次错误)
这不是前次描述的项目
| 前次分析(错误) |
实际代码(正确) |
| Python 写的 Web 应用 |
Rust 核心 + 多语言绑定 |
| manage.py / main.py / api/ |
无此文件,完全不同的项目 |
| 三级检索(关键词+全文+图谱向量) |
仅 FTS 文本检索,无向量,无图谱 |
| Claude Desktop 聊天 Web UI |
无 Web UI,纯 SDK+MCP+HTTP 适配器 |
| 待审池机制 |
完全不存在 |
| Read-Before-Write 机制 |
存在,但实现方式不同 |
真实技术栈
Workspace
├── crates/
│ ├── memory-core/ Rust 核心库 (SQLite + 业务逻辑)
│ ├── memory-http/ Axum HTTP 适配器
│ └── memory-node/ Node.js Native Binding (napi-rs)
├── packages/
│ ├── node/ TypeScript Node SDK
│ └── mcp/ MCP 适配器 (TypeScript)
├── python/ Python SDK (PyO3/Maturin 绑定)
└── tools/locomo/ LoCoMo 检索评估脚本
语言分布:Rust 56.4% / Shell 19.5% / Python 12.8% / TypeScript 10.5%
二、核心数据模型(实际代码)
数据结构
// request.rs — 写入请求
pub struct UpsertFactRequest {
pub namespace: String, // "user" | "runtime" | "workspace"
pub scope_id: String, // 逻辑隔离单元
pub entity: String, // 实体名
pub attribute: String, // 属性名
pub value: serde_json::Value,
pub confidence: Option<f32>,
pub tags: Vec<String>,
pub valid_from: Option<DateTime<Utc>>,
pub source_kind: String, // "manual" | 其他
pub source_ref: Option<String>,
pub evidence_summary: Option<String>,
}
// model.rs — 存储记录
pub struct FactRecord {
pub id: String,
pub namespace: String,
pub scope_id: String,
pub entity: String,
pub attribute: String,
pub value_json: Value,
pub value_text: Option<String>,
pub confidence: Option<f32>,
pub valid_from: DateTime<Utc>,
pub valid_to: Option<DateTime<Utc>>, // 软删除机制
pub updated_at: DateTime<Utc>,
}
数据库 Schema(4 张表)
facts -- 当前事实(valid_to IS NULL = 当前有效)
fact_versions -- 历史版本链(每次 upsert 写入一条)
evidence -- 证据来源(source_kind, source_ref, summary)
facts_fts -- FTS5 全文搜索虚拟表
设计亮点:
- 事实以
(namespace, scope_id, entity, attribute) 为主键
valid_from / valid_to 实现双时态(bitemporal)语义
evidence 表实现溯源,记录每次写入的来源
三、核心逻辑审查
3.1 upsert_fact 写入逻辑(实际代码)
// store.rs — 真实的 Read-Before-Write 实现
pub fn upsert_fact(&mut self, req: UpsertFactRequest) -> Result<FactRecord, MemoryError> {
req.validate()?;
let tx = self.conn.transaction()?;
if let Some(current) = find_current_fact(&tx, &req)? {
if current.value_json == req.value {
// ✅ 幂等:值未变则只更新时间戳
tx.execute("UPDATE facts SET updated_at = ? WHERE id = ?", ...)?;
append_evidence(...)?;
tx.commit()?;
return Ok(refreshed);
}
// ✅ 值变化:关闭旧版本,创建新版本
close_current_fact(&tx, ¤t.id, &now_text)?;
close_current_version(&tx, &req, &now_text)?;
}
let inserted = insert_new_fact(&tx, &req, now)?;
let version_id = insert_fact_version(&tx, &inserted, &req, &now_text)?;
append_evidence(&tx, &inserted.id, Some(&version_id), &req, &now_text)?;
upsert_fts_row(...)?;
tx.commit()?;
Ok(inserted)
}
✅ 亮点:幂等写入、版本链保留、证据记录、事务保证,逻辑设计完整
3.2 FTS 检索逻辑(实际代码)
// fts.rs — 停用词表 + 查询归一化
const STOPWORDS: &[&str] = &["a","an","and","are","as","at","activities",
"activity","be","been","by","change","changes"...]; // 约 50 个停用词
pub fn build_fts_query(text: &str) -> Option<String> {
let tokens = normalize_query_tokens(text);
if tokens.is_empty() { return None; }
Some(tokens.iter().map(|t| format!("{t}*")).collect::<Vec<_>>().join(" OR "))
}
实际检索流程:
Query 文本
↓
normalize_query_tokens() // 分词 + 去停用词 + 去重 + 截断(max 12)
↓
build_fts_query() // 生成 FTS5 OR 查询
↓
SQLite FTS5 // 全文搜索 + 排名
↓
phrase continuity 重排 // store.rs 中的自定义重排序逻辑
3.3 MCP 工具(实际代码)
// packages/mcp/src/tools.ts
// 实际暴露的 5 个 MCP 工具:
"memory_upsert_fact" // 写入事实
"memory_recall" // 检索事实
"memory_list" // 列举事实
"memory_forget" // 删除事实
"memory_history" // 查询历史版本
⚠️ 问题:所有工具均无参数 Schema 定义(server.tool("name", handler as any)),Claude/Cursor 无法自动感知参数格式。
四、真实存在的问题(基于代码)
🔴 P0:MCP 工具无 Schema 定义
代码证据:
// tools.ts — 实际代码
server.tool("memory_upsert_fact", upsert as any); // ← 无参数 schema
server.tool("memory_recall", recall as any); // ← 无参数 schema
问题:MCP 协议要求工具注册时提供 JSON Schema,描述参数名称、类型、必填项。缺失 schema 会导致:
- Claude Desktop 无法提示用户正确的参数
- 自动调用时参数错误率高
- 与 MCP 标准不符
建议修复:
server.tool(
"memory_upsert_fact",
{
namespace: { type: "string", description: "命名空间: user/runtime/workspace" },
scope_id: { type: "string", description: "作用域 ID" },
entity: { type: "string", description: "实体名称" },
attribute: { type: "string", description: "属性名称" },
value: { description: "任意 JSON 值" },
source_kind: { type: "string", description: "来源类型,如 manual/agent" },
confidence: { type: "number", description: "置信度 0.0-1.0", optional: true },
evidence_summary: { type: "string", optional: true },
},
upsert
);
🔴 P0:FTS 索引只在写入时追加,从不更新
代码证据:
// fts.rs
pub fn upsert_fts_row(tx, fact_id, ...) -> rusqlite::Result<()> {
tx.execute(
"INSERT INTO facts_fts (fact_id, namespace, ...)", // ← 只 INSERT,无 DELETE
...
)?;
Ok(())
}
upsert_fact 中的调用:
// store.rs — 无论是新建还是值变化,都直接 INSERT FTS
upsert_fts_row(&tx, &inserted.id, ...)?;
问题:每次 upsert 都在 FTS5 表中追加一行,旧版本的 FTS 条目永远不会被删除。随着时间推移:
- FTS 搜索会返回已过期事实(
valid_to 非 NULL)
- FTS 表无限增长,检索噪音越来越多
- 同一 fact_id 在 FTS 表中可能有多行
建议修复:
// 在 close_current_fact 时同步删除旧 FTS 行
fn close_current_fact(tx, fact_id, now_text) -> Result<()> {
tx.execute("UPDATE facts SET valid_to = ? WHERE id = ?", ...)?;
tx.execute("DELETE FROM facts_fts WHERE fact_id = ?", [fact_id])?; // ← 新增
Ok(())
}
🔴 P0:HTTP 层使用全局 Mutex,高并发场景阻塞
代码证据:
// state.rs (推断自 routes.rs 用法)
pub struct AppState {
pub store: Arc<tokio::sync::Mutex<MemoryStore>>, // ← 全局单锁
}
// routes.rs — 每个请求都持锁
pub async fn recall(...) -> Result<...> {
let store = state.store.lock().await; // ← 独占锁,读操作也上锁
let result = store.recall(req)?;
Ok(Json(result))
}
问题:recall、list、history 均为只读操作,但使用同一把 Mutex(非 RwLock),导致:
- 多个并发读请求互相阻塞
- 单个慢写入会阻塞所有读请求
建议修复:
// 将 Mutex 改为 RwLock
pub store: Arc<tokio::sync::RwLock<MemoryStore>>,
// 读操作用 read() 锁
pub async fn recall(State(state): State<AppState>, ...) {
let store = state.store.read().await; // ← 读锁,并发友好
...
}
// 写操作用 write() 锁
pub async fn upsert_fact(State(state): State<AppState>, ...) {
let mut store = state.store.write().await; // ← 写锁
...
}
🟡 P1:ID 生成机制存在竞态风险
代码证据:
// store.rs
static ID_COUNTER: AtomicU64 = AtomicU64::new(1);
问题:
- 进程重启后 ID 计数器从 1 重置,若 DB 已有数据会产生 ID 碰撞
- 实际 ID 生成逻辑(未见
fetch_add 调用)需确认是否正确使用
- 多进程访问同一 DB 文件时计数器不共享
建议:改用 UUID v4 或 ulid(既有唯一性又有时间序):
// 使用 uuid crate
let id = uuid::Uuid::new_v4().to_string();
🟡 P1:Python SDK 的 recall 丢失 as_of 参数
代码证据:
# python/memory_sdk/client.py
def recall(self, **kwargs):
payload = {
"namespace": kwargs["namespace"],
"scope_id": kwargs["scope_id"],
"entity": kwargs.get("entity"),
"attribute": kwargs.get("attribute"),
"text_query": kwargs.get("text_query"),
"include_history": kwargs.get("include_history", False),
# ← 缺少 "as_of": kwargs.get("as_of")
}
对比 Rust RecallRequest:
pub struct RecallRequest {
pub as_of: Option<DateTime<Utc>>, // ← Python SDK 无法传递此参数
}
影响:Python 用户无法使用时态查询(as_of),是跨层语义缺失的典型问题。
🟡 P1:forget 的实现未确认是软删除还是硬删除
代码证据(已有的 routes.rs):
pub async fn forget(...) -> Result<Json<serde_json::Value>, ApiError> {
let mut store = state.store.lock().await;
store.forget(req)?; // ← forget 的实现在 store.rs 中,但未读到完整实现
Ok(Json(json!({ "ok": true })))
}
设计文档声明:
forget should logically retire facts by default, not hard-delete them
测试用例也验证了:
# test_sdk_core.py
result = client.recall(...)
assert result["facts"] == [] # forget 后无法 recall
但 FTS 表和 fact_versions 表是否同步清理仍需确认。
🟡 P1:FTS 停用词表不完整,影响检索质量
代码证据:
// fts.rs — 现有停用词
const STOPWORDS: &[&str] = &[
"a","an","and","are","as","at","activities","activity",
"be","been","by","change","changes","did","do","does",
"for","from","had","has","have","her","his","how","in",
"is","it","kind","kinds","many","of","on","or",
"done","seen","some","that","the","their","this","to",
"way","ways","was","we","what","when","where","which",
"who","why","with",
];
问题:
- 缺少
not、no、but、if、then、also、just、like、my、your、they、he、she、i、me、him、us 等常用词
- 缺少中文分词支持(若有中文数据则 FTS 完全失效)
- 手工维护停用词表容易遗漏,建议引入标准 NLP 停用词表
🟡 P1:facts 表缺少关键索引
代码证据:
-- schema.rs
CREATE TABLE IF NOT EXISTS facts (
id TEXT PRIMARY KEY,
namespace TEXT NOT NULL,
scope_id TEXT NOT NULL,
entity TEXT NOT NULL,
attribute TEXT NOT NULL,
...
valid_to TEXT,
...
);
-- ← 无复合索引!
问题:核心查询 WHERE namespace = ? AND scope_id = ? AND entity = ? AND attribute = ? AND valid_to IS NULL 在数据量大时全表扫描。
建议:
CREATE INDEX IF NOT EXISTS idx_facts_key
ON facts(namespace, scope_id, entity, attribute, valid_to);
CREATE INDEX IF NOT EXISTS idx_fact_versions_key
ON fact_versions(namespace, scope_id, entity, attribute);
CREATE INDEX IF NOT EXISTS idx_evidence_fact
ON evidence(fact_id);
🟢 P2:Windows 平台支持未测试
代码证据:
# .github/workflows/locomo-full-gate.yml
jobs:
full-gate:
runs-on: ubuntu-latest # ← 仅 Linux
README 声明:
Clean-Run Checklist (macOS + Linux) # ← 标题明确只有 macOS + Linux
问题:项目明确不支持 Windows CI,但 README 中的 Environment Setup 未提及此限制,可能误导 Windows 用户尝试安装。
🟢 P2:include_history 字段保留但有误导性
代码证据:
// request.rs
pub struct RecallRequest {
// Reserved in v1. Kept for compatibility; current core recall semantics ignore this flag.
pub include_history: bool,
}
// models.ts
// Reserved in v1; forwarded for compatibility but currently ignored by core recall semantics.
includeHistory?: boolean;
问题:字段存在于所有 SDK 接口中,但完全无效,容易让用户误以为能用。建议在注释中更明确地写出"此字段 v1 中无效,v2 实现时间历史查询请使用 history() 方法"。
🟢 P2:MemoryStore 非线程安全,但无文档说明
代码证据:
pub struct MemoryStore {
conn: rusqlite::Connection, // ← rusqlite::Connection 不是 Send + Sync
}
rusqlite::Connection 不实现 Send,因此 MemoryStore 无法跨线程共享,HTTP 层用 Mutex 封装解决了这个问题,但 Python SDK 和 Node SDK 若在多线程环境调用需要注意。
五、亮点(真实代码中确认的)
| 设计 |
代码证据 |
评价 |
| 幂等写入 |
if current.value_json == req.value 分支 |
✅ 优雅,避免无效版本 |
| Bitemporal 语义 |
valid_from / valid_to / as_of |
✅ 业界最佳实践 |
| 证据溯源 |
evidence 表 + source_kind/ref/summary |
✅ 可解释性强 |
| 事务安全 |
let tx = self.conn.transaction()? |
✅ 写入全部在事务中 |
| LoCoMo 评估 |
完整的评估脚本体系 + CI gate |
✅ 工程严谨 |
| 命名空间隔离 |
测试文件 namespace_isolation.rs |
✅ 多租户基础具备 |
| 短语连续性排名 |
ranking_prefers_phrase_continuity 测试 |
✅ FTS 排名有深度思考 |
| CI 自动化 |
locomo-full-gate.yml |
✅ 检索质量有门控 |
六、优先级汇总
| 优先级 |
问题 |
文件 |
影响 |
| 🔴 P0 |
MCP 工具无参数 Schema |
packages/mcp/src/tools.ts |
Claude/Cursor 无法正确调用 |
| 🔴 P0 |
FTS 行只增不减,旧版本污染检索 |
crates/memory-core/src/fts.rs |
检索结果越来越差 |
| 🔴 P0 |
HTTP 读操作使用 Mutex 而非 RwLock |
crates/memory-http/src/routes.rs |
并发性能差 |
| 🟡 P1 |
ID 生成器重启后重置 |
crates/memory-core/src/store.rs |
潜在 ID 碰撞 |
| 🟡 P1 |
Python recall 丢失 as_of 参数 |
python/memory_sdk/client.py |
跨层语义不一致 |
| 🟡 P1 |
核心查询无复合索引 |
crates/memory-core/src/schema.rs |
大数据量下性能劣化 |
| 🟡 P1 |
FTS 停用词表不完整 |
crates/memory-core/src/fts.rs |
检索召回质量损失 |
| 🟢 P2 |
Windows 无 CI,文档未说明 |
CI + README |
用户困惑 |
| 🟢 P2 |
include_history 无效但误导性强 |
所有 SDK |
API 设计困惑 |
七、建议
这是一个工程质量相当高的项目:
- Rust 核心设计严谨(事务、幂等、版本链、证据溯源)
- 跨语言绑定完整(Python + Node + MCP + HTTP)
- CI 评估体系(LoCoMo gate)在同类项目中少见
最值得立即修复的三项:
-
MCP Schema(1小时):在 tools.ts 中为每个工具添加参数 schema,这是使项目真正可用的关键一步
-
FTS 清理(2小时):在 close_current_fact 中添加 DELETE FROM facts_fts WHERE fact_id = ?,否则数据越多检索越差
-
数据库索引(30分钟):在 schema.rs 的 ALL_SCHEMA 中添加复合索引,这是最低投入最高回报的改动
📝 Technical Review & Optimization Suggestions
Hi @Cocoblood9527,概括:
Diving into the
LocalMemOScodebase and am genuinely impressed by the architecture. The use of a Rust core with bitemporal data modeling (valid_from/valid_to), idempotent upserts, and evidence-based traceability is excellent. The engineering quality is very high.While reviewing the implementation, I identified a few areas where we could potentially improve performance, search quality, and MCP integration. I've categorized these based on impact for your consideration:
🔴 P0: Critical Improvements (High Impact)
1. Missing MCP Tool Schemas
Currently, MCP tools are registered without JSON Schemas (e.g.,
server.tool("memory_upsert_fact", upsert as any)). This prevents Claude Desktop/Cursor from providing parameter hints and causes issues with automatic tool calling.packages/mcp/src/tools.ts.2. FTS5 Index Cleanup
In
store.rs, theupsert_fts_rowfunction inserts new entries but never deletes old ones when a fact is updated or retired. This leads to "index bloat," where search results include stale/retired facts.close_current_fact, add aDELETE FROM facts_fts WHERE fact_id = ?to keep the search index clean.3. HTTP Concurrency Bottleneck
The
AppStateuses a globalMutexfor theMemoryStore. Sincerecallandlistare read-only operations, they are currently blocking each other.std::sync::Mutextotokio::sync::RwLockto allow concurrent read operations.🟡 P1: Important Optimizations
1. Missing Database Indexes
The
factstable lacks composite indexes for the core lookup query (namespace,scope_id,entity,attribute). This will cause full table scans as the dataset grows.(namespace, scope_id, entity, attribute, valid_to).2. Python SDK Semantic Gap
The Python
recallmethod is missing theas_ofparameter, which is available in the Rust core. This prevents users from performing historical point-in-time queries via the Python SDK.3. FTS Stopword List
The current
STOPWORDSlist is quite minimal.🟢 P2: Maintenance & DX
ID_COUNTER(AtomicU64) resets on process restart. Consider switching toULIDorUUID v4to ensure global uniqueness across restarts.include_historyis reserved for future use to avoid user confusion.Summary
This is an outstanding project with a very solid foundation. These suggestions are just my observations while studying the code. I am happy to open PRs for some of these (especially the MCP Schema and Indexing) if you think they align with your roadmap!
Keep up the great work!
LocalMemOS 深度技术审查报告(基于真实源码)
一、项目真实架构(纠正前次错误)
这不是前次描述的项目
真实技术栈
语言分布:Rust 56.4% / Shell 19.5% / Python 12.8% / TypeScript 10.5%
二、核心数据模型(实际代码)
数据结构
数据库 Schema(4 张表)
设计亮点:
(namespace, scope_id, entity, attribute)为主键valid_from / valid_to实现双时态(bitemporal)语义evidence表实现溯源,记录每次写入的来源三、核心逻辑审查
3.1 upsert_fact 写入逻辑(实际代码)
✅ 亮点:幂等写入、版本链保留、证据记录、事务保证,逻辑设计完整
3.2 FTS 检索逻辑(实际代码)
实际检索流程:
3.3 MCP 工具(实际代码)
server.tool("name", handler as any)),Claude/Cursor 无法自动感知参数格式。四、真实存在的问题(基于代码)
🔴 P0:MCP 工具无 Schema 定义
代码证据:
问题:MCP 协议要求工具注册时提供 JSON Schema,描述参数名称、类型、必填项。缺失 schema 会导致:
建议修复:
🔴 P0:FTS 索引只在写入时追加,从不更新
代码证据:
upsert_fact 中的调用:
问题:每次 upsert 都在 FTS5 表中追加一行,旧版本的 FTS 条目永远不会被删除。随着时间推移:
valid_to非 NULL)建议修复:
🔴 P0:HTTP 层使用全局 Mutex,高并发场景阻塞
代码证据:
问题:
recall、list、history均为只读操作,但使用同一把Mutex(非RwLock),导致:建议修复:
🟡 P1:ID 生成机制存在竞态风险
代码证据:
问题:
fetch_add调用)需确认是否正确使用建议:改用 UUID v4 或
ulid(既有唯一性又有时间序):🟡 P1:Python SDK 的
recall丢失as_of参数代码证据:
对比 Rust RecallRequest:
影响:Python 用户无法使用时态查询(
as_of),是跨层语义缺失的典型问题。🟡 P1:
forget的实现未确认是软删除还是硬删除代码证据(已有的 routes.rs):
设计文档声明:
测试用例也验证了:
但 FTS 表和 fact_versions 表是否同步清理仍需确认。
🟡 P1:FTS 停用词表不完整,影响检索质量
代码证据:
问题:
not、no、but、if、then、also、just、like、my、your、they、he、she、i、me、him、us等常用词🟡 P1:facts 表缺少关键索引
代码证据:
问题:核心查询
WHERE namespace = ? AND scope_id = ? AND entity = ? AND attribute = ? AND valid_to IS NULL在数据量大时全表扫描。建议:
🟢 P2:Windows 平台支持未测试
代码证据:
README 声明:
问题:项目明确不支持 Windows CI,但 README 中的
Environment Setup未提及此限制,可能误导 Windows 用户尝试安装。🟢 P2:
include_history字段保留但有误导性代码证据:
问题:字段存在于所有 SDK 接口中,但完全无效,容易让用户误以为能用。建议在注释中更明确地写出"此字段 v1 中无效,v2 实现时间历史查询请使用
history()方法"。🟢 P2:
MemoryStore非线程安全,但无文档说明代码证据:
rusqlite::Connection不实现Send,因此MemoryStore无法跨线程共享,HTTP 层用Mutex封装解决了这个问题,但 Python SDK 和 Node SDK 若在多线程环境调用需要注意。五、亮点(真实代码中确认的)
if current.value_json == req.value分支valid_from / valid_to / as_ofevidence表 +source_kind/ref/summarylet tx = self.conn.transaction()?namespace_isolation.rsranking_prefers_phrase_continuity测试locomo-full-gate.yml六、优先级汇总
packages/mcp/src/tools.tscrates/memory-core/src/fts.rscrates/memory-http/src/routes.rscrates/memory-core/src/store.rsrecall丢失as_of参数python/memory_sdk/client.pycrates/memory-core/src/schema.rscrates/memory-core/src/fts.rsinclude_history无效但误导性强七、建议
这是一个工程质量相当高的项目:
最值得立即修复的三项:
MCP Schema(1小时):在
tools.ts中为每个工具添加参数 schema,这是使项目真正可用的关键一步FTS 清理(2小时):在
close_current_fact中添加DELETE FROM facts_fts WHERE fact_id = ?,否则数据越多检索越差数据库索引(30分钟):在
schema.rs的ALL_SCHEMA中添加复合索引,这是最低投入最高回报的改动