记忆

为你的代理提供一种超越单次对话生命周期的记忆。会话状态保存的是当前对话;记忆则是代理在每轮开始时读取、并在学习过程中写回的长期存储——因此下一次会话已经了解用户。

本节将从头开始介绍:ADK-Rust 提供的两种记忆类型、核心类型、后端、双时态知识图谱,以及如何将它们全部接入代理。

刚开始使用 ADK-Rust? 请先阅读简介会话与状态——记忆是持久化的会话对应物,而会话是临时的。

两种记忆

ADK-Rust 在同一个MemoryService trait 下提供两种互补的记忆模型,因此代理可以通过一个接口使用其中任意一种:

语义存储知识图谱
形态可搜索的文本条目集合实体、观察结果和类型化关系
召回对条目进行相似度 / 关键词搜索配置文件卡片 + 基于 token 评分的节点搜索
适用于“我们讨论了关于 X 的什么内容?”“关于此用户现在有什么事实?”
后端InMemory、SQLite、Postgres、Redis、MongoDB、Neo4jGraphMemoryService(SQLite,双时态)
页面概念 · 后端知识图谱

你不必进行全局选择——可以根据每个 agent 的需求,在基于记录的回忆或对用户的清晰、可查询模型之间进行选择。

心智模型

  Agent turn
     │  search_memory(query)         ← recall relevant context at turn start
     ▼
  adk_core::Memory                   ← the interface the agent sees
     │  (MemoryServiceAdapter bridges to…)
     ▼
  MemoryService                      ← add_session / search / delete_user …
     ├─ InMemoryMemoryService        (dev)
     ├─ Sqlite/Postgres/Redis/…      (semantic store)
     └─ GraphMemoryService           (bi-temporal knowledge graph)
  • MemoryService 是存储后端:它存储条目(或图节点),并回答 search
  • MemoryServiceAdapter 将其封装为 adk_core::Memory,作用域限定为 (app_name, user_id, project_id?),而这正是 agent 的 search_memory 实际调用的对象。
  • Runner 持有 Memory 并将其提供给 agent;memory tools 让 agent 可以主动搜索和整理记忆。

安装

# Semantic store — pick the backend you need
adk-memory = { version = "2.1.0", features = ["sqlite-memory"] }

# Bi-temporal knowledge graph
adk-memory = { version = "2.1.0", features = ["graph-memory"] }
功能添加内容
(默认)InMemoryMemoryService — 零配置,适用于开发
sqlite-memorySqliteMemoryService — 基于文件的语义存储
graph-memoryGraphMemoryService — 双时态知识图谱(SQLite)
database-memoryPostgresMemoryServicepgvector
redis-memoryRedisMemoryService
mongodb-memoryMongoMemoryService
neo4j-memoryNeo4jMemoryService

60 秒快速开始

存储几条记忆并搜索它们:

use adk_memory::{InMemoryMemoryService, MemoryService, MemoryEntry, SearchRequest};
use adk_core::Content;
use chrono::Utc;

# async fn run() -> anyhow::Result<()> {
let memory = InMemoryMemoryService::new();

memory.add_session("support", "alice", "s1", vec![
    MemoryEntry { content: Content::new("user").with_text("I prefer email over phone"),
                  author: "user".into(), timestamp: Utc::now() },
]).await?;

let hits = memory.search(SearchRequest {
    app_name: "support".into(), user_id: "alice".into(),
    query: "how should we contact this customer?".into(),
    ..Default::default()
}).await?;

for entry in hits.entries { println!("{:?}", entry.content); }
# Ok(()) }

在真实的代理中,你不需要手动调用 search —— 将服务附加到 Runner,让代理自行回忆和整理记忆。

接下来去哪里

  1. 概念 —— MemoryEntryMemoryService trait、搜索、项目范围限定和 GDPR 擦除。
  2. 后端 —— 六种存储、功能标志以及如何选择。
  3. 知识图谱 —— GraphMemoryService,以及双时间为何重要。
  4. 工具与代理 —— 将记忆接入代理;remember/relate 和记忆工具。