Class: Parse::Retrieval::Reranker::Voyage

Inherits:
Base
  • Object
show all
Defined in:
lib/parse/retrieval/reranker/voyage.rb

Overview

Voyage AI cross-encoder reranker. Wraps POST /v1/rerank.

Takes a query plus a list of document strings and returns a relevance-ordered list of { index, relevance_score } objects. It is a distinct endpoint from /v1/embeddings; do NOT confuse it with Embeddings::Voyage (the embeddings provider).

== Endpoints

The same models are served by Voyage's own API and by MongoDB's Atlas Embedding and Reranking API, with an identical wire contract. An Atlas model API key (prefix ATLAS_KEY_PREFIX) routes to ATLAS_BASE_URL automatically, matching the embeddings provider. Pass base_url: to target either host (or a proxy) explicitly.

The HTTP stack mirrors Cohere: explicit proxy: nil unless opted in, bounded timeouts, capped retries with backoff on 429/5xx, a response-size cap, and a redacted #inspect.

Examples:

reranker = Parse::Retrieval::Reranker::Voyage.new(
  api_key: ENV.fetch("VOYAGE_API_KEY"),
  model:   "rerank-3",
)
reranker.rerank(query: "rain songs", documents: lyrics, top_n: 5)

Defined Under Namespace

Classes: AuthenticationError, BadRequestError, RateLimitError, TransientError

Constant Summary collapse

DEFAULT_BASE_URL =
"https://api.voyageai.com/v1"
ATLAS_BASE_URL =
"https://ai.mongodb.com/v1"
ATLAS_KEY_PREFIX =

Atlas model API keys carry this prefix and authenticate only against ATLAS_BASE_URL.

"al-"
DEFAULT_MODEL =
"rerank-3"
DEFAULT_TIMEOUT =
30
DEFAULT_OPEN_TIMEOUT =
5
DEFAULT_MAX_RETRIES =
2
MODELS =

Current and still-served rerank models. Informational: the constructor accepts any non-empty model name so a newly released model works without an SDK upgrade.

%w[rerank-3 rerank-3-lite rerank-2.5 rerank-2.5-lite rerank-2 rerank-2-lite].freeze
MAX_RESPONSE_BYTES =

Voyage documents a cap of 1000 documents per rerank call; the Base::MAX_DOCUMENTS cap (1000) already enforces this.

5 * 1024 * 1024

Constants inherited from Base

Base::MAX_DOCUMENTS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#rerank

Constructor Details

#initialize(api_key:, model: DEFAULT_MODEL, base_url: nil, truncation: true, timeout: DEFAULT_TIMEOUT, open_timeout: DEFAULT_OPEN_TIMEOUT, max_retries: DEFAULT_MAX_RETRIES, allow_faraday_proxy: false) ⇒ Voyage

Returns a new instance of Voyage.

Parameters:

  • api_key (String) —

    Voyage API key, or an Atlas model API key.

  • model (String) (defaults to: DEFAULT_MODEL) —

    rerank model (default DEFAULT_MODEL).

  • base_url (String, nil) (defaults to: nil) —

    API base. Defaults to ATLAS_BASE_URL for an Atlas key, else DEFAULT_BASE_URL.

  • truncation (Boolean) (defaults to: true) —

    forward Voyage's truncation: field. Defaults true (Voyage's default). false makes over-length inputs a 400 instead of silently truncating them.

  • timeout (Integer) (defaults to: DEFAULT_TIMEOUT) —

    read timeout (seconds).

  • open_timeout (Integer) (defaults to: DEFAULT_OPEN_TIMEOUT) —

    connect timeout (seconds).

  • max_retries (Integer) (defaults to: DEFAULT_MAX_RETRIES) —

    retry budget for 429 / 5xx / transient connection errors.

  • allow_faraday_proxy (Boolean) (defaults to: false) —

    permit Faraday to honor *_proxy env vars (default false, explicit proxy: nil).

Raises:

  • (ArgumentError)


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/parse/retrieval/reranker/voyage.rb', line 75

def initialize(api_key:, model: DEFAULT_MODEL, base_url: nil, truncation: true,
               timeout: DEFAULT_TIMEOUT, open_timeout: DEFAULT_OPEN_TIMEOUT,
               max_retries: DEFAULT_MAX_RETRIES, allow_faraday_proxy: false)
  validate_api_key!(api_key)
  @api_key = api_key
  @model = model.to_s
  raise ArgumentError, "Reranker::Voyage: model must be non-empty." if @model.empty?
  base_url ||= api_key.start_with?(ATLAS_KEY_PREFIX) ? ATLAS_BASE_URL : DEFAULT_BASE_URL
  @base_url = base_url.to_s
  validate_base_url!(@base_url)
  unless [true, false].include?(truncation)
    raise ArgumentError, "Reranker::Voyage: truncation must be true or false (got #{truncation.inspect})."
  end
  @truncation = truncation
  @timeout = Integer(timeout)
  @open_timeout = Integer(open_timeout)
  @max_retries = Integer(max_retries)
  raise ArgumentError, "Reranker::Voyage: max_retries must be >= 0." if @max_retries.negative?
  @allow_faraday_proxy = allow_faraday_proxy ? true : false
  @connection = build_connection
end

Instance Attribute Details

#model ⇒ String (readonly)

Returns the rerank model name.

Returns:

  • (String) —

    the rerank model name.



98
99
100
# File 'lib/parse/retrieval/reranker/voyage.rb', line 98

def model
  @model
end

Instance Method Details

#atlas? ⇒ Boolean

Returns true when routed through ATLAS_BASE_URL.

Returns:



101
102
103
# File 'lib/parse/retrieval/reranker/voyage.rb', line 101

def atlas?
  safe_base_host == URI.parse(ATLAS_BASE_URL).host
end

#inspect ⇒ Object



105
106
107
108
# File 'lib/parse/retrieval/reranker/voyage.rb', line 105

def inspect
  "#<#{self.class} model=#{@model.inspect} base=#{safe_base_host.inspect} " \
  "retries=#{@max_retries} api_key=[REDACTED]>"
end

#rerank_scores(query, documents, top_n) ⇒ Object (protected)



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/parse/retrieval/reranker/voyage.rb', line 112

def rerank_scores(query, documents, top_n)
  require_faraday!
  body = {
    "model" => @model,
    "query" => query,
    "documents" => documents,
    "top_k" => top_n,
    "truncation" => @truncation,
  }
  payload = post_rerank(body)
  extract_results!(payload)
end