Conduit:一個(gè)無界面的節(jié)點(diǎn)系統(tǒng)
这是Amazon Q 开发者挑战赛:探索可能性的旅程
我建的我创建了一个名为Conduit的领域特定语言(DSL),它让开发人员能够采用直观的语法创建可重复使用的构建块,这些构建块可以混合搭配,以构建复杂的数据处理流水线。它类似于ComfyUI这样的图形界面节点工具,但没有图形界面,提供了一种更灵活且可嵌入的纯代码优先的方法。
Conduit 最强大的功能之一是它真正的跨语言兼容性。不同于许多绑定到特定语言或平台的工作流工具,Conduit 的工作流可以编译为本地库(.so/.dll),并通过 FFI(即外来函数接口)无缝集成到几乎任何支持 FFI 的编程语言中。这意味着你可以使用 Conduit 直观的 DSL 来定义工作流,然后可以从 JavaScript、Python、PHP、Java、Go 或任何其他支持 FFI 的语言中使用它们,同时保持原生级别的性能。这种语言无关的方法消除了复杂互操作层和不同技术栈之间性能下降桥梁的需要。
这个项目特别的地方在于,Amazon Q Developer 转变了我的开发过程。有了它的帮助,我只用了两天就完成了通常需要一个月才能完成的工作,包括创建自定义 DSL 解析器、实现 ECS 架构、开发过程宏等——这些都是 Rust 开发中的难题,通常需要投入大量时间和专业知识。
示例(一个简单的示例)该项目包括一些实际的工作示例,展示出Conduit(通道)的功能和潜力:
- 一个使用 Rust 的示例,如下所示:读取一个图像文件,调整大小并保存结果如下。
let pipeline = r#"
调整大小 {
源 <- 读取文件 {
输入 <- "./examples/conduit-example/cover.png"
}
宽度 <- 512
高度 <- 215
输出 -> 写入文件 {
目的地 <- "./examples/conduit-example/cover.smaller.png"
}
}
"#;
let mut engine = Engine::new();
engine.运行管道(pipeline);
全屏模式,退出全屏
如果你是视觉学习者,就可以这样来看上面的例子。
示例代码可以在这里找到:这里。
- 一个使用 Node.js 的示例,展示如何在 JavaScript 中使用 Conduit。
import { 管道引擎 } from './Engine'
const 引擎 = new 管道引擎()
const 管道 = `
resizer {
源 <- 读取文件 {
输入 <- "../conduit-example/cover.png"
}
宽 <- 512
高 <- 215
输出 -> 写入文件 {
目标 <- "../conduit-example/cover.smaller.png"
}
}
`
引擎.运行管道(管道)
引擎.销毁()
进入全屏 退出全屏
代码库
这是我提交给 "亚马逊 Q 开发者挑战" 的主要仓库。
Conduit 是一种用 Rust 创建基于节点的工作流的领域特定语言 (DSL)。它使你能够使用简单且声明式的语法构建数据处理管道,这些管道是复杂的。
目录 如何安装在你的 Cargo.toml
文件中添加 康杜特
(Conduit):
# 引入 conduit 和 conduit-derive 依赖包
[dependencies]
conduit = { git = "https://github.com/milewski/conduit-challange.git", version = "0.1.0" }
conduit-derive = { git = "https://github.com/milewski/conduit-challange.git", version = "0.1.0" }
全屏,退出全屏
快速入门 use conduit::Engine;
use conduit_derive::Node;
#[derive(Node)]
pub struct Logger {
pub left: Input<String>,
pub right: Input<String>,
}
impl 可执行节点 for Logger {
fn run(&self) {
println!("{} {}", self.left.read);
}
注意,在 self.left.read
这里缺少一个分号,保持了原样。
您的任务是仔细阅读并编辑从英语到中文的翻译,考虑到专家的建议和建设性的批评。请提供需要翻译的英文文本,以便进行准确的翻译改进。
全屏模式 退出
我打算把这个项目做成一个开源项目,因为内心深处,这才是我理想中的ComfyUI的样子。还有很长的路要走才能完成所有自定义节点的构建,特别是考虑到大多数AI工作流的代码都是用Python编写的,这特别有挑战性。然而,有了我用Candle和Burn库的经验,我或许能达到目标。
(注:此部分为空,保持与原文一致。)
(最终翻译:)
问题与启发
我是 ComfyUI 的忠实粉丝,这是一个强大的基于节点的系统,我在黑客马拉松和个人项目中经常使用它。但是,尽管它功能强大,我还是遇到了两个始终存在的限制。
-
当我需要超出现有节点或社区贡献所提供的功能时,我不得不自己动手创建它——通常用Python,通过一个手动且常常很笨拙的过程。
- 像 ComfyUI 这样的系统不容易嵌入。有时我只是想要一个轻量级、可嵌入的引擎,可以直接在我的代码或语言环境中运行——无需设置服务器、界面或处理特定平台的特有问题这些。
这让我想到一个问题:
如果有一个像ComfyUI这样的工具,但完全是代码驱动的——没有阻碍,只有灵活的构建模块,会怎么样?
(注:根据专家建议,“会怎么样?”可以去掉以使句子更流畅,但由于原文句式中包含疑问语气,保留了“会怎么样?”以保持原文语气。)
最终翻译:
如果有一个像ComfyUI这样的工具,但完全是代码驱动的——没有阻碍,只有灵活的构建模块。
如果我能创建的不仅仅是针对机器学习模型的节点工作流,而是用于任何事情的工作流——比如调用API接口、评估表达式、链接命令行命令、验证表单信息,甚至是简单的加法运算,那会怎么样?
这就是Conduit的设计理念:一个基于节点的系统,完全没有用户界面,可嵌入,专为希望在编辑器内实现完全控制的开发者设计。
技术实施
Conduit 的语法既简单又直观,深受像 Verilog 这样的硬件描述语言的影响。创建自定义节点非常简单——只需要定义一个 Rust 结构体,然后使用 Node 宏来扩展它,你就可以开始构建了。无需担心 Python 或 JavaScript。一切都是纯 Rust,还可以通过 FFI 从其他语言调用。
我在这里写了一个简单的教程,它涵盖了你需要知道的所有关于DSL的语法信息,https://github.com/milewski/conduit-challenge?tab=readme-ov-file#basic-syntax 这里解释了DSL的语法。
Conduit 的一个关键优势是其跨语言兼容性。你可以构建你的工作流,将其编译为 .so
/.dll 动态库,然后通过 FFI 在 任意 编程语言中使用它。我提供了一个在 JavaScript 中使用的示例,但没有限制——你可以将其与 Dart、PHP、Java 或其他任何语言集成。因为这些工作流是原生执行的,你将获得原生性能,从而不会受到每种语言运行时环境特有的瓶颈限制。
技术栈
该项目完全使用 Rust 构建,使用 PEST 编写了一个自定义领域特定语言(DSL)。该语言的语法(PEG)可以在 schema.pest 文件中查看。
性能是 Conduit 架构的一大核心优势。通过利用 Rust 的零成本抽象和 ECS 模式,无论工作流多么复杂,Conduit 的工作流能够以接近原生性能执行。与传统的基于脚本的工作流系统不同,后者在运行时解释代码或依赖特定语言的虚拟机,Conduit 将工作流编译为优化的机器代码。这样做的话,消除了解释器的开销,并实现了独立节点的自动并行化。在实际应用中,这意味着 Conduit 可以比用解释型语言实现的等效实现方式更快地处理数据密集型工作流(如图像处理或大型数据集转换),同时保证内存使用的可预测性,并避免垃圾回收导致的暂停。
conduit 采用了一种实体组件系统(ECS)设计模式,使用了 bevy-ecs,这使得并行化操作变得简单,从而实现了极其高效的流程处理。它还利用了 inventory 系统自动注册节点,进一步提高了项目的易用性。
这个项目被分为两个库:
- Conduit: 负责处理 DSL 解析并执行节点流程的主要 crate
-
Conduit-Derive: 一个过程宏库,用于简化新节点的创建,减少样板代码
-
- *
在参加这次黑客松之前,我并不知道亚马逊Q CLI的存在。最初,我以为它会像其他IDE工具一样,比如GitHub Copilot或Gemini Assistant——主要功能是代码自动补全。然而,我感到非常惊喜,发现它是一个功能齐全的CLI助手,这是我第一次直接从命令行使用AI的体验。
与亚马逊Q一起的开发旅程
我的旅程始于向亚马逊Q求助于黑客马拉松项目的想法。我提到我对类似ComfyUI这样的节点系统很感兴趣,它建议我构建类似Conduit那样的系统。当我要求一个原型时,输出的质量立即让我确信这是一个强大的工具。
亚马逊Q生成的代码与我自己写的差不多,这让我有了继续下去的信心。原本需要我花几个月才能完成的任务,有了亚马逊Q的帮助,我只用了两天就搞定了!
还有一个值得一提的地方是:虽然AWS Q网站上有大量文档,但我直接跳过这些,直接进入安装。命令行自带的/help
命令会告诉你所有可用的功能,这让使用该工具变得非常简单。这种易用性给我带来了令人愉快的惊喜。
架构设计决策
我从零开始,首先建立基础,然后请亚马逊Q逐个功能地帮忙构建。对于简单任务,我自己动手写代码,但对于更复杂的挑战,通常需要花费大量时间来找到最佳方案时,我请亚马逊Q提供多个解决方案。
最令我印象深刻的是Amazon Q生成大量代码的同时还能保持步步为营的策略。我可以讨论诸如“我认为如果你这样改变这个结构,可能需要添加生命周期参数,并且在实现XYZ时可能会遇到问题”这样的担忧,它能理解我的顾虑并提出与现有代码库匹配的替代方案。
Rust 的高级特性和功能
一旦我的第一个版本可以正常工作了,我就想简化代码库以减少样板代码,创建一个更易用的库。这时我让亚马逊Q帮我生成一个过程宏来生成所有必要的样板代码。亚马逊Q将其浓缩为一个简洁的#[derive(Node)]
属性,并使代码变得非常简洁易用!诚然,用 Rust 编写过程宏很难,我自己实现可能需要很长时间来完成,但只需要一次提示,亚马逊Q就成功地构建并使它工作起来了!
我还与Amazon Q讨论了哪些最佳设计模式可以应用到该项目以提高性能、实现并行执行和多线程。最初,我是用通道实现的,但Amazon Q建议我改用ECS模式,这使实现变得简单多了。这种架构决策的指导非常宝贵。
使用 Amazon Q 的一些小贴士
-
逐步完成任务:可以分步骤请Amazon Q编写或修改代码,而是将大型功能拆分成小的部分来处理。这并非因为它无法处理复杂任务,而是因为较小的改动更容易理解和检查。如果不理解生成的代码,就很难跟进修改或修复错误。因此,逐步推进是更有效的做法。
-
经常性地提交代码:在请求 Amazon Q 修改代码之前,经常性地提交你的代码。尽管它会显示并确认更改,保留 Git 提交历史可以更清晰地看出改动的地方。
-
明确指示:告诉 Amazon Q 你想要完成的任务。明确哪些文件需要修改,具体要做哪些改动,以及如何实施。最好给出具体的文件和函数名称。
-
创建一个名为AmazonQ.md的文件:编写一份指南,说明Amazon Q应该做什么以及不应该做什么,包括项目背景。包含始终运行测试和编译项目说明,有助于确保Amazon Q在最终确定更改前会验证所有更改并修复任何错误。
-
- *
如果你喜欢这个项目,并希望帮助它向前发展,非常欢迎你的加入和支持!我们的路线图上列出了许多功能和改进。
- 异步运行时/调度器:实现支持异步运行的节点
- 增强的错误处理:完成与
thiserror
的集成,以实现更强大的错误处理 - 算术表达式:更新 DSL 以支持算术运算
node { property <- (500 * 5) / (10 * another::module) }
点这里进入全屏模式,点那里退出全屏模式。
- 条件逻辑功能:添加条件节点功能:
test { property <- if (true 与 false, "真时", "假时") }
进入全屏 退出全屏
- 扩展节点库:实现更多适用于各种场景的节点
非常感谢大家提交Pull请求来改进这些领域!
[MCP]: 模型上下文协议(MCP)
[LLM]: 大规模语言模型
[RAG]: 检索增强生成
[SSE]: 服务器端事件
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章