整个知识库,装进一个文件

Urna 把已经转换为向量的文本、图片和引用存进单个 .urna 文件。你的应用复制这个文件,就能回答问题并注明出处,无需服务器、无需联网、无需 API key。
v0.5.1 · 基于 MIT 开源 · Rust + Python
.csv
.jsonl
.sqlite
.jpg
Island
Basic Land · Island
corpus/
01001001 01110011 01101100 01100001 01101110 01100100IslandBasic Land · Island每个 chunk 256 个数,来自 potion
corpus.toml
[source] kind = "sqlite"
[[models]] preset = "potion"
[[models]] preset = "clip-vit-b32"
Island
JPEGAV1
Basic Land · Island
JPEGAV1
103 kB → 13 kB每张卡平均JPEG,来源 · AV1,文件内
drift p50 0.961
卡牌扫描4 GB
.urna533 MB
更小
100% 相对 exact61% 相对 exact34% 相对 exact26% 相对 exact21% 相对 exact
model_hashclip-vit-b32
HNSW + BM25 → cosine
Island
Forest
Mountain
p50,文本到图像
Island
Basic Land · Island
urna validateheader段文件内容
runtime 从不打开 socket

一个文件夹加几行 TOML,变成一个 .urna:chunks、向量、索引、媒体和 manifest,每个段都有签名。

卡牌扫描图以 AV1 存进文件,向量换成更小的 preset。文件变小,引用保持不变。

model_hash 关卡核对模型,HNSW 沿图游走,BM25 匹配关键词,精确余弦决定顺序。

答案带着引用回到来源,urna validate 在第一次查询前离线核对每一层。

工作原理

从一个文档文件夹
到一个能回答问题的文件

1
收集数据源
文本、PDF、表格、图片。用几行 TOML 描述每项内容的来源,以及由哪个模型读取。
2
生成 .urna
一次调用完成其余工作:在 Python 里用 urna.build,或在仓库的 checkout 里用 urna build --spec。它切分片段、计算向量、构建索引,并用 SHA-256 为每个 section 签名。结果是单个文件,在任何机器上都逐字节一致。
3
在应用内提问
Rust 运行时通过 mmap 打开文件,返回最相近的片段,每个片段都带有一条 urna:// 引用,可以追溯到原文。
可审计,数据库本该如此
自包含、可校验、可复现、离线。
文件就是整个数据库
片段、向量、索引、媒体和 manifest 都在同一个 .urna 里。像复制 SQLite 文件一样复制它,用 git 做版本管理,随安装包一起分发。没有需要启动的服务,也没有需要同步的索引。
每个回答都指向一个可以核对的片段
每个 section 都有 SHA-256,整个文件有,解码后的内容也有。文本压缩之后,引用 urna://content_hash/chunk_id 保持不变,urna cite 会把它解析为存储的片段。
离线,没有例外
运行时从不打开 socket。默认文本模型随 Python 包附带,其他安装方式下由 urna setup 在安装时下载一次。如果查询所用的模型与文件的模型不一致,搜索会立即停止,而不是返回一堆看起来像答案的垃圾。
实践

公开基准测试,同一把尺子

urna 对比 usearch、hnswlib、sqlite-vec 和 lancedb,在同一台机器上运行,附带数据和复现命令
0.72 ms
p50
1.02 ms
p99
recall 1.0
每次查询 0.72 ms,recall 1.0
10 万个 384 维向量,200 次查询,单线程。hybrid preset 的 p50 为 0.72 ms,p99 为 1.02 ms。它是表中唯一在第一次查询前校验自身字节的引擎;这在打开时大约花费 360 ms。
在文档中查看: 每次查询 0.72 ms,recall 1.0
3.8 万张 Magic 卡牌,533 MB
4 GB 的 JPEG 扫描图变成了一个小 7.46 倍的文件,文本、向量、索引和 AV1 图像都在里面,搜索找到卡牌的比例与 lossless 文件一样。
在文档中查看: 3.8 万张 Magic 卡牌,533 MB
30,725
片段
7
数据集
FakeRecogna1.2万
Fake.br7200
FakeTrue.Br3600
factck-br1300
3 万个事实核查片段
truw 对照七个公开的假新闻数据集,为葡萄牙语的说法打分。语料是一个包含 30,725 个片段的 .urna:exact preset 下为 120 MB,tiny 下为 31 MB。
在文档中查看: 3 万个事实核查片段

