你的 search index 已经是一个 agent 记忆系统 : 用于 Claude Code 的持久化 agent memory

作者:来自 Elastic Jeff Vestal

为你的人工智能代理使用Elasticsearch实现持久跨会话记忆:混合检索、知识图谱和跨设备交接。三条安装命令。

Elasticsearch 与行业领先的生成式 AI 工具和提供商具有原生集成。查看我们的网络研讨会,了解如何在 超越 RAG 基础 或使用 Elastic 向量数据库**构建生产就绪应用**。

为了为你的用例构建最佳搜索解决方案,可以启动一个**免费云试用,或立即在你的 本地机器**上尝试 Elastic。


当你需要 AI 代理的持久记忆时,一个常见的方案是使用专用的记忆层,例如专用的记忆编排服务和独立的向量数据库。这些都是真实的解决方案。但它们也意味着另一个服务、另一个 API、以及更多需要构建和维护的组件。如果 Elastic 搜索已经在你的技术栈中,你可能已经拥有所需的一切。

仅会话内记忆的问题

Claude Code agent 是无状态的。每个会话都从全新开始。你的 agent 不会记得昨天做出的决策,上周重构的文件,或者三天前标记的阻塞依赖。你可以在指向文件时让它读取文件,但读取文件并不等同于回忆相关上下文。

具体成本体现在以下几个方面:

  • 重新推导结论。 一个没有记住之前推理的 agent 会反复读取相同文件,重新检查相同权衡,有时甚至得出不同答案。开发者会在不同会话之间遇到不一致的 agent 行为,却无法理解原因。

  • 多设备摩擦。 在多台机器上工作的开发者对此感受尤其明显。如果没有跨设备记忆,切换机器意味着必须从头加载 agent 的上下文:执行 git pull,用 grep 搜索相关文件,并手动把项目状态粘贴进对话。这会在每一次交接中增加摩擦成本。

  • 跨会话上下文丢失。 agent 生成的最有价值内容 ------ 架构决策、阻塞依赖的任务 ID、方法变更的理由、解释为什么选择某条路径的上下文锚点 ------ 都存在于工作内存中,并在会话结束时消失。文件提交只记录了成果产物,并不记录推理过程。

常见的解决方案是使用专用的记忆层或独立的 向量数据库。这些都是可靠的工具。但如果你已经在运行 Elasticsearch,那么在你的技术栈中再添加一个服务可能会带来不必要的开销。

你的搜索索引已经在做什么

在查看 agent-memory 之前,有必要先说明 Elasticsearch 在不做任何自定义的情况下,已经为这个问题提供了什么能力。

  • 开箱即用的 Hybrid search Elasticsearch 结合了 BM25 词法评分与稠密的 vector searchsemantic_text 字段类型可以自动处理 embedding 生成。将字段映射为 semantic_text,指向一个 inference endpoint,你就可以在不自己管理 embedding 流水线的情况下获得混合检索能力。

  • 通过 ES|QL 实现查询表达能力。 在 Elasticsearch 中,你的 memory 是可以通过完整查询语言访问的文档。ES|QL 支持按类型、日期范围、agent ID、访问范围或任意组合进行过滤,同时支持聚合、时间函数以及 FUSE 多 retrieval 融合。ES|QL 是一门完整的查询语言,具备聚合与时间函数能力,这比大多数 vector store 提供的轻量级 metadata 过滤更强。不过一些专用 vector store 确实在查询表达能力上更灵活,但与该类别中常见的轻量过滤 API 相比差距最大。

  • 在语义评分之前进行 metadata 过滤。 按 agent 作用域隔离 memory、时间窗口过滤、基于类型过滤,这些都是 Elasticsearch 的标准查询能力。你不需要构建自定义逻辑,只需要组合已有原语。

  • 通过 DECAY 实现时间衰减。 在 hybrid recall 部分会详细说明,但系统会对最近的 memory 赋予更高权重,使其排名高于过时内容。这使用 ES|QL 中的 DECAY 函数。注意:DECAY 需要 Elasticsearch 9.3+ 或 Elasticsearch Serverless。请使用 interval literal 语法 ------ 45 days(而不是带引号的 "45d"),因为某些 Serverless 部署会拒绝带引号的形式。如果仍然遇到类型错误(third argument of [DECAY(...)] must be [time_duration]),可以使用 fallback 评分方式:EVAL final_score = _score / (1 + DATE_DIFF("day", created_at, NOW()) / 45.0)。该 fallback 会产生等价的时间衰减效果,并且适用于所有版本。

  • 你已经具备的运维能力。 监控、告警、索引生命周期管理、备份:这些在你的 Elasticsearch 部署中都已经存在。增加更多索引并不会带来新的运维面。

