乐于分享
好东西不私藏

OpenClaw记忆管理系统架构设计

OpenClaw记忆管理系统架构设计

本文主要介绍了OpenClaw忆管理系统架构设计,包括双后端架构,记忆存储数据结构,记忆同步记忆,容错机制,还有记忆系统运行状态。

OpenClaw的记忆管理系统是一个高性能、可扩展的AI记忆检索解决方案,专为AI Agent和对话系统设计。该系统采用创新的双后端架构,结合了向量搜索和全文搜索的优势,为AI提供语义理解和关键词匹配的混合检索能力。创新的架构设计实现包括:

  • 高可用性 - 双后端自动降级

  • 高性能 - 混合搜索+缓存优化

  • 高可扩展性 - 支持多种嵌入提供商

  • 实时性 - 文件监听+自动同步

  • 容错性 - 多层错误恢复机制

这种架构使得OpenClaw能够为AI Agent提供可靠、高效的记忆检索服务,是实现长期记忆和上下文感知的关键基础设施。

1.核心架构

1.1 双后端设计

(1)QMD后端(外部)

  • 基于外部QMD进程的记忆管理

  • 支持更高级的搜索特性和性能优化

  • 通过进程间通信进行交互

  • 具备自动降级能力,失败时回退到内置索引

(2)内置索引后端

  • 基于SQLite的本地实现

  • 集成向量搜索(通过vec0扩展)

  • 全文搜索(FTS5)

  • 完全离线工作,无需外部依赖

// 后端选择逻辑exporttype MemoryBackend = "builtin" | "qmd";// 自动降级包装器class FallbackMemoryManager implements MemorySearchManager {private primary: MemorySearchManager;private fallback: MemorySearchManager | null = null;private primaryFailed = false;}

1.2 分层架构

┌─────────────────────────────────────────┐│         Agent Tools Layer               ││  (memory_search, memory_get)            │└──────────────┬──────────────────────────┘               │┌──────────────▼──────────────────────────┐│      Memory Manager Interface          ││  (MemorySearchManager)                  │└──────────────┬──────────────────────────┘               │       ┌───────┴────────┐       │                │┌──────▼─────┐   ┌─────▼──────────┐│  QMD       │   │  Built-in      ││  Backend   │   │  Index         │└────────────┘   └────────────────┘                       │       ┌───────────────┼───────────────┐       │               │               │┌──────▼──────┐ ┌─────▼─────┐ ┌──────▼──────┐│  Vector     │ │    FTS    │ │   Embedding ││  Search     │ │   Search  │ │  Provider   │└─────────────┘ └───────────┘ └─────────────┘

1.3 核心组件

1.3.1 MemoryIndexManager [3]

内置索引的主要实现类,继承自MemoryManagerEmbeddingOps

  • 管理SQLite数据库连接

  • 协调向量搜索和全文搜索

  • 处理文件监听和自动同步

  • 实现缓存和批处理优化

1.3.2 QmdMemoryManager [4]

外部QMD后端的封装:

  • 通过CLI命令与QMD进程通信

  • 解析QMD输出的搜索结果

  • 处理作用域和权限验证

  • 管理进程生命周期

2.数据模型 - 记忆存储结构

OpenClaw中的记忆默认存储在 SQLite 数据库文件中,路径为~/.openclaw/memory/memory.db

2.1 记忆存储结构

// 记忆来源类型exporttype MemorySource = "memory" | "sessions";// 搜索结果exporttype MemorySearchResult = {  path: string;           // 文件相对路径  startLine: number;      // 起始行号  endLine: number;        // 结束行号  score: number;          // 相关性分数  snippet: string;        // 内容片段  source: MemorySource;   // 来源类型  citation?: string;      // 引用标记};

2.2 memory vs sessions

2.2.1 memory — 用户记忆文件

来源:用户主动编写的 Markdown 文件

路径示例:

MEMORY.md              # 根记忆文件memory/                # 记忆目录  ├── 2026-03-24.md    # 日期记忆  ├── architecture.md  # 架构文档  ├── patterns.md      # 设计模式  └── conventions.md   # 编码规范

特点:

  • 永久性知识

  • 用户主动维护

  • 支持时间衰减(日期文件)

  • 常青记忆不衰减(如 MEMORY.md

用途:

存储项目知识、决策记录、编码规范等

2.2.2 sessions — Agent 会话记录

来源:AI Agent 对话的历史记录

路径示例:

~/.openclaw/agents/<agentId>/sessions/  ├── 2026-03-24T10-30-00.123Z.jsonl  ├── 2026-03-24T14-22-33.456Z.jsonl  └── ...

特点:

  • JSONL 格式存储

  • 自动生成(对话结束时)

  • 包含完整对话上下文

  • 增量同步

内容结构(每行一个 JSON)

"role""user""content""用户消息" }"role""assistant""content""AI 回复""toolCalls": [...] }
2.2.3 实际应用场景

搜索时的行为:

{"memorySearch": {"sources": ["memory""sessions"]  }}

memory 来源返回结果示例:

{"path""memory/architecture.md","source""memory","score"0.85,"snippet""..."}

sessions 来源返回结果示例:

{"path""~/.openclaw/agents/xxx/sessions/2026-03-24T10-30-00.123Z.jsonl","source""sessions","score"0.92,"snippet""..."}
2.2.4 为什么分开存储
特性
memory
sessions
创建方式
手动编写
自动生成
更新频率
低频编辑
高频追加
内容类型
结构化知识
对话历史
时间衰减
支持(30天半衰期)
更快衰减
可搜索性
语义+关键词
语义+关键词
2.2.5 实际查询示例

