☰
USearch 向量相似度搜索引擎在 Unity RAG 中的集成:HNSW 原理与 LLMUnity 本地化改造实战
2026/10/16 16:50:53 网站建设 项目流程
  • 桌面应用
  • 数字人
  • AI 应用

【免费下载链接】Mate-Engine

A free Desktop Mate alternative with a lightweight interface and custom VRM support, though with more features.

项目地址:https://gitcode.com/gh_mirrors/ma/Mate-Engine
点击查看免费下载

导读

本文以 Mate-Engine 仓库中 Assets/LLMUnity/Runtime/RAG/usearch/README.md 为主体,系统讲解 USearch——一个基于 HNSW 算法的单文件向量相似度搜索引擎——及其在 LLMUnity RAG(检索增强生成)模块中的落地方式。你将了解到 USearch 与 FAISS 的对比结论、索引的序列化与磁盘服务、精确与近似检索、量化与内存优化等核心机制,并通过 NativeMethods.cs、USearchIndex.cs、DBSearch.cs 等仓库源码,掌握这套引擎在 Unity 中如何被本地化改造并以DBSearch组件的形式驱动 RAG 语义检索。

一、USearch 是什么:定位与许可证

USearch 是一个相似度搜索引擎(Similarity Search Engine),其核心卖点是"更小、更快"的单文件实现:

  • 基于 HNSW(Hierarchical Navigable Small World)近邻图算法,提供比 FAISS 更快的向量检索实现;
  • 以单个 C++11 头文件为核心实现,简单且可扩展;
  • 开箱即用地支持十余种编程语言(C++、Python、JavaScript、Java、Rust、C99、Objective-C、Swift、C#、GoLang、Wolfram 等);
  • 覆盖 Linux、macOS、Windows、iOS、WebAssembly 等平台;
  • 支持 SIMD 优化与用户自定义距离度量(可 JIT 编译);
  • 支持f16、i8等半精度/四分之一精度存储;
  • 支持从磁盘直接 view 大索引而不必加载进 RAM;
  • 支持异构查询、键重命名与运行时删除;
  • 内置 Binary Tanimoto 与 Sorensen 系数,适用于基因组学与化学分子检索;
  • 提供uint40_t紧凑邻居编号,可支撑 40 亿以上规模的点集;
  • 兼容 OpenMP 与自定义 executor,可精细控制 CPU 利用率;
  • 支持近实时聚类与子聚类、语义搜索与 fuzzy/语义 Join。

许可证方面,USearch 以Apache-2.0协议分发,仓库内保留了完整的许可文本:LICENSE。

二、仓库内的本地化改造:从 NuGet 到 Unity 的移植

这是关联文档的重点章节,记录了本仓库对 USearch C# 绑定所做的全部改动。原文列出的修改项如下:

  1. NativeMethods.cs:新增导入usearch_view_buffer与usearch_load_buffer两个原生函数;
  2. USearchIndex.cs:save与load函数被修改,改为在一个ZipArchive中同时保存/加载IndexOptions与索引本身;
  3. .meta文件由 Unity 自动生成;
  4. 新增 Cloud.Unum.USearch.asmdef,用于声明程序集名称;
  5. arm64 目录下的 dll 由 USearch 官方代码库为 arm64 macOS 单独编译。

结合源码逐一核实,可看到这些改动的具体落地:

2.1 原生互操作层 NativeMethods.cs

NativeMethods.cs 是整个绑定层的底层,通过DllImport("libusearch_c", CallingConvention = CallingConvention.Cdecl)对接 C 原生库,并用别名声明了句柄类型:

  • usearch_index_t = IntPtr、usearch_key_t = UInt64、usearch_error_t = IntPtr、usearch_distance_t = Single。

其中暴露的核心函数包括:

函数作用
usearch_init按IndexOptions创建索引
usearch_free释放索引
usearch_save/usearch_load/usearch_view文件级保存、加载、只读视图
usearch_size/usearch_capacity/usearch_dimensions/usearch_connectivity查询索引元信息
usearch_reserve预扩容
usearch_add添加向量(float[]/double[]两个重载)
usearch_contains/usearch_count/usearch_get查询键是否存在、键下向量数量、取回向量
usearch_remove/usearch_rename删除与重命名键
usearch_search近似最近邻搜索(含指针版、float[]、double[]三个重载)

文档中提到被"额外导入"的两个 buffer 函数也确在其中:

[DllImport(LibraryName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void usearch_load_buffer(usearch_index_t index, void_ptr_t buffer, size_t length, out usearch_error_t error); [DllImport(LibraryName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void usearch_view_buffer(usearch_index_t index, void_ptr_t buffer, size_t length, out usearch_error_t error);

此外,LLMUnity 还额外追加了一个usearch_filtered_search(带过滤回调的搜索)以及FilterCallback委托声明,为分组检索提供了底层支撑。

2.2 托管包装类 USearchIndex

USearchIndex.cs 是IDisposable的托管包装类,内部持有IntPtr _index句柄。构造函数接受MetricKind、ScalarKind(量化类型)、dimensions、connectivity、expansionAdd、expansionSearch、multi等参数,组装成IndexOptions后调用usearch_init创建索引;另有从IndexOptions直接构造、以及(path, view)两种加载构造。它实现了:

  • 元信息查询:Size()、Capacity()、Dimensions()、Connectivity();
  • 增删改查:Add(key, vector)(含float[]/double[]单条与批量重载)、Get(单条与多条)、Remove、Rename、Contains、Count;
  • 自动扩容:Add前通过CheckIncreaseCapacity判断,容量不足时调用usearch_reserve预扩容;
  • 错误处理:每次原生调用后经HandleError检查错误指针,非空则抛出 USearchException;
  • 资源释放:Dispose+ 析构函数双保险,确保原生索引被usearch_free释放。

文档提到的 ZipArchive 持久化也在此落实:

public void Save(ZipArchive zipArchive) { string indexPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Save(indexPath); try { zipArchive.CreateEntryFromFile(indexPath, GetIndexFilename()); } catch (Exception ex) { Debug.LogError(...); } File.Delete(indexPath); } public void Load(ZipArchive zipArchive) { ... ZipArchiveEntry entry = zipArchive.GetEntry(GetIndexFilename()); // 读出到 managedBuffer,用 GCHandle 钉住后交给 usearch_load_buffer usearch_load_buffer(_index, unmanagedBuffer, (UIntPtr)managedBuffer.Length, out error); ... }

即:Save先把索引临时落盘,再把文件写入 Zip 归档的usearch/index条目;Load则从归档中读出字节流,经 GCHandle 固定托管缓冲后直接调用usearch_load_buffer从内存重建索引。

2.3 新增的搜索扩展(LLMUnity 附加部分)

在文件末尾//========== Additional methods from LLMUnity ==========//标记之下,USearchIndex还提供了带过滤条件的搜索能力:

  • FilterFunction静态委托与filterLock锁对象;
  • 使用[MonoPInvokeCallback]标记的StaticFilter静态回调——这是为了在Android(IL2CPP)平台下把托管回调安全地传给原生代码;其他平台则直接使用 C# lambda 闭包;
  • Search<T>(queryVector, count, out keys, out distances, scalarKind, filter)核心实现:用 GCHandle 钉住查询向量,无过滤时调用usearch_search,有过滤时调用usearch_filtered_search,最后按实际匹配数收缩结果数组。

2.4 类型定义与程序集

USearchTypes.cs 定义了:

  • MetricKind枚举:Cos、Ip(内积)、L2sq、Haversine、Pearson、Jaccard、Hamming、Tanimoto、Sorensen;
  • ScalarKind枚举:Float32、Float64、Float16、Int8、Byte1;
  • 可序列化的IndexOptions结构体(StructLayout.Sequential),字段与原生侧一一对应:metric_kind、metric、quantization、dimensions、connectivity、expansion_add、expansion_search、multi。文件内还留有"自定义度量委托"的 TODO 注释,说明该能力在 C# 绑定中尚未启用。

Cloud.Unum.USearch.asmdef 则将上述 C# 代码声明为Cloud.Unum.USearch程序集,使其可被 LLMUnity 的 RAG 模块直接引用。

2.5 各平台原生库

README 提到"runtime dlls 由 NuGet 包导出并加入 x86_64 文件夹"。在本仓库中,各平台的原生库被集中放置在 Assets/LLMUnity/Resources/usearch:

  • windows/libusearch_c.dll;
  • linux/libusearch_c.so;
  • macos/libusearch_c.dylib;
  • Android/libusearch_c.so;
  • iOS/libusearch_static_c.a(静态库)。

这也解释了为什么NativeMethods.cs中的LibraryName统一为"libusearch_c"——Unity 会在运行时按平台自动选择对应后缀的原生库。

三、核心参数体系:IndexOptions 与构造示例

上游 README 给出了 Python 端的灵活构造示例,本仓库的 C# 端与之对应:

index = Index( ndim=3, # 输入向量的维度 metric='cos', # 可选 'l2sq'、'haversine' 等,默认 'ip' dtype='f32', # 可按需量化为 'f16' 或 'i8',默认 'f32' connectivity=16, # 可选:限制每个图节点的邻居数 expansion_add=128, # 可选:控制建索引时的召回率 expansion_search=64, # 可选:控制搜索质量 multi=False, # 可选:是否允许一个键对应多个向量,默认 False )

C# 侧的USearchIndex构造函数参数与之一一对应:

USearchIndex( MetricKind metricKind, // 距离度量,如 MetricKind.Cos ScalarKind quantization, // 量化类型,如 ScalarKind.Float16 ulong dimensions, // 向量维度 ulong connectivity = 0, // 图节点邻居数上限 ulong expansionAdd = 0, // 建索引时的扩展系数 ulong expansionSearch = 0,// 搜索时的扩展系数 bool multi = false // 是否允许一键多向量 )

参数对效果的影响(依据 USearchIndex.cs 与 DBSearch.cs 的实现注释):connectivity限制近邻图中每个节点的连接数,expansionAdd控制添加向量时的检索范围(越大召回越高、建索引越慢),expansionSearch控制查询时的扩展范围(越大搜索结果越接近精确、延迟越高),multi允许同一键下挂多个向量。

四、与 FAISS 的对比:设计哲学与实测差异

上游 README 中有一张详细的对比表,双方都采用 HNSW 算法,但设计取向截然不同——USearch 在保持性能的同时更紧凑、更易移植,主打用户自定义度量和零依赖:

维度FAISSUSearch改进幅度
1 亿个 96df32/f16/i8向量索引耗时2.6 / 2.6 / 2.6 h0.3 / 0.2 / 0.2 h9.6 / 10.4 / 10.7 x
1 亿个 1536df32/f16/i8向量索引耗时5.0 / 4.1 / 3.8 h2.1 / 1.1 / 0.8 h2.3 / 3.6 / 4.4 x
代码库规模84 K SLOC3 K SLOC更易维护
支持的度量9 种固定度量任意度量可扩展
支持的语言C++、Python10 种语言可移植
支持的 ID 类型32 位、64 位32 位、40 位、64 位更省空间
必需依赖BLAS、OpenMP无更轻量
绑定方式SWIG原生绑定更低延迟
Python 绑定体积~10 MB<1 MB更易部署

上述索引耗时数据来自上游在 Intel Sapphire Rapids 上以最简单的内积距离测试的结果(同等召回率与内存消耗,同时搜索速度也大幅领先)。

基础用法两者几乎一致(这就是"熟悉 ANN 的人上手零成本"的原因):

$ pip install numpy usearch import numpy as np from usearch.index import Index index = Index(ndim=3) vector = np.array([0.2, 0.6, 0.4]) index.add(42, vector) matches = index.search(vector, 10) assert matches[0].key == 42 assert matches[0].distance <= 0.001 assert np.allclose(index[42], vector)

五、序列化与从磁盘服务索引

USearch 支持三种序列化形式:

  • 写入文件(以路径定义);
  • 写入流(用回调增量序列化或重建);
  • 写入定长缓冲区 / 支持随机访问的内存映射文件。

最后一种方式允许直接以只读view方式从外部内存服务索引,从而把"建索引"与"在线服务"的机器成本分开优化,README 中提到这在 AWS 等公有云上可带来约20 倍的成本削减。

index.save("index.usearch") loaded_copy = index.load("index.usearch") view = Index.restore("index.usearch", view=True) other_view = Index(ndim=..., metric=...) other_view.view("index.usearch")

在 C# 端,USearchIndex的(string path, bool view)构造函数正是对应这一能力:view=true时走usearch_view(内存映射、不载入 RAM),否则走usearch_load(完整载入)。而在 LLMUnity RAG 场景中,索引进一步被封装进 ZipArchive(见 2.2 节),随RAG.Save/Load一起持久化到.zip文件。

六、精确搜索 vs 近似搜索

近似搜索(如 HNSW)主要用于精确暴力搜索代价过高的场景——典型是集合内有数百万条记录时。对于小集合,可直接用search方法做精确搜索:

from usearch.index import search, MetricKind, Matches, BatchMatches import numpy as np # 生成 10'000 个 1024 维随机向量 vectors = np.random.rand(10_000, 1024).astype(np.float32) vector = np.random.rand(1024).astype(np.float32) one_in_many: Matches = search(vectors, vector, 50, MetricKind.L2sq, exact=True) many_in_many: BatchMatches = search(vectors, vectors, 50, MetricKind.L2sq, exact=True)

传入exact=True时,系统完全跳过索引,直接用 SimSIMD 优化的相似度度量对全量数据暴力搜索。README 引用的对比测试中,FAISSIndexFlatL2耗时 55.3 ms,而usearch.index.search仅 2.54 ms。需要说明的是,这是上游文档给出的单一场景数据,实际提升幅度取决于硬件与数据分布。

七、多索引组合、聚类与 Join

7.1 多索引并行查询

面对十亿乃至万亿级向量时,与其构建一个巨型索引,不如构建多个小索引再统一查看:

from usearch.index import Indexes multi_index = Indexes( indexes: Iterable[usearch.index.Index] = [...], paths: Iterable[os.PathLike] = [...], view: bool = False, threads: int = 0, ) multi_index.search(...)

7.2 聚类与子聚类

索引构建完成后,USearch 本身就可以被看作一种聚类结构,支持比 SciPy、UMap、tSNE 等独立聚类库更快的 KNN 聚类,也支持迭代加深的"子聚类":

clustering = index.cluster( min_count=10, # 可选 max_count=15, # 可选 threads=..., # 可选 ) # 获取聚类中心及规模 centroid_keys, sizes = clustering.centroids_popularity # 用 Matplotlib 画直方图 clustering.plot_centroids_popularity() # 导出 NetworkX 图 g = clustering.network # 获取某个簇的成员 first_members = clustering.members_of(centroid_keys[0]) # 对簇继续细分,支持同样的参数 sub_clustering = clustering.subcluster(min_count=..., max_count=...)

这种聚类与 K-Means 等传统方法结果并不完全相同,但用途一致。README 提到:在 5 万个聚类的规模上,USearch 与传统聚类方法的性能差距可达 100 倍量级;作为对比,Scikit-Learn 处理 100 万点数据集的聚类查询可能需要数分钟到数小时。

7.3 Join:一对一、一对多、多对多映射

与"对每条记录逐一搜索"不同,join要求在一对一映射下禁止不同搜索结果之间的冲突,是模糊匹配场景的基础。USearch 可实现次二次复杂度的近似、模糊与语义 Join:

men = Index(...) women = Index(...) pairs: dict = men.join(women, max_proposals=0, exact=False)

八、用户自定义度量

大多数向量检索库只提供内积与欧氏距离,USearch 则允许任何用户自定义度量,从而覆盖从地理坐标的 Haversine 距离,到由多个 AI 模型拼接出的复合 embedding 度量等场景。HNSW 不需要向量等长,只要求"可比较",因此甚至可以拿 GZip 压缩比作为距离函数做模糊文本匹配。

需要如实说明:在本仓库的 C# 绑定中,USearchTypes.cs的IndexOptions.metric字段默认置空,自定义度量委托仍处于 TODO 状态,该能力目前主要在 Python 等绑定中可用。

九、内存效率、降精度与量化

训练量化模型 + 降维是加速向量搜索的常见手段,但这种方式并不总是可靠,可能改变数据统计特性,且分布漂移时需要频繁调整。USearch 的做法是:对降精度后的向量做高精度算术。同一个索引的add与search操作会在f64、f32、f16、i8与单比特表示之间自动降/升精度。

可用如下命令检查硬件加速是否启用:

$ python -c 'from usearch.index import Index; print(Index(ndim=768, metric="cos", dtype="f16").hardware_acceleration)' > avx512+f16 $ python -c 'from usearch.index import Index; print(Index(ndim=166, metric="tanimoto").hardware_acceleration)' > avx512+popcnt

使用更小的数值类型能省下存储向量的 RAM,还可以压缩构成近邻图的邻居列表。默认用 32 位uint32_t枚举邻居,无法支撑超过 40 亿条数据;此时可用自定义uint40_t类型,它仍比常见的 8 字节整数省 37.5% 空间,且可扩展到 1 万亿条记录。

十、跨语言功能矩阵

上游 README 给出的功能覆盖情况(核心功能在所有绑定中均已支持,更宽泛的功能按需移植):

功能C++ 11Python 3C 99JavaJavaScriptRustGoLangSwift
添加、搜索、删除✅✅✅✅✅✅✅✅
保存、加载、查看✅✅✅✅✅✅✅✅
用户自定义度量✅✅❌❌❌❌❌❌
批量操作❌✅❌❌✅❌❌❌
Join✅✅❌❌❌❌❌❌
变长向量✅❌❌❌❌❌❌❌
40 亿以上容量✅❌❌❌❌❌❌❌

值得一提的是,README 特别说明:某些场景下"功能对等"没有意义——例如批量操作,宿主语言本身具备完整的多线程能力,而 USearch 索引结构天生并发安全,因此用户完全可以在自己语言里实现最优的批处理/调度/负载均衡。

十一、典型应用示例

11.1 AI 多模态语义搜索

用多模态编码器(如 UForm)+ Web 框架(如 UCall)+ USearch,约 20 行 Python 即可搭出文搜图平台:

import ucall import uform import usearch import numpy as np import PIL as pil server = ucall.Server() model = uform.get_model('unum-cloud/uform-vl-multilingual') index = usearch.index.Index(ndim=256) @server def add(key: int, photo: pil.Image.Image): image = model.preprocess_image(photo) vector = model.encode_image(image).detach().numpy() index.add(key, vector.flatten(), copy=True) @server def search(query: str) -> np.ndarray: tokens = model.preprocess_text(query) vector = model.encode_text(tokens).detach().numpy() matches = index.search(vector.flatten(), 3) return matches.keys server.run()

11.2 RDKit 分子检索

化学中常见的做法是把 SMILES 结构编码为二进制指纹,再用 Tanimoto 等二值相似度度量检索:

from usearch.index import Index, MetricKind from rdkit import Chem from rdkit.Chem import AllChem import numpy as np molecules = [Chem.MolFromSmiles('CCOC'), Chem.MolFromSmiles('CCO')] encoder = AllChem.GetRDKitFPGenerator() fingerprints = np.vstack([encoder.GetFingerprint(x) for x in molecules]) fingerprints = np.packbits(fingerprints, axis=1) index = Index(ndim=2048, metric=MetricKind.Tanimoto) keys = np.arange(len(molecules)) index.add(keys, fingerprints) matches = index.search(fingerprints, 10)

11.3 GIS 地理检索(iOS)

借助 Objective-C 与 Swift 绑定,USearch 可轻松用于移动应用——把经纬度编码为二维向量,用 Haversine 距离在移动地图上实时查找最近的兴趣点(POI),且易于扩展至高维向量。

十二、在 Mate-Engine 的 LLMUnity RAG 中的实际集成

这是本仓库最值得关注的部分:上述引擎被封装为DBSearch,与暴力检索的SimpleSearch并列为 LLMUnity RAG 的两种搜索方法。参见 RAG.cs 中的SearchMethods枚举定义:

public enum SearchMethods { DBSearch, // 基于 USearch 的 ANN 检索,推荐 SimpleSearch, // 简单暴力检索 }

12.1 DBSearch 如何驱动 USearch

DBSearch.cs 继承自SearchMethod,在Awake中通过InitIndex()创建索引,其参数与 USearch 的IndexOptions一一对应:

[ModelAdvanced] public ScalarKind quantization = ScalarKind.Float16; // 量化类型:半精度 [ModelAdvanced] public MetricKind metricKind = MetricKind.Cos; // 度量:余弦相似度 [ModelAdvanced] public ulong connectivity = 32; // 图节点邻居数上限 [ModelAdvanced] public ulong expansionAdd = 40; // 建索引扩展系数 [ModelAdvanced] public ulong expansionSearch = 16; // 搜索扩展系数 public void InitIndex() { index = new USearchIndex(metricKind, quantization, (ulong)llmEmbedder.llm.embeddingLength, connectivity, expansionAdd, expansionSearch, false); }

也就是说:embedding 的维度直接取自 LLM embedder 的embeddingLength,向量以Float16量化存储,用余弦距离度量语义相似度——这些都是可在 Unity Inspector 中调节的"模型高级选项"。

DBSearch通过以下抽象方法把SearchMethod的生命周期桥接到USearchIndex:

  • AddInternal(key, embedding)→index.Add((ulong)key, embedding);
  • RemoveInternal(key)→index.Remove((ulong)key);
  • SaveInternal(ZipArchive)/LoadInternal(ZipArchive)→index.Save/Load(archive)(即 2.2 节的 ZipArchive 持久化);
  • ClearInternal()→index.Dispose()后重建索引。

12.2 分组检索的底层实现

DBSearch.IncrementalFetchKeys展示了带过滤的增量检索流程:它先构造一个过滤委托,把不属于目标 group 或已见过的键排除掉,再调用带 filter 的搜索:

Func<int, int> filter = (int key) => !dataSplit.Contains(key) || seenKeys.Contains(key) ? 0 : 1; index.Search(embedding, k, out ulong[] keys, out float[] distances, filter);

这个委托最终会进入USearchIndex.Search,在 Android(IL2CPP)上通过[MonoPInvokeCallback]的StaticFilter+ 锁转发到原生usearch_filtered_search,其他平台则直接用 lambda。这与SimpleSearch(SimpleSearch.cs)先对组内所有 embedding 计算InverseDotProduct再排序的暴力方式形成鲜明对比:数据量大时,DBSearch的 ANN 检索显著更快。

12.3 RAG 的完整链路

从 RAG.cs 看,RAG 组件由"搜索方法 + 可选分块方法"组成:

rag.Init(SearchMethods.DBSearch, ChunkingMethods.TokenSplitter, llm); rag.Add(phrase); // 文本 -> embedding -> 入库 (string[] similarPhrases, float[] distances) = await rag.Search(query, k); rag.Save(ragPath); // 全部内容打包进 zip await rag.Load(ragPath);

结合 Chunking.cs 可以看到:启用分块时,长文本先被Split成多个 chunk,每个 chunk 作为独立条目加入DBSearch,并通过sentenceToPhrase/phraseToSentences映射回原始短语;ReturnChunks(true/false)决定搜索结果返回 chunk 还是整段原文。

12.4 测试佐证

仓库的 TestSearch.cs 对两套搜索方法做了完全对称的行为验证,可从中观察 USearch 检索的预期行为:

  • TestDBSearch与TestSimpleSearch共用同一套用例(TestSearchMethod<T>),验证了Add/Remove/Clear、按 group 计数、Top-k 搜索结果与距离、增量检索的分批取回、以及Save/Load往返一致性;
  • 测试使用固定的语义相近句子("how is the weather today?" 与 "is it raining?"),并断言固定距离差weatherRainingDiff = 0.2073563f,说明Cos度量下的语义距离是可复现的;
  • TestRAG_DBSearch_*系列把 DBSearch 分别与NoChunking、TokenSplitter、SentenceSplitter组合,验证了分块模式下返回 chunk 与返回原文两种行为的正确性。

例如,TestDBSearch会验证:添加weather、raining、sometext三条后,用weather查询 Top-2 时第一个结果必须是weather本身(距离约 0),第二个是raining(距离 0.2073);Save 后 Clear 再 Load,计数与检索结果均保持一致。

十三、已知边界与使用建议

综合文档与源码,有几个值得注意的边界需要如实说明:

  • 自定义度量尚未在 C# 绑定中启用:USearchTypes.cs留有"实现自定义度量委托"的 TODO,IndexOptions.metric字段当前固定为默认值。若需要 Haversine、Tanimoto 等度量,请使用已枚举的MetricKind;
  • 批量添加在 C# 侧是循环实现:USearchIndex.Add(keys[], vectors[][])逐条调用usearch_add,并非原生批量接口,大规模灌库时性能上不如 Python 绑定;
  • 原生库按平台分发:只有 Resources/usearch 下列出的 Windows、Linux、macOS、Android、iOS 五个平台有对应二进制,其他平台需要自行编译libusearch_c;
  • 过滤器在 Android 上串行化:为绕开 IL2CPP 回调限制,Android 平台的带过滤搜索使用了filterLock全局锁,多线程并发搜索场景下会有锁竞争。

十四、许可证与引用

本模块以Apache-2.0协议分发,完整文本见 Assets/LLMUnity/Runtime/RAG/usearch/LICENSE。若在论文或产品中引用 USearch,可参考上游 README 提供的 BibTeX 条目(其版本号为 2.8.16,DOI 为 10.5281/zenodo.7949416):

@software{Vardanian_USearch_2023, doi = {10.5281/zenodo.7949416}, author = {Vardanian, Ash}, title = {{USearch by Unum Cloud}}, url = {https://github.com/unum-cloud/usearch}, version = {2.8.16}, year = {2023}, month = oct, }

总结

USearch 以"单文件 HNSW + 无依赖 + 多语言绑定"的轻量设计,成为向量相似度检索领域 FAISS 之外的高性价比选择。在 Mate-Engine 仓库中,它经由 NativeMethods.cs 的原生互操作层、USearchIndex.cs 的托管包装(含 ZipArchive 持久化与过滤搜索扩展)被完整移植进 Unity,并通过 DBSearch.cs 接入 LLMUnity RAG,为桌面伴侣应用提供"先向量检索、再生成回答"的语义问答能力。理解这套引擎的参数体系(度量、量化、connectivity、expansion)与序列化机制,是在本项目里打造高效、可持久化语义搜索系统的关键。

  • 桌面应用
  • 数字人
  • AI 应用

【免费下载链接】Mate-Engine

A free Desktop Mate alternative with a lightweight interface and custom VRM support, though with more features.

项目地址:https://gitcode.com/gh_mirrors/ma/Mate-Engine
点击查看免费下载

相关推荐

上一篇:New API 大模型网关部署与多协议转换实战:Docker 快速上手、环境变量与网关架构解析
下一篇:First Contributions 项目实战:Git 用户身份与配置作用域完全指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询