xorq
xorq 是一个专为机器学习数据流水线设计的开源工具,旨在通过“可组合表达式”简化从开发到部署的全流程。它核心解决了传统 ML 工程中常见的痛点:不同计算引擎(如 DuckDB、Snowflake)间的代码重写、缺乏统一的缓存机制导致重复计算、以及因环境差异引发的“在我机器上能跑”等问题。
xorq 让开发者只需编写一次声明式代码,即可在多种后端引擎间无缝切换执行,无需编写繁琐的适配胶水代码。其独特亮点在于将每个计算任务转化为结构化的 YAML“清单(Manifest)”,这不仅明确了数据血缘和上下文,还内置了智能缓存系统,自动管理中间结果,避免不必要的重算。此外,xorq 基于 Ibis 构建,利用 Arrow 作为数据传输管道,确保了高效且确定的执行体验。
这款工具非常适合数据工程师、机器学习研究者以及需要构建复杂特征流水线的开发团队使用。如果你希望摆脱碎片化的工具链,追求更高效、可复现且易于维护的数据处理流程,xorq 提供了一个现代化且优雅的解决方案。
使用场景
某电商数据团队正在构建用户特征管道,需将本地开发的 DuckDB 原型迁移至 Snowflake 生产环境并支持实时服务。
没有 xorq 时
- 重复造轮子:从 DuckDB 迁移到 Snowflake 需重写大量胶水代码,不同计算引擎间无法直接复用逻辑。
- 盲目运行:只能在任务执行时才发现错误,缺乏运行前的静态验证与反馈机制。
- 无效重算:因无法精准识别数据或逻辑变更,每次部署都全量重跑,浪费算力且耗时。
- 链路黑盒:特征逻辑、元数据和血缘分散在不同系统,排查问题如同“考古”,效率极低。
- 环境漂移:本地能跑的代码在生产报错,复现结果需反向工程他人配置,维护成本高昂。
使用 xorq 后
- 一次编写,多端运行:基于声明式 Ibis 表达式构建管道,xorq 自动处理 DuckDB 到 Snowflake 的引擎切换,无需重写代码。
- 编译期洞察:xorq 将计算逻辑转化为结构化 Manifest,在运行前即可验证完整性,提前拦截潜在错误。
- 智能缓存:通过
.cache()声明节点,xorq 自动管理缓存键与失效逻辑,仅重算变更部分,大幅缩短迭代时间。 - 统一血缘视图:所有逻辑、元数据与血缘信息内建于 Manifest 中,调试时可一键追溯完整数据链路。
- 确定性复现:环境差异被屏蔽,任何人在任何机器上均可通过同一 Manifest 精确复现计算结果。
xorq 通过将 ML 计算转化为可组合的表达式与标准化清单,彻底消除了数据管道中的引擎孤岛与运维摩擦。
运行环境要求
- 未说明
未说明
未说明

快速开始
问题
你编写了一个特征流水线,在本地使用 DuckDB 能正常运行。但当部署到 Snowflake 上时,却不得不重新改写代码。为了缓存中间结果,你又引入了额外的基础设施和结果命名机制。随后,由于需要追踪流水线的变化,你还搭建了一个元数据存储系统。恭喜你,终于将模型上线了!接下来该添加推理服务层了……
然而,仅仅六个月后,你就拥有了五个互不相通的工具,而这条流水线只有你自己才完全理解。
| 痛点 | 表现 |
|---|---|
| 到处都是胶水代码 | 每个计算引擎都像孤岛一样独立运作,跨引擎迁移意味着重写而非组合。 |
| 运行时反馈不足 | 使用的是命令式 Python 代码,只有在作业运行时才能发现潜在的错误。 |
| 不必要的重复计算 | 对于哪些部分发生了变化缺乏统一的认知,导致每次都要从头开始执行。 |
| 血缘关系不透明 | 特征逻辑、元数据和血缘关系分散在不同的系统中,调试起来如同考古一般。 |
| “在我机器上能跑” | 环境会逐渐漂移,想要复现结果就必须逆向工程别人的配置,并不断调整自己的环境。 |
| 有状态的编排工具 | 重试逻辑、任务状态、失败恢复……这些都需要额外的管理,也增加了出错的可能性。 |
特征存储、模型注册表、工作流编排工具:这些都是垂直化的孤岛,无法支持需要上下文和技能的自主型流程,而不仅仅是按类别划分。
Xorq