记忆存储的实际索引映射显示该模式非常简单:

bash 复制代码
`

1.  {
2.    "mappings": {
3.      "properties": {
4.        "memory_id":        { "type": "keyword" },
5.        "agent":            { "type": "keyword" },
6.        "type":             { "type": "keyword" },
7.        "category":         { "type": "keyword" },
8.        "title":            { "type": "text", "fields": { "keyword": { "type": "keyword" } } },
9.        "title_semantic":   { "type": "semantic_text", "inference_id": "jina-v5-embeddings" },
10.        "content":          { "type": "text" },
11.        "content_semantic": { "type": "semantic_text", "inference_id": "jina-v5-embeddings" },
12.        "tags":             { "type": "keyword" },
13.        "source":           { "type": "keyword" },
14.        "created_at":       { "type": "date" },
15.        "updated_at":       { "type": "date" },
16.        "access_scope":     { "type": "keyword" }
17.      }
18.    }
19.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

semantic_text 字段(title_semanticcontent_semantic)是 Jina v5 embeddings 存放的位置。Elasticsearch 在索引时通过 inference endpoint 处理 embedding 生成。你写入一个 memory document;embeddings 会被自动计算。在 Elasticsearch Serverless 上,semantic_text 默认通过 Elastic Inference Service 使用 Jina v5 text-small。

这里真正区分 Elasticsearch 的有两点:

  • 查询表达能力。 ES|QL 是一门完整的查询语言,而不是一个过滤 API。你可以在同一个查询中组合基于 embedding 的检索、精确匹配、时间衰减以及聚合。

  • 运维整合能力。 如果 Elasticsearch 已经在你的技术栈中,这只是一个索引,而不是一个新服务。其他向量数据库同样允许你定义 schema,但关键差异在于定义之后你能做什么,以及你是否引入了新的运维依赖。

agent-memory 架构

agent-memory 是让 Elasticsearch 能够作为 Claude Code 的 agent memory 使用的层。入口是一个叫 bridge 的 CLI。其背后有七个 Elasticsearch indices。

各组件如何组合如下:

Claude Code agent 与 Elasticsearch 的通信完全通过 bridge 命令行界面(CLI)完成。三个 hooks 会将 bridge 自动接入 agent 生命周期;agent 无需显式调用。当 Elasticsearch 可访问时,bridge 会直接写入。当离线时,写入会进入本地 fallback/outbox/ 队列,以 JSON 文件形式保存,bridge sync 会在下一次在线会话时通过 bulk API 批量写回。

bridge 之下,Elasticsearch 保存七个索引:agent-memory(决策、模式、上下文)、agent-messages(agent 间通信)、agent-tasks(任务生命周期)、agent-sessions(动作历史)、agent-status(心跳)、{agent}-entities(markdown 知识图谱)、以及 {agent}-entity-history(用于 diff 的时间序列快照)。bridge graph 命令(search、related、check-blockers、semantic-diff 和 gen-handoff、reconcile)运行在 entity 索引之上。

七个索引

索引 存储内容
agent-memory 决策、模式、上下文、反馈(记忆存储)
agent-messages agent 之间的类型化消息,支持线程与优先级
agent-tasks 任务生命周期:从创建到完成或失败
agent-sessions 会话级动作日志,可按 agent、时间范围或标签查询
agent-status 心跳记录:哪些 agent 处于活跃状态以及所在机器
{agent}-entities 将 markdown 文件作为可检索的知识图谱实体
{agent}-entity-history 实体状态的时间快照,用于做 temporal diff

Hook 集成

集成点在 hooks。三个 Claude Code hooks 将系统接入 normal agent 行为,而无需显式调用:

  • SessionStart :运行 bridge sync-memories 将自动 memory 文件同步到 Elasticsearch,并运行 bridge heartbeat 注册该 agent 处于活跃状态。

  • PostToolUse (在 Write、Edit、MultiEdit 时触发):在每一次 .md 写入时调用 bridge entity index-file。你的项目文件会在工作过程中持续被索引。

  • Stop :记录一个 session-end 事件到 agent-sessions

结果是:agent 不需要记得去更新 memory,它会自动发生。SessionStart 会对本地 memory 文件进行 hash,同步并且只重新索引发生变化的文件 ------ 未变化的文件会被跳过。首次 session sync(所有文件都是新的)会比后续 session 更慢。

离线队列

当 Elasticsearch 不可用时,写入不会失败,而是会进入 fallback/{agent}/outbox/,以 JSON 文件形式保存。bridge sync(在 SessionStart 时自动调用)会在连接恢复后通过 bulk API 清空队列。你可以离线工作,不会丢失任何数据。

读取操作(bridge recallbridge graph search)在 ES 不可用时会以非零退出码优雅失败,没有本地读取缓存。但 agent session 仍然可以正常继续,只是 memory 降级。fallback 队列没有自动大小限制;如果离线时间较长,可以使用 bridge sync --batch-size 100 来避免 bulk 请求过大。

bridge CLI 供 agent 直接使用的命令如下:

sql 复制代码
`