基准测试日期 2026-09-10,arm64,单线程。Urna 不做的事:原地更新和删除、元数据过滤、并发写入。 查看完整表格。

基准测试

urna 基准测试

在存入 .urna 文件的 38,627 张 Magic 卡牌(3.98 GB 的 JPEG)上测量压缩、搜索和延迟,并在相同的向量、同一台机器上对比 urna 与 usearch、hnswlib、sqlite-vec和lancedb

压缩与按名称搜索

7 个文件 · 每个 1,000 次查询
不损失搜索效果的压缩倍数7.46x

是相对 3.98 GB 源 JPEG 的缩小倍数。crf50 档的文件为 533 MB,按名称找到卡牌的比例与 3.61 GB 的 lossless 文件相当:txt@1 相差 +0.001,在标准误差之内。

lossless · 3.61 GB
neardup · 1.37 GB
crf50 · 533 MB

这个指标衡量什么

txt@1 是 1,000 次查询中正确卡牌排在第一位的比例。查询是卡牌名称的文本("artwork of the card {name}"),在 clip 的图像空间中搜索:模型只看得到卡图,所以每个文件的水平都很低;关键是它在哪里开始下降。

drift 是压缩图像的向量与原图向量之间的余弦:1.00 表示完全相同,值越低,codec 对模型所见内容的改动越大。最差十分位(p10)是变化最大的那 10% 卡牌边界上的那一张;中位数(p50)是居中的那一张。

如何阅读这张图

每一列是一个文件,包含同样的 38,627 张卡牌,从 lossless(3.61 GB)到 crf60 的 AV1(230 MB),按压缩程度排列。

上图中,两条 drift 线一路下降,从第二个文件起就跌破 gate floor。下图中,搜索效果到 crf50 为止保持平稳:绿色柱与 lossless 的差距在一个标准误差以内;虚线标出搜索开始下降的位置,红色柱是虚线之后的文件。

文件大小drift p10txt@1±1 标准误差z vs lossless
lossless3.61 GB0.99680.0920.00910.00
neardup1.37 GB0.96660.0960.00930.31
avif q481.2 GB0.96800.0960.00930.31
crf40981 MB0.95940.0890.0090-0.23
crf50533 MB0.93890.0930.00920.08
crf55370 MB0.92110.0740.0083-1.46
crf60230 MB0.88660.0690.0080-1.89

每个文件 1,000 次查询,所有文件使用相同的卡牌;二项分布标准误差;z 是每个文件的 txt@1 与 lossless 之间以合并标准误差计的距离:到 crf50 为止,没有一个超过 1。

测于 2026-09-12 · benchmark/experiments/14-utility-ladder/results.json