清单 = 上下文。 每次机器学习计算都会被转化为一个结构化、以输入为地址的 YAML 清单。
表达式 = 工具。 它们构成了一个目录,可以被发现;同时也是一个构建系统,能够在任何地方以确定性的方式执行,并支持用户自定义的缓存策略。
模板 = 技能。 提供多种开箱即用的技能,例如 scikit-learn 流水线、特征存储、语义层等。
$ pip install xorq[examples]
$ xorq init -t penguins
表达式
编写声明式的 Ibis 表达式,就像使用工具一样轻松运行。Xorq 在 Ibis 的基础上扩展了缓存功能、多引擎执行能力以及用户自定义函数的支持。
import ibis
import xorq.api as xo
from xorq.common.utils.ibis_utils import from_ibis
from xorq.caching import ParquetCache
penguins = ibis.examples.penguins.fetch()
penguins_agg = (
penguins
.filter(ibis._.species.notnull())
.group_by("species")
.agg(avg_bill_length=ibis._.bill_length_mm.mean())
)
expr = (
from_ibis(penguins_agg)
.cache(ParquetCache.from_kwargs())
)
只需在任意节点上调用 .cache() 方法,剩下的工作就由 Xorq 自动完成。无需手动生成或管理缓存键,也不需要编写失效逻辑。
跨引擎组合
一份表达式,可在多个引擎上运行。你的流水线的一部分可以在 DuckDB 上执行,另一部分则利用 Xorq 内置的 DataFusion 引擎,通过 Arrow Flight 执行 UDF。Xorq 以低开销的方式系统化地处理数据传输,告别胶水代码。
expr = from_ibis(penguins).into_backend(xo.sqlite.connect())
expr.ls.backends
(<xorq.backends.sqlite.Backend at 0x7926a815caa0>,
<xorq.backends.duckdb.Backend at 0x7926b409faa0>)
表达式是工具,Arrow 是管道
Unix 让我们通过标准输出实现小工具之间的组合,而 Xorq 则让你的表达式通过 Arrow 实现组合。
In [6]: expr.to_pyarrow_batches()
Out[6]: <pyarrow.lib.RecordBatchReader at 0x15dc3f570>
清单
构建一个表达式,就能得到一份清单。
$ xorq build expr.py
builds/28ecab08754e
$ tree builds/28ecab08754e
builds/28ecab08754e
├── database_tables
│ └── f2ac274df56894cb1505bfe8cb03940e.parquet
├── expr.yaml
├── metadata.json
└── profiles.yaml
无需外部的元数据存储,也不需要单独的血缘追踪工具。构建目录本身就是版本化、可缓存且便于移植的产物。
# 以输入为地址,可组合且便携
# expr.yaml 摘录
nodes:
'@read_31f0a5be3771':
op: Read
name: penguins
source: builds/28ecab08754e/.../f2ac274df56894cb1505bfe8cb03940e.parquet
'@filter_23e7692b7128':
op: Filter
parent: '@read_31f0a5be3771'
predicates:
- NotNull(species)
'@remotetable_9a92039564d4':
op: RemoteTable
remote_expr:
op: Aggregate
parent: '@filter_23e7692b7128'
by: [species]
metrics:
avg_bill_length: Mean(bill_length_mm)
'@cachednode_e7b5fd7cd0a9':
op: CachedNode
parent: '@remotetable_9a92039564d4'
cache:
type: ParquetCache
path: parquet
可复现的构建
清单是可往返且机器可写的。你可以用 Git diff 来比较不同版本的流水线,进行代码审查,跟踪 Python 依赖项,甚至仅凭 YAML 文件就能重新构建。
$ xorq uv build expr.py
builds/28ecab08754e/
$ ls builds/28ecab08754e/*.tar.gz
builds/28ecab08754e/sdist.tar.gz builds/28ecab08754e/my-pipeline-0.1.0.tar.gz
构建过程会捕获所有内容:表达式图、依赖关系以及内存表。分享包含 sdist 的构建文件,就能获得完全一致的结果,不再出现“在我机器上能跑”的情况。
只重新计算发生变化的部分
清单是以输入为地址的:相同的输入会产生相同的哈希值。一旦输入发生改变,就会生成新的哈希值。
expr.ls.get_cache_paths()
(PosixPath('/home/user/.cache/xorq/parquet/letsql_cache-7c3df7ccce5ed4b64c02fbf8af462e70.parquet'),)
这个哈希值就是缓存的键。无需再调试失效逻辑。只要表达式相同,哈希值就相同,缓存自然有效。一旦输入发生变化,就会产生新的哈希值,从而触发重新计算。
传统的缓存机制会问:“这个是否过期了?”而基于输入地址的缓存机制则会问:“这是不是同一份计算?”后者的问题有着确定性的答案。
工具
清单提供了上下文,而工具则赋予了具体的技能:目录管理、自我检查、服务提供和执行。
目录
# 添加到目录
$ xorq catalog add builds/28ecab08754e/ --alias penguins-agg
已将构建 28ecab08754e 添加为条目 a498016e-5bea-4036-aec0-a6393d1b7c0f,修订版 r1
# 列出条目
$ xorq catalog ls
别名:
penguins-agg a498016e-5bea-4036-aec0-a6393d1b7c0f r1
条目:
a498016e-5bea-4036-aec0-a6393d1b7c0f r1 28ecab08754e
运行
$ xorq run builds/28ecab08754e -o out.parquet
服务
通过 Arrow Flight 在任何地方提供表达式:
$ xorq serve-unbound builds/28ecab08754e/ \
--to_unbind_hash 31f0a5be37713fe2c1a2d8ad8fdea69f \
--host localhost --port 9002
import xorq.api as xo
backend = xo.flight.connect(host="localhost", port=9002)
f = backend.get_exchange("default")
data = {
"species": ["Adelie", "Gentoo", "Chinstrap"],
"island": ["Torgersen", "Biscoe", "Dream"],
"bill_length_mm": [39.1, 47.5, 49.0],
"bill_depth_mm": [18.7, 14.2, 18.5],
"flipper_length_mm": [181, 217, 195],
"body_mass_g": [3750, 5500, 4200],
"sex": ["male", "female", "male"],
"year": [2007, 2008, 2009],
}
xo.memtable(data).pipe(f).execute()
species avg_bill_length
0 Adelie 39.1
1 Chinstrap 49.0
2 Gentoo 47.5
放心调试
不再需要繁琐的溯源工作。 lineage 被编码在清单中,而不是分散在各个工具中,并且可以通过 CLI 查询。
$ xorq lineage penguins-agg
Lineage for column 'avg_bill_length':
Field:avg_bill_length #1
└── Cache xorq_cached_node_name_placeholder #2
└── RemoteTable:236af67d399a4caaf17e0bf5e1ac4c0f #3
└── Aggregate #4
├── Filter #5
│ ├── Read #6
│ └── NotNull #7
│ └── Field:species #8
│ └── ↻ see #6
├── Field:species #9
│ └── ↻ see #5
└── Mean #10
└── Field:bill_length_mm #11
└── ↻ see #5
无状态的工作流
没有任务状态。只需在失败时重试即可。
Xorq 将表达式作为 Arrow RecordBatch 流来执行。不存在需要检查点的 DAG 任务图,只有数据在算子间流动。如果某处失败,只需从清单重新运行。缓存节点会立即解析,其余部分则会重新计算。
scikit-learn 集成
Xorq 可以将 scikit-learn Pipeline 对象转换为延迟表达式:
from xorq.expr.ml.pipeline_lib import Pipeline
sklearn_pipeline = ...
xorq_pipeline = Pipeline.from_instance(sklearn_pipeline)
模板
作为技能的开箱即用代码:
$ xorq init -t <template>
| 模板 | 描述 |
|---|---|
penguins |
极简示例:缓存、聚合、多引擎 |
sklearn |
分类流水线,训练与预测分离 |
人类友好的技能
模板是易于上手的组件,其中包含可与您的数据源组合的现成表达式。
即将推出
feast— 特征存储集成boring-semantic-layer— 指标和维度目录dbt— dbt 模型组合- 特征选择
水平堆栈
使用 Python 编写。以 YAML 形式编目。通过 Ibis 在任何地方进行组合。基于 DataFusion 构建的可移植计算引擎。通过 Arrow Flight 实现通用 UDF。

Lineage、缓存和版本控制随清单一起传递;被编目而非锁定在某个供应商的数据库中。
集成: Ibis • scikit-learn • Feast(开发中)• dbt(即将推出)
了解更多
1.0 版本之前,可能会有破坏性变更,并提供迁移指南。
版本历史
v0.3.192026/04/14v0.3.182026/04/07v0.3.172026/04/01v0.3.162026/03/24v0.3.152026/03/17v0.3.142026/03/09v0.3.132026/03/06v0.3.122026/03/04v0.3.112026/02/24v0.3.102026/02/18v0.3.92026/02/10v0.3.82026/02/06v0.3.72026/01/08v0.3.62026/01/05v0.3.52025/12/22v0.3.42025/11/19v0.3.32025/11/11v0.3.22025/11/03v0.3.12025/08/30v0.3.02025/07/28常见问题
相似工具推荐
openclaw
OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你
stable-diffusion-webui
stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。
everything-claude-code
everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上
ComfyUI
ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。
gemini-cli
gemini-cli 是一款由谷歌推出的开源 AI 命令行工具,它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言,它提供了一条从输入提示词到获取模型响应的最短路径,无需切换窗口即可享受智能辅助。 这款工具主要解决了开发过程中频繁上下文切换的痛点,让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用,还是执行复杂的 Git 操作,gemini-cli 都能通过自然语言指令高效处理。 它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口,具备出色的逻辑推理能力;内置 Google 搜索、文件操作及 Shell 命令执行等实用工具;更独特的是,它支持 MCP(模型上下文协议),允许用户灵活扩展自定义集成,连接如图像生成等外部能力。此外,个人谷歌账号即可享受免费的额度支持,且项目基于 Apache 2.0 协议完全开源,是提升终端工作效率的理想助手。
markitdown
MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具,专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片(含 OCR)、音频(含语音转录)、HTML 乃至 YouTube 链接等多种格式的解析,能够精准提取文档中的标题、列表、表格和链接等关键结构信息。 在人工智能应用日益普及的今天,大语言模型(LLM)虽擅长处理文本,却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点,它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式,成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外,它还提供了 MCP(模型上下文协议)服务器,可无缝集成到 Claude Desktop 等 LLM 应用中。 这款工具特别适合开发者、数据科学家及 AI 研究人员使用,尤其是那些需要构建文档检索增强生成(RAG)系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性,但其核心优势在于为机器
