지식 그래프
GraphMemoryService는 다른 형태의 메모리입니다. 텍스트 항목 더미 대신 사용자(엔티티, 엔티티에 연결된 사실("관찰"), 엔티티 간의 유형화된 관계)의 지식 그래프를 저장하고 이 모든 것을 이중 시간적으로 추적합니다. 이것은 Mindfulness-with-Mia 예시 및 실시간 메모리 페이지의 백엔드입니다.
다른 백엔드와 동일한 MemoryService 트레이트를 구현하므로 에이전트에 동일한 방식으로 삽입되지만, 그 위에 더 풍부한 그래프 API를 노출합니다.
데이터 모델
Entity "Alice" (type: person)
├─ observation: "prefers email over phone" valid_from 2026-06-01
├─ observation: "timezone is CET" valid_from 2026-06-10
└─ relation: Alice ──works_at──▶ "Acme"
Entity— 자유 형식entity_type를 가진 이름 있는 것(사람, 장소, 선호도, 주제).Observation— 안정적인id와valid_from타임스탬프를 가진 엔티티에 연결된 하나의 사실.Relation— 두 엔티티(source ──relation_type──▶ target) 사이의 유형화된 엣지, 예:Alice ──works_at──▶ Acme.
또한 큐레이션된 그래프와 별도로 원시 턴을 기록하는 에피소드 저장소(kg_episodic)가 있으므로 대본과 정제된 모델을 모두 유지할 수 있습니다.
이중 시간적인 이유
모든 관찰과 관계는 두 시간 축을 따라 추적됩니다.
- 유효 시간 — 세상에서 사실이 참이었던 시점(
valid_from→valid_to). - 수집 시간 — 시스템이 그것을 학습한 시점.
사실이 변경될 때, 이전 사실은 삭제되지 않습니다. 무효화(valid_to가 설정됨)되고 새로운 사실이 추가됩니다. 이는 그래프가 *"사용자의 현재 선호도는 무엇인가?"*라는 질문에 *"이전에는 무엇이었는가?"*를 잃지 않고 답할 수 있음을 의미합니다. 대체된 사실은 현재를 덮어쓰는 대신 기록에 남아 있습니다. 이는 몇 달 동안 신뢰할 수 있는 메모리에 정확히 필요한 것입니다.
kg.invalidate_observation(old_id).await?; // mark a fact no longer valid
kg.invalidate_relation(old_id).await?; // mark an edge no longer valid
생성하기
graph-memory는 SQLite 기반이므로 파일(또는 테스트용 인메모리)입니다.
use adk_memory::GraphMemoryService;
use std::sync::Arc;
let kg = GraphMemoryService::new("sqlite://mia-memory.db").await?;
kg.migrate().await?; // idempotent schema setup
let kg = Arc::new(kg);
그래프에 쓰기
use adk_memory::{CreateEntityInput, CreateRelationInput};
kg.create_entities("coach", "alice", vec![CreateEntityInput {
name: "Alice".into(),
entity_type: "person".into(),
observations: vec!["prefers morning sessions".into(), "goal: run a 10k".into()],
}]).await?;
kg.create_relations("coach", "alice", vec![CreateRelationInput {
source: "Alice".into(), relation_type: "training_for".into(), target: "10k race".into(),
}]).await?;
// add facts to an existing entity later
kg.add_observations("coach", "alice", /* entity */ "Alice", vec!["timezone is CET".into()]).await?;
엔티티 생성은 upsert입니다. 알려진 엔티티를 다시 생성하면 중복하는 대신 해당 유형과 타임스탬프가 업데이트됩니다.
다시 읽기
트레이트의 search 외에 세 가지 리콜 형태:
// 1. Token-scored relevance search → entities + their relations + a score
let hits = kg.search_nodes("coach", "alice", "what is she training for?", 5).await?;
// 2. Fetch specific entities by name
let nodes = kg.open_nodes("coach", "alice", &["Alice".into()]).await?;
// 3. The whole graph (small graphs / debugging)
let graph = kg.read_graph("coach", "alice").await?;
프로필 카드
에이전트의 핵심 기능: profile_card는 사용자가 누구인지에 대한 간결하고 현재의 요약(가장 최근에 업데이트된 엔티티와 유효한 관찰)을 렌더링하여 세션 시작 시 시스템 프롬프트에 주입할 준비를 합니다.
let card = kg.profile_card("coach", "alice").await?;
// → a short text block: "Alice (person): prefers morning sessions; goal: run a 10k…"
그래프가 커져도 프롬프트가 작게 유지되도록 예산으로 크기를 제한합니다.
let kg = GraphMemoryService::new(url).await?
.with_profile_budget(/* entities */ 12, /* observations per entity */ 5);
에이전트가 큐레이션하도록 하기
프로덕션에서 create_entities를 수동으로 호출하는 경우는 거의 없습니다. 대신 에이전트에게 학습하면서 그래프에 쓸 도구를 제공합니다. 위의 호출에 직접 매핑되고 adk-tool에 포함된 remember 및 relate에 대해서는 도구 및 에이전트를 참조하십시오.
다음: 도구 및 에이전트 →