05-infrastructure-graph-relationships

Dec 7, 2025

Graph Relationship Schema

코드: lib/graph/relationships.ts

개요

FalkorDB에서 관계(엣지)를 생성하고 관리하기 위한 스키마와 헬퍼 함수입니다.

관계 분류

분류

생성 방식

예시

Implicit

자동 추론 (구조적 속성)

SAME_THREAD, SIMILAR_CONTENT

Explicit

LLM 추출

MENTIONS, ASSIGNED_TO

Implicit Relationships (암시적 관계)

구조적 속성에서 자동으로 추론되는 관계입니다.

엣지 레이블

Label

설명

강도(strength)

SAME_THREAD

같은 이메일 스레드

1.0 (확정)

SAME_SENDER

같은 발신자

0.8

SAME_ENTITY

같은 엔티티 언급

0.7

TEMPORAL_ADJACENT

시간적 인접

0.1~1.0 (시간 차이에 따라)

SIMILAR_CONTENT

내용 유사 (임베딩)

0.5~1.0 (유사도)

프로퍼티

// SAME_THREAD
(a)-[:SAME_THREAD {
  strength: 1.0,
  threadId: "thread-123",
  createdAt: "2025-01-01T00:00:00Z"
}]->(b)

// SIMILAR_CONTENT
(a)-[:SIMILAR_CONTENT {
  strength: 0.85,
  similarityScore: 0.85,
  createdAt: "2025-01-01T00:00:00Z"
}]->(b)

사용 예시

import { client, createImplicitRelationship } from '@/lib/graph';

// 같은 스레드 관계 생성
await createImplicitRelationship(client, {
  sourceId: 'mem-123',
  targetId: 'mem-456',
  type: 'SAME_THREAD',
  strength: 1.0,
  metadata: { threadId: 'thread-789' }
});

// 유사 내용 관계 생성
await createImplicitRelationship(client, {
  sourceId: 'mem-123',
  targetId: 'mem-999',
  type: 'SIMILAR_CONTENT',
  strength: 0.85,
  metadata: { similarityScore: 0.85 }
});

Explicit Relationships (명시적 관계)

LLM이 이메일 내용에서 추출한 관계입니다.

엣지 레이블

Label

설명

Source → Target

IS_PART_OF

A는 B의 일부

Task → Memory, Memory → Thread

MENTIONS

A가 B를 언급

Memory → Entity/Person

REFERS_TO

A가 B를 참조

Memory → Memory

FOLLOWS_UP

A는 B의 후속

Memory → Memory

CONTRADICTS

A와 B가 상충

Memory → Memory

UPDATES

A가 B를 갱신

Memory → Memory

ASSIGNED_TO

태스크 할당

Task → Person

INVOLVES

A에 B가 관련됨

Memory → Person

BELONGS_TO

A가 B에 속함

Memory → Thread

WORKS_AT

A가 B에서 근무

Person → Entity

PRODUCES

A가 B를 생산

Entity → Entity

프로퍼티

// MENTIONS
(m:Memory)-[:MENTIONS {
  confidence: 0.95,
  evidence: "The email mentions John Smith as the project lead",
  extractedAt: "2025-01-01T00:00:00Z"
}]->(p:Person)

// UPDATES
(new:Memory)-[:UPDATES {
  confidence: 0.9,
  evidence: "Meeting time changed from 2pm to 3pm",
  extractedAt: "2025-01-01T00:00:00Z"
}]->(old:Memory)

사용 예시

import { client, createExplicitRelationship } from '@/lib/graph';

// MENTIONS 관계 생성
await createExplicitRelationship(client, {
  sourceId: 'mem-123',
  targetId: 'person-456',
  type: 'MENTIONS',
  confidence: 0.95,
  evidence: 'The email mentions John Smith as the project lead'
});

// UPDATES 관계 생성
await createExplicitRelationship(client, {
  sourceId: 'mem-new',
  targetId: 'mem-old',
  type: 'UPDATES',
  confidence: 0.9,
  evidence: 'Meeting time changed from 2pm to 3pm'
});

엣지 인덱스

관계 쿼리 성능을 위한 인덱스입니다.

Label

Property

용도

SAME_THREAD

strength

강도 필터링

SAME_SENDER

strength

강도 필터링

SAME_ENTITY

strength

강도 필터링

TEMPORAL_ADJACENT

strength

강도 필터링

SIMILAR_CONTENT

strength

강도 필터링

SIMILAR_CONTENT

similarityScore

유사도 필터링

MENTIONS

confidence

신뢰도 필터링

INVOLVES

confidence

신뢰도 필터링

ASSIGNED_TO

confidence

신뢰도 필터링

BELONGS_TO

confidence

신뢰도 필터링

UPDATES

confidence

신뢰도 필터링

REFERS_TO

confidence

신뢰도 필터링

인덱스 초기화

import { client, initializeSchema, initializeEdgeIndexes } from '@/lib/graph';

// 노드 인덱스 초기화
await initializeSchema(client);

// 엣지 인덱스 초기화
const result = await initializeEdgeIndexes(client);
console.log(`Created ${result.created.length} edge indexes`);

쿼리 패턴

특정 타입의 관계 조회

-- 메모리에서 언급하는 모든 사람 (confidence >= 0.8)
MATCH (m:Memory {id: $memoryId})-[r:MENTIONS]->(p:Person)
WHERE r.confidence >= 0.8
RETURN p, r.confidence, r.evidence

관련 메모리 탐색

-- 같은 스레드의 다른 메모리들
MATCH (m:Memory {id: $memoryId})-[:SAME_THREAD]-(related:Memory)
RETURN related

-- 유사한 내용의 메모리들 (similarity >= 0.7)
MATCH (m:Memory {id: $memoryId})-[r:SIMILAR_CONTENT]-(related:Memory)
WHERE r.similarityScore >= 0.7
RETURN related, r.similarityScore
ORDER BY r.similarityScore DESC

사람 중심 탐색

-- 특정 사람이 관련된 모든 메모리
MATCH (p:Person {email: $email})<

설계 결정

왜 strength와 confidence를 분리했는가?

  • strength: 암시적 관계의 강도 (구조적으로 계산)

  • confidence: 명시적 관계의 LLM 추출 신뢰도

둘은 의미가 다르므로 분리하여 명확성 확보.

왜 MERGE 헬퍼를 제공하는가?

중복 관계 방지를 위해. 예를 들어, 같은 스레드의 두 메모리 사이에 SAME_THREAD 관계가 여러 번 생성되는 것을 방지.

// 중복 생성 방지
await mergeRelationship(client, {
  sourceId: 'mem-123',
  targetId: 'mem-456',
  type: 'SAME_THREAD',
  properties: { strength: 1.0, threadId: 'thread-789' }
});

다음 문서

  • 벡터 인덱스 - 임베딩 기반 유사도 검색 (예정)

  • TypeScript 관계 타입 - 타입 정의