Arcana.Agent.Searcher behaviour (Arcana v1.3.3)

View Source

Behaviour for search execution in the Agent pipeline.

The searcher retrieves relevant chunks from a knowledge base based on the query. This allows swapping Arcana's built-in pgvector search for any search backend.

Built-in Implementations

Implementing a Custom Searcher

defmodule MyApp.ElasticsearchSearcher do
  @behaviour Arcana.Agent.Searcher

  @impl true
  def search(question, collection, opts) do
    limit = Keyword.get(opts, :limit, 5)

    # Your Elasticsearch query
    case Elasticsearch.search(collection, question, limit: limit) do
      {:ok, hits} ->
        chunks = Enum.map(hits, &to_chunk/1)
        {:ok, chunks}
      {:error, reason} ->
        {:error, reason}
    end
  end

  defp to_chunk(hit) do
    %{
      id: hit["_id"],
      text: hit["_source"]["content"],
      metadata: hit["_source"]["metadata"],
      similarity: hit["_score"]
    }
  end
end

Using a Custom Searcher

Agent.new(question, repo: repo, llm: llm)
|> Agent.search(searcher: MyApp.ElasticsearchSearcher)
|> Agent.answer()

Using an Inline Function

Agent.search(ctx,
  searcher: fn question, collection, opts ->
    {:ok, my_search(question, collection, opts)}
  end
)

Chunk Format

The searcher must return chunks as maps with at least these fields:

  • :id - Unique identifier for the chunk
  • :text - The text content
  • :metadata - Optional metadata map
  • :similarity - Optional similarity score (0.0-1.0)

Summary

Callbacks

Searches for relevant chunks matching the question.

Callbacks

search(question, collection, opts)

@callback search(
  question :: String.t(),
  collection :: String.t(),
  opts :: keyword()
) :: {:ok, [map()]} | {:error, term()}

Searches for relevant chunks matching the question.

Parameters

  • question - The search query
  • collection - The collection name to search in
  • opts - Options passed to Agent.search/2, including:
    • :repo - The Ecto repo (for database-backed searchers)
    • :limit - Maximum chunks to return (default: 5)
    • :threshold - Minimum similarity threshold (default: 0.5)
    • Any other options passed to Agent.search/2

Returns

  • {:ok, chunks} - List of chunk maps with :id, :text, :metadata, :similarity
  • {:error, reason} - On failure