Behaviour for combined entity and relationship extraction in GraphRAG.
A GraphExtractor extracts both entities and relationships in a single pass, which is more efficient than separate extractors when using LLMs.
Built-in Implementations
Arcana.Graph.GraphExtractor.LLM- LLM-based extraction (default)
Configuration
Configure your graph extractor in config.exs:
# Combined extractor (efficient, 1 LLM call per chunk):
config :arcana, :graph,
extractor: Arcana.Graph.GraphExtractor.LLM
# Or configure separately (flexible, 2 LLM calls per chunk):
config :arcana, :graph,
entity_extractor: Arcana.Graph.EntityExtractor.NER,
relationship_extractor: Arcana.Graph.RelationshipExtractor.LLMWhen extractor is set, it takes priority over separate extractors.
Implementing a Custom Extractor
Create a module that implements this behaviour:
defmodule MyApp.CustomExtractor do
@behaviour Arcana.Graph.GraphExtractor
@impl true
def extract(text, opts) do
# Extract entities and relationships together
entities = [%{name: "Entity", type: :concept}]
relationships = [%{source: "A", target: "B", type: "RELATED"}]
{:ok, %{entities: entities, relationships: relationships}}
end
endOutput Format
Extractors must return a map with:
:entities- List of entity maps with:name,:type, and optional:description:relationships- List of relationship maps with:source,:target,:type, and optional:descriptionand:strength
Summary
Callbacks
Extracts entities and relationships from text in a single pass.
Functions
Extracts graph data using the configured extractor.
Callbacks
Functions
Extracts graph data using the configured extractor.
The extractor can be:
- A
{module, opts}tuple where module implements this behaviour A function
(text, opts) -> {:ok, result} | {:error, reason}nilto skip extraction (returns empty result)
Examples
# With module
extractor = {Arcana.Graph.GraphExtractor.LLM, llm: my_llm}
{:ok, result} = GraphExtractor.extract(extractor, text)
# With inline function
extractor = fn text, _opts ->
{:ok, %{entities: [], relationships: []}}
end
{:ok, result} = GraphExtractor.extract(extractor, text)