用于从大文本中语义化创建分块的 NPM 包。适用于涉及大语言模型(LLMs)的工作流。
工作原理
npm install semantic-chunking
运行 semantic-chunking 最简单的方法是使用 Docker Compose:
# 启动 Web UI 服务器
npm run docker:compose:up
# 在 http://localhost:3000 访问 Web UI
# 停止服务器
npm run docker:compose:down
docker-compose.yml 配置包括:
- 端口映射:3000:3000 用于 Web UI
- 卷映射:挂载 ./models 目录以在容器重启间持久化下载的嵌入模型
- 健康检查和自动重启策略
# 构建 Docker 镜像
npm run docker:build
# 使用 models 卷运行容器
npm run docker:run
# 或直接使用 docker-compose
docker-compose up -d
要直接使用分块函数(不仅仅是 Web UI):
# 在容器内执行 chunkit 示例
docker-compose exec semantic-chunking node example/example-chunkit.js
# 执行 cramit 示例
docker-compose exec semantic-chunking node example/example-cramit.js
# 执行 sentenceit 示例
docker-compose exec semantic-chunking node example/example-sentenceit.js
./models 目录被挂载为卷,用于持久化下载的 ONNX 嵌入模型。模型在首次使用时自动下载,大小从 23MB 到 548MB 不等,具体取决于您选择的模型。持久化此目录意味着:
- 模型仅下载一次
- 容器重启更快
- 模型在容器更新后得以保留
- 您可以在运行 Docker 之前使用 npm run download-models 预下载模型
将 semantic-chunking 作为微服务 API 运行,以便集成到您的应用程序中。
启动 API 服务器:
# 使用 Docker Compose(推荐)
npm run docker:compose:up
# 或在本地运行
npm run api-server
API 将在 http://localhost:3001 可用,并显示一个终端风格的登录页面,其中包含使用说明。
POST /api/chunkit - 基于相似度的语义分块POST /api/cramit - 无相似度分析的密集打包POST /api/sentenceit - 将文本分割成句子GET /api/health - 健康检查GET /api/version - API 版本curl -X POST http://localhost:3001/api/chunkit \
-H "Content-Type: application/json" \
-d '{
"documents": [
{
"document_name": "test",
"document_text": "Your text here..."
}
],
"options": {
"maxTokenSize": 500,
"similarityThreshold": 0.5
}
}'
通过设置 API_AUTH_TOKEN 环境变量启用 Bearer 令牌身份验证:
# 在 .env 文件中
API_AUTH_TOKEN=your-secret-token-here
# 或在 docker-compose.yml 中
environment:
- API_AUTH_TOKEN=your-secret-token-here
启用后,在请求中包含令牌:
curl -X POST http://localhost:3001/api/chunkit \
-H "Authorization: Bearer your-secret-token-here" \
-H "Content-Type: application/json" \
-d '...'
docker-compose 配置包括两个服务:
API 服务器(默认):
docker-compose up -d
# 在 http://localhost:3001 可用
API 服务器 + Web UI:
docker-compose --profile webui up -d
# API: http://localhost:3001
# Web UI: http://localhost:3000
有关所有端点、请求/响应格式、错误处理和部署指南的完整 API 文档,请参阅 API.md。
基本用法:
import { chunkit } from 'semantic-chunking';
const documents = [
{ document_name: "document1", document_text: "contents of document 1..." },
{ document_name: "document2", document_text: "contents of document 2..." },
...
];
const chunkitOptions = {};
const myChunks = await chunkit(documents, chunkitOptions);
注意 🚨 嵌入模型 (onnxEmbeddingModel) 将在首次运行时下载到此包的缓存目录中(文件大小取决于指定的模型;请参阅模型表)。
chunkit 接受一个文档对象数组和一个可选的配置对象。以下是每个参数的详细信息:
documents:文档数组。每个文档是一个包含 document_name 和 document_text 的对象。
documents = [
{ document_name: "document1", document_text: "..." },
{ document_name: "document2", document_text: "..." },
...
]
Chunkit 选项对象:
logging:布尔值(可选,默认 false)- 启用详细处理步骤的日志记录。
maxTokenSize:整数(可选,默认 500)- 每个分块的最大令牌大小。similarityThreshold:浮点数(可选,默认 0.5)- 确定句子是否足够相似以属于同一分块的阈值。值越高要求相似度越高。dynamicThresholdLowerBound:浮点数(可选,默认 0.4)- 动态相似度阈值的最小可能值。dynamicThresholdUpperBound:浮点数(可选,默认 0.8)- 动态相似度阈值的最大可能值。numSimilaritySentencesLookahead:整数(可选,默认 3)- 为计算相似度而向前查看的句子数量。combineChunks:布尔值(可选,默认 true)- 确定是否重新平衡并将分块合并成更大的块,直到达到最大令牌限制。combineChunksSimilarityThreshold:浮点数(可选,默认 0.5)- 在再平衡和合并阶段基于相似度合并分块的阈值。onnxEmbeddingModel:字符串(可选,默认 Xenova/all-MiniLM-L6-v2)- 用于创建嵌入的 ONNX 模型。dtype:字符串(可选,默认 fp32)- 嵌入模型的精度(选项:fp32, fp16, q8, q4)。device:字符串(可选,默认 cpu)- 模型使用的执行提供程序(选项:cpu, webgpu)。localModelPath:字符串(可选,默认 null)- 保存和加载模型的本地路径(例如:./models)。modelCacheDir:字符串(可选,默认 null)- 缓存下载模型的目录(例如:./models)。returnEmbedding:布尔值(可选,默认 false)- 如果设置为 true,每个分块将包含一个嵌入向量。这对于需要分块语义理解的应用很有用。嵌入模型将与 onnxEmbeddingModel 中指定的相同。returnTokenLength:布尔值(可选,默认 false)- 如果设置为 true,每个分块将包含令牌长度。这对于理解每个分块在令牌方面的大小很有用,这对于基于令牌的处理限制很重要。令牌长度使用 onnxEmbeddingModel 中指定的分词器计算。chunkPrefix:字符串(可选,默认 null)- 添加到每个分块的前缀(例如:"search_document: ")。这对于使用经过特定任务前缀训练的嵌入模型(如 nomic-embed-text-v1.5 模型)特别有用。前缀在计算嵌入或令牌长度之前添加。excludeChunkPrefixInResults:布尔值(可选,默认 false)- 如果设置为 true,分块前缀将从结果中移除。当您希望从结果中移除前缀,同时在嵌入计算中仍保留前缀时,这很有用。输出是一个分块数组,每个分块包含以下属性:
document_id:整数 - 文档的唯一标识符(当前时间戳,毫秒)。document_name:字符串 - 被分块的文档名称(如果提供)。number_of_chunks:整数 - 从输入文本返回的最终分块总数。chunk_number:整数 - 当前分块的编号。model_name:字符串 - 使用的嵌入模型名称。dtype:字符串 - 使用的嵌入模型的精度(选项:fp32, fp16, q8, q4)。text:字符串 - 分块后的文本。embedding:数组 - 嵌入向量(如果 returnEmbedding 为 true)。token_length:整数 - 令牌长度(如果 returnTokenLength 为 true)。了解您选择的模型在对文本分块时的行为非常重要。
强烈建议使用 Web UI 调整所有参数,以便为您的用例获得最佳结果。
Web UI README
示例 1:使用自定义相似度阈值的基本用法:
import { chunkit } from 'semantic-chunking';
import fs from 'fs';
async function main() {
const documents = [
{
document_name: "test document",
document_text: await fs.promises.readFile('./test.txt', 'utf8')
}
];
let myChunks = await chunkit(documents, { similarityThreshold: 0.4 });
myChunks.forEach((chunk, index) => {
console.log(`\n-- Chunk ${index + 1} --`);
console.log(chunk);
});
}
main();
示例 2:使用较小的最大令牌大小进行分块:
import { chunkit } from 'semantic-chunking';
const frogText = "A frog hops into a deli and croaks to the cashier, \"I'll have a sandwich, please.\" The cashier, surprised, quickly makes the sandwich and hands it over. The frog takes a big bite, looks around, and then asks, \"Do you have any flies to go with this?\" The cashier, taken aback, replies, \"Sorry, we're all out of flies today.\" The frog shrugs and continues munching on its sandwich, clearly unfazed by the lack of fly toppings. Just another day in the life of a sandwich-loving amphibian! 🐸🥪";
const documents = [
{
document_name: "frog document",
document_text: frogText
}
];
async function main() {
let myFrogChunks = await chunkit(documents, { maxTokenSize: 65 });
console.log("myFrogChunks", myFrogChunks);
}
main();
查看 example\example-chunkit.js 文件,了解使用所有可选参数的更复杂示例。
可以使用选项对象中的几个可选参数来微调 chunkit 函数的行为。了解每个参数如何影响函数可以帮助您根据特定需求优化分块过程。
loggingfalsemaxTokenSize500similarityThreshold0.456dynamicThresholdLowerBound0.2dynamicThresholdUpperBound0.8numSimilaritySentencesLookahead2combineChunkstruemaxTokenSize 合并成较大的块。这可以通过更有效地分组密切相关的内容来增强输出的可读性。combineChunksSimilarityThreshold0.4similarityThreshold,但专门用于重新平衡现有分块。调整此参数有助于微调最终分块的粒度。onnxEmbeddingModelXenova/all-MiniLM-L6-v2devicecpucpu 和 webgpu。使用 webgpu 以利用 GPU 加速进行更快的处理。请注意,WebGPU 支持可能因环境而异。dtypefp32fp32, fp16, q8, q4。fp32 是最高精度,但也是最大尺寸且加载最慢。如果模型支持,q8 是尺寸和速度之间的良好折衷。所有模型都支持 fp32,但只有部分支持 fp16, q8 和 q4。| 模型 | 精度 | 链接 | 大小 |
|---|---|---|---|
| nomic-ai/nomic-embed-text-v1.5 | fp32, q8 | https://huggingface.co/nomic-ai/nomic-embed-text-v1.5 | 548 MB, 138 MB |
| thenlper/gte-base | fp32 | https://huggingface.co/thenlper/gte-base | 436 MB |
| Xenova/all-MiniLM-L6-v2 | fp32, fp16, q8 | https://huggingface.co/Xenova/all-MiniLM-L6-v2 | 23 MB, 45 MB, 90 MB |
| Xenova/paraphrase-multilingual-MiniLM-L12-v2 | fp32, fp16, q8 | [https://huggingface.co/Xenova/paraphrase-multilingual-MiniLM-L12-v2](https://huggingface.co/Xenova/paraphrase-multilingual-Mini |