knowledge-models
v0.0.0-beta.2
Published
SpecFlow Knowledge Models — 本地向量模型服务(bge-base-zh-v1.5 ONNX 量化版)+ 异步编码 API
Maintainers
Readme
Knowledge Models
本地向量模型服务,基于 BAAI/bge-base-zh-v1.5(ONNX 量化版),提供高性能中文文本向量化 API。
技术概要
| 项目 | 说明 | |------|------| | 模型 | BAAI/bge-base-zh-v1.5(ONNX 量化) | | 向量维度 | 768 维 float32 | | 适用场景 | 语义搜索、文本相似度、RAG 检索、聚类 | | 语言 | 中文(也支持英文) | | 模型大小 | ~100MB(量化后) | | 推理方式 | 本地 ONNX Runtime,无需 GPU |
安装
npm install knowledge-models快速开始
方式一:启动 HTTP 服务
npx embedding-server方式二:Node.js 客户端调用
const { EmbeddingClient } = require('knowledge-models/client');
const client = new EmbeddingClient({ baseUrl: 'http://localhost:38771' });
const vector = await client.encode('你好世界');
// vector: number[],长度为 768方式三:进程内直接编码
const { BGEEncoder } = require('knowledge-models');
const encoder = new BGEEncoder();
await encoder.load();
const vector = await encoder.encode('你好世界', true);HTTP API
服务配置
| 环境变量 | 默认值 | 说明 |
|----------|--------|------|
| EMBEDDING_PORT | 38771 | 服务端口 |
| EMBEDDING_CONCURRENCY | 4 | 最大并发数 |
| EMBEDDING_BATCH_SIZE | 16 | 批处理大小 |
POST /encode
单条文本编码。
Request
POST /encode
Content-Type: application/json{
"text": "人工智能正在改变世界"
}| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| text | string | 是 | 待编码文本 |
Response 200
{
"vector": [0.0123, -0.0456, 0.0789, "..."],
"dim": 768,
"model": "BAAI/bge-base-zh-v1.5",
"latency": 45
}| 字段 | 类型 | 说明 |
|------|------|------|
| vector | number[] | 768 维浮点向量 |
| dim | number | 向量维度,固定 768 |
| model | string | 模型名称 |
| latency | number | 编码耗时(毫秒) |
POST /encode/batch
批量文本编码。
Request
POST /encode/batch
Content-Type: application/json{
"texts": ["文本一", "文本二", "文本三"]
}| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| texts | string[] | 是 | 待编码文本数组 |
Response 200
{
"vectors": [
[0.0123, -0.0456, "..."],
[0.0234, -0.0567, "..."],
[0.0345, -0.0678, "..."]
],
"dim": 768,
"model": "BAAI/bge-base-zh-v1.5",
"latency": 128
}| 字段 | 类型 | 说明 |
|------|------|------|
| vectors | number[][] | 每条文本对应的 768 维向量 |
| dim | number | 向量维度,固定 768 |
| model | string | 模型名称 |
| latency | number | 总耗时(毫秒) |
GET /health
健康检查。
GET /healthResponse 200
{
"status": "ok",
"modelLoaded": true,
"queueLength": 0,
"processing": 0,
"uptime": 3600,
"memory": {
"heapUsed": 524288000,
"heapTotal": 1073741824,
"rss": 1610612736
}
}| 字段 | 类型 | 说明 |
|------|------|------|
| status | "ok" \| "loading" \| "error" | 服务状态 |
| modelLoaded | boolean | 模型是否加载完成 |
| queueLength | number | 等待中的任务数 |
| processing | number | 正在处理的任务数 |
| uptime | number | 运行时长(秒) |
| memory.heapUsed | number | 堆内存已用(字节) |
| memory.heapTotal | number | 堆内存总量(字节) |
| memory.rss | number | 常驻内存(字节) |
GET /stats
服务统计信息。
GET /statsResponse 200
{
"requests": 15420,
"successCount": 15398,
"failCount": 22,
"avgLatency": 52,
"queueLength": 3,
"processing": 2,
"modelLoaded": true,
"startTime": 1752134400000
}| 字段 | 类型 | 说明 |
|------|------|------|
| requests | number | 累计请求数 |
| successCount | number | 成功次数 |
| failCount | number | 失败次数 |
| avgLatency | number | 平均延迟(毫秒) |
| queueLength | number | 当前排队数 |
| processing | number | 正在处理数 |
| modelLoaded | boolean | 模型是否就绪 |
| startTime | number | 服务启动时间戳 |
GET /task/:id
查询异步任务状态与结果。
GET /task/{taskId}Response 200
{
"id": "abc123-def456",
"status": "completed",
"results": [
[0.0123, -0.0456, "..."],
[0.0234, -0.0567, "..."]
],
"completed": 2,
"total": 2,
"progress": 1.0
}| 字段 | 类型 | 说明 |
|------|------|------|
| id | string | 任务 ID |
| status | "pending" \| "processing" \| "completed" \| "failed" | 任务状态 |
| results | number[][] | 编码结果(完成时) |
| error | string | 错误信息(失败时) |
| completed | number | 已完成条数 |
| total | number | 总条数 |
| progress | number | 进度 0.0~1.0 |
Error 404
{ "success": false, "error": "Task not found" }Node.js API
EmbeddingClient
远程客户端,连接 HTTP 编码服务。
const { EmbeddingClient } = require('knowledge-models/client');
const client = new EmbeddingClient({
baseUrl: 'http://localhost:38771', // 服务地址
timeout: 60000, // 超时(毫秒),默认 60000
retries: 3, // 重试次数,默认 3
retryDelay: 1000, // 重试间隔(毫秒),默认 1000
});client.encode(text)
单条文本编码。
| 参数 | 类型 | 说明 |
|------|------|------|
| text | string | 待编码文本 |
返回值 Promise<number[]> — 768 维浮点向量。
client.encodeBatch(texts)
批量文本编码。
| 参数 | 类型 | 说明 |
|------|------|------|
| texts | string[] | 待编码文本数组 |
返回值 Promise<number[][]> — 每条文本对应的向量。
client.health()
健康检查。
返回值 Promise<HealthResponse> — 服务健康状态对象。
client.stats()
获取服务统计。
返回值 Promise<ServerStats> — 服务运行统计。
client.waitForTask(taskId, options?)
等待异步任务完成并返回结果。
| 参数 | 类型 | 说明 |
|------|------|------|
| taskId | string | 任务 ID |
| options.timeout | number | 超时(毫秒),默认 60000 |
| options.pollInterval | number | 轮询间隔(毫秒),默认 500 |
返回值 Promise<number[][]> — 编码结果。
便捷函数
const { createLocalClient, createEncodeFn } = require('knowledge-models/client');
// 快速创建本地客户端
const client = createLocalClient(38771);
// 直接获得编码函数
const encode = await createEncodeFn('http://localhost:38771');
const result = await encode('文本文本');
// result: Float32Array(768)BGEEncoder
进程内编码器,直接加载模型推理。
const { BGEEncoder } = require('knowledge-models');
const encoder = new BGEEncoder();
await encoder.load(); // 加载模型
const vec = await encoder.encode('文本', true); // 编码(isQuery=true 用于检索)
const vecs = await encoder.encodeBatch(['a', 'b']); // 批量编码isQuery 参数说明:设为 true 时添加查询前缀以优化检索效果,设为 false 时用于文档入库。
语义搜索示例(余弦相似度)
function cosineSimilarity(a, b) {
let dot = 0, normA = 0, normB = 0;
for (let i = 0; i < a.length; i++) {
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
}
// 查询
const qVec = await client.encode('什么是向量检索?');
// 计算每个文档的相似度
const scores = docVectors.map(dv => cosineSimilarity(qVec, dv));
// 排序取 topK
const topK = scores
.map((s, i) => ({ score: s, doc: documents[i] }))
.sort((a, b) => b.score - a.score)
.slice(0, 5);使用 curl 测试
# 健康检查
curl http://localhost:38771/health
# 单条编码
curl -X POST http://localhost:38771/encode \
-H "Content-Type: application/json" \
-d '{"text":"语义搜索基于向量相似度"}'
# 批量编码
curl -X POST http://localhost:38771/encode/batch \
-H "Content-Type: application/json" \
-d '{"texts":["文本1","文本2","文本3"]}'
# 服务统计
curl http://localhost:38771/stats