用户:之前讨论过的数据库优化方案在哪?

搜索结果

1.sessions/2026-03-15.jsonl (score: 0.95)snippet: "关于数据库优化,我们讨论了..."2.memory/2026-03-15.md (score: 0.82)snippet: "数据库优化会议纪要..."3.memory/architecture.md (score: 0.76)snippet: "数据库索引优化策略..."

这种设计让 AI 能同时检索 讨论过程(sessions) 和 结论知识(memory),从而提供更全面的上下文。

3.数据库Schema - chunks表 - 文本块存储

3.1 chunks表

存储文本块的原始内容、文件关联和元数据 。

CREATETABLE chunks (idINTEGER PRIMARY KEY,  file_id INTEGERNOTNULL,  chunk_index INTEGERNOTNULL,contentTEXTNOTNULL,sourceTEXTNOTNULL,  provider_model TEXT,  created_at INTEGER,FOREIGNKEY (file_id) REFERENCES files(id));

3.2 chunks 表结构说明

字段名
类型
解释
id
INTEGER PRIMARY KEY
文本块唯一标识符,自增主键
file_id
INTEGER NOT NULL
关联的文件ID,外键指向 files 表
chunk_index
INTEGER NOT NULL
文本块在文件中的顺序索引(从0开始)
content
TEXT NOT NULL
文本块的实际内容
source
TEXT NOT NULL
来源类型:"memory" 或 "sessions"
provider_model
TEXT
生成嵌入的模型名称,如 "text-embedding-3-small"
created_at
INTEGER
创建时间戳(Unix毫秒)

3.3 示例数据

id
file_id
chunk_index
content
source
provider_model
created_at
1
42
0
"OpenClaw记忆管理..."
memory
text-embedding-3-small
1711267200000
2
42
1
"向量嵌入系统..."
memory
text-embedding-3-small
1711267200000
3
103
0
"用户问:如何配置..."
sessions
text-embedding-3-small
1711270800000

3.4 关键关系

files (id=42, path="MEMORY.md")  └─ chunks (file_id=42, chunk_index=0) → content: "第一段内容"  └─ chunks (file_id=42, chunk_index=1) → content: "第二段内容"  └─ chunks (file_id=42, chunk_index=2) → content: "第三段内容"

说明:同一个文件被切分成多个 chunk,使用 chunk_index 保持原始顺序。

4.数据库Schema - chunks_vec表 - 向量索引(语义检索)

4.1 chunks_vec表

存储向量嵌入,通过向量距离计算实现语义相似度搜索,找到与查询语义最相近的文本块。

CREATEVIRTUALTABLE chunks_vec USING vec0(  chunk_id INTEGER PRIMARY KEY,  vector_float(1536),  -- 根据模型维度调整sourceTEXT);

4.2 chunks_vec 表结构说明

字段名
类型
解释
chunk_id
INTEGER PRIMARY KEY
关联 chunks 表的 ID,作为主键和外键
vector_float
FLOAT(1536)
向量嵌入数据,1536维(OpenAI text-embedding-3-small 默认维度)
source
TEXT
来源类型:"memory" 或 "sessions",用于过滤搜索范围

4.3 向量维度说明

模型
维度
vector_float() 参数
text-embedding-3-small
1536
vector_float(1536)
text-embedding-3-large
3072
vector_float(3072)
gemini-embedding-2
768
vector_float(768)
voyage-3
1024
vector_float(1024)
mistral-embed
1024
vector_float(1024)

4.4 示例数据

chunk_id
vector_float (简化展示)
source
1
[0.12, -0.34, 0.56, ..., 0.78]
memory
2
[-0.23, 0.45, -0.67, ..., 0.12]
memory
3
[0.34, -0.12, 0.89, ..., -0.45]
sessions

4.5 与 chunks 表的关系

chunks (id=1, content="OpenClaw记忆管理...")  └─ chunks_vec (chunk_id=1, vector_float=[0.12, -0.34, ...])

4.6 关联查询示例

SELECT  c.id,  c.content,  c.source,  v.vector_floatFROM chunks cJOIN chunks_vec v ON c.id = v.chunk_idWHERE c.source = 'memory'

4.7 使用场景 - 语义搜索(按相似度排序)

SELECT  c.id,  c.content,  vec0_distance_chunks_vec(c.vector_float, ?) AS distanceFROM chunks cJOIN chunks_vec v ON c.id = v.chunk_idWHERE c.source = 'memory'ORDERBY distanceLIMIT10;

4.8 使用场景 - 只搜索 memory 来源

SELECT chunk_idFROM chunks_vecWHEREsource = 'memory';

4.9 使用场景 - 只搜索 sessions 来源

SELECT chunk_idFROM chunks_vecWHEREsource = 'sessions';

5.数据库Schema - chunks_fts表 - 全文搜索(关键词检索)

5.1 chunks_fts表

通过关键词匹配和 BM25 排序实现精确的文本搜索,补充向量搜索的不足。

CREATEVIRTUALTABLE chunks_fts USING fts5(content,source,  tokenize='porter unicode61');

5.2 chunks_fts 表结构说明

字段名
类型
解释
content
TEXT
文本块内容,FTS5 自动创建全文索引
source
TEXT
来源类型:"memory" 或 "sessions",用于过滤搜索范围
tokenize
配置参数
使用 porter 词干提取 + unicode61 分词器

5.3 FTS5 特性