1.  # Store a decision with type and scope
2.  bridge remember decision "Use Jina v5 for all embedding inference" \
3.    --title "embedding model choice" \
4.    --tags "ml,infrastructure" \
5.    --scope shared

7.  # Recall with hybrid search (default)
8.  bridge recall "embedding model decisions"

10.  # Recall with keyword-only (exact term matching)
11.  bridge recall "Jina v5" --keyword

13.  # Knowledge graph search
14.  bridge graph search "blocked infrastructure projects" --types initiative --days 90

16.  # Generate a cross-device handoff payload
17.  bridge graph gen-handoff --hours 8

19.  # Surface stale blockers
20.  bridge graph check-blockers --stale-days 3

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

混合召回:记忆检索的实际工作方式

许多 agent memory 实现只使用单一的 vector lookup。查询输入后,通过 cosine similarity 找到最近邻结果并返回。这种方式在语义召回上有效,但在两种常见模式下会失败:精确词项匹配和时间新鲜度。

agent-memory 的 hybrid recall 使用了两种 fusion 策略。memory recall 查询使用 ES|QL 的 FUSE(Reciprocal Rank Fusion,k=60,ES|QL 默认值)。graph entity 查询使用 FUSE LINEAR 并显式设置权重 ------ 0.3 BM25 / 0.7 semantic ------ 因为 entity search 更依赖语义匹配。下面是来自 lib/memory.sh 的 memory recall 查询:

