Arcana.Graph.CommunityDetector behaviour (Arcana v1.3.3)

View Source

Behaviour for community detection in GraphRAG.

Community detectors partition entities into groups based on their relationships. Arcana provides a built-in Leiden implementation, but you can implement custom detectors for different algorithms.

Built-in Implementations

Installation

To enable community detection, add leidenfold to your dependencies:

defp deps do
  [
    {:arcana, "~> 1.2"},
    {:leidenfold, "~> 0.2"}
  ]
end

Precompiled binaries are available for macOS (Apple Silicon) and Linux (x86_64, ARM64).

Configuration

Configure your community detector in config.exs:

# Default: Leiden algorithm (requires leidenfold)
config :arcana, :graph,
  community_detector: :leiden

# Disable community detection
config :arcana, :graph,
  community_detector: nil

# Custom module implementing this behaviour
config :arcana, :graph,
  community_detector: MyApp.LouvainDetector

# Custom module with options
config :arcana, :graph,
  community_detector: {MyApp.LouvainDetector, resolution: 0.5}

# Inline function
config :arcana, :graph,
  community_detector: fn entities, relationships, opts ->
    {:ok, my_detect(entities, relationships, opts)}
  end

Implementing a Custom Detector

Create a module that implements this behaviour:

defmodule MyApp.LouvainDetector do
  @behaviour Arcana.Graph.CommunityDetector

  @impl true
  def detect(entities, relationships, opts) do
    resolution = Keyword.get(opts, :resolution, 1.0)
    # Run Louvain algorithm...
    {:ok, communities}
  end
end

Community Format

Detectors must return communities as maps with:

  • :level - Hierarchy level (0 = finest, higher = coarser)
  • :entity_ids - List of entity IDs in this community

Summary

Callbacks

Detects communities in the entity graph.

Functions

Detects communities using the configured detector.

Callbacks

detect(entities, relationships, opts)

@callback detect(
  entities :: [map()],
  relationships :: [map()],
  opts :: keyword()
) :: {:ok, [map()]} | {:error, term()}

Detects communities in the entity graph.

Parameters

  • entities - List of entity maps with :id and :name
  • relationships - List of relationship maps with :source_id, :target_id, :strength
  • opts - Options passed from the detector configuration

Returns

  • {:ok, communities} - List of community maps
  • {:error, reason} - On failure

Functions

detect(fun, entities, relationships)

Detects communities using the configured detector.

The detector can be:

  • A {module, opts} tuple where module implements this behaviour
  • A function (entities, relationships, opts) -> {:ok, communities} | {:error, reason}

  • nil to skip community detection (returns empty list)

Examples

# With module
detector = {Arcana.Graph.CommunityDetector.Leiden, resolution: 1.0}
{:ok, communities} = CommunityDetector.detect(detector, entities, relationships)

# With inline function
detector = fn entities, _rels, _opts ->
  {:ok, [%{level: 0, entity_ids: Enum.map(entities, & &1.id)}]}
end
{:ok, communities} = CommunityDetector.detect(detector, entities, relationships)

# Skip detection
{:ok, []} = CommunityDetector.detect(nil, entities, relationships)