特性
说明
VIRTUAL TABLE
虚拟表,数据实际存储在内部内容表
全文索引
自动对所有字段建立倒排索引
BM25 排序
内置 BM25 算法计算相关性分数

5.4 Tokenize 参数详解

参数
作用
porter
Porter 词干提取算法,将单词还原为词根形式
unicode61
支持 Unicode 6.1 标准的分词器,正确处理中文、日文、emoji 等多语言字符

示例效果:

  • 输入:"机器学习 machine learning running"

  • 分词结果:["机器", "学习", "machine", "run"]

说明:

  • running → run(词干提取)

  • 与 chunks 表的关系:chunks_fts 是 chunks 的全文索引视图,通过 rowid 自动关联。

关联查询示例:

SELECT  c.id,  c.content,  c.start_line,  c.end_line,  bm25(chunks_fts, 0AS scoreFROM chunks_fts ftsJOIN chunks c ON fts.rowid = c.idWHERE chunks_fts MATCH'机器学习'ORDERBY scoreLIMIT10;

5.5 搜索示例

5.5.1 简单关键词搜索
SELECT * FROM chunks_ftsWHEREcontentMATCH'database'LIMIT10;
5.5.2 多词 OR 搜索
SELECT * FROM chunks_ftsWHEREcontentMATCH'"database" OR "optimization"'LIMIT10;
5.5.3 短语精确匹配
SELECT * FROM chunks_ftsWHEREcontentMATCH'"memory management system"'LIMIT10;
5.5.4 按来源过滤
SELECT c.*FROM chunks_fts ftsJOIN chunks c ON fts.rowid = c.idWHERE fts.content MATCH'embedding'AND c.source = 'memory';

5.6 BM25 分数计算

BM25 分数范围:0(最相关)到 ∞(不相关)。转换为归一化分数:

SELECT  c.content,  bm25(chunks_fts, 0AS bm25_score,  (bm25(chunks_fts, 0) / (1 + bm25(chunks_fts, 0))) AS normalized_scoreFROM chunks_fts ftsJOIN chunks c ON fts.rowid = c.idWHERE fts.content MATCH'query'ORDERBY bm25_score;

6.OpenClaw 记忆同步机制

OpenClaw 通过三种机制协同工作,确保记忆索引与文件系统、会话数据保持实时或准实时同步。

6.1 文件监听 (File Watcher)

6.1.1 工作原理
protected watcher: FSWatcher | null = null;private ensureWatcher(): void {// 监听 memory 目录下的所有文件const memoryPaths = [    path.join(this.workspaceDir, "MEMORY.md"),    path.join(this.workspaceDir, "memory"),      // memory/*.md    ...this.settings.extraPaths,                 // 额外路径  ];this.watcher = chokidar.watch(memoryPaths, {    ignored: /(^|[\/\\])\../,     // 忽略 .git, .node_modules 等    persistent: true,              // 持续监听,不自动退出    ignoreInitial: false,          // 初始扫描也触发事件  });// 任何文件变化都标记为 dirtythis.watcher.on('all'(event, filePath) => {    log.debug(`Memory file changed: ${event}${filePath}`);this.dirty = true;              // 标记需要同步  });}
6.1.2 触发场景
事件
触发条件
dirty 标记
add
新增文件
change
修改文件内容
unlink
删除文件
addDir
新增目录
unlinkDir
删除目录
6.1.3 实际流程
用户编辑 memory/architecture.md           ↓chokidar 检测到 change 事件           ↓this.dirty = true           ↓下次搜索时触发 sync()           ↓重新索引 architecture.md           ↓更新 chunks / chunks_vec / chunks_fts 表           ↓this.dirty = false

6.2 会话同步 (Session Listener)

6.2.1 工作原理
protected sessionUnsubscribe: (() => void) | null = null;protectedsessionsDirtyFiles = newSet<string>();protectedsessionsDirty = false;privateensureSessionListener()void {  // 监听 Agent 会话结束事件this.sessionUnsubscribe = onAgentSessionEnd((sessionFile) => {    log.debug(`Session ended: ${sessionFile}`);this.sessionsDirtyFiles.add(sessionFile);  // 记录变更的会话文件this.sessionsDirty = true;                  // 标记需要同步  });}
6.2.2 触发时机
Agent 对话进行中...           ↓用户结束对话 / 超时           ↓触发 onAgentSessionEnd 事件           ↓写入会话文件: ~/.openclaw/agents/xxx/sessions/2026-03-25T10-30-00.jsonl           ↓sessionListener 收到通知           ↓sessionsDirty = true
6.2.3 增量更新策略
async sync(params?: { sessionFiles?: string[] }) {if (params?.sessionFiles) {// 增量同步指定的会话文件for (const sessionFile of params.sessionFiles) {awaitthis.indexSessionFile(sessionFile);    }  } else {// 全量同步awaitthis.indexAllSessions();  }}

6.3 定期同步 (Interval Sync)

6.3.1 工作原理
private intervalTimer: NodeJS.Timeout | null = null;private ensureIntervalSync(): void {// 每分钟检查一次是否需要同步this.intervalTimer = setInterval(() => {if (this.dirty || this.sessionsDirty) {      log.debug("Periodic sync triggered");voidthis.sync({ reason: "interval" }).catch((err) => {        log.warn(`Periodic sync failed: ${String(err)}`);      });    }  }, 60 * 1000);  // 60秒}
6.3.2 触发条件
if (this.dirty || this.sessionsDirty) {// 有变更才同步this.sync({ reason: "interval" });}
6.3.3 时间线示例
10:00:00 - 启动定时器10:01:00 - 检查: dirty=false, 跳过10:02:00 - 检查: dirty=false, 跳过10:03:00 - 用户编辑 memory/arch.md → dirty=true10:03:45 - 检查: dirty=true → 执行 sync()10:04:00 - 检查: dirty=false, 跳过

6.4 三种机制的协作关系

6.4.1 触发优先级
async search(query: string, opts?: SearchOptions) {// 1. 会话预热(最高优先级)voidthis.warmSession(opts?.sessionKey);// 2. 搜索触发同步if (this.settings.sync.onSearch && (this.dirty || this.sessionsDirty)) {voidthis.sync({ reason: "search" });  }// 3. 执行搜索...return results;}
6.4.2 完整同步流程
┌─────────────────────────────────────────────────┐│           三种触发源                             │├──────────┬──────────────┬──────────────────────┤│ 文件监听  │ 会话监听     │ 定时器                ││ (实时)   │ (会话结束)   │ (每分钟)              │└────┬─────┴──────┬───────┴──────┬───────────────┘     │            │              │     ▼            ▼              ▼  dirty=true   sessionsDirty=true  检查标记     │            │              │     └────────────┴──────────────┘                    │                    ▼           ┌────────────────┐           │  sync() 方法   │           └────────────────┘                    │      ┌─────────────┼─────────────┐      │             │             │      ▼             ▼             ▼  ┌───────┐   ┌─────────┐   ┌──────────┐  │文件监听│   │会话同步  │   │清理标记  │  │索引变更│   │增量更新  │   │dirty=false│  └───────┘   └─────────┘   └──────────┘
6.4.3 并发控制
private syncing: Promise<void> | null = null;async sync(params?: SyncParams): Promise<void> {// 如果正在同步,返回现有 Promiseif (this.syncing) {// 如果有新的会话文件,加入队列if (params?.sessionFiles) {returnthis.enqueueTargetedSessionSync(params.sessionFiles);    }returnthis.syncing;  }// 开始新的同步this.syncing = this.runSync(params).finally(() => {this.syncing = null;  // 完成后清除  });returnthis.syncing;}

6.5 配置选项

{"memorySearch": {"sync": {"onSearch"true,      // 搜索时自动同步"onSessionStart"true// 会话开始时预热    }  }}
选项
默认值
说明
onSearch
true
搜索时触发同步(有 dirty 时)
onSessionStart
true
会话开始时预加载最新记忆

6.6 性能优化

6.6.1 防抖策略
// 文件监听设置 dirty,但不立即同步this.watcher.on('all'(event, path) => {this.dirty = true;  // 只标记,不同步});// 等待搜索或定时器触发if (this.dirty && this.settings.sync.onSearch) {awaitthis.sync();  // 批量处理所有变更}
6.6.2 增量索引

只对标记为 dirty 的变更文件重新分块和嵌入,避免全量索引的性能开销。

async runSync(params?: SyncParams) {if (this.dirty) {const changedFiles = awaitthis.collectChangedFiles();for (const file of changedFiles) {awaitthis.indexFile(file);  // 增量更新    }  }if (this.sessionsDirty) {for (const sessionFile of this.sessionsDirtyFiles) {awaitthis.indexSessionFile(sessionFile);    }this.sessionsDirtyFiles.clear();  }this.dirty = false;this.sessionsDirty = false;}
6.6.3 队列机制

将并发的会话文件更新请求收集到队列中,等待当前同步完成后批量处理,防止资源竞争和重复索引。

private enqueueTargetedSessionSync(sessionFiles: string[]) {for (const file of sessionFiles) {this.queuedSessionFiles.add(file);  }if (!this.queuedSessionSync) {this.queuedSessionSync = (async () => {awaitthis.syncing?.catch(() => undefined);while (this.queuedSessionFiles.size > 0) {const files = Array.from(this.queuedSessionFiles);this.queuedSessionFiles.clear();awaitthis.sync({ sessionFiles: files });      }    })();  }}

6.7 总结

这三种机制共同确保记忆索引始终与实际内容保持同步,兼顾实时性、可靠性和性能。

机制
触发条件
优先级
延迟
用途
文件监听
文件系统变化
0s
实时响应用户编辑
会话同步
Agent 对话结束
0s
捕获最新对话上下文
定期同步
每60秒检查
≤60s
兜底机制,防止遗漏

7.OpenClaw 容错机制

只读数据库恢复和后端降级,这两者结合确保 OpenClaw 记忆系统的高可用性和容错能力。

7.1 只读数据库恢复 (Readonly Database Recovery)

处理临时性的数据库访问问题,通过重新连接尝试自动恢复。

7.1.1 触发场景
// 检测只读数据库错误private isReadonlyDbError(err: unknown): boolean {const readonlyPattern =/attempt to write a readonly database|database is read-only|SQLITE_READONLY/i;// 检查错误消息const message = err instanceofError ? err.message : String(err);return readonlyPattern.test(message);}

常见原因:

  • 🔒 SQLite 数据库文件被设置为只读权限

  • 💾 磁盘空间不足

  • 📁 文件被其他进程锁定

  • 🔄 文件系统错误(如网络挂载断开)

7.1.2 恢复流程
privateasync runSyncWithReadonlyRecovery(params?: SyncParams): Promise<void> {try {// 第一次尝试:正常同步awaitthis.runSync(params);return;  } catch (err) {// 1. 检查是否是只读错误if (!this.isReadonlyDbError(err) || this.closed) {throw err;  // 不是只读错误或已关闭,直接抛出    }const reason = this.extractErrorReason(err);this.readonlyRecoveryAttempts += 1;this.readonlyRecoveryLastError = reason;    log.warn(`memory sync readonly handle detected; reopening sqlite connection`, { reason });// 2. 关闭旧连接try {this.db.close();    } catch {}// 3. 重新打开数据库连接this.db = this.openDatabase();// 4. 重置向量扩展状态this.vectorReady = null;this.vector.available = null;this.vector.loadError = undefined;// 5. 重新初始化 Schemathis.ensureSchema();// 6. 读取元数据(验证连接)const meta = this.readMeta();this.vector.dims = meta?.vectorDims;// 7. 重试同步try {awaitthis.runSync(params);this.readonlyRecoverySuccesses += 1;  // 成功计数    } catch (retryErr) {this.readonlyRecoveryFailures += 1;   // 失败计数throw retryErr;    }  }}
7.1.3 完整时间线
┌─────────────────────────────────────────────────────┐│ 正常流程                                            │├─────────────────────────────────────────────────────┤│                                                     ││  runSync()                                          ││     │                                               ││     ├─> 打开事务                                    ││     ├─> 写入 chunks                                 ││     ├─> ❌ SQLITE_READONLY: attempt to write a...   ││     │                                               ││     ▼                                               ││ 捕获错误                                            ││     │                                               ││     ├─> isReadonlyDbError(err) → true              ││     │                                               ││     ▼                                               ││ 恢复流程                                            ││     │                                               ││     ├─> db.close()                                 ││     ├─> db = openDatabase()                        ││     ├─> ensureSchema()                             ││     ├─> vectorReady = null                          ││     │                                               ││     ▼                                               ││ 重试同步                                            ││     │                                               ││     ├─> runSync()                                  ││     ├─> ✅ 成功                                     ││     │                                               ││     ▼                                               ││ readonlyRecoverySuccesses++                        ││                                                     │└─────────────────────────────────────────────────────┘
7.1.4 监控指标
status(): MemoryProviderStatus {return {// ...    custom: {      readonlyRecovery: {        attempts: this.readonlyRecoveryAttempts,      // 尝试次数        successes: this.readonlyRecoverySuccesses,    // 成功次数        failures: this.readonlyRecoveryFailures,      // 失败次数        lastError: this.readonlyRecoveryLastError,    // 最后的错误      },    },  };}

7.2 后端降级 (Backend Fallback)

QMD 不可用时自动切换到内置索引,确保记忆搜索始终可用。

7.2.1 架构设计
class FallbackMemoryManager implements MemorySearchManager {private primary: MemorySearchManager;       // 主后端(QMD)private fallback: MemorySearchManager | null// 备用后端private primaryFailed = false;              // 主后端失败标记private lastError?: string;                 // 最后的错误信息}
7.2.2 降级触发流程
async search(query: string, opts?: SearchOptions) {// 1. 尝试主后端if (!this.primaryFailed) {try {returnawaitthis.deps.primary.search(query, opts);    } catch (err) {// 主后端失败this.primaryFailed = true;this.lastError = err instanceofError ? err.message : String(err);      log.warn(`qmd memory failed; switching to builtin index: ${this.lastError}`);// 清理主后端awaitthis.deps.primary.close?.().catch(() => {});// 驱逐缓存,下次可以重试 QMDthis.evictCacheEntry();    }  }// 2. 降级到备用后端const fallback = awaitthis.ensureFallback();if (fallback) {returnawait fallback.search(query, opts);  }// 3. 备用后端也不可用thrownewError(this.lastError ?? "memory search unavailable");}
7.2.3 备用后端初始化
privateasync ensureFallback(): Promise<MemorySearchManager | null> {// 如果已经有备用后端,直接返回if (this.fallback) {returnthis.fallback;  }try {// 创建内置索引管理器const { MemoryIndexManager } = await loadManagerRuntime();const manager = await MemoryIndexManager.get(this.params);if (!manager) {      log.warn("memory fallback requested but builtin index is unavailable");returnnull;    }this.fallback = manager;returnthis.fallback;  } catch (err) {const message = err instanceofError ? err.message : String(err);    log.warn(`memory fallback unavailable: ${message}`);returnnull;  }}
7.2.4 完整降级时间线
┌─────────────────────────────────────────────────────────┐│ 后端降级流程                                             │├─────────────────────────────────────────────────────────┤│                                                         ││  用户发起搜索                                            ││     │                                                   ││     ▼                                                   ││  primaryFailed = false?                                 ││     │                                                   ││     ├─ Yes ───────────────────────┐                    ││     │                              │                    ││     ▼                              │                    ││  尝试 QMD 后端                     │                    ││     │                              │                    ││     ├─ ✅ 成功 ──> 返回结果         │                    ││     │                              │                    ││     └─ ❌ 失败                      │                    ││        │                           │                    ││        ▼                           │                    ││     primaryFailed = true           │                    ││     lastError = "..."              │                    ││     关闭 QMD 连接                   │                    ││     驱逐缓存条目                    │                    ││        │                           │                    ││        ▼                           ▼                    ││     检查 fallback 是否存在          │                    ││        │                           │                    ││        ├─ 存在 ──> 使用 fallback    │                    ││        │                           │                    ││        └─ 不存在 ──> 创建           │                    ││           │                        │                    ││           ▼                        │                    ││        MemoryIndexManager.get()    │                    ││           │                        │                    ││           ├─ ✅ 成功 ──> 使用它     │                    ││           │                        │                    ││           └─ ❌ 失败 ──> 抛出错误    │                    ││                                      │                    │└──────────────────────────────────────┴────────────────────┘
7.2.5 状态报告

主后端正常时直接返回其状态,降级后在备用后端状态中追加降级来源和原因信息。

status(): MemoryProviderStatus {if (!this.primaryFailed) {// 主后端正常returnthis.deps.primary.status();  }// 已降级,报告降级状态const fallbackStatus = this.fallback?.status();return {    ...fallbackStatus,    fallback: {from"qmd",      reason: this.lastError ?? "unknown"    },    custom: {      ...fallbackStatus?.custom,      fallback: {        disabled: true,        reason: this.lastError ?? "unknown"      }    }  };}
7.2.6 缓存驱逐策略

失败后从全局缓存中移除失效的管理器,下次请求创建新实例以重试主后端。

private evictCacheEntry(): void {if (this.cacheEvicted) {return;  // 已经驱逐过  }this.cacheEvicted = true;this.onClose?.();  // 从全局缓存中移除}// 下次请求会创建新的管理器,可以重试 QMDexportasyncfunctiongetMemorySearchManager(params{const cached = QMD_MANAGER_CACHE.get(cacheKey);if (cached) {return { manager: cached };  // 使用缓存的  }// 创建新的管理器(QMD 可能已恢复)const manager = await QmdMemoryManager.create({ ... });return { manager };}

7.3 两种机制的对比

特性
只读数据库恢复
后端降级
触发条件
数据库只读错误
QMD 后端失败
恢复策略
重新打开连接
切换到内置索引
重试次数
自动重试一次
切换后不再重试
状态保留
记录成功/失败次数
标记 primaryFailed
用户体验
无感知(自动恢复)
可能影响搜索质量
适用场景
临时文件系统问题
QMD 进程崩溃/不可用

7.4 实际应用场景

7.4.1 场景1:外部磁盘断开
  • 用户挂载网络磁盘 /mnt/memory

  • SQLite 数据库在网络磁盘上

  • 网络中断 → SQLITE_READONLY

  • readonlyRecovery 触发

  • 重新打开连接 → 失败(磁盘仍不可用)

  • readonlyRecoveryFailures++

  • 抛出错误给用户

7.4.2 场景2:QMD 进程崩溃
  • 用户配置 backend = "qmd"

  • QMD 进程意外崩溃

  • search() 调用失败

  • 自动降级到 MemoryIndexManager

  • 使用内置索引继续搜索

  • status() 显示 fallback 信息

7.4.3 场景3:权限问题
  • 数据库文件被设为只读:chmod 444 memory.db

  • sync() 尝试写入 → SQLITE_READONLY

  • readonlyRecovery 重新打开连接

  • 仍然只读 → 恢复失败

  • 提示用户检查权限

8.MemoryProviderStatus 详细解释

这些性能指标帮助用户和开发者实时了解记忆系统的运行状态。

exporttype MemoryProviderStatus = {// 基础配置  backend: "builtin" | "qmd";     // 后端类型  provider: string;                // 嵌入提供商ID  model?: string;                  // 嵌入模型名称// 索引统计  files?: number;                  // 已索引的文件数量  chunks?: number;                 // 文本块总数  dirty?: boolean;                 // 是否有待同步的变更// 向量搜索状态  vector?: {    enabled: boolean;              // 是否启用向量搜索    available?: boolean;           // vec0 扩展是否可用    dims?: number;                 // 向量维度(1536/3072/768等)  };// 全文搜索状态  fts?: {    enabled: boolean;              // 是否启用 FTS    available: boolean;            // FTS5 是否可用  };// 缓存状态  cache?: {    enabled: boolean;              // 是否启用嵌入缓存    entries?: number;              // 当前缓存条目数    maxEntries?: number;           // 最大缓存条目数  };// 额外信息  fallback?: {                     // 降级状态fromstring;                  // 从哪个后端降级    reason?: string;               // 降级原因  };  batch?: {                        // 批处理状态    enabled: boolean;              // 批处理是否启用    failures: number;              // 失败次数    limit: number;                 // 失败上限    wait: boolean;                 // 是否等待重试    concurrency: number;           // 并发数    pollIntervalMs: number;        // 轮询间隔    timeoutMs: number;             // 超时时间    lastError?: string;            // 最后的错误    lastProvider?: string;         // 最后的提供商  };  custom?: Record<string, unknown>; // 自定义字段};

8.1 字段信息详解

8.1.1 基础配置信息
字段
类型
说明
可选值/示例
backend"builtin" | "qmd"
当前使用的记忆后端类型
"builtin"
 — 内置 SQLite"qmd" — 外部 QMD
providerstring
向量嵌入提供商标识
"openai"
"gemini""voyage""mistral""ollama""local""none"
modelstring?
使用的嵌入模型名称
"text-embedding-3-small"
"gemini-embedding-2""voyage-3"
8.1.2 索引统计信息
字段
类型
说明
计算方式/示例
filesnumber?
已索引的文件总数
SELECT COUNT(*) FROM files
示例: 42
chunksnumber?
文本块总数
SELECT COUNT(*) FROM chunks
示例: 1580
dirtyboolean?
是否有待同步的变更
true
 — 需要同步false — 已同步
8.1.3 向量搜索状态
字段
类型
说明
可选值/示例
vector.enabledboolean
是否启用向量搜索
true
 — 启用false — 仅 FTS
vector.availableboolean?vec0
 扩展是否可用
true
 — 可用false — 不可用undefined — 未检测
vector.dimsnumber?
向量维度
1536
 — OpenAI small3072 — OpenAI large768 — Gemini1024 — Voyage / Mistral
8.1.4 全文搜索状态
字段
类型
说明
可选值
fts.enabledboolean
是否启用 FTS5 全文搜索
true
 — 启用false — 仅向量
fts.availableboolean
FTS5 是否可用
true
 — 可用false — 创建失败
8.1.5 缓存状态
字段
类型
说明
计算方式/示例
cache.enabledboolean
是否启用嵌入缓存
配置来源: memorySearch.cache.enabled
cache.entriesnumber?
当前缓存中的条目数
SELECT COUNT(*) FROM embedding_cache
示例: 1580
cache.maxEntriesnumber?
最大缓存条目数
配置来源: memorySearch.cache.maxEntries示例: 10000
8.1.6 额外状态字段
字段
类型
说明
示例
fallback.fromstring
从哪个后端降级
"qmd"
fallback.reasonstring?
降级原因
"Connection refused"
batch.enabledboolean
批处理是否启用
true
batch.failuresnumber
失败次数
0
batch.limitnumber
失败上限
2
batch.concurrencynumber
并发数
4
batch.pollIntervalMsnumber
轮询间隔 (ms)
5000
batch.timeoutMsnumber
超时时间 (ms)
30000
8.1.7 向量维度对照表
模型
提供商
维度
text-embedding-3-small
OpenAI
1536
text-embedding-3-large
OpenAI
3072
gemini-embedding-2
Gemini
768
gemini-embedding-2-preview
Gemini
768
voyage-3
Voyage AI
1024
voyage-3-lite
Voyage AI
1024
mistral-embed
Mistral AI
1024
8.1.8 状态示例速查
场景
backendproviderdirtyvector.available
说明
正常运行
builtinopenaifalsetrue
所有功能正常
需要同步
builtingeminitruetrue
有文件变更待同步
FTS-only
builtinnonefalsefalse
无嵌入,仅全文搜索
QMD 降级
qmdgeminifalse-fallback
 字段包含降级信息

8.2 字段速查表

字段路径
类型
说明
示例值
backend"builtin" | "qmd"
后端类型
"builtin"
providerstring
嵌入提供商ID
"openai"
"gemini""none"
modelstring?
嵌入模型名称
"text-embedding-3-small"
filesnumber?
已索引文件数
42
chunksnumber?
文本块总数
1580
dirtyboolean?
是否需要同步
true
 / false
vector.enabledboolean
向量搜索启用
true
vector.availableboolean?
vec0 扩展可用
true
 / false
vector.dimsnumber?
向量维度
1536
7683072
fts.enabledboolean
FTS 启用
true
fts.availableboolean
FTS5 可用
true
 / false
cache.enabledboolean
缓存启用
true
cache.entriesnumber?
缓存条目数
1580
cache.maxEntriesnumber?
最大缓存数
10000

8.3 完整状态示例

8.3.1 内置索引后端 - 正常状态
{           // ========== 基础配置 =========="backend""builtin",              // 后端类型: "builtin"(内置SQLite) | "qmd"(外部QMD)                                                                        "provider""openai",              // 嵌入提供商: openai/gemini/voyage/mistral/ollama/local/none"model""text-embedding-3-small"// 嵌入模型名称 (FTS-only时为undefined)                                                                                    // ========== 索引统计 =========="files"42,                       // 已索引的文件总数 (memory + sessions)                                                                                    "chunks"1580,                    // 文本块总数 (一个文件可能切分为多个chunk)"dirty"false,                    // 是否有待同步的变更 (true=需重新索引, false=已最新)// ========== 向量搜索状态 =========="vector": {"enabled"true,                 // 是否启用向量搜索 (由 memorySearch.store.vector.enabled 控制)"available"true,               // vec0扩展是否可用 (false表示扩展加载失败)"dims"1536// 向量维度 (根据模型: 1536/3072/768/1024)                                                                                     },// ========== 全文搜索状态 ==========  "fts": {"enabled"true,                 // 是否启用FTS5全文搜索 (由 memorySearch.query.hybrid.enabled 控制)"available"true// FTS5是否可用 (false表示表创建失败)    },// ========== 缓存状态 =========="cache": {"enabled"true,                 // 是否启用嵌入缓存 (由 memorySearch.cache.enabled 控制)"entries"1580,                 // 当前缓存的嵌入条目数                                                                                                    "maxEntries"10000// 最大缓存条目数 (由 memorySearch.cache.maxEntries 控制)    },                                                                                                                                                            // ========== 批处理状态 =========="batch": {"enabled"true,                 // 批处理是否启用"failures"0,                   // 累计失败次数"limit"2,                      // 失败上限 (达到上限后禁用批处理)"wait"true,                    // 失败后是否等待重试"concurrency"4,                // 并发处理的请求数                                                                                                        "pollIntervalMs"5000,          // 批处理轮询间隔 (毫秒)"timeoutMs"30000// 单次批处理超时时间 (毫秒)                                                                                                   },                                     // ========== 自定义字段 =========="custom": {"searchMode""hybrid",          // 搜索模式: "hybrid"(向量+FTS) | "fts-only"(仅FTS)"readonlyRecovery": {            // 只读数据库恢复统计"attempts"0,                 // 恢复尝试次数                                                                                                            "successes"0,                // 恢复成功次数"failures"0// 恢复失败次数                                                                                                                  }                                        }}
8.3.2 QMD 后端 - 降级状态
{            // ========== 基础配置 =========="backend""qmd",                       // 后端类型: "qmd"(外部QMD) | "builtin"(内置SQLite)                                                                   "provider""gemini",                   // 嵌入提供商: gemini/openai/voyage/mistral等"model""gemini-embedding-2",          // QMD使用的嵌入模型名称                                                                                              // ========== 索引统计 ==========                                                                                                                             "files"42,                            // 已索引的文件总数 (来自fallback后端)"chunks"1580,                         // 文本块总数 (来自fallback后端)                                                                                      "dirty"false,                         // 是否有待同步的变更 (来自fallback后端)// ========== 降级信息 =========="fallback": {"from""qmd",                        // 从哪个后端降级 (原主后端)"reason""Connection refused"// 降级原因 (QMD进程崩溃/不可用/超时等)    },                                                                                                                                                            // ========== 自定义字段 ==========                                                                                                                           "custom": {                            "fallback": {                         // fallback详细状态"disabled"true,                   // fallback已禁用标记"reason""Connection refused"// fallback禁用原因 (与fallback.reason相同)      }    }}
8.3.3 FTS-only 模式
{         // ========== 基础配置 =========="backend""builtin",                  // 后端类型: "builtin"(内置SQLite)                                                                                     "provider""none",                    // ⚠️ 嵌入提供商: "none" 表示无向量嵌入"model"undefined,                    // ⚠️ 模型名称: undefined (无嵌入时为空)                                                                               // ========== 索引统计 =========="files"42,                           // 已索引的文件总数"chunks"1580,                        // 文本块总数                                                                                                          "dirty"false,                        // 是否有待同步的变更// ========== 向量搜索状态 ==========  "vector": {"enabled"false,                    // ❌ 向量搜索未启用"available"false// ❌ vec0扩展不可用 (无嵌入时自然不可用)    },// ========== 全文搜索状态 =========="fts": {"enabled"true,                     // ✅ FTS5全文搜索启用 (FTS-only模式的主要搜索方式)"available"true// ✅ FTS5可用                                                                                                         ─    },// ========== 自定义字段 ==========    "custom": {"searchMode""fts-only",            // ⚠️ 搜索模式: "fts-only" (仅全文搜索,无向量)"providerUnavailableReason""No API key configured"// 无嵌入提供商的原因    }}

8.4 使用场景

8.4.1 命令行查询

执行 openclaw memory status 快速查看记忆系统的后端、提供商、索引统计和组件状态。

$ openclaw memory statusBackend: builtinProvider: openai (text-embedding-3-small)Files: 42Chunks: 1,580Dirty: noVector: enabled, available, 1536 dimsFTS: enabled, availableCache: enabled, 1,580/10,000 entries
8.4.2 程序化查询

通过 status() 方法获取状态对象,在代码中检查 dirty 标记、向量可用性和缓存使用率等指标。

const status = memoryManager.status();if (status.dirty) {console.log("需要同步记忆索引");}if (!status.vector?.available) {console.warn("向量搜索不可用,将使用 FTS");}if (status.cache?.entries && status.cache.maxEntries) {const usage = (status.cache.entries / status.cache.maxEntries * 100).toFixed(1);console.log(`缓存使用率: ${usage}%`);}
8.4.3 健康检查

根据后端类型、提供商可用性和向量状态返回系统健康等级。

functioncheckMemoryHealth(status: MemoryProviderStatus): "healthy" | "degraded" | "down{if (status.backend === "qmd" && status.fallback) {return"degraded";  // QMD 降级到 builtin  }if (status.provider === "none") {return"degraded";  // FTS-only 模式  }if (status.vector?.enabled && !status.vector?.available) {return"down";  // 向量搜索失败  }return"healthy";}

参考文献

[1] OpenClaw记忆管理系统架构设计:https://my.feishu.cn/wiki/DbGbwTj1OijmOUkVMrCc4VVQnrh

[2] QMD GitHub 仓库: https://github.com/tobi/qmd

核心特性:结合 BM25(全文搜索)+ Vectors(向量搜索)+ Reranking(重排序)

[3] MemoryIndexManager 类结构总结:https://my.feishu.cn/wiki/HKfUw5q2ViXqzvkk8XOcYuIynme

[4] QmdMemoryManager 类结构总结:https://my.feishu.cn/wiki/O7mywzep3iaQYUkhIOvcz7V7n1b


知识星球:Dify源码剖析及答疑,OpenClaw源码剖析及答疑。加微信buxingtianxia21进NLP工程化资料群,Dify源码交流群,OpenClaw源码交流群。

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-03-25 19:18:22 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/485986.html
  2. 运行时间 : 0.174045s [ 吞吐率:5.75req/s ] 内存消耗:4,947.18kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=d6d25296382f047377cad71977ca80ff
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.68 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.80 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000508s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000761s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.001508s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000284s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000484s ]
  6. SELECT * FROM `set` [ RunTime:0.000206s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000518s ]
  8. SELECT * FROM `article` WHERE `id` = 485986 LIMIT 1 [ RunTime:0.001615s ]
  9. UPDATE `article` SET `lasttime` = 1774437502 WHERE `id` = 485986 [ RunTime:0.003855s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.005100s ]
  11. SELECT * FROM `article` WHERE `id` < 485986 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001236s ]
  12. SELECT * FROM `article` WHERE `id` > 485986 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.022884s ]
  13. SELECT * FROM `article` WHERE `id` < 485986 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.006406s ]
  14. SELECT * FROM `article` WHERE `id` < 485986 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.011840s ]
  15. SELECT * FROM `article` WHERE `id` < 485986 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.011289s ]
0.178033s