api-embedding — 文本向量化契约
包名: @aalis/api-embedding
源码: packages/api-embedding/src/index.ts
实现: @aalis/plugin-embedding-openai, @aalis/plugin-embedding-ollama
概述
最小化的 Embedding 服务契约:把一段文本转成 number[] 向量。被 vector memory / 语义搜索 / RAG 等场景消费。描述符 embedding 不给 bind,业务层就是 EmbeddingService 形状的活句柄(caps.embedding.use)。
服务接口
ts
interface EmbeddingService {
readonly modelId?: string;
embed(text: string, options?: { signal?: AbortSignal }): Promise<number[]>;
}契约里没有列模型的方法:提供者要给自己配置里的模型字段出下拉,经贡献点 webui:options 交自己的可选项来源(见 api-webui)。
modelId 是可选的向量空间标识:modelId 相同的两次 embed 结果可以直接比较,换模型必须换值。消费方可把它并入向量缓存的失效键,从而在换模型(包括同维度换模型)后识别并重算旧向量;提供者不声明时,消费方无法区分模型。两个第一方实现分别声明为 openai:<model> 与 ollama:<model>。
调用方可传入 options.signal,在回合取消或检索超时时终止请求。Ollama 和 OpenAI 实现都会将它传至底层 HTTP 请求;调用方取消不触发重试,provider 自身的超时与重试策略仍然生效。
获取方式
ts
import { embedding } from '@aalis/api-embedding';
import { definePlugin } from '@aalis/core';
export default definePlugin({
name: '@acme/plugin-example-embedding',
uses: { embedding },
apply({ embedding }) {
if (!embedding.present) return;
void embedding.use.embed('the quick brown fox');
},
});业务句柄 embedding.use 是活的,选择、缺席与固定同一家的规则见 选择层与业务层。
注意事项
- 向量维度由具体 provider 决定(如 OpenAI text-embedding-3-small = 1536;ollama nomic-embed-text = 768),契约不暴露维度。消费方应避免假设维度,也不能靠维度区分模型(同维度换模型的向量同样不可比较)。
plugin-memory-vector不探测维度,靠modelId区分模型:提供者声明了它时,写入的向量 metadata 带上modelId,检索只保留与查询向量同模型的候选。 - 多个 embedding 实现并存时,
embedding.use只打到本插件选中的那一家(通过 instanceId / 偏好区分多实例)。