AshArcadic.Preparations.VectorSearch (AshArcadic v0.1.0)

Copy Markdown View Source

Read-action preparation that turns an Ash read into a vector search — dense kNN, sparse (learned-sparse / BM25-style) kNN, or hybrid fusion (dense/sparse/full-text arms). Attach it to a read action whose arguments carry the query data:

# dense (default kind)
read :semantic_search do
  argument :query_vector, {:array, :float}, allow_nil?: false
  argument :k, :integer, allow_nil?: false
  prepare {AshArcadic.Preparations.VectorSearch, index: :embedding}
end

# sparse
read :sparse_search do
  argument :query_tokens, {:array, :integer}, allow_nil?: false
  argument :query_weights, {:array, :float}, allow_nil?: false
  argument :k, :integer, allow_nil?: false
  prepare {AshArcadic.Preparations.VectorSearch, kind: :sparse, index: :sparse_embedding}
end

# hybrid — arms name the indexes/properties (developer config); the caller passes the values
read :hybrid_search do
  argument :query_vector, {:array, :float}, allow_nil?: false
  argument :query_tokens, {:array, :integer}, allow_nil?: false
  argument :query_weights, {:array, :float}, allow_nil?: false
  argument :text_query, :string, allow_nil?: false
  argument :k, :integer, allow_nil?: false
  prepare {AshArcadic.Preparations.VectorSearch,
           kind: :hybrid,
           arms: [{:dense, :embedding}, {:sparse, :sparse_embedding}, {:fulltext, :body}],
           fusion: :rrf}
end

Options:

  • :kind (default :dense) — :dense | :sparse | :hybrid.

  • :index (required for :dense/:sparse, atom) — the declared vector_index / sparse_vector_index name.
  • :arms (required for :hybrid) — a list (len ≥ 2) of {:dense, index} | {:sparse, index} | {:fulltext, property}. The full-text arm's property is an attribute with a host-created full-text index (there is no full-text DSL declaration — that is a later slice); the caller passes the :text_query argument. :fusion (:rrf default | :dbsf | :linear), :weights, :group_by, :group_size ride the fused output. A single :k argument bounds every arm and the fused result.

  • :allow_global? (default false) — permit a cross-tenant search when no tenant is resolved. The Ash action must ALSO permit the no-tenant read (multitenancy :allow_global/:bypass), else Ash rejects it upstream with TenantRequired.
  • :ef_search, :max_distance — dense only (sparse/fuse reject them); :group_by, :group_size — sparse pass-through.

It reads the query arguments, resolves the declared index metadata, validates a dense vector's length against the declared dimensions, and stashes the request onto the query context (:vector_search), which the data layer's set_context/3 copies onto %AshArcadic.Query{}. All failures are value-free (never echo a vector / tokens / weights / text value).

Summary

Functions

supports(opts)

Callback implementation for Ash.Resource.Preparation.supports/1.