less 复制代码
`

1.  FROM agent-memory METADATA _id, _score, _index
2.  | FORK (
3.      WHERE (access_scope == "shared" OR access_scope == "kk-only" OR agent == "kk") 
4.        AND (content:"vector search" OR title:"vector search" OR tags:"vector search")
5.      | SORT _score DESC | LIMIT 50
6.  ) (
7.      WHERE (access_scope == "shared" OR access_scope == "kk-only" OR agent == "kk") 
8.        AND content_semantic:"vector search"
9.      | SORT _score DESC | LIMIT 50
10.  )
11.  | FUSE
12.  | EVAL final_score = _score * DECAY(created_at, NOW(), 45 days)
13.  | EVAL display = COALESCE(title, SUBSTRING(content, 1, 80))
14.  | SORT final_score DESC | LIMIT 5
15.  | KEEP memory_id, type, display, access_scope, agent

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

FORK 并行运行两种检索:第一条分支是在 title、content 和 tags 上进行 BM25 词法检索 ;第二条分支是在 content_semantic 字段上进行 语义检索FUSE 使用 Reciprocal Rank Fusion 将两个排序列表合并。DECAY 函数基于 created_at 应用时间权重。

为什么 hybrid 优于纯语义的 agent memory

关键词检索可以捕捉语义搜索遗漏的精确引用。如果 agent 存储了一条 memory:"task ID kk-task-20260428-deploy-blocker",那么对 "deploy blocker" 的语义查询会找到概念上相似的内容,但这个具体的 task ID 只会在 BM25 分支中获得较高排名。如果没有它,你只能得到概念,而无法得到需要的引用。

语义检索可以捕捉精确匹配遗漏的相关概念。一条 memory 标题是 "switched default chunking strategy to sentence-level for better recall on short queries",即使查询是 "chunking config",两者词面不重合,这条记录仍然相关。语义分支可以找到它,而仅靠关键词搜索无法做到。

BRIDGE_MEMORY_DECAY_WINDOW 变量(默认 45d)设置时间衰减函数的半衰期。今天写入的 memory 比 90 天前写入的 memory 得分更高(其他条件相同)。这反映了 agent memory 的实际使用方式:最近上下文几乎总是比旧上下文更相关,即使旧上下文在语义上更接近查询。

lib/graph.sh 中的 graph search 使用 FUSE LINEAR(而不是普通 FUSE),因为 entity recall 更依赖语义匹配而不是关键词精确匹配。下面是该查询:

sql 复制代码
`

1.  FROM kk-entities METADATA _id, _score, _index
2.  | FORK (
3.      WHERE MATCH(title, "vector search projects") OR MATCH(content, "vector search projects")
4.      | WHERE updated_at >= NOW() - 180 days
5.      | SORT _score DESC | LIMIT 20
6.  ) (
7.      WHERE MATCH(title_semantic, "vector search projects") OR MATCH(content_semantic, "vector search projects")
8.      | WHERE updated_at >= NOW() - 180 days
9.      | SORT _score DESC | LIMIT 20
10.  )
11.  | FUSE LINEAR WITH { "weights": { "fork1": 0.3, "fork2": 0.7 }, "normalizer": "minmax" }
12.  | SORT _score DESC | LIMIT 10
13.  | KEEP _id, entity_id, entity_type, title, status, priority, updated_at

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

The FUSE LINEAR 语法带有显式权重是你在 ES|QL 中调优 BM25 / 语义平衡的方式。将权重向 0 调整会获得更强的关键词精确匹配;向 1 调整会获得更强的语义泛化。

知识图谱层

来自一个正在运行的实例的数据:每个项目、决策以及被阻塞的依赖关系都跨会话进行跟踪;大约有 1,364 条关系边是从 frontmatter 字段(initiativeblocked_bydepends_on)解析出来的。这些数据来自一个 Kuchi Kopi agent 实例,它在两台笔记本电脑上已经持续运行了数个月。

需要先明确一点:这不是一个图数据库。遍历深度被限制在 2,没有 Cypher 查询语言或属性图模型,并且一致性完全依赖 frontmatter 的规范性。它本质上是一个可查询的实体层,拥有足够的关系数据来暴露 agent 工作中的阻塞项和差异。

这个索引所保存的内容,是 agent 自身随时间产生的工作记录(决策、项目状态以及被阻塞的依赖),而不是一个经过整理的外部事实或世界知识的 知识库。检索通过 embedding 相似度和 BM25 在这些工作记录上进行。

实体层是构建在 Elasticsearch 文档之上的知识图谱。每一个被监控目录中的 markdown 文件都会通过 PostToolUse hook 被索引为一个实体。实体 ID 采用 {agent}-{type}-{slug} 的格式,这使得重新 indexing 是幂等的。重写文件时,实体会在原地更新。关系边从三个 frontmatter 字段中提取:initiative(项目分组)、blocked_by(依赖关系)以及 depends_on(软依赖)。实体 ID 通过 {agent} 前缀进行命名空间隔离------不会检查跨 agent 的冲突,因此运行多个 agent 的团队需要确保 agent 标识符唯一。

图谱命令在这个索引之上运行:

