docsv0.5.1

urna search-ann

Reference for urna search-ann, which forces the HNSW path with a JSON query vector, reranks the candidates by exact cosine, and falls back to exact.

urna search-ann searches a .urna file through its HNSW index with a query vector you supply as a JSON array. The index proposes candidates, every candidate is rescored by exact cosine, and the top k are printed. If the file has no HNSW section, the verb runs the exact path instead.

Usage

urna search-ann [OPTIONS] <FILE> <QUERY>

Arguments

ArgumentDescription
<FILE>Path to the .urna file
<QUERY>The query vector as a JSON array of numbers, with exactly embedding_dim values

Options

OptionDefaultDescription
-k, --k <K>10Number of hits to return. Must be greater than 0
--ef <EF>100Requested HNSW beam width. The effective beam is never below k or the file's ef_construction (see below)
-h, --helpPrint help

Behavior

  1. Opens the file with the full runtime check, which decodes the HNSW section when present.
  2. Parses <QUERY> as JSON.
  3. If the file has no hnsw_index section, runs urna search and prints its result (index_type: exact, reranked=false).
  4. Otherwise validates and L2-normalizes the query, walks the HNSW graph with a beam of max(ef, k, ef_construction), rescores every candidate by exact cosine against the stored vectors, and returns the top k.

The verb forces the HNSW path whatever the manifest declares. There is no model gate: embed the query with the model the file names (model and model_hash in urna stats).

--ef below ef_construction does nothing

The runtime raises the beam to the ef_construction the file was built with. Files built by Python or the forge use ef_construction = 400, so on those files any --ef of 400 or less gives the same candidates and the same hits. The quickstart corpus was built with 400. See Known limits.

The rerank makes every score a real cosine. It does not make the candidate list complete: a chunk HNSW never proposes cannot appear. Compare against exact with urna benchmark --ann, which reports recall@k.

Output

The same block as urna search. On the HNSW path the result says index_type: hnsw, recall is printed as (not computed; rerank guarantees real cosine), and every hit has reranked=true.

Exit codes

CodeMeaning
0Search ran and printed its result
1Any error: file missing or unreadable, a failed integrity check or a malformed HNSW payload, invalid query JSON, wrong dimension, NaN or Inf, zero-norm query, k of 0 or less. Printed to stderr as Error: <message>
2Usage error: a missing or unparseable argument

Examples

query.json holds the stored embedding of the quickstart corpus's first chunk:

urna search-ann examples/quickstart/out/quickstart.urna "$(cat query.json)" -k 2 --ef 50
index_type:   hnsw
recall:       (not computed; rerank guarantees real cosine)
truncated:    true
k_requested:  2
k_returned:   2
query_time:   0.040 ms
hits:
  [  1] chunk_id=sha256:19f36b3e072d553eb83626bf30db5e8f3b1f729a495f7826999ffeae53848e6e score=1.000000 score_type=cosine source_uri=demo/01-what-is-urna.md offset=0-1 model=minishlab/potion-base-8M/v1 index_type=hnsw reranked=true file_hash=sha256:e4d5f8907faad38c192dc6929e36dbf16db558410b2dae5abb4d65f10f508832 content_hash=sha256:1147b2560863331b21bd9d60fe6bdd99507dc34e17108444dc38194f8e6f09df citation_id=urna://sha256:1147b2560863331b21bd9d60fe6bdd99507dc34e17108444dc38194f8e6f09df/sha256:19f36b3e072d553eb83626bf30db5e8f3b1f729a495f7826999ffeae53848e6e
  [  2] chunk_id=sha256:47ecc7e1141759d285f08545d74de807a0196a73d5db27b024e7bbe3b2f78bb4 score=0.664475 score_type=cosine source_uri=demo/03-citations.md offset=6-7 model=minishlab/potion-base-8M/v1 index_type=hnsw reranked=true file_hash=sha256:e4d5f8907faad38c192dc6929e36dbf16db558410b2dae5abb4d65f10f508832 content_hash=sha256:1147b2560863331b21bd9d60fe6bdd99507dc34e17108444dc38194f8e6f09df citation_id=urna://sha256:1147b2560863331b21bd9d60fe6bdd99507dc34e17108444dc38194f8e6f09df/sha256:47ecc7e1141759d285f08545d74de807a0196a73d5db27b024e7bbe3b2f78bb4

The scores equal the exact path's scores for the same chunks, bit for bit, because both come from the same rerank. --ef 50 ran at the file's ef_construction of 400.

The HNSW path and its limits are described in Search paths and the exact rerank.

On this page