【免费下载链接】rocketride-server
High-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.
导读
本文围绕 RocketRide 开源仓库中的landing_ai节点包展开,系统讲解如何通过 Landing.ai 的 Agentic Document Extraction(ADE)服务,在 RocketRide 管道中完成「非结构化文档 → 干净 Markdown 与表格 → 符合 JSON Schema 的结构化字段」的完整处理链路。读完本文,你将掌握两个子节点(Landing.ai Parse、Landing.ai Extract)的 lane 接线方式、全部配置参数与默认值、API Key 认证机制,以及底层 Python 实现的运行细节与边界行为,可以直接在画布上搭建可运行的文档抽取管道。
Landing.ai ADE 与节点包的定位
Landing.ai 提供 Agentic Document Extraction(ADE),一种面向文档处理的云端服务,可以把非结构化文件转换成可用文本和结构化数据。在本仓库中,ADE 被封装为两个可组合的子节点,位于 nodes/src/nodes/landing_ai:
- Landing.ai Parse:接收文档字节,调用 ADE 的
parse操作,输出干净的 Markdown 文本以及表格块; - Landing.ai Extract:接收 Parse 产出的 Markdown,结合上传的 JSON Schema 调用 ADE 的
extract操作,输出结构化答案(answers)或文档(documents)。
选择本包的前提是你需要同一个 ADE 服务同时提供解析与抽取两种操作;如果只需要可读的文档文本和表格,单独使用 Parse 即可。典型的管道接线为Parse → Extract,因为 Extract 消费的是 Parse 产生的 Markdown 而不是原始文档。
数据流与 Lanes
两个子节点的 lane 定义集中在各自的 service 描述文件里:services.parse.json 声明"lanes": {"tags": ["text", "table"]},services.extract.json 声明"lanes": {"text": ["answers", "documents"]}。汇总如下:
| Lane in | Lane out | 说明 |
|---|---|---|
tags | text | Landing.ai Parse 写入文档的 Markdown 响应 |
tags | table | Landing.ai Parse 写入每个类型为table的 ADE chunk |
text | answers | Landing.ai Extract 将结构化抽取结果作为 JSON 答案写入 |
text | documents | Landing.ai Extract 将抽取结果作为 JSON 文档内容写入 |
Parse 的输入是二进制字节流(由 tag 流状态机接收),支持 PDF、图片、电子表格(XLSX/CSV)等输入类型;Extract 的输入是textlane 上的解析后 Markdown,因此必须放置在 Parse 下游。
配置模型与参数详解
两个服务都只有一个defaultprofile。节点读取配置时,get_node_config会先获取节点配置,再解包嵌套的default字典(landing_ai_base.py):
config = Config.getNodeConfig(logical_type, conn_config) if not isinstance(config, dict): return {} inner = config.get('default') return inner if isinstance(inner, dict) else config因此画布上的服务配置会落到landing_ai_parse.default/landing_ai_extract.default这样的对象字段上(见两个 service JSON 中的shape与fields.default定义)。
Landing.ai Parse 配置
Model控制发送给 ADEparse调用的模型值,默认dpt-2-latest,这也是当前节点唯一提供的取值(service JSON 的enum只有["dpt-2-latest", "DPT-2 (latest)"])。除非节点配置被扩展支持其他 ADE 模型,否则保持默认即可。
Region默认production,需要欧盟部署时选择eu(对应 eu-west-1 数据驻留端点)。解析器会把任何其他配置值静默重置为production——对应源码 parse.py:
if self._region not in ('production', 'eu'): self._region = 'production'所以请只使用production与eu两个取值。
Landing.ai Extract 配置
Extraction Schema(JSON Schema 文件)是服务元数据中的必填项( 注意 Schema 用于定义响应必须包含的字段,并支持 ADE 的 Strict默认关闭。关闭时,文档不完全满足 Schema 也会返回部分抽取结果;开启后,不满足 Schema 的文档会失败而非产出部分结果。 Region与 Parse 行为一致( Landing.ai Extract( Landing.ai Parse( 在每个服务的API Key字段填入 Landing.ai ADE Key,或在该字段为空时设置环境变量 保存配置时, 两个子节点的 文档字节通过 处理前会先检查输出是否有人监听(IInstance.py):如果 真正调用发生在 响应映射 extract/IInstance.py 通过 当 两条失败语义值得注意:缺 key 与空输入是"fail-closed 返回空",而 ADE 远端失败是"log-and-re-raise"(见 parse.py 与 extract.py),避免把远端故障静默伪装成"没有内容"。 节点包附带了两组独立单测,用项目 mock 遮蔽"required": ["landing_ai_extract.schema_file"])。上传的必须是JSON 对象形式的>_MAX_SCHEMA_BYTES = 2 * 1024 * 1024 if len(raw) > _MAX_SCHEMA_BYTES: raise ValueError(f'... uploaded schema is too large ...') schema = json.loads(raw.decode('utf-8')) ... if not isinstance(schema, dict): raise ValueError('Landing.ai Extract: extraction schema must be a JSON object')json.loads同时捕获RecursionError,用来拦截在体积上限之下、但嵌套深度病态的 JSON,避免解析时递归崩溃。Schema 内容被当作不透明数据,只重新序列化发送给 ADE,不会被读取字段值或写盘。x-alternativeNames与format关键字。上传错误会在校验阶段以warning形式报告,但不会阻塞画布编辑;真正运行时抽取调用会失败。service JSON 的preconfig.default自带一个最小可用示例:{ "type": "object", "properties": { "summary": { "type": "string" } } }production/eu二选一),其他值同样被归一化为production(extract.py)。完整参数表(由 nodes:docs-generate 生成)
services.extract.json)字段 类型 说明 默认 landing_ai_extract.api_keystringAPI Key。Landing.ai ADE API Key,留空时回退到 ROCKETRIDE_LANDING_AI_KEY环境变量。landing_ai_extract.regionstringRegion。调用哪个 Landing.ai 部署。使用 EU 指向 eu-west-1 数据驻留端点。 "production"landing_ai_extract.schema_filestringExtraction Schema(JSON Schema 文件)。上传描述待抽取字段的 .json 文件,支持 ADE 的 x-alternativeNames与format关键字。landing_ai_extract.strictbooleanStrict。文档不匹配 Schema 时让抽取失败,而不是返回部分结果。 falseservices.parse.json)字段 类型 说明 默认 landing_ai_parse.api_keystringAPI Key。Landing.ai ADE API Key,留空时回退到 ROCKETRIDE_LANDING_AI_KEY环境变量。landing_ai_parse.modelstringModel。使用的 ADE parse 模型。 "dpt-2-latest"landing_ai_parse.regionstringRegion。调用哪个 Landing.ai 部署。使用 EU 指向 eu-west-1 数据驻留端点。 "production"认证:API Key 与环境变量回退
ROCKETRIDE_LANDING_AI_KEY。解析顺序由 resolve_api_key 实现:优先取配置中的api_key(去除首尾空白),为空则回退到环境变量,再为空返回None:return (config.get('api_key') or '').strip() or (os.environ.get('ROCKETRIDE_LANDING_AI_KEY') or '').strip() or NonevalidateConfig会做一次便宜的只读校验:调用parse_jobs.list(landing_ai_base.py),该接口是只读的、不消耗额度。校验失败只输出 warning,不会阻止编辑管道:client = build_client(api_key, config.get('region') or 'production') client.parse_jobs.list(page=0, page_size=1)IGlobal.validateConfig(parse/IGlobal.py、extract/IGlobal.py)都用try/except包裹校验逻辑并统一降级为 warning;Extract 还会额外检查 schema_file 是否为空以及能否成功解码。运行机制:从源码看底层调用链
Parse:tag 流状态机与 ADE
parse调用tagslane 流入,由 parse/IInstance.py 的writeTag状态机处理:识别OMET元数据标签、SBGN流开始、SDAT二进制数据块(通过 header 长度剥离 tag 头、累积document_data)、SEND流结束并触发处理。text和table都没有 listener,则完全跳过 ADE 远程调用,这是节省额度的关键优化:has_text_listener = self.instance.hasListener('text') has_table_listener = self.instance.hasListener('table') if not has_text_listener and not has_table_listener: debug('Landing.ai Parse: no text/table listeners connected; skipping parse') returnParser.parse(parse.py):error并返回空文本、无表格(fail-closed);guess_filename(file_data, 'pdf')嗅探出带类型的文件名,因为 ADE 依赖文件名推断文档类型;build_client创建一次性的LandingAIADE客户端(每次调用新建,保证并发安全,见 landing_ai_base.py),以(filename, bytes)元组直传 SDK、不落临时文件:response = client.parse(document=(file_name, file_data), model=self._model)_map_response(parse.py)把response.markdown作为文本,遍历response.chunks,只把type(不区分大小写)为table且 Markdown 非空的 chunk 放进表格列表;同时从metadata读取credit_usage(debug 日志)和failed_pages(若有则 warning 提示部分页解析失败)。Extract:Markdown 累积与 ADE
extract调用writeText把textlane 上收到的所有 Markdown 片段累积进markdown_parts,对象关闭时用空行连接成一个整体再触发抽取:markdown = '\n\n'.join(self.markdown_parts).strip() if markdown: extraction = self.IGlobal.extractor.extract(markdown)Extractor.extract(extract.py)的行为:ValueError(延迟到运行时而非在beginGlobal崩溃整个管道);{};response = client.extract(markdown=markdown, schema=json.dumps(self._schema), strict=self._strict)_map_response取response.extraction,若metadata.warnings存在则 warning 提示部分抽取,但依然返回响应中的 extraction。Extract 的 documents 输出规则
documentslane 有连接时,IInstance._to_documents 会把抽取结果包装成文档:对象结果转成一个 JSON 文档;若抽取值是列表,则每个元素各转成一个 JSON 文档,并且每个输入对象的 chunk ID 从 0 开始递增编号:items = extraction if isinstance(extraction, list) else [extraction] for item in items: ... documents.append(Doc(page_content=json.dumps(item), metadata=metadata)) self.chunkId += 1失败与边界行为速查
场景 Parse 行为 Extract 行为 输出无 listener 完全跳过 ADE 调用 — 缺 API Key 返回空文本、无表格(记 error) 返回空抽取 {}(记 error)空文档 / 空 Markdown 返回空结果 返回空抽取 {}ADE 请求失败 记录日志并重新抛出异常 记录日志并重新抛出异常 Schema 无效 — 校验期 warning,运行时抛 ValueError上游返回抽取 warnings — 记录日志,但仍返回响应中的 extraction 测试验证与源码佐证
landingai_adeSDK,无需真实服务即可运行:parse()把 ADE 响应映射为(markdown, [table blocks]);SDK 收到的是(filename, bytes)元组与配置的模型;缺文件名时嗅探出.pdf后缀;无 Key 时返回空结果;SDK 异常被重新抛出;_map_response仅按不区分大小写的table类型过滤表格 chunk。
【免费下载链接】rocketride-server
High-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.
相关推荐
5个Zutilo技巧让你成为Zotero文献管理高手
5个Zutilo技巧让你成为Zotero文献管理高手 还在为Zotero的批量操作烦恼吗?每天面对成百上千的文献条目,手动复制标签、关联项目、整理元数据是否让你
SpotLight项目删除背后的技术债务与维护成本分析
SpotLight项目删除背后的技术债务与维护成本分析 SpotLight项目(GitHub加速计划)作为曾经备受关注的开源项目,其突然删除的消息引发了开发者社
RocketRide 中集成 Landing.ai ADE 实现文档解析与结构化抽取的完整指南
RocketRide 中集成 Landing.ai ADE 实现文档解析与结构化抽取的完整指南 本文以 RocketRide 开源仓库中的 Landing.ai