Class: Pikuri::VectorDb::Reranker::LlamaServer
- Inherits:
-
Object
- Object
- Pikuri::VectorDb::Reranker::LlamaServer
- Defined in:
- lib/pikuri/vector_db/reranker/llama_server.rb
Overview
Cross-encoder reranker via HTTP POST /v1/rerank against a llama.cpp
server, in the same wire format Cohere's hosted reranker speaks — so a
Reranker::Cohere later is a base-URL + auth-header swap on this client:
POST <endpoint>/v1/rerank { "model"?, "query", "documents": [...] }
→ 200 { "results": [ { "index": 0, "relevance_score": 0.92 }, ... ] }
#rerank extracts results, re-sorts descending by relevance_score
(defensively — servers usually pre-sort), and maps each to a Hit.
endpoint: is the base URL (+/v1/rerank+ appended); most setups point it
at the same router-mode llama-server as chat/embedder. model: is
optional (llama.cpp infers the loaded model; Cohere requires it — set it
forward-compatibly).
Errors are loud (same posture as Tokenizer::LlamaServer): non-2xx,
missing results, malformed body, Faraday::Error all raise. The
Tools::Search caller catches and falls back to vector-only top-k —
outages degrade at the tool level, not by the client lying about scores.
Instance Method Summary collapse
- #initialize(endpoint:, model: nil, connection: nil) ⇒ LlamaServer constructor
-
#rerank(query:, documents:) ⇒ Array<Hit>
Score every document against
queryvia the cross-encoder.
Constructor Details
#initialize(endpoint:, model: nil, connection: nil) ⇒ LlamaServer
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/pikuri/vector_db/reranker/llama_server.rb', line 37 def initialize(endpoint:, model: nil, connection: nil) raise ArgumentError, 'endpoint must be non-empty' if endpoint.nil? || endpoint.empty? @endpoint = endpoint @model = model @connection = connection || Faraday.new(url: endpoint) do |f| f.request :json f.response :json f.adapter Faraday.default_adapter end end |
Instance Method Details
#rerank(query:, documents:) ⇒ Array<Hit>
Score every document against query via the
cross-encoder. Returns an Array<Hit> sorted
descending by score; one entry per input document.
Empty documents short-circuits to [].
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/pikuri/vector_db/reranker/llama_server.rb', line 62 def rerank(query:, documents:) return [] if documents.empty? body = { query: query, documents: documents } body[:model] = @model if @model response = @connection.post('/v1/rerank') do |req| req.headers['Content-Type'] = 'application/json' req.body = body end unless response.status == 200 raise "Reranker::LlamaServer: POST #{@endpoint}/v1/rerank returned " \ "HTTP #{response.status}: #{response.body.inspect}" end results = response.body.is_a?(Hash) ? response.body['results'] : nil unless results.is_a?(Array) raise "Reranker::LlamaServer: response missing 'results' array " \ "(got #{response.body.inspect})" end hits = results.map do |entry| idx = entry.is_a?(Hash) ? entry['index'] : nil score = entry.is_a?(Hash) ? entry['relevance_score'] : nil unless idx.is_a?(Integer) && score.is_a?(Numeric) raise "Reranker::LlamaServer: malformed result entry " \ "(expected {index:Integer, relevance_score:Float}, got #{entry.inspect})" end Hit.new(index: idx, score: score.to_f) end hits.sort_by { |h| -h.score } rescue Faraday::Error => e raise "Reranker::LlamaServer: #{e.class.name.split('::').last} " \ "calling #{@endpoint}/v1/rerank: #{e.}" end |