bash 复制代码
`

1.  # Hybrid semantic search across all entities
2.  bridge graph search "infrastructure blockers"

4.  # Traverse relationships from a specific entity (depth 1 or 2)
5.  bridge graph related kk-initiative-platform --depth 2 --rel-type blocks

7.  # Surface stale blocked or waiting entities
8.  bridge graph check-blockers --stale-days 3

10.  # Diff entity state between two dates
11.  bridge graph semantic-diff 2026-04-01 2026-04-20

13.  # Generate a structured context payload for cross-device handoff
14.  bridge graph gen-handoff --hours 8

16.  # Remove ES entities whose source files no longer exist
17.  bridge graph reconcile

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

关系边是从 markdown 文件中的 frontmatter 字段(initiativeblocked_bydepends_on)推断出来的。这个图谱不需要单独的关系存储,它直接读取你已有的文档结构。

图谱之所以是连贯的,是因为 markdown 文件具有结构化 frontmatter,而系统会持续一致地读取这些结构。schema 纪律性是其可用性的关键。如果你的文件没有一致的 frontmatter 字段,图谱会退化为扁平的实体搜索。缺失或格式错误的 frontmatter 字段会导致关系边被静默跳过;实体仍然会被索引,但不会出现在图遍历中。运行 bridge graph reconcile 可以找出缺失关系的实体。实体删除不会级联,而 bridge graph reconcile 也会清理指向已删除实体的边。

从规模来看,这套系统已经在数百个实体、跨数月的实际使用中得到验证。Elasticsearch 理论上可以处理更大规模的数据,但 agent-memory 本身没有做过大规模压力测试。对于更大的实体集合,可以使用 --types--days 过滤器来限定遍历范围。

graph semantic-diff 命令是其中一个非常有用的应用。它用于比较两个日期之间的实体状态快照:新增实体、状态变化、新增阻塞工作以及已完成项目。在每周同步之前运行它,可以生成一个结构化的变更日志,而不需要逐条读取 session log。注意:如果请求的时间范围内没有实体快照,该命令会返回错误(Cannot iterate over null)。需要先运行 bridge entity index-all 来生成初始快照基线。

跨设备记忆在实践中的表现

我在出差笔记本上启动了一个 session,三天后在公司台式机上继续处理同一个项目,这两个公司机器上都在工作。agent 在一次 search round-trip 内就回忆起了相关 memory entries。没有等待 git pull。没有通过文件扫描来重建上下文。跨设备交接通过 Elasticsearch 完成。

原因如下:我在两台机器之间工作,而 Elasticsearch 可以从两端访问。共享 index 是唯一事实来源,而不是本地文件系统。agent 调用 bridge recall,并从共享 index 获取上下文,而不管是哪台机器存储的。

没有 agent-memory:Git repository 之外没有任何内容。agent 可以读取文件,但无法回忆上一轮 session 的推理过程、没有写入 commit 的决策、或者已经标记但尚未解决的阻塞依赖。

agent-memory:SessionStart hook 会运行 bridge sync-memories,读取 Claude Code 自动 memory 文件(~/.claude/projects/<cwd>/memory/*.md),对每个文件进行 hash,并只将发生变化的文件重新写入 Elasticsearch。本地 memory 文件在每台机器上都作为事实来源,而 bridge sync-memories 会将本地状态推送到 Elasticsearch。在另一台机器上未同步的更改,在切换时会被新机器的本地状态覆盖。来自两台设备的并发写入由 Elasticsearch 的 document versioning 正确处理。不会丢失数据,但每个 document 是 last write wins,因此应避免在两台机器同时编辑同一个 memory 文件。

需要如实说明:这依赖 Elasticsearch Serverless(或任何可被两台机器访问的 Elasticsearch 实例)。部署在 VPN 或防火墙后的自建 Elasticsearch 也可以工作,但连接性要求是真实存在的。这不是一个纯本地方案。

bridge graph gen-handoff 命令会生成一个结构化 JSON payload,包含时间窗口内更新的 entities、active blockers 和最近 session logs。使用可选的 --synthesize 参数时,会通过 Agent Builder agent 生成一段叙述性段落。该 payload 就是新 session 用来重建上下文而无需逐个读取文件的输入。

什么时候这是正确答案(以及什么时候不是)

这种方案在以下情况下效果很好:

  • Elasticsearch 已经在你的技术栈中。 在现有部署上增加 indices 代价很低,运维模型是熟悉的。

  • 查询表达能力很重要。 你希望用完整 query language 将 memory 当作数据来查询,而不是 vendor filter API。

  • 你的 agent 产出结构化 artifact。 带一致 frontmatter 的 markdown 文件让 knowledge graph 保持一致性。如果 agent 不产生结构化输出,这一层价值有限。

  • 你需要跨设备或跨 agent memory。 共享 Elasticsearch index 可以实现这一点,而不需要额外基础设施。

以下情况 purpose-built memory service 更优:

  • 你没有现成的 search infrastructure。 用 Elasticsearch 解决 memory 问题是合理的,但这是一个明显的基础设施投入。

  • 你希望纯语义 recall 且零 schema 管理。 专用 vector database service 会完全抽象 index mapping。如果你不想处理 mapping 和 fields,这种取舍是有价值的。

  • 你预期 schema 高频演进。 你控制的 schema 同时也是你维护的 schema。如果 memory 结构经常变化,index mapping 的迁移成本可能超过灵活性收益。托管服务通常会帮你处理 schema evolution。

  • 你需要低运维 SaaS。 Elasticsearch Serverless 已经显著缩小了差距,但仍然不是零运维。

诚实总结:agent-memory 不是通用答案。它是在你已经运行 Elasticsearch,并且不想在 AI 技术栈中再增加一个依赖时的正确答案。

开始使用

三条命令即可运行系统:

bash 复制代码
`