preset
选择大小,内容不变
五个 preset 组合了文本压缩、向量精度和索引,另有 micro 负责裁掉维度。这里列出三个,全部见文档
适合含缩写、专有名词、罕见术语的问题:
文本用 zstd 压缩
float32 向量
HNSW + BM25 作为候选
按精确余弦 rerank
查看 preset
在 30,725 个片段上测得。 这里的 recall 衡量的是量化下排序的稳定性,而不是真实问题上的准确度。 查看全部五个 preset 和 micro。
集成
一条命令安装,五行代码集成
一个 Rust 二进制,包含三组子命令(engine、agent、setup),外加一个 Python API。安装之后,下面的所有内容都无需网络即可运行
$
安装
安装器
$
构建
urna build
$
提问
urna ask
安装器在写入前校验 SHA-256。urna setup 会下载一次离线 embedder,最后运行 urna doctor;如果有哪一层出错,它会告诉你是哪一层。
curl -sSf https://raw.githubusercontent.com/hoffresearch/urna/main/scripts/install.sh | sh urna setup
数据源、媒体和模型写在一个 TOML 里,在仓库的 checkout 中运行。同一份 spec 在任何机器上都生成相同的数据库。
urna build --spec corpus.toml
带引用的片段,直接在终端里输出。
urna ask corpus.urna "离线能用吗?" -k 3
输出 JSONL,包含片段、来源、分数和引用,可以直接交给你的应用或 agent。
urna retrieve corpus.urna "离线能用吗?" -k 5 --format jsonl
通过 mmap 打开,返回带引用的结果。预期的 model_hash 会在搜索前拦下错误的模型。
import urna from urna.embed_potion import potion_embedder emb, db = potion_embedder(), urna.open("corpus.urna") qvec = emb.embed_texts(["离线能用吗?"])[0] hits = db.retrieve(qvec, 5, expected_model_hash=emb.model_hash())
分发前检查所有校验和:文件头、各 section、整个文件、内容。
urna validate corpus.urna
从引用回到存储的文本,并附上可以证明这一点的哈希。
urna cite corpus.urna "urna://content_hash/chunk_id"
在你的机器、你的语料上测量延迟和 recall。
urna benchmark corpus.urna -q 100 -k 10 --ann 100
渠道

一次发布,所有包管理器

crates.io、PyPI、npm 和 Homebrew 上是同一个 urna 0.5.1,每个文件旁边都有校验和与 attestation
到处都是同一个二进制
cargo、pip、npm、bun、pnpm、yarn、brew、curl 一行命令和 PowerShell 装的是同一个构建:macOS 和 Linux 支持 arm64 与 x86_64,Windows 支持 x86_64。npx 和 uvx 不用安装就能运行。
在文档中查看: 到处都是同一个二进制
tar.xz
zip
sha256
sigstore
SBOM
ssh tag
可以核验的发布
每个归档都带有自己的 .sha256 和一份 sigstore attestation(用 gh attestation verify 校验),外加 CycloneDX SBOM 和用 cargo-auditable 构建的二进制。发布 tag 由 ssh 签名。
在文档中查看: 可以核验的发布
放进你的应用,不需要 CLI
urna-format 和 urna-runtime 在 crates.io 上供 Rust 使用,Python 包打开的是同一个文件。仓库里有 fastapi、flask 和 jupyter 的示例和一个 Dockerfile;cargo install urna --no-default-features 会得到一个只含 engine 的 2.1 MB CLI。
在文档中查看: 放进你的应用,不需要 CLI
无需安装npx @urna/cli validate corpus.urnauvx --from urna urna validate corpus.urnacargo binstall urna
终端里

三组子命令,外加一个操作界面

urna tui 打开一个 .urna,向它提问并检查安装,全程不离开终端。urna setup 在写入任何东西之前先展示计划,最后运行 doctor 检查
urna tui 的 ask 标签页:一个问题的十条带引用的结果、所选结果存储的文本及其引用
urna tui
urna setup 的 verify 步骤,所有检查都通过
urna setup
engine

输入文件和向量,输出结果。不用 Python。

  • inspect
  • validate
  • stats
  • media
  • search
  • search-ann
  • search-graph
  • search-space
  • search-text
  • benchmark
  • cite
  • doctor
agent

输入文本或 spec,输出带引用的答案,经由离线的 Python embedder。

  • ask
  • retrieve
  • build
setup

每个渠道最后都要运行的安装器,以及终端里的浏览器。

  • setup
  • tui
开始之前
第一次阅读时常见的疑问。其余内容都在文档里,附有命令和输出
阅读文档

你的知识库,随时可以带走

安装,构建语料,把文件复制进应用。剩下的交给 mmap
安装
v0.5.1 · MIT · macOS、Linux 和 Windows