主题
记忆与 RAG API
本文引用的源码文件
本文引用的文件
目录
简介
本参考文档面向“长期记忆管理”和“检索增强生成(RAG)知识库”两套能力,覆盖以下目标:
- 说明记忆管理端点
/api/memory/add、/api/memory/query、/api/memory/tags、/api/memory/tier的调用方式、参数、状态码与错误处理。 - 说明 RAG 检索端点
/api/rag/search、/api/rag/index、/api/rag/documents的行为、配置项与使用示例。 - 解释混合检索引擎:语义搜索、关键词匹配、结果重排序(RRF)。
- 说明向量嵌入生成、文档分块策略与索引构建流程。
- 提供完整的 API 调用示例、参数配置选项、性能优化建议与故障诊断方法。
本项目采用双进程架构:Chrome 扩展端(Manifest V3)通过本地 HTTP/WebSocket 调用 Agent(Node.js)提供的能力;Agent 源码修改后必须重启进程,新接口才生效。
章节来源
项目结构
记忆与 RAG 功能集中在 Agent 端的 agent/src/memory 与 agent/src/rag 两个子系统中,由统一 HTTP 服务器 server.js 进行认证、CORS、请求体解析与路由分发。
graph TB Client["客户端Chrome 扩展 / 本地脚本"] --> Server["HTTP 服务器<br/>agent/src/server.js"] Server --> MemoryRouter["记忆路由<br/>agent/src/memory/routes.js"] Server --> RagRouter["RAG 路由<br/>agent/src/rag/routes.js"] MemoryRouter --> MemoryService["记忆服务<br/>agent/src/memory/service.js"] MemoryService --> Tags["标签逻辑<br/>agent/src/memory/tags.js"] MemoryService --> Tier["召回档位<br/>agent/src/memory/tier.js"] RagRouter --> Searcher["检索器<br/>agent/src/rag/searcher.js"] Searcher --> Store["向量存储适配器"] Searcher --> Embedding["嵌入提供者"]
图表来源
- agent/src/server.js#L417-L548
- agent/src/memory/routes.js#L149-L199
- agent/src/rag/routes.js#L133-L282
- agent/src/memory/service.js#L143-L150
- agent/src/rag/searcher.js#L27-L38
章节来源
核心组件
- HTTP 服务器与认证层:负责 Bearer Token 校验、CORS、JSON body 解析、Multipart 上传、健康检查与通用错误响应。
- 记忆服务:实现记忆的增删改查、会话级去重、关键词检索、可选语义通道、标签名次加成、价值评估与压缩淘汰。
- RAG 路由与管理器:实现知识库 CRUD、文档导入、单库/跨库检索、安装检测、嵌入连通性测试。
- 混合检索器:向量相似度 + 关键词命中抬分 + 旁路探测 + 阈值过滤。
- 标签与召回档位:标签在有查询时仅做名次加成;无查询时作为唯一选择器;召回档位根据 embedding 配置与 RAG 依赖决定 none/remote/local。
章节来源
- agent/src/server.js#L417-L548
- agent/src/memory/service.js#L1-L20
- agent/src/rag/routes.js#L1-L21
- agent/src/rag/searcher.js#L1-L26
- agent/src/memory/tags.js#L1-L12
- agent/src/memory/tier.js#L1-L38
架构总览
下图展示一次典型“跨知识库语义检索”的请求路径:客户端经 Bearer Token 访问 /api/rag/search,服务器完成认证后交给 RAG 路由,路由再调用管理器执行跨库检索;每个知识库内部使用 Searcher 进行向量检索与关键词增强,最终合并返回。
sequenceDiagram
participant C as "客户端"
participant S as "HTTP 服务器<br/>server.js"
participant R as "RAG 路由<br/>rag/routes.js"
participant M as "RAG 管理器"
participant SR as "检索器<br/>searcher.js"
participant ST as "向量存储"
participant E as "嵌入提供者"
C->>S : POST /api/rag/search {collectionIds, query, topK, threshold}
S->>S : 校验 Bearer Token
S->>R : ragRouter(req, res, pathname, url, t, body)
R->>M : searchMulti(collectionIds, query, options)
loop 每个知识库
M->>SR : search(query, options)
SR->>E : embedQuery(query)
E-->>SR : 查询向量
SR->>ST : search(queryVector, query, {topK*2})
ST-->>SR : 候选结果
SR->>SR : _boostByKeywords(query, candidates)
SR->>SR : 阈值过滤 + 旁路探测
SR-->>M : 单库结果
end
M-->>R : 跨库合并结果
R-->>S : {success, results, total, hasContext, fallback}
S-->>C : JSON 响应
图表来源
章节来源
详细组件分析
记忆管理端点
记忆端点由 memoryDispatch 统一分发,支持 store/recall/manage/injectSelect/reindex 等动作,并附带 embedding 配置与探活端点。
/api/memory/store(添加/更新/删除记忆)
- 方法:POST
- 用途:新增事实或摘要、更新已有记忆、按 id 删除记忆。
- 关键行为:
- 写入前校验 action/type/content/importance 等字段。
- 对 add/update 内容执行注入模式拦截,命中提示注入短语直接拒绝。
- 带 sessionId 的写入有进程内频率上限,防止批量投毒。
- 写成功后异步补向量(懒补),失败不阻塞主流程。
- 删除时会同步清理派生向量缓存,避免孤儿向量。
- 成功响应:
{ success: true, message, memory/action/stats } - 业务失败:HTTP 400,
{ success: false, error, code? } - 未匹配路径:HTTP 404,
{ success: false, error: "unknownApiPath" }
调用示例(概念描述):
- 添加事实:POST
/api/memory/store,body 包含action: "add"、type: "fact"、content、可选tags、importance、sourceSessionId。 - 更新记忆:POST
/api/memory/store,body 包含action: "update"、memoryId、可选content/tags/importance/category/title。 - 删除记忆:POST
/api/memory/store,body 包含action: "delete"、memoryId。
章节来源
/api/memory/recall(查询记忆)
- 方法:POST
- 用途:从长期记忆中检索相关信息,支持关键词通道与可选语义通道融合。
- 关键行为:
- 支持
query、tags、memoryType、limit。 - 无向量通道时走纯关键词匹配;有向量通道时走 RRF 排名融合。
- 标签在有查询时仅做名次加成;无查询时作为唯一选择器。
- 会话级去重:同一 sessionId 重复返回的记忆会被优先替换为未召回过的条目。
- 访问计数在收尾阶段重读真源后安全写回。
- 支持
- 成功响应:
{ success: true, message, results, total, query, tier, vectorMatched } - 业务失败:HTTP 400,
{ success: false, error }
调用示例(概念描述):
- 普通查询:POST
/api/memory/recall,body 包含query、可选tags、memoryType、limit、sessionId。
章节来源
- agent/src/memory/routes.js#L149-L199
- agent/src/memory/service.js#L461-L740
- agent/src/memory/tags.js#L1-L63
/api/memory/manage(审查与压缩)
- 方法:POST
- 用途:review(计算价值分数并返回淘汰建议)、compact(淘汰低价值记忆)。
- 关键行为:
- review 输出所有记忆的价值分数,低于阈值的标记为候选淘汰。
- compact 实际执行淘汰,并维护 stats/version/updatedAt。
- 成功响应:
{ success: true, ... } - 业务失败:HTTP 400,
{ success: false, error }
调用示例(概念描述):
- 审查:POST
/api/memory/manage,body 包含action: "review"。 - 压缩:POST
/api/memory/manage,body 包含action: "compact"。
章节来源
/api/memory/embedding-config(记忆嵌入配置)
- GET:返回脱敏后的当前配置(隐藏 apiKey,保留 hasApiKey)。
- POST:保存新的 embedding 配置,返回脱敏后的配置。
- 非法模式:返回 400,
{ success: false, error: "invalidEmbeddingMode" }。
章节来源
/api/memory/test-embedding(记忆嵌入连通性测试)
- 方法:POST
- 用途:用临时配置调用一次 embedQuery,返回实际维度,用于验证远端向量服务连通性。
- 超时保护:默认 8 秒,超时返回 400,
{ success: false, error: "embedding_timeout" }。
章节来源
/api/memory/vector-status(向量缓存状态)
- 方法:GET
- 用途:返回向量缓存是否 stale、已索引条数等只读状态。
- 成功响应:
{ success: true, ...data } - 失败响应:HTTP 400,
{ success: false, error }
章节来源
/api/memory/reindex(重建向量缓存)
- 方法:POST
- 用途:显式为全部记忆重建向量缓存,模型变更后或首次启用向量档后调用一次。
- 行为:若向量通道关闭则返回 skipped;若读取失败返回 400;后台失败会记录日志但整体仍可报告部分成功。
章节来源
关于 /api/memory/add、/api/memory/query、/api/memory/tags、/api/memory/tier
- 代码中的记忆业务入口是
/api/memory/store、/api/memory/recall、/api/memory/manage、/api/memory/embedding-config、/api/memory/test-embedding、/api/memory/vector-status、/api/memory/reindex。 - 扩展端工具层将
store、recall、manage映射到对应端点;inject由系统提示词分级注入直接调用。 - 因此,“添加记忆”应使用
/api/memory/store(action=add),“查询记忆”应使用/api/memory/recall,“标签管理”通过 recall 的 tags 参数与 manage 的 review/compact 配合,“层级管理”通过 embedding-config 与 tier 判定逻辑控制。
章节来源
RAG 检索端点
RAG 路由仅在 RAG 依赖可用时按需加载,所有受保护端点需 Bearer Token。
/api/rag/search(跨知识库检索)
- 方法:POST
- 用途:跨多个知识库执行语义检索;未指定 collectionIds 时搜索全部启用库。
- 参数:
collectionIds:数组,显式指定要检索的知识库 ID。query:检索文本。topK:返回结果数量预算。threshold:语义阈值。
- 行为:
- 显式 IDs 原样放行,即使库被停用也可检索(@ 手动引用链路)。
- 未指定 IDs 时跳过 disabled 库。
- 多库时 topK 配额按库均分,保证每个被引用的库都有结果。
- 成功响应:
{ success: true, results, total, hasContext, fallback } - 业务失败:HTTP 400,
{ success: false, error, code? }
调用示例(概念描述):
- 跨库检索:POST
/api/rag/search,body 包含collectionIds、query、topK、threshold。
章节来源
/api/rag/collections/{id}/search(单库检索)
- 方法:POST
- 用途:对单个知识库执行检索。
- 参数:
query、topK、threshold。 - 成功响应:
{ success: true, results, total, hasContext, fallback }
章节来源
/api/rag/collections(知识库管理)
- GET:列出所有知识库(脱敏 embeddingConfig)。
- POST:创建知识库。
- PUT:更新名称/描述/向量配置;向量空间变更自动触发后台重建。
- DELETE:删除知识库。
- POST
{id}/toggle:启用/停用知识库。 - GET
{id}/stats:文档数/分块数统计。 - GET
{id}/documents:文档列表。 - DELETE
{id}/documents/{docId}:删除文档。
章节来源
/api/rag/collections/{id}/ingest(文档导入)
- 方法:POST
- 用途:导入 text/file/url 三种类型文档,同步执行;进度可通过
/ingest/status轮询。 - 参数:
type、metadata、chunkConfig,以及按类型区分的 content/path/url。 - 成功响应:
{ success: true, ... } - 不支持类型:HTTP 400,
{ success: false, error: "unsupportedType", code: "unsupportedType" }
章节来源
/api/rag/collections/{id}/ingest/status(导入进度)
- 方法:GET
- 用途:轮询导入进度快照;无任务时 progress 为 null。
章节来源
/api/rag/status、/api/rag/test-embedding、/api/rag/install、/api/rag/detect
/api/rag/status:返回 available 与 install 状态。/api/rag/test-embedding:测试远端向量服务连通性,返回 mode/model/dimensions。/api/rag/install:触发白名单依赖安装。/api/rag/detect:重新检测 RAG 依赖可用性。
章节来源
混合检索引擎
混合检索由两条通道组成:
- 语义通道:使用 embeddingProvider.embedQuery 生成查询向量,再通过向量存储检索候选。
- 关键词通道:自建中英文匹配,英文/数字按词边界匹配,中文取最长命中片段;高频单元剔除;命中 chunk 保底分 + 单元加分。
- 重排序:RRF(Reciprocal Rank Fusion),关键词与向量各排各的名次,按
1/(60 + rank)合并,不比较绝对分数。
flowchart TD
Start(["开始检索"]) --> Embed["生成查询向量"]
Embed --> VectorSearch["向量检索 topK*2"]
VectorSearch --> KeywordBoost["关键词命中增强"]
KeywordBoost --> Threshold["阈值过滤"]
Threshold --> Empty{"结果为空?"}
Empty --> |否| Return["返回 topK 结果"]
Empty --> |是| Fallback["旁路探测放宽阈值"]
Fallback --> FallbackEmpty{"放宽后为空?"}
FallbackEmpty --> |否| Return
FallbackEmpty --> |是| NoResult["返回空结果"]
图表来源
章节来源
向量嵌入生成
- 本地模式:默认使用 Xenova/bge-small-zh-v1.5,512 维,经 transformers 本地运行。
- 远端模式:OpenAI 兼容端点,支持连通性测试并返回实际维度。
- 记忆侧与 RAG 侧共用 embedding 工厂,但记忆侧额外支持 lazy backfill 与 backfillVectors 重建。
章节来源
- agent/README.zh-CN.md#L483-L486
- agent/src/rag/routes.js#L148-L163
- agent/src/memory/service.js#L194-L212
文档分块策略
- 默认 chunkSize=400,overlap=80,separator='\n\n'。
- 先按段落切,再合并到接近 chunkSize;单段超长强制按字符切;硬上限 500 字符。
- 返回 chunks 包含 startPos/endPos,为 BM25 混合检索预留。
章节来源
索引构建流程
- 文档解析:text/md/json/csv/html/pdf/office 等格式由对应 parser 输出纯文本。
- 分块:chunker 按策略切分。
- 向量化:embeddingProvider 生成向量。
- 存储:VectraStore 使用 LocalIndex,beginUpdate/endUpdate 事务包裹逐条 upsertItem,失败 cancelUpdate。
- 重建:向量空间或分块参数变更时后台自动重建,临时目录重放 → 原子换入。
章节来源
依赖关系分析
记忆与 RAG 模块之间的耦合关系如下:
- server.js 负责认证与通用路由,不关心具体业务。
- memory/routes.js 依赖 service.js、tags.js、tier.js、embedding-config.js。
- rag/routes.js 依赖 manager.js、embedding/index.js、errors.js、detect.js、install.js。
- searcher.js 依赖 config.js、errors.js、keyword-match.js。
graph LR Server["server.js"] --> MemoryRoutes["memory/routes.js"] Server --> RagRoutes["rag/routes.js"] MemoryRoutes --> MemoryService["memory/service.js"] MemoryService --> Tags["memory/tags.js"] MemoryService --> Tier["memory/tier.js"] RagRoutes --> Searcher["rag/searcher.js"] Searcher --> Config["rag/config.js"] Searcher --> Errors["rag/errors.js"]
图表来源
- agent/src/server.js#L417-L548
- agent/src/memory/routes.js#L4-L11
- agent/src/rag/routes.js#L22-L26
- agent/src/rag/searcher.js#L11-L13
章节来源
- agent/src/server.js#L417-L548
- agent/src/memory/routes.js#L4-L11
- agent/src/rag/routes.js#L22-L26
- agent/src/rag/searcher.js#L11-L13
性能考虑
- 记忆侧:
- 向量嵌入调用带 8 秒超时,失败降级到关键词通道。
- 懒补向量不 await,避免每次 store 增加网络往返。
- recall 分三阶段:锁内只读、锁外补齐、锁内收尾,避免外部嵌入拖垮全进程。
- 标签在有查询时仅做名次加成,避免三个硬门槛叠加导致误杀。
- RAG 侧:
- 关键词扫描限制 KEYWORD_SCAN_LIMIT,超过则跳过关键词通道防止大库卡顿。
- 旁路探测放宽阈值区分“无数据”与“被过滤”。
- 多库检索 topK 按库均分,避免高得分库垄断结果。
- 通用:
- MAX_BODY_SIZE 限制 JSON body 大小。
- 流式上传支持二进制,避免 base64 膨胀。
- 认证冷却与操作防重入,防止 DoS。
章节来源
- agent/src/memory/routes.js#L13-L14
- agent/src/memory/service.js#L174-L187
- agent/src/memory/service.js#L461-L740
- agent/src/rag/searcher.js#L17-L21
- agent/src/server.js#L132-L136
- agent/src/server.js#L792-L800
故障诊断指南
常见错误与处理方式:
- 401 未认证:缺少 Authorization: Bearer <token>。
- 403 无效 Token:Token 校验失败。
- 400 业务错误:参数缺失、JSON 解析失败、Multipart 解析失败、RAG 不支持类型、记忆注入模式拦截等。
- 404 未知路径:记忆端点未匹配或 RAG 路径未匹配。
- 500 内部错误:服务器异常兜底。
- embedding_timeout:向量服务响应超时,记忆侧自动降级关键词通道。
- vector_status_failed:向量状态查询失败。
- invalidEmbeddingMode:embedding 模式非法。
- rebuild recovery scan failed:RAG 重建恢复扫描失败。
排查步骤:
- 确认 Bearer Token 是否正确。
- 检查请求体是否为合法 JSON。
- 对于 RAG 导入,确认 type 是否在 text/file/url 中。
- 对于记忆写入,确认 action/type/content/importance 是否符合要求。
- 对于向量相关错误,检查 embedding-config 与 test-embedding 返回值。
- 查看进程日志中的
[Memory] route error、[RAG] route error、[RAG] rebuild recovery scan failed等关键字。
章节来源
- agent/src/server.js#L417-L424
- agent/src/memory/routes.js#L188-L191
- agent/src/rag/routes.js#L68-L79
- agent/src/rag/routes.js#L31-L34
结论
记忆管理与 RAG 检索共同构成 AI 助手的核心知识能力:记忆用于短期对话上下文之外的长期事实与摘要,RAG 用于结构化知识库的语义检索。两者都强调:
- 可扩展的嵌入提供者(本地/远端)。
- 稳健的错误降级(向量失败不破坏关键词通道)。
- 清晰的 API 契约(认证、CORS、JSON 响应、错误码)。
- 可观测的状态(vector-status、rag/status、ingest/status)。
在实际使用中,建议:
- 首次启用向量通道后调用
/api/memory/reindex重建缓存。 - 使用
/api/rag/test-embedding验证远端向量服务连通性与维度。 - 合理设置 topK 与 threshold,平衡召回率与精确率。
- 定期使用
/api/memory/manage?action=compact清理低价值记忆。
附录:API 参考
记忆管理端点
| 方法 | 路径 | 说明 | 主要参数 | 成功响应 | 失败响应 |
|---|---|---|---|---|---|
| POST | /api/memory/store | 添加/更新/删除记忆 | action, type, content, memoryId, tags, importance, sourceSessionId | { success: true, message, memory/action/stats } | 400 { success: false, error, code? } |
| POST | /api/memory/recall | 查询记忆 | query, tags, memoryType, limit, sessionId | { success: true, message, results, total, query, tier, vectorMatched } | 400 { success: false, error } |
| POST | /api/memory/manage | 审查/压缩 | action: review/compact | { success: true, ... } | 400 { success: false, error } |
| GET | /api/memory/embedding-config | 获取嵌入配置 | 无 | { success: true, config } | 400 { success: false, error } |
| POST | /api/memory/embedding-config | 保存嵌入配置 | mode, apiKey, modelName, dimensions | { success: true, config } | 400 { success: false, error } |
| POST | /api/memory/test-embedding | 测试嵌入连通性 | mode, apiKey, modelName, dimensions | { success: true, dimensions } | 400 { success: false, error } |
| GET | /api/memory/vector-status | 向量缓存状态 | 无 | { success: true, ...data } | 400 { success: false, error } |
| POST | /api/memory/reindex | 重建向量缓存 | 无 | { success: true, indexed/skipped } | 400 { success: false, error } |
RAG 检索端点
| 方法 | 路径 | 说明 | 主要参数 | 成功响应 | 失败响应 |
|---|---|---|---|---|---|
| POST | /api/rag/search | 跨知识库检索 | collectionIds, query, topK, threshold | { success: true, results, total, hasContext, fallback } | 400 { success: false, error, code? } |
| POST | /api/rag/collections/{id}/search | 单库检索 | query, topK, threshold | { success: true, results, total, hasContext, fallback } | 400 { success: false, error, code? } |
| GET | /api/rag/collections | 列出知识库 | 无 | { success: true, collections } | 400 { success: false, error, code? } |
| POST | /api/rag/collections | 创建知识库 | name, description, embeddingConfig | { success: true, collection } | 400 { success: false, error, code? } |
| PUT | /api/rag/collections/{id} | 更新知识库 | name, description, embeddingConfig, chunkConfig | { success: true, collection } | 400 { success: false, error, code? } |
| DELETE | /api/rag/collections/{id} | 删除知识库 | 无 | { success: true, ... } | 400 { success: false, error, code? } |
| POST | /api/rag/collections/{id}/toggle | 启用/停用 | 无 | { success: true, ... } | 400 { success: false, error, code? } |
| GET | /api/rag/collections/{id}/stats | 统计信息 | 无 | { success: true, stats } | 400 { success: false, error, code? } |
| POST | /api/rag/collections/{id}/ingest | 导入文档 | type, metadata, chunkConfig, content/path/url | { success: true, ... } | 400 { success: false, error, code? } |
| GET | /api/rag/collections/{id}/ingest/status | 导入进度 | 无 | { success: true, progress } | 400 { success: false, error, code? } |
| GET | /api/rag/collections/{id}/documents | 文档列表 | 无 | { success: true, documents } | 400 { success: false, error, code? } |
| DELETE | /api/rag/collections/{id}/documents/{docId} | 删除文档 | 无 | { success: true, ... } | 400 { success: false, error, code? } |
| GET | /api/rag/status | RAG 能力与安装状态 | 无 | { success: true, available, install } | 400 { success: false, error, code? } |
| POST | /api/rag/test-embedding | 测试远端向量服务 | mode, apiKey, modelName, dimensions | { success: true, mode, model, dimensions } | 400 { success: false, error, code? } |
| POST | /api/rag/install | 安装 RAG 依赖 | 无 | { success: true, started } | 400 { success: false, error, code? } |
| POST | /api/rag/detect | 重新检测 RAG 依赖 | 无 | { success: true, available } | 400 { success: false, error, code? } |
章节来源