1.  git clone https://github.com/jeffvestal/agent-memory && cd agent-memory
2.  ./install.sh
3.  ./bridge status

`AI写代码

install.sh 会交互式引导你输入凭据(或读取已有的 .env),如果不存在则创建 Jina v5 语义 inference endpoint,创建所有七个索引并使用正确的 mappings,并安装 Claude Code hooks。它是幂等的(同一个操作执行一次和执行多次,结果都是一样的,不会产生额外副作用)。如果出错或者你添加了新机器,可以重新运行它。

在运行 installer 之前需要了解几件事:

  • Jina v5 inference endpoint :在自建 Elasticsearch 上,installer 会创建该 endpoint,但需要在 service_settings 中配置 Jina API key。在 Elasticsearch Serverless 上,Elastic Inference Service 会自动提供 Jina v5,不需要 API key;installer 会检测 Serverless 并跳过这一步。

  • Elasticsearch Serverless vs. 9.3+ :两者都可以使用。DECAY 函数和 FUSE 语法用于 recall queries,需要 Serverless 或 Elasticsearch 9.3+。

  • Dashboard import :Kibana dashboard(位于 setup/dashboards/)会在 .env 中设置 KIBANA_URL 时由 install.sh 自动导入。如果你跳过这一步,可以设置 KIBANA_URL 后重新运行 install.sh(它是幂等的)。

你需要:

  • 一个 Elasticsearch Serverless endpoint(或 Elasticsearch 9.3+)。

  • 一个具有 agent-* 索引权限的 API key。

  • 本地安装 jq(macOS 上可用 brew install jq)。

bridge status 确认连接之后,运行:

python 复制代码
`

1.  bridge entity index-all    # index existing markdown files
2.  bridge remember decision "First memory --- install confirmed working" --title "setup"
3.  bridge recall "install"    # confirm hybrid recall works

