Rag.GraphStore behaviour (rag v0.3.4)
View SourceBehaviour for knowledge graph storage backends.
Supports entity-relationship storage for GraphRAG patterns. GraphRAG extends traditional RAG by:
- Extracting entities and relationships from text
- Building a knowledge graph
- Detecting communities via graph algorithms
- Generating hierarchical summaries
- Using graph structure for contextual retrieval
Architecture
The GraphStore provides operations for:
- Node operations: Create and retrieve entities with embeddings
- Edge operations: Model relationships between entities
- Graph traversal: Navigate relationships (BFS/DFS)
- Vector search: Find similar entities via embeddings
- Community operations: Cluster entities and generate summaries
Usage
# Initialize store with your repo
store = %Rag.GraphStore.Pgvector{repo: MyApp.Repo}
# Create entities
{:ok, alice} = GraphStore.create_node(store, %{
type: :person,
name: "Alice",
properties: %{role: "engineer"},
embedding: [0.1, 0.2, ...],
source_chunk_ids: [1, 2]
})
{:ok, bob} = GraphStore.create_node(store, %{
type: :person,
name: "Bob",
properties: %{role: "manager"},
embedding: [0.3, 0.4, ...],
source_chunk_ids: [3]
})
# Create relationship
{:ok, edge} = GraphStore.create_edge(store, %{
from_id: alice.id,
to_id: bob.id,
type: :reports_to,
weight: 1.0
})
# Find neighbors
{:ok, neighbors} = GraphStore.find_neighbors(store, alice.id, limit: 10)
# Traverse graph
{:ok, nodes} = GraphStore.traverse(store, alice.id, max_depth: 2)
# Vector search
{:ok, similar} = GraphStore.vector_search(store, query_embedding, limit: 5)
# Create community
{:ok, community} = GraphStore.create_community(store, %{
level: 0,
entity_ids: [alice.id, bob.id],
summary: "Engineering team"
})Implementation
To implement a custom GraphStore backend:
defmodule MyGraphStore do
@behaviour Rag.GraphStore
defstruct [:config]
@impl true
def create_node(store, node_attrs) do
# Implementation
end
# ... implement other callbacks
end
Summary
Callbacks
Create a community (cluster) of related entities.
Create a new relationship (edge) between entities.
Create a new entity (node) in the graph.
Find neighboring entities connected by edges.
Get all entities belonging to a community.
Retrieve an entity by ID.
Traverse the graph from a starting entity.
Update the summary of a community.
Search for entities by embedding similarity.
Functions
Convenience function to create a community using the store's implementation.
Convenience function to create an edge using the store's implementation.
Convenience function to create a node using the store's implementation.
Convenience function to find neighbors using the store's implementation.
Convenience function to get community members using the store's implementation.
Convenience function to get a node using the store's implementation.
Convenience function to traverse the graph using the store's implementation.
Convenience function to update community summary using the store's implementation.
Convenience function to perform vector search using the store's implementation.
Types
@type community() :: %{ id: any(), level: non_neg_integer(), summary: String.t() | nil, entity_ids: [any()] }
Callbacks
@callback create_community(store :: struct(), community :: map()) :: {:ok, community()} | {:error, term()}
Create a community (cluster) of related entities.
Parameters
store- The graph store implementationcommunity- Map with community attributes (level, entity_ids, summary)
Returns
{:ok, community}- The created community{:error, reason}- If creation fails
Create a new relationship (edge) between entities.
Parameters
store- The graph store implementationedge- Map with edge attributes (from_id, to_id, type, weight, properties)
Returns
{:ok, edge}- The created edge with assigned ID{:error, reason}- If creation fails
@callback create_node(store :: struct(), node :: map()) :: {:ok, graph_node()} | {:error, term()}
Create a new entity (node) in the graph.
Parameters
store- The graph store implementationnode- Map with entity attributes (type, name, properties, embedding, source_chunk_ids)
Returns
{:ok, node}- The created node with assigned ID{:error, reason}- If creation fails
@callback find_neighbors(store :: struct(), node_id :: any(), opts :: keyword()) :: {:ok, [graph_node()]} | {:error, term()}
Find neighboring entities connected by edges.
Parameters
store- The graph store implementationnode_id- The starting entity IDopts- Options::limit- Maximum number of neighbors (default: 10):direction-:in,:out, or:both(default: :both):edge_type- Filter by edge type (optional)
Returns
{:ok, [node]}- List of neighboring entities{:error, reason}- If query fails
@callback get_community_members(store :: struct(), community_id :: any()) :: {:ok, [graph_node()]} | {:error, term()}
Get all entities belonging to a community.
Parameters
store- The graph store implementationcommunity_id- The community ID
Returns
{:ok, [node]}- List of entities in the community{:error, :not_found}- If community doesn't exist
@callback get_node(store :: struct(), id :: any()) :: {:ok, graph_node()} | {:error, :not_found}
Retrieve an entity by ID.
Parameters
store- The graph store implementationid- The entity ID
Returns
{:ok, node}- The entity if found{:error, :not_found}- If entity doesn't exist
@callback traverse(store :: struct(), start_id :: any(), opts :: keyword()) :: {:ok, [graph_node()]} | {:error, term()}
Traverse the graph from a starting entity.
Supports breadth-first search (BFS) and depth-first search (DFS).
Parameters
store- The graph store implementationstart_id- Starting entity IDopts- Options::max_depth- Maximum traversal depth (default: 2):algorithm-:bfsor:dfs(default: :bfs):limit- Maximum nodes to return (optional)
Returns
{:ok, [node]}- List of reachable entities with depth info{:error, reason}- If traversal fails
@callback update_community_summary( store :: struct(), community_id :: any(), summary :: String.t() ) :: {:ok, community()} | {:error, term()}
Update the summary of a community.
Used after generating community summaries via LLM.
Parameters
store- The graph store implementationcommunity_id- The community IDsummary- New summary text
Returns
{:ok, community}- The updated community{:error, :not_found}- If community doesn't exist
@callback vector_search(store :: struct(), embedding :: [float()], opts :: keyword()) :: {:ok, [graph_node()]} | {:error, term()}
Search for entities by embedding similarity.
Uses vector distance (L2) to find semantically similar entities.
Parameters
store- The graph store implementationembedding- Query embedding vectoropts- Options::limit- Maximum results (default: 10):type- Filter by entity type (optional)
Returns
{:ok, [node]}- List of similar entities ordered by distance{:error, reason}- If search fails
Functions
Convenience function to create a community using the store's implementation.
Convenience function to create an edge using the store's implementation.
@spec create_node( struct(), map() ) :: {:ok, graph_node()} | {:error, term()}
Convenience function to create a node using the store's implementation.
@spec find_neighbors(struct(), any(), keyword()) :: {:ok, [graph_node()]} | {:error, term()}
Convenience function to find neighbors using the store's implementation.
@spec get_community_members( struct(), any() ) :: {:ok, [graph_node()]} | {:error, term()}
Convenience function to get community members using the store's implementation.
@spec get_node( struct(), any() ) :: {:ok, graph_node()} | {:error, :not_found}
Convenience function to get a node using the store's implementation.
@spec traverse(struct(), any(), keyword()) :: {:ok, [graph_node()]} | {:error, term()}
Convenience function to traverse the graph using the store's implementation.
@spec update_community_summary(struct(), any(), String.t()) :: {:ok, community()} | {:error, term()}
Convenience function to update community summary using the store's implementation.
@spec vector_search(struct(), [float()], keyword()) :: {:ok, [graph_node()]} | {:error, term()}
Convenience function to perform vector search using the store's implementation.