RocketRide preprocessor_llm 节点实战指南:用 LLM 驱动文档分块并输出向量库就绪的 Document
【免费下载链接】rocketride-serverHigh-performance AI pipeline engine with a C core and 50 Python-extensible nodes. Build, debug, and scale LLM workflows with 13 model providers, 8 vector databases, and agent orchestration, all from your IDE. Includes VS Code extension, TypeScript/Python SDKs, and Docker deployment.项目地址https://gitcode.com/gh_mirrors/ro/rocketride-server点击查看免费下载本篇围绕 RocketRiderocketride-server中的preprocessor_llm预处理节点展开讲清它如何利用已连接的 LLM 把文档文本切分为适合向量嵌入embedding存储的语义块、如何处理表格与超长文本、以及如何通过numberOfTokens一个参数对齐你的嵌入模型。读完本文你将掌握该节点的双泳道lane数据流、配置项含义、LLM 提示词的 JSON 契约以及底层预分块算法的源码级细节可以直接把该节点接入 RAG 流水线。节点定位什么时候该选 LLM 分块而不是规则分块preprocessor_llm是一个 RocketRide 预处理节点它借助已连接的 LLM 将文档文本拆分为 chunk供后续向量嵌入存储。官方文档给出的选型建议是只有当你认为让 LLM 基于整篇文档做分块指导值得一次模型调用开销时才选择它如果你的场景更偏好确定性的本地切分应选用通用文本预处理器general-text preprocessor如果对象是源代码语法则应选代码预处理器code preprocessor。从节点声明文件 services.json 可以看到它的注册信息协议preprocessor_llm://类别classType为preprocessor引擎中的注册方式是filterUI 显示名 LLM图标preprocessor-llm.svg功能描述为分析文档内容以提取摘要、要点与命名实体并将文档切分以存入向量数据库。节点目录 nodes/src/nodes/preprocessor_llm 下除 README 外包含 IGlobal.py、IInstance.py、requirements.txt 与 services.json遵循 RocketRide Python 节点全局配置 每对象实例的两层结构。关于 LangChain 依赖README 专门说明了一点容易误解的事实该节点的软件包声明了langchain与langchain-core依赖但模型操作本身是通过 RocketRide 的 LLM 连接invoke connection完成的LangChain 只是包依赖层面的存在。这一点可以从 requirements.txt 得到印证其中仅声明了# Preprocessor: LangChain (LLM-only) langchain # LangChain deps langchain-core这些依赖并不改变节点通过 LLM 连接调模型的工作方式真正发起模型调用的是rocketlib提供的IInvokeLLM机制见下文closing()流程。依赖在节点初始化时会被动态安装。IGlobal.py 的beginGlobal()方法中requirements_path os.path.dirname(os.path.realpath(__file__)) /requirements.txt depends(requirements_path) config Config.getNodeConfig(self.glb.logicalType, self.glb.connConfig) self.numberOfTokens config.get(numberOfTokens, 384)即引擎在节点启动阶段自动安装requirements.txt中列出的包再从节点配置系统读取numberOfTokens缺省 384覆盖类属性默认值。连接Connections与泳道Lanes节点需要连接一个 LLM 才能工作文档中的连接表如下连接是否必需说明llm必需用于处理文档文本的 LLM。services.json 中对应的声明是invoke: { llm: { min: 1 } }即至少需要 1 个 LLM 连接。数据流方面文档给出的泳道表为输入 Lane输出 Lane描述textdocuments对象关闭时累积文本并交给 LLM 分块。tabledocuments在本地把表格切成文档 chunk不走 LLM。这与 services.json 中的泳道声明完全一致lanes: { table: [documents], text: [documents] }两个输入泳道最终都汇入同一个documents输出泳道下游通常是向量库写入节点如各类 store 节点。配置项numberOfTokens 与 profileREADME 的 Schema 部分给出了完整的字段表字段类型说明默认值preprocessor_llm.numberOfTokensnumber每个文档 chunk 的目标 token 数必须与你的嵌入模型匹配384preprocessor_llm.profilestringdefault这两个字段的定义同样位于 services.json 的fields段preprocessor_llm.numberOfTokens类型为number、默认 384标题即Number of tokens per document chunk. Needs to match your embedding model.preprocessor_llm.profile是一个隐藏字段hidden: true枚举值仅default用于按 profile 组织配置。preconfig段则定义了默认 profile 的合并基线preconfig: { default: default, profiles: { default: { numberOfTokens: 384 } } }文档强调默认配置使用 384 tokens 作为提示词中的目标 chunk 大小并且由于节点在第一个对象上就要读取该连接 LLM 的上下文长度、输出长度和 token 计数器所以处理前必须先接好 LLM。numberOfTokens的准确语义值得单独展开README 的说明是它被写进 LLM 提示词作为目标 chunk 大小同时给出3/4 数量词数的回退表述应把它设置为接收这些文档的嵌入模型合适的 chunk 容量它还决定了表格在行边界处切分所用的 token 预算如果表格 chunk 对下游嵌入模型来说过大就应该调小它它不是发给 LLM 之前对文本做预分块的限额——那个限额来自已连接 LLM 的上下文与输出容量。运行时流程从累积到 closing 的完整调用链节点的行为是典型的累积器accumulator模式。IInstance.py 中每个对象的生命周期方法如下def open(self, object: Entry): self.text self.chunks [] def writeText(self, text: str): self.text text # 文本累积到 self.text def writeTable(self, text: str): self.chunks.append( {content: text, table: True} # 表格先记账标记 tableTrue )writeTable说明表格在写入时就被打上table: True标记进入self.chunks不经过 LLM真正的表格切分延迟到closing()阶段用本地算法完成。closing()首次初始化时读取 LLM 能力closing()是该节点最核心的方法。它在第一个对象关闭时一次性完成 LLM 能力探测if not self._init: self._maxContextTokens self.instance.invoke(IInvokeLLM.GetContextLength()) self._maxOutputTokens self.instance.invoke(IInvokeLLM.GetOutputLength()) self._tokenCounter self.instance.invoke(IInvokeLLM.GetTokenCounter()) chunkQuestion self._buildChunkQuestion() # 空文本仅用于测量 self._baseChunkTokens self._tokenCounter(chunkQuestion.getPrompt()) self._init True这印证了 README 中节点在第一个对象上读取该连接的 context length、output length 和 token counter的说法。注意_buildChunkQuestion()允许传入空文本专门用来测量提示词本身的 token 基线开销_baseChunkTokens后续预算计算都要扣除它。随后进入主流程先对累积的self.text执行_splitText()预分块对每一段调用_extractChunks()请求 LLM把返回 JSON 中的chunks数组合并进总列表最后统一走_add_chunk()生成带DocMetadata的Doc对象通过self.instance.writeDocuments(documents)一次性发射到documents泳道。提示词契约chunks JSON 数组与摘要块发给 LLM 的问题由_buildChunkQuestion()构造角色设定为为向量嵌入存储准备内容的文档处理助手并包含三段指令Chunking Guidelines要求切出逻辑、连贯、适合向量嵌入存储的 chunk——完整思想不截断、独立阅读可懂、保留原文精确文本、尊重文档结构段落/章节/列表、无适合切分内容时返回空数组以及关键的目标大小tokens self.IGlobal.numberOfTokens words tokens * 0.75 # 提示词中Aim for chunk sizes of {tokens} tokens, or {words} words # if token count is not available这就是 README 所说以 384 tokens 为目标、附 3/4 词数回退的出处。Document Summary要求附加一个文档摘要 chunk必须位于 chunks 数组末尾若一个 chunk 都找不到则不输出摘要。Result Format给出期望的 JSON 结构示例{ chunks: [ {content: 第一个 chunk 的实际文本内容}, {content: 下一个 chunk 的实际文本内容}, {content: 文档摘要, summary: true} ] }并通过question.expectJson True声明要求 JSON 响应。节点随后调用result self.instance.invoke(IInvokeLLM.Ask(questionquestion)) return result.getJson()响应解析的容错行为README 明确描述了 LLM 响应形状的解析规则节点从 JSON 响应中读取chunks键如果该键缺失或为空文本输入就不会产生任何文本文档但已收集好的表格 chunk 仍然可以被发射。源码中对应两处closing()里chunks results.get(chunks, [])缺失即空列表以及_add_chunk()之前对每个 chunk 的content.strip()判空——内容为空的 chunk 会被直接丢弃。超长文本预分块65,536 字符阈值与四级降级在请求 LLM 之前节点要先保证每段送出去的文本放得进模型窗口。README 的说明是先扣除提示词基线与 500 tokens 的 JSON 格式化开销再取剩余上下文预算与模型输出容量两者中较小者并从 65,536 字符阈值开始逐级尝试拆分。IInstance.py 的_splitText()精确实现了这一点raw_tokens min(self._maxContextTokens - self._baseChunkTokens, self._maxOutputTokens) max_tokens_per_chunk raw_tokens - 500 # 预留 JSON 格式化开销 max_text_per_chunk 64 * 1024 # 65,536 字符拆分采用层级降级策略当某段文本超过预算时依次尝试——按段落\n\n切分按行\n切分按句子. 切分切分时把句号补回最后按词word贪心拼组且用预算的 80% 作为更保守的临时上限以留出分隔符余量。文档特别提到一个边界情况源码同样如此处理单个超大单词可以保持原样而不再被继续切开_add_words中的Single word is too large ... handle it gracefully by adding it anyway。表格处理纯本地、行边界切分表格完全绕过 LLM。_split_table()的算法是按行遍历逐行用 token 计数器累计一旦加入下一行会超过numberOfTokens预算就封存当前 chunk只有行边界是切分点注释写明splits only at line boundaries to maintain table row integrity。若某一行本身就超过预算它会单独成为一个 chunk空表内容直接返回空列表。发射阶段closing()对每个table: True的条目执行_split_table(content)同一来源表格的所有切块共享同一个递增的tableId——这正是 README 所说表格来源的 chunk 会被标记为表格并带有其源表格共享的tableId。输出文档的元数据模型每条最终发射的Doc都会携带DocMetadataIInstance.py 中的构造为metadata DocMetadata( self, chunkIdchunk_counter, # 全局递增的 chunk 序号 isSummaryisSummary, # 来自 LLM 返回的 summary 标记 isTableisTable, # 来自写入时的 table 标记 tableIdtable_id, # 表格块共享的来源表格编号 isDeletedFalse, ) doc Doc(page_contentcontent, typeDocument, metadatametadata)即 README 总结的三条输出特性在源码中一一对应每个发出的文档都有chunkId自增计数器LLM 生成的摘要块通过响应中的summary: true被标记为 summary表格块被标记为 table且同一张表的各 chunk 共享tableId。Doc、DocMetadata、Question等数据模型统一来自 packages/ai/src/ai/common/schema/init.py该模块从rocketride包Python SDK再导出Answer、Question、QuestionType、Doc、DocMetadata、DocGroup等类型节点代码通过from ai.common.schema import ...引用保证了与 RocketRide 客户端 SDK 的契约一致。依赖与适用前提Python 依赖langchain、langchain-core见 requirements.txt节点启动时由引擎动态安装运行前提管道中必须为llm连接配置一个可用的 LLM节点依赖该连接提供上下文长度、输出长度与 token 计数器参数约束preprocessor_llm.numberOfTokens默认 384应与下游嵌入模型的 chunk 容量一致——它同时是 LLM 提示词中的目标大小和表格本地切分的 token 预算成本特性每个对象关闭时累积文本会被预分块后逐段调用一次 LLM文档越大、模型窗口越小预分块产生的调用次数越多这也是 README 建议规则分块更划算时不要选本节点的量化依据。小结preprocessor_llm在 RocketRide 管道中扮演语义级文档切分器角色文本泳道走本地预分块 → LLM 按 chunks JSON 契约切分 → 摘要块殿后的路径表格泳道走行边界本地切分的免模型路径两者统一产出带chunkId/isSummary/isTable/tableId元数据的Doc对象写入documents泳道。理解numberOfTokens嵌入模型对齐 表格预算与 LLM 上下文预算预分块限额这两个看起来都是 token 数、作用却完全不同的数值边界是正确配置该节点的关键。赞分享【免费下载链接】rocketride-serverHigh-performance AI pipeline engine with a C core and 50 Python-extensible nodes. Build, debug, and scale LLM workflows with 13 model providers, 8 vector databases, and agent orchestration, all from your IDE. Includes VS Code extension, TypeScript/Python SDKs, and Docker deployment.项目地址https://gitcode.com/gh_mirrors/ro/rocketride-server点击查看免费下载相关推荐MinerU 文档解析引擎实战指南将 PDF 与 Office 文档解析为 LLM 就绪的 Markdown/JSONMinerU 文档解析引擎实战指南将 PDF 与 Office 文档解析为 LLM 就绪的 Markdown/JSON MinerU 是一个面向 LLM、RA人工智能大模型OCR计算机视觉RocketRide preprocessor_langchain 节点基于 LangChain 文本切分器的确定性分块预处理实战RocketRide preprocessor_langchain 节点基于 LangChain 文本切分器的确定性分块预处理实战 RocketRide 的用 ADK 构建 LLM Auditor面向 LLM 输出的自动化事实核查智能体实战指南用 ADK 构建 LLM Auditor面向 LLM 输出的自动化事实核查智能体实战指南 LLM Auditor 是 Agent Development Ki示例工程上一篇Bumbler入门教程3分钟学会追踪Rails项目初始化加载进度下一篇sway-farm测试策略智能合约单元测试与端到端测试实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考