`AI写代码

然后把 hooks/settings.json.template 中的 hooks 添加到你的 Claude Code settings.json 中。从那一刻起,每次 session start、文件写入和 session end 都会自动更新 memory store。

完整源码(包括用于 memory analytics 的 Kibana dashboard)在这里:github.com/jeffvestal/...

可以直接在你的 agent 上试用。如果你遇到问题,或者把它扩展到其他 AI 框架,可以提交 issue 或 PR。

常见问题

什么是 agent memory,为什么 AI agent 需要它?

像 Claude Code 这样的 AI agent 是跨 session 无状态的:一旦 session 结束,它们不会保留之前的对话、决策或上下文。agent memory 是一个持久化存储系统,让 agent 可以跨 session 和设备回忆之前的推理、决策和项目上下文。没有它,agent 会反复重新推导结论,在多设备工作流中丢失上下文,并且无法在已有工作的基础上继续构建。

Elasticsearch 能否替代专用 vector database 来做 agent memory?

对于已经在使用 Elasticsearch 的团队来说,可以,而且还有明显优势。Elasticsearch 通过 semantic_text 字段提供 BM25 + 语义 hybrid search,通过 ES|QL 提供结构化 memory 查询能力、metadata 过滤以及时间衰减评分。代价是你需要自己管理 schema 和运维体系。如果你没有现成的 search infrastructure,专用 vector database 的托管抽象会更合适。

纯语义搜索只能匹配概念相似内容,但会遗漏精确引用:task ID、文件名、具体版本号等。纯关键词搜索可以捕捉精确匹配,但会遗漏相关概念。hybrid search(BM25 + Jina v5 dense vectors 通过 Reciprocal Rank Fusion 组合)可以同时覆盖两者。在实践中,这意味着无论是概念查询还是具体标识符查询,都能召回正确的 memory。

什么是 agent-memory 项目,如何安装?

agent-memory 是一个开源层,用于给 Claude Code agent 提供基于 Elasticsearch 的持久化跨 session、跨设备 memory。通过三条命令即可安装。installer 会自动创建 Elasticsearch indices 和 inference endpoint。

跨设备 memory 如何在多台机器之间工作?

在 session start 时,SessionStart hook 会运行 bridge sync-memories,将 Claude Code 的 auto-memory 文件同步到 Elasticsearch。由于多台机器连接的是同一个 Elasticsearch 实例,因此无论在哪台机器写入,都可以被统一检索。切换 laptop 时不需要 git pull 或手动重建上下文。agent 通过 bridge recall 从共享 index 获取上下文。

使用 Elasticsearch 作为 agent memory 系统有哪些限制?

主要限制包括:跨设备 memory 需要 Elasticsearch Serverless 或可网络访问的 cluster,因此不是纯本地方案。knowledge graph traversal 深度限制为 2。图谱一致性依赖 markdown frontmatter 的规范性,schema 不一致会降低质量。相比托管 memory SaaS,Elasticsearch 需要更多初始配置。在长时间离线情况下可以本地运行 session,并在恢复连接后用 bridge sync 手动同步,fallback queue 不会丢数据。导出或归档 memory 可以使用 bridge export --format ndjson 生成可用于 Elasticsearch bulk import 的文件。

BRIDGE_MEMORY_DECAY_WINDOW 是什么,它如何影响 recall?

BRIDGE_MEMORY_DECAY_WINDOW 定义了 memory recall score 的时间衰减半衰期,默认是 45d(45 天)。今天写入的 memory 比 90 天前写入的 memory 得分更高(其他条件相同)。这反映了 agent context 的实际特性:最近决策通常比旧决策更重要,即使旧内容在语义上更接近查询。你可以增大该窗口让旧 memory 更有竞争力,或者减小它以更强地强调新鲜度。

原文:Persistent memory for agents: Claude Code on Elasticsearch - Elasticsearch Labs

相关推荐
Elasticsearch1 小时前
使用 LangChain Deep Agents 框架与 Elasticsearch 进行系统性研究
elasticsearch
master3362 小时前
git仓库通过脚本完成多个远程仓库同步
大数据·git·elasticsearch
金融支付架构实战指南2 小时前
ES电商检索方案设计案例
大数据·elasticsearch·搜索引擎
Java 码思客19 小时前
【ElasticSearch从入门到架构师】第9章:ES 读写底层流程深度拆解
大数据·elasticsearch·搜索引擎
daad77721 小时前
记录一个zmq客户端的性能调优
大数据·elasticsearch·搜索引擎
就改了1 天前
Windows Elasticsearch 完整上手教程
大数据·windows·elasticsearch
就改了1 天前
ElasticsearchRestTemplate使用方法详解!!!
java·elasticsearch·springboot
阿维的博客日记1 天前
Elasticsearch 部署手册
大数据·elasticsearch
沪漂阿龙1 天前
Vector Store:FAISS、Chroma、Milvus、Qdrant、ES 怎么选?
人工智能·elasticsearch·架构·milvus·faiss