A guide to the rerank package in Geppetto, covering cross-encoder reranking, the llama.cpp adapter, profile integration, and the JavaScript API.
Reranking is a retrieval stage that takes one query and an ordered set of candidate documents and scores them with a cross-encoder model. Unlike embedding retrieval (where query and document vectors are produced independently), a cross-encoder scores the query and each document together, producing a relevance score per document. This typically yields higher-quality ordering than first-stage vector or BM25 retrieval.
Reranking is Geppetto's third model-service primitive, alongside inference (pkg/inference/engine) and embeddings (pkg/embeddings).
Use cases:
The rerank request carries only a caller-controlled unique ID and exact text per document. Application metadata and first-stage retrieval scores stay outside the provider request. This keeps the interface reusable and reduces accidental disclosure.
HTTP reranker protocols identify results by the zero-based position of the submitted document. Array position is transport identity, not application identity. The adapter maps:
request.Documents[i].ID
-> provider request documents[i]
-> provider response result.index == i
-> response.Results[*].DocumentID
A caller must never infer application identity from response order alone.
TopN controls response cardinality. Some providers return only the highest-scoring TopN documents. A caller that needs one score per input must set TopN == len(Documents). The package validates the actual response against the requested cardinality. TopN is never defaulted: explicit cardinality lets complete-score callers prove they requested all candidates.
Scores are provider- and model-specific. They may be negative and must not be interpreted as probabilities. The package accepts any finite score and sorts descending.
Reranking usually consumes input tokens but produces no generated output tokens. The Usage record carries input and total tokens when the provider reports them. A nil Cost means pricing is unknown; a pointer to zero means the provider is explicitly free/local under the selected pricing policy. nil and zero are intentionally distinguishable.
import (
"github.com/go-go-golems/geppetto/pkg/rerank"
"github.com/go-go-golems/geppetto/pkg/rerank/llamacpp"
"github.com/go-go-golems/geppetto/pkg/security"
)
provider, err := llamacpp.New(llamacpp.Options{
BaseURL: "http://127.0.0.1:18012",
Model: "qllama/bge-reranker-v2-m3:q4_k_m",
OutboundURL: security.OutboundURLOptions{
AllowHTTP: true,
AllowLocalNetworks: true,
},
})
if err != nil { panic(err) }
resp, err := provider.Rerank(ctx, rerank.Request{
Query: "How does TTC calculate a payroll adjustment?",
Documents: []rerank.Document{
{ID: "chunk-001", Text: "A payroll adjustment corrects wages or deductions."},
{ID: "chunk-002", Text: "Cypress trees tolerate dry conditions."},
},
TopN: 2,
})
if err != nil { panic(err) }
for _, r := range resp.Results {
fmt.Println(r.Rank, r.DocumentID, r.Score)
}
Reranking integrates with Geppetto's engine profile system. A rerank-only profile stacks a base API profile:
inference_settings:
api:
base_urls:
rerank-base-url: http://127.0.0.1:18012
allow_http:
rerank: true
allow_local_networks:
rerank: true
rerank:
type: llamacpp
engine: qllama/bge-reranker-v2-m3:q4_k_m
max_request_bytes: 2097152
max_response_bytes: 1048576
Construct from resolved InferenceSettings:
import (
rerankfactory "github.com/go-go-golems/geppetto/pkg/rerank/factory"
)
factory, err := rerankfactory.NewSettingsFactoryFromInferenceSettings(resolvedSettings)
if err != nil { panic(err) }
provider, err := factory.NewProvider()
if err != nil { panic(err) }
ValidateInferenceSettingsForRerank gives profile-oriented diagnostics before construction.
A Cohere profile needs no base URL — the adapter defaults to the canonical
https://api.cohere.com endpoint — only an API key and a model:
inference_settings:
api:
api_keys:
cohere-api-key: ${COHERE_API_KEY}
rerank:
type: cohere
engine: rerank-v3.5
Notes:
cohere-base-url under api.base_urls is an optional override for proxies
or tests. Plain-HTTP or local-network overrides are rejected unless the
allow_http.rerank / allow_local_networks.rerank flags are set, exactly
like llama.cpp.meta.billed_units.search_units). Response.Usage therefore stays nil
(the provider did not report token usage), and Response.Cost stays nil
unless a per-search rate is configured (GEPPETTO-RERANKER-002, DR-3).id), not a header.max_tokens_per_doc is intentionally not exposed; callers
pre-truncate Document.Text (DR-4).The require("geppetto") module exposes reranker(settings), consistent with embeddings(settings):
const gp = require("geppetto");
const settings = gp.inferenceProfiles
.load("~/.config/pinocchio/profiles.yaml")
.resolve("bge-reranker-local");
const reranker = gp.reranker(settings);
// Synchronous (for bounded scripts):
const response = reranker.rerank(
"How does TTC calculate a payroll adjustment?",
[
{id: "chunk-001", text: "A payroll adjustment corrects wages or deductions."},
{id: "chunk-002", text: "Cypress trees tolerate dry conditions."}
],
{topN: 2}
);
for (const result of response.results) {
console.log(result.rank, result.documentId, result.score);
}
For event-loop applications, use rerankAsync to avoid blocking the runtime owner thread:
const handle = reranker.rerankAsync(query, documents, {topN: documents.length});
try {
const response = await handle.promise;
// ...
} finally {
handle.close();
}
The handle exposes cancel() and close() for cancellation and runtime shutdown. The provider goroutine touches no JavaScript value; Promise settlement happens on the runtime owner thread.
JavaScript cannot supply an endpoint, credential, HTTP client, local-network exception, or provider implementation directly. Those capabilities remain in host/profile configuration. The settings argument must be the hidden-reference InferenceSettings wrapper returned by inferenceProfiles.resolve.
The llama.cpp adapter enforces:
MaxRequestBytes, MaxResponseBytes).Two providers are supported, both constructed through the same factory and
usable from Go profiles and gp.reranker(settings) without any
provider-specific JavaScript:
llamacpp — a self-hosted llama.cpp /v1/rerank server. Local HTTP and
local networks must be explicitly allowed in the profile.cohere — the hosted Cohere v2 /rerank API (e.g. rerank-v3.5).
Authenticates with api_keys.cohere-api-key, defaults to
https://api.cohere.com, and requires no allow flags.The core package is transport-neutral; future adapters (Jina, voyage) can be
added without changing the Provider interface.
Use the runnable example for interactive qualification. It accepts either a resolved rerank profile or complete inline rerank settings and emits one row per ranked document, so both JSON and table output remain readable:
go run ./cmd/examples/rerank-profile-smoke run \
--rerank-type llamacpp \
--rerank-engine qllama/bge-reranker-v2-m3:q4_k_m \
--rerank-base-url http://127.0.0.1:18012 \
--output json
The opt-in test remains the automation guard:
GEPPETTO_LIVE_RERANK=1 \
GEPPETTO_RERANK_BASE_URL=http://127.0.0.1:18012 \
GEPPETTO_RERANK_MODEL=qllama/bge-reranker-v2-m3:q4_k_m \
go test ./pkg/rerank/llamacpp -run TestLive -v -count=1
It skips unless GEPPETTO_LIVE_RERANK=1 is set exactly, never falls back to a fixture, and never starts external services itself.
The equivalent opt-in test exists for Cohere and requires a real API key:
GEPPETTO_LIVE_RERANK=1 \
COHERE_API_KEY=<your-key> \
GEPPETTO_RERANK_MODEL=rerank-v3.5 \
go test ./pkg/rerank/cohere -run TestLive -v -count=1
Applications (such as a RAG system) adapt Geppetto reranking through a thin domain adapter. The dependency direction is:
application -> geppetto/pkg/rerank
geppetto/pkg/rerank -X-> any application package
The application owns evidence IDs, manifests, truncation, complete-score requirements, traces, citations, and evaluation. Geppetto owns the provider transport.