- 后端
- AI 应用
- NLP
【免费下载链接】xberg
Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.
导读
本文讲解 xberg 在 Kotlin / Android 绑定中如何通过Xberg.listEmbeddingBackends()枚举当前进程内已注册的全部 Embedding 后端名称。该 API 属于 xberg 插件体系(registry)中的"只读、无副作用"查询能力,是 xberg-cli、REST API 与 MCP server 共同依赖的底层能力在 Android 端的一等公民封装;读完本文你将掌握该方法的准确签名、返回值语义、底层 JNI→Rust 调用链,以及它与EmbeddingBackendBridge注册/注销/清空 API 的配套关系,并能在自己的 Android 项目中直接落地。
一、这个 API 解决什么问题
xberg 的 Embedding 后端是"进程内插件":调用方可以把自己已经加载好的模型封装(例如llama-cpp-python、sentence-transformers或自研 ONNX 模型)注册进全局注册表,供 chunking 切分与独立 embed 请求在配置中按名称引用,全程无需 HuggingFace 下载、无需 ONNX Runtime、也无需 HTTP 侧车进程(参见 api-kotlin-android.md 中EmbeddingModelType.Plugin的说明)。
既然后端是运行时注册的,"当前到底注册了哪些后端"就成了一个高频且必须的查询:无论是诊断、配置生成还是故障排查,都需要一个无副作用、只读、幂等的枚举入口。listEmbeddingBackends()正是这个入口,其返回的是当前注册表中全部后端名称的列表,供上层决定后续配置引用哪个后端。
二、Kotlin (Android) 中的标准用法
来自生成文档 list_embedding_backends.md 的最小可运行示例:
import io.xberg.* fun main() { val result = Xberg.listEmbeddingBackends() println(result) }这个片段虽短,但包含了三个关键事实:
- 入口类:
io.xberg.Xberg是 Kotlin/Android 绑定的门面类,所有原生能力通过它暴露; - 方法名:
listEmbeddingBackends(),与 Rust 侧list_embedding_backends、JSON-RPC 调用名list_embedding_backends(见下文 fixtures)一一对应; - 返回值:
result是一个字符串列表,直接println即可输出。
官方 API 参考 api-kotlin-android.md 给出了更精确的签名:
@Throws(XbergError::class) fun listEmbeddingBackends(): List<String>要点:
- 返回类型:
List<String>——只返回名称,不返回能力元数据。若需要每个后端的语言/维度等能力信息,应使用同族的listOcrBackendCapabilities()思路(OCR 侧)或查询具体的注册表实现;Embedding 名称列表本身按注册表内部顺序给出。 - 错误语义:该调用几乎不会失败,但签名上仍标注
@Throws(XbergError::class);Rust 侧仅在"无法获取注册表读锁"这种极端环境下才返回错误,见下文源码。
三、从 Kotlin 到 Rust 的完整调用链
这个看似简单的方法,实际穿透了三层实现。在 Xberg.kt 中:
/** * List the names of all registered embedding backends. * * Used by `xberg-cli`, the api/mcp endpoints, and generated language * bindings. */ fun listEmbeddingBackends(): List<String> { val resultJson = XbergBridge.nativeListEmbeddingBackends() return mapper.readValue(resultJson, object : TypeReference<List<String>>() {}) }调用链逐层如下:
- Kotlin 门面(
Xberg.kt):将 JNI 返回的 JSON 字符串反序列化为List<String>; - JNI 声明(XbergBridge.kt):
external fun nativeListEmbeddingBackends(): String,由 Android 侧加载的xberg_jni原生库实现; - Rust 实现(plugins/embedding.rs):
/// List the names of all registered embedding backends. /// /// Used by `xberg-cli`, the api/mcp endpoints, and generated language /// bindings. pub fn list_embedding_backends() -> Result<Vec<String>> { use crate::plugins::registry::get_embedding_backend_registry; let registry = get_embedding_backend_registry(); let registry = registry.read(); Ok(registry.list()) }可以看到 Rust 侧的实现极其轻量:拿到全局注册表的读锁后直接调用registry.list()返回名称向量。注释中明确写道该函数"被xberg-cli、api/mcp 端点以及各语言生成绑定使用"——这正是跨绑定行为一致的根源:所有语言端的list_embedding_backends最终都收敛到同一个 Rust 实现。
四、配套的注册表管理 API:注册、注销、清空
listEmbeddingBackends()之所以有值,是因为它配合一套完整的"运行时管理"API。在 EmbeddingBackendBridge.kt 中定义了注册表桥接对象:
EmbeddingBackendBridge.register(impl: IEmbeddingBackend)——把实现IEmbeddingBackend接口的 Kotlin 对象包装为EmbeddingBackendJniDispatcher(JSON 调度包装器,见 EmbeddingBackendJniDispatcher.kt),再通过XbergBridge.nativeRegisterEmbeddingBackend交给原生注册表;EmbeddingBackendBridge.unregister(name: String)——按名称移除;EmbeddingBackendBridge.clearAll()——清空全部;EmbeddingBackendBridge.getAll(): Map<String, IEmbeddingBackend>——返回本地缓存的全部注册项。
对应的 JNI 原生方法声明集中在 XbergBridge.kt:
external fun nativeRegisterEmbeddingBackend(impl: io.xberg.EmbeddingBackendJniDispatcher) external fun nativeUnregisterEmbeddingBackend(name: String) external fun nativeClearEmbeddingBackends()因此一个完整的"注册→验证→使用→注销"生命周期大致是:
import io.xberg.* // 1. 注册一个 Embedding 后端(实现 IEmbeddingBackend 接口) EmbeddingBackendBridge.register(myBackend) // 2. 枚举验证:应包含 myBackend 的名称 val backends = Xberg.listEmbeddingBackends() println(backends) // 输出形如 [myBackend, ...] // 3. 使用完毕按名称注销 EmbeddingBackendBridge.unregister(myBackend.name)接口IEmbeddingBackend(IEmbeddingBackend.kt)是对 Rust 侧Arc<dyn EmbeddingBackend>特征的镜像,Rust 侧会在 chunking 过程中并发回调已注册的后端,因此实现方需要注意线程安全与生命周期管理(接口文档中特别提到引用持有与释放的约定)。
五、实际业务场景:注册后如何在配置中引用
listEmbeddingBackends()的典型消费场景是:先枚举拿到可用名称,再把它写进 chunking 配置。
在 api-kotlin-android.md 的EmbeddingModelType说明中,Plugin变体正是"通过插件系统注册的进程内 Embedding 后端",其字段只有name: String——而这个 name 必须与注册表里的名称精确匹配。从源码结构可以推断,一个典型的配置流程是:
import io.xberg.* // 动态发现可用后端,避免硬编码名称 val available = Xberg.listEmbeddingBackends() val target = available.first { it == "my-custom-embedder" } // 将名称写入 EmbeddingConfig,选择 Plugin 模型类型 // EmbeddingConfig(model = EmbeddingModelType.Plugin(name = target), ...)Plugin模型类型的特性是:宿主自行持有模型生命周期,因此batch_size、cache_dir、show_download_progress、acceleration等模型加载字段均被忽略,只有normalize(调用后 L2 归一化)与调度超时字段生效。"先 list、再引用"的做法可以避免配置中引用一个从未注册或已被注销的后端名称。
六、测试与跨端一致性验证
该 API 的正确性在仓库中有多层验证:
- e2e 测试:RegistryTest.kt 中的
testListEmbeddingBackends()直接调用Xberg.listEmbeddingBackends()并断言结果非空;EmbeddingBackendManagementTest.kt 则在"清空所有后端"之后再次枚举,验证清空语义与枚举的联动。 - fixture 契约:list_embedding_backends.json 定义了该调用的契约——
"category": "registry"、"call": "list_embedding_backends"、"input": {}(无需入参)、断言not_error(必须成功返回)。e2e 用例正是由 alef 工具链依据这类 fixture 生成并保持同步的。 - 跨绑定一致:
list_embedding_backends在 java、dart、php、swift、typescript、wasm 等绑定的 snippets 中都有对应生成文件(如 api-typescript.md、api-java.md),全部收敛到 Rust 侧同一实现,Android 端只是其中之一。若你想在服务端先验证结果,也可通过 REST API / MCP 的 registry 端点调用同名操作(Rust 注释中已点明该函数服务于xberg-cli与 api/mcp 端点)。
七、注意事项与最佳实践
- 只读无副作用:fixture 明确标注该调用
side_effect: safe,可放心在任何时机调用(例如每轮配置生成前做一次健康检查),不会触发模型下载、网络请求或状态变更。 - 名称即契约:注册表按名称索引,
listEmbeddingBackends()返回的名称必须与EmbeddingModelType.Plugin(name = ...)中的 name 完全一致;建议用枚举结果驱动配置,而不是硬编码。 - 并发安全:Rust 侧通过读锁访问注册表,调用本身线程安全;但返回的列表是注册表在加锁瞬间的快照,若并发注册/注销,快照可能与最新状态有细微差异,业务上应允许重试或重新枚举。
- 与 OCR 等其它注册表类比:
registry类别下还有list_ocr_backends、list_post_processors、list_renderers、list_validators等平行 API(见 fixtures/registry),它们遵循完全相同的"枚举→按名称引用"模式,理解了一个即可举一反三。
总而言之,Xberg.listEmbeddingBackends()是 xberg Android 插件体系中成本最低、也最常用的探针式 API:三层调用链清晰、行为与 CLI/MCP/其余 14 种绑定完全对齐,配合EmbeddingBackendBridge的注册族 API,即可在 Android 应用内构建"注册—枚举—按名引用"的完整 Embedding 插件工作流。
- 后端
- AI 应用
- NLP
【免费下载链接】xberg
Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.
相关推荐
xberg Java 绑定实战:使用 listEmbeddingBackends() 枚举已注册的 Embedding 后端
xberg Java 绑定实战:使用 listEmbeddingBackends 枚举已注册的 Embedding 后端 本篇技术指南围绕 xberg(以 Ru
后端AI 应用NLPxberg Dart 绑定:使用 listEmbeddingBackends 查询已注册的 Embedding 插件后端
xberg Dart 绑定:使用 listEmbeddingBackends 查询已注册的 Embedding 插件后端 本文围绕 xberg 项目 Dart/
后端AI 应用NLPxberg C FFI 插件 API 实战:xberg_list_embedding_backends 枚举已注册嵌入后端
xberg C FFI 插件 API 实战:xberg_list_embedding_backends 枚举已注册嵌入后端 本文以 xberg 的 C FFI
后端AI 应用NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考