- 人工智能
- AI Agent
- Agent 编排
- 低代码
- AI 技能
- RAG
【免费下载链接】nexent
Nexent 是一个开源智能体SDK和平台,能够将描述流程的自然语言转化为完整的多模态服务 —— 无需编排,无需复杂拖拉拽。基于 MCP 工具生态系统构建,Nexent 提供灵活的模型集成、可扩展的数据处理和强大的知识库管理。我们的目标很简单:将数据、模型和工具整合到一个智能中心中,让任何人都能轻松地将 Nexent 集成到项目中,使日常工作流程更智能、更互联。
Nexent 的开源 SDK 将"文件 → 文本块(chunks)→ 向量 → 知识库"这条链路收敛到一个统一入口DataProcessCore上:无论是 PDF、Word、Excel 还是 Markdown,只需传入内存字节与文件名,即可自动完成格式识别、内容解析、分块(chunking),并在多模态场景下同步提取文档内嵌图片。本文以 SDK 源码实现为佐证,完整讲解file_process()/file_split()的签名、参数、处理器选择规则与返回结构,覆盖 5 个可直接运行的实战示例、4 个辅助方法、错误处理与性能调优,最后结合后端 Celery + Ray + MinIO + Elasticsearch 的调用链说明它在知识库流水线中的真实位置。读完本文,你将能在自己的项目中独立接入 Nexent 的文件处理能力。
一、DataProcessCore 是什么
DataProcessCore是 sdk/nexent/data_process/core.py 中定义的一个外观类(Facade),它将三种文件处理器与一个文件拆分器统一注册到内部processors字典中:
| 注册名 | 实现类 | 职责 |
|---|---|---|
Unstructured | UnstructuredProcessor | 通用格式解析与分块(txt/pdf/docx/html/md 等) |
OpenPyxl | OpenPyxlProcessor | Excel(.xlsx/.xls)专用解析,输出 Markdown 表格 |
UniversalImageExtractor | UniversalImageExtractor | 按需提取文档内嵌图片(PDF/Office) |
FileSplitter | FileSplitter | 大文件按格式拆分 |
从源码结构看,DataProcessCore遵循"按扩展名自动选择处理器 + 按需叠加图像提取器"的设计:解析流程与图像提取流程相互独立,最后以(chunks, images_info)二元组统一返回,便于上层(向量化、知识库入库)直接消费。
模块的公共导出位于 sdk/nexent/data_process/init.py,from nexent.data_process import DataProcessCore即可使用。注意 SDK 要求 Python>=3.11,<3.12(见 sdk/pyproject.toml),且unstructured相关依赖需要通过pip install "nexent[data_process]"安装(extra 声明为unstructured[all-docs]与unstructured-inference==1.2.0)。
二、核心方法:file_process()
2.1 函数签名
def file_process(self, file_data: bytes, filename: str, chunking_strategy: str = "basic", processor: Optional[str] = None, **params) -> Tuple[List[Dict], List[Dict]]2.2 参数说明
| 参数 | 类型 | 必填 | 说明 | 取值 |
|---|---|---|---|---|
file_data | bytes | 是 | 文件字节数据(内存处理) | 任意合法字节流 |
filename | str | 是 | 文件名,用于自动识别文件类型并选择处理器 | 任意合法文件名 |
chunking_strategy | str | 否 | 分块策略 | "basic"、"by_title"、"none" |
processor | str | 否 | 显式指定处理器;缺省时按扩展名自动选择 | "Unstructured"、"OpenPyxl" |
**params | dict | 否 | 附加处理参数 | 见下文参数细节 |
2.3 分块策略(chunking_strategy)详解
| 策略 | 说明 | 适用场景 | 输出特征 |
|---|---|---|---|
"basic" | 基础分块策略 | 大多数文档处理场景 | 按内容长度自动分块 |
"by_title" | 按标题分块 | 结构化文档(技术文档、报告等) | 在标题边界处切分 |
"none" | 不分块 | 短文档或需要完整内容时 | 返回包含全部内容的单个块 |
从源码看,三种策略由 UnstructuredProcessor._process_elements 落实:"none"将分区得到的全部元素文本用"\n\n"拼接为单个文档;其余策略则逐元素生成块。而在 UnstructuredProcessor._prepare_partition_kwargs 中,chunking_strategy会直接透传给unstructured.partition.auto.partition(当为"none"时置为None),由底层库完成标题感知的切分。
2.4 处理器选择规则
- 扩展名位于
EXCEL_EXTENSIONS(.xlsx、.xls)→ 使用OpenPyxl处理器; - 其他受支持扩展名 → 使用
Unstructured处理器; - 当
params中包含model_type="multi_embedding"且扩展名位于EXTRACT_IMAGE_EXTENSIONS(.pdf、.doc、.docx、.xls、.xlsx、.ppt、.pptx)时,额外调用UniversalImageExtractor提取文档内嵌图片。
该逻辑对应 core.py 的_select_processor_by_filename:处理器选择只看扩展名(大小写不敏感),图像提取器选择则同时依赖model_type与扩展名。测试 test/sdk/data_process/test_core.py 中的参数化用例进一步验证了组合规则,例如test.pptx在无multi_embedding时提取器为None,而test.pdf、test.docx在multi_embedding下均会挂载UniversalImageExtractor。
2.5 附加参数(**params)详解
| 参数 | 类型 | 默认值 | 说明 | 适用处理器 |
|---|---|---|---|---|
max_characters | int | 1536 | 每个块的最大字符数 | 通用(Unstructured) |
new_after_n_chars | int | 1024 | 超过该字符数后开启新块 | 通用(Unstructured) |
strategy | str | "fast" | 处理策略 | 通用(Unstructured) |
skip_infer_table_types | list | [] | 跳过推断的表类型 | 通用(Unstructured) |
task_id | str | "" | 任务标识 | 通用(Unstructured) |
model_type | str | None | 嵌入模型类型;"multi_embedding"触发图像提取 | 通用 |
这些默认值与 UnstructuredProcessor.init中维护的default_params完全一致;用户传入的参数通过_merge_params覆盖默认值后透传给unstructured.partition。后端还会额外注入table_transformer_model_path与unstructured_default_model_initialize_params_json_path(见 backend/data_process/ray_actors.py),供UniversalImageExtractor在 hi_res 策略下加载表格识别模型。
2.6 返回值格式
返回Tuple[List[Dict], List[Dict]],即(chunks, images_info)。
chunks(文本块列表)公共字段:
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
content | str | 文本内容 | "This is the first paragraph of the document..." |
filename | str | 文件名 | "document.pdf" |
可选字段:
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
metadata | dict | 元数据信息(可选) | {"chunk_index": 0, "source_type": "..."} |
language | str | 语言标识(可选) | "en" |
从源码看,Unstructured 处理器在生成块时会尽力携带丰富元数据:chunk_index、元素类型(element_type,如CompositeElement)、page_number、coordinates坐标信息,以及从元素元数据中读取的首个语言标签(见 unstructured_processor.py 的_create_chunked_documents);"none"策略下也会尽力写入language(_create_single_document)。Excel 处理器则输出{"chunk_index": i, "file_type": "xlsx"|"xls"}元数据。
images_info(图像信息列表):提取到的内嵌图片元数据字典列表;未触发图像提取时为空列表。每个条目包含image_bytes(原始字节)、image_format(png/jpg)、position(位置信息:PDF/PPT 为page_number+ 归一化坐标,Excel 为sheet_name+ 行列坐标)。
三、支持的文件类型
Excel 文件
.xlsx— Excel 2007 及以后版本.xls— Excel 97-2003
通用文件
.txt— 纯文本.pdf— PDF 文档.docx— Word 2007 及以后.doc— Word 97-2003.html、.htm— HTML 文档.md— Markdown 文件.rtf— 富文本格式.odt— OpenDocument 文本.pptx— PowerPoint 2007 及以后.ppt— PowerPoint 97-2003.epub— EPUB 电子书.xml— XML 数据文件.json— JSON 数据文件.csv— 逗号分隔值文件
支持清单由 UnstructuredProcessor.get_supported_formats 提供,DataProcessCore.get_supported_file_types()会将其汇总为{"excel": [...], "generic": [...]}。需要特别说明的是JSON 文件的专门处理:UnstructuredProcessor._process_file会对.json走独立分支(_partition_json),由 json_chunk_processor.py 的JSONChunkProcessor负责拆分——它优先保持 JSON 顶层键值对的完整性,仅在无法安全切分时退化为标点边界切分,并且不会切断转义序列(如\n、\"),保证输出与 unstructured 元素格式一致。
四、使用示例
示例 1:处理本地文本文件(先读入内存)
from nexent.data_process import DataProcessCore core = DataProcessCore() # 将文件读入内存(file_process 只接受内存字节数据) with open("/path/to/document.txt", "rb") as f: file_bytes = f.read() chunks, images_info = core.file_process( file_data=file_bytes, filename="document.txt", chunking_strategy="basic" ) print(f"Processed into {len(chunks)} chunks") for i, chunk in enumerate(chunks): print(f"Chunk {i}: {chunk['content'][:100]}...")示例 2:处理 Excel 文件
with open("/path/to/spreadsheet.xlsx", "rb") as f: file_bytes = f.read() chunks, images_info = core.file_process( file_data=file_bytes, filename="spreadsheet.xlsx", chunking_strategy="none" # Excel 文件通常无需分块 ) for chunk in chunks: print(f"File: {chunk['filename']}") print(f"Content: {chunk['content']}") print(f"Metadata: {chunk.get('metadata')}")从 openpyxl_processor.py 的实现看,Excel 解析并非简单逐格读取:它先定位表头行(_get_title_row,按非空单元格最多的行判定)、处理合并单元格(_merge_columns/_merge_all_cells将左上角值填充到整个合并区域)、提取表头前的备注(_get_remark),然后把每一行转换为Markdown 表格并追加"————工作表名"后缀(_build_row_content);单列数据则逐行拼接、换行替换为<br>。这意味着 Excel 内容会以结构化表格形式进入知识库,检索时语义更完整。
示例 3:使用自定义参数处理内存中的 PDF
with open("/path/to/document.pdf", "rb") as f: file_bytes = f.read() chunks, images_info = core.file_process( file_data=file_bytes, filename="document.pdf", chunking_strategy="by_title", max_characters=2000 # 自定义参数 )示例 4:为多模态嵌入提取内嵌图片
chunks, images_info = core.file_process( file_data=file_bytes, filename="report.docx", chunking_strategy="basic", model_type="multi_embedding" # 触发 UniversalImageExtractor 提取内嵌图片 ) print(f"Extracted {len(images_info)} images")UniversalImageExtractor对不同格式采用不同提取路径(extract_image.py):
- PDF:以
strategy="hi_res"调用unstructured.partition,并开启extract_images_in_pdf=True/extract_image_block_to_payload=True,从元素元数据中还原image_base64,记录页码与坐标; - PPTX:直接用
python-pptx遍历幻灯片的图片形状,将 EMU 单位按emu_per_inch(默认 914400)与dpi(默认 96)换算为像素坐标; - XLSX:直接解压 zip 包,解析工作表 XML → drawing → 关系文件 → 锚点(twoCellAnchor/oneCellAnchor),还原图片及其所在行列;
- XLS / PPT / DOC / DOCX:先通过 LibreOffice(
soffice --headless --convert-to)转换为中间格式,再复用上述提取逻辑;转换超时限制为 60 秒,且临时文件在finally中统一清理。
所有路径均使用 SHA-256 哈希做图片去重,同一文档中重复出现的图片只会提取一次。
示例 5:拆分大文件
parts = core.file_split( file_data=file_bytes, filename="large_document.pdf", max_size=10 * 1024 * 1024, # 每个分片最大 10MB(可选参数) ) print(f"Split into {len(parts)} parts")file_split()返回List[BytesIO],其内部委托 FileSplitter 按格式拆分:
- PDF:按页拆分(
pypdf),支持max_size按字节自适应或target_parts指定份数; - Word(doc/docx):先经 LibreOffice 转为 PDF 再按页拆分,若最终无需拆分则保留原始 Word 字节;
- Excel:按行分组重建工作簿,并尽力保留原图(
copy_images_safe); - JSON:用
ijson流式读取,按条目累计字节分批; - Markdown:基于
langchain_text_splitters.MarkdownHeaderTextSplitter从最高级标题逐层下探,保证标题层级完整; - CSV / TXT:按行累积到目标大小;EPUB:按文档条目分组重建电子书;XML:按根节点子元素分组重组。
拆分涉及的扩展名白名单SPLIT_EXTENSIONS定义在 core.py(.csv/.epub/.xlsx/.xls/.json/.md/.pdf/.txt/.xml/.doc/.docx);不支持拆分时file_split会原样返回[BytesIO(file_data)],拆分器抛异常或返回非法格式时也会优雅回退,对应测试见 test_core.py 的 file_split 用例。
五、辅助方法
1. 获取支持的文件类型
core = DataProcessCore() supported_types = core.get_supported_file_types() print("Excel files:", supported_types["excel"]) print("Generic files:", supported_types["generic"])2. 校验文件类型
is_supported = core.validate_file_type("document.pdf") print(f"Is PDF supported: {is_supported}")validate_file_type对空文件名返回False,对扩展名做小写归一后与支持清单比对;测试中.unknown、.exe均被判定为不支持(test_core.py)。
3. 获取处理器信息
info = core.get_processor_info("spreadsheet.xlsx") print(f"Processor type: {info['processor_type']}") print(f"File extension: {info['file_extension']}") print(f"Is supported: {info['is_supported']}")get_processor_info返回{"processor_type": "excel"|"generic", "file_extension": ".xlsx", "is_supported": "True"|"False"}(注意is_supported是字符串),Excel 扩展名大小写不敏感(TEST.XLSX同样识别为 excel,见 test_core.py)。
4. 获取支持的分块策略与处理器类型
strategies = core.get_supported_strategies() processors = core.get_supported_processors() print(f"Supported chunking strategies: {strategies}") print(f"Supported processor types: {processors}")六、错误处理
常见异常
| 异常 | 触发条件 | 解决方案 |
|---|---|---|
ValueError | 参数非法(如不支持的分块策略或处理器类型) | 检查参数取值 |
UnsupportedFileFormatError | 文件扩展名不受支持,或无法从内存字节识别类型(未安装 libmagic 时内存类型检测失败) | 确认扩展名受支持;处理内存字节前先安装 libmagic |
ImportError | 缺少必需处理依赖(如 unstructured) | 安装nexent[data_process]extra |
RuntimeError | file_split()拆分失败 | 查看日志定位拆分错误 |
参数校验在 core.py 的_validate_parameters中完成:分块策略必须属于CHUNKING_STRATEGIES = {"basic", "by_title", "none"},显式指定的处理器必须属于PROCESSORS = {"Unstructured", "OpenPyxl", "UniversalImageExtractor"},否则抛出带支持列表提示的ValueError(对应测试 test_core.py)。
💡libmagic 依赖说明:
file_process()只接受内存字节数据,而 unstructured 依赖系统 libmagic 从内存字节识别文件类型。Linux/macOS 通常自带;Windows 默认不提供,需先安装(如pip install python-magic-bin),否则处理.txt等格式会抛出UnsupportedFileFormatError。
错误处理示例
from unstructured.partition.common import UnsupportedFileFormatError try: chunks, images_info = core.file_process( file_data=file_bytes, filename="document.txt", chunking_strategy="invalid_strategy" ) except ValueError as e: print(f"Invalid parameter: {e}") except UnsupportedFileFormatError as e: print(f"Unsupported or unrecognizable file type: {e}") except ImportError as e: print(f"Missing dependency: {e}") except Exception as e: print(f"Processing failed: {e}")此外,file_process与file_split都会通过监控管理器(monitoring_manager.trace_operation)上报knowledge.preprocess.*观测 span(含ingestion.stage、file.extension、file.size_bytes、processor.name、chunk.count等属性,见 core.py),生产排查时可结合链路追踪定位失败阶段。
七、性能优化建议
- 选择合适的分块策略:
- 小文件用
"none" - 大文件用
"basic" - 结构化文档用
"by_title"
- 小文件用
- 调优分块参数:
- 根据下游处理需求调整
max_characters - 在速度与内存占用之间取舍
- 根据下游处理需求调整
- 文件类型优化:
- Excel 通常无需分块
- PDF 建议使用更大的
max_characters
- 批量处理:
- 复用
DataProcessCore实例 - 避免重复初始化
- 复用
从后端实际配置看,分块参数并非只能手动指定:Ray Actor 会根据所选 embedding 模型的记录动态注入expected_chunk_size与maximum_chunk_size(ray_actors.py 的_apply_model_chunk_sizes),常量默认值分别为 1024 与 1536(backend/consts/const.py),与 SDK 侧new_after_n_chars=1024、max_characters=1536的默认值相互呼应。
八、知识库流水线中的真实调用链
原文档描述的四种流程(用户请求流、AI Agent 执行流、知识库文件处理流、实时文件处理流)中,DataProcessCore是知识库文件处理流的核心执行器:
File upload → Temporary storage → Data processing → Vectorization → Knowledge base storage → Index update数据处理/入库流程图(基于当前实现的完整流水线):
详细步骤:
- 文件上传:前端接收用户上传的文件
- 临时存储:文件存入 MinIO
- 任务排队:创建处理任务并推入 Redis 任务队列
- 数据处理:data process 服务消费任务,
DataProcessCore.file_process()完成格式解析与分块(超大文件可先用file_split()预拆分);多模态嵌入场景下同步提取内嵌图片 - 向量化:由
EmbeddingAdapter嵌入模型生成向量表示 - 知识库存储:处理结果经
ElasticSearchCore.vectorize_documents()批量写入 Elasticsearch - 索引更新:刷新搜索索引并更新任务状态,支撑检索
源码级佐证:每一步的落点
- Celery + Redis 队列:任务由 backend/data_process/tasks.py 定义(
process/forward链式任务),worker 启动脚本见 backend/data_process/worker.py,支持QUEUES=process_q、WORKER_CONCURRENCY等环境变量控制队列与并发; - Ray 分布式处理:
DataProcessCore实例被封装进@ray.remote的 DataProcessorRayActor,通过全局共享 actor 池做预热与轮询调度;拆分后的分片会写入 Redis,等待超时按DP_REDIS_CHUNKS_WAIT_TIMEOUT_S计算并允许按波次线性放宽(tasks.py); - 批量入库:ElasticSearchCore.vectorize_documents 会按文档量自动选择策略——总量 ≥64 或
large_mode时走"索引设置优化 + 大批量"路径,否则走wait_for实时刷新路径;EmbeddingAdapter位于 sdk/nexent/core/gateway/modality/embedding/embedding_adapter.py,作为多模态网关的一部分提供向量生成能力; - 配置常量:
DP_FILE_SPLIT_SIZE_MB默认 5(拆分阈值)、DP_PART_PROCESSOR_COUNT默认 3(Ray 处理 actor 数)、MAX_CONCURRENT_CONVERSIONS默认 5(LibreOffice 转换并发上限)等均可在 backend/consts/const.py 中查看并通过环境变量覆盖。
实时文件处理流
File upload → Temporary storage → Data processing → Agent processing → Real-time answer详细步骤:
- 文件上传:用户在会话中上传文件
- 临时存储:文件被临时保存待处理
- 数据处理:实时提取文件内容与结构
- Agent 处理:AI Agent 分析文件内容
- 实时回答:基于文件内容即时回复
后端对该场景的封装示例是 DataProcessService.process_uploaded_text_file:它直接调用DataProcessCore.file_process()得到块列表,汇总为text、chunks、chunks_count、text_length、processing_time等字段返回,印证了 SDK 与后端服务之间的直接复用关系。
九、数据处理优化策略
- 异步处理:大文件处理使用异步任务队列(Celery + Redis)
- 批量操作:多文件处理时使用批量优化(Ray actor 池、ES 分批写入)
- 缓存:重复文件可缓存处理结果
- 流式处理:大文件采用内存流式处理(如
file_split的流式拆分与ijson流式读取)
小结
DataProcessCore把"按扩展名选处理器、按策略分块、按需提取图片、大文件预拆分"四件事收敛为一个入口,屏蔽了unstructured、openpyxl、python-pptx、pypdf、LibreOffice 等底层组件的差异;向上以(chunks, images_info)标准结构对接EmbeddingAdapter与ElasticSearchCore,向下被后端 Celery 任务与 Ray Actor 以分布式方式消费。无论你是想在自有 Python 项目中快速接入文件解析,还是想深入理解 Nexent 知识库从上传到检索的完整链路,都可以以 sdk/nexent/data_process 为起点,配合 test/sdk/data_process/test_core.py 的测试用例验证各边界行为。
- 人工智能
- AI Agent
- Agent 编排
- 低代码
- AI 技能
- RAG
【免费下载链接】nexent
Nexent 是一个开源智能体SDK和平台,能够将描述流程的自然语言转化为完整的多模态服务 —— 无需编排,无需复杂拖拉拽。基于 MCP 工具生态系统构建,Nexent 提供灵活的模型集成、可扩展的数据处理和强大的知识库管理。我们的目标很简单:将数据、模型和工具整合到一个智能中心中,让任何人都能轻松地将 Nexent 集成到项目中,使日常工作流程更智能、更互联。
相关推荐
Nexent SDK DataProcessCore 使用指南:多格式文件解析、智能分块与向量化落库全流程
Nexent SDK DataProcessCore 使用指南:多格式文件解析、智能分块与向量化落库全流程 导读 本文面向需要在 Nexent 平台上处理非结构
AI AgentAI 应用后端前端大模型RAGNexent DataProcessCore 使用指南:统一文件解析、分块与知识库入库全流程解析
Nexent DataProcessCore 使用指南:统一文件解析、分块与知识库入库全流程解析 Nexent 的 DataProcessCore (位于 sd
AI AgentAI 应用后端前端大模型RAGRyujinx Switch模拟器:从零安装到流畅运行的完整实战指南
Ryujinx Switch模拟器:从零安装到流畅运行的完整实战指南 Ryujinx 是一款用 C 编写的开源 Nintendo Switch 模拟器:它模拟
硬件仿真图形学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考