workflows: 에이전트 워크플로우를 위한 호스트 불가지론적(host-agnostic) Rust 엔진 (오픈 소스)
요약
자동화 워크플로우를 WorkflowGraph로 모델링하는 오픈 소스 Rust 엔진인 'workflows'를 소개합니다. 사용자의 자연어 설명을 기반으로 트리거, 검색, 요약 등의 노드를 포함한 그래프를 구축하고, 이를 컴파일하여 결정론적으로 실행할 수 있는 구조를 제공합니다.
핵심 포인트
- Rust 기반의 호스트 불가지론적(host-agnostic) 워크플로우 엔진
- WorkflowGraph를 통한 타입 지정 노드 및 엣지 모델링
- 병렬 팬아웃을 결정론적으로 유지하는 머지 리듀서 구조
- LLM 에이전트, HTTP 요청, 샌드박스 코드 등 다양한 노드 카탈로그 지원
우리는 최근 자사 제품인 OpenHuman에 새로운 기능을 출시했습니다. 이 기능은 사용자가 "매일 아침 Twitter에서 상위 5개 AI 트렌드를 가져와 나에게 이메일로 보내줘"와 같이 평이한 영어로 자동화를 설명하면, 에이전트가 트리거(trigger), 검색(search), 요약(summarize), 전송(send)과 같은 실제 워크플로우 그래프(workflow graph)를 구축해 주는 방식입니다. 이후 대화하듯 수정할 수 있으며, 실제 작업이 실행되기 전에 승인을 요청합니다.
이 포스트는 제품 홍보가 아닌 엔진에 관한 내용입니다. 즉, 엔진이 실제로 무엇을 하는지, 어떻게 구축되었는지, 그리고 아직 무엇이 부족한지에 대해 다룹니다.
이것은 무엇인가?
workflows는 (호스팅되는 서비스가 아닌) 자동화를 WorkflowGraph로 모델링하는 Rust 라이브러리 크레이트(crate)입니다. WorkflowGraph는 타입이 지정된 노드(node)와 엣지(edge)로 구성된 유향 그래프(directed graph)입니다. 사용자가 해당 그래프를 구축하거나 생성하면, 구조적 검증(structural validation)을 거쳐 불투명한 CompiledWorkflow로 컴파일되며, engine::run을 통해 상태 그래프 실행 엔진(state-graph execution engine)인 tinyagents 위로 실행당 한 번씩 로워링(lowering)됩니다.
model::WorkflowGraph -> validate -> compiler::compile -> engine::run
(타입 지정 그래프) (구조적 검증) (검증된 핸들) (tinyagents 위로 로워링하여 실행 완료까지 구동)
실행 상태(Run state)는 { "run": { "trigger": … }, "nodes": { "": { "items": [ … ] } } } 형태의 단일 JSON 값입니다. 머지 리듀서(merge reducer)는 각 노드의 출력을 해당 ID 아래로 접어(fold) 넣으므로, 독립적인 브랜치들이 서로 충돌하지 않습니다. 이것이 병렬 팬아웃(parallel fan-out)을 결정론적(deterministic)으로 유지하는 비결입니다.
노드 카탈로그
종류 | 역할
trigger | 워크플로우를 시작하는 엔트리 노드 (그래프당 정확히 하나); 실행 모드는 호스트 주도형(host-driven)
agent | LLM 에이전트 턴을 실행하며, 선택적으로 채팅 모델(chat-model) / 메모리(memory) / 도구(tool) / 출력 파서(output-parser) 서브 포트를 가짐
tool_call | LLM 개입 없이 특정 통합 액션(integration action)을 결정론적으로 호출
http_request | 아웃바운드 HTTP 요청
code | 샌드박스화된 사용자 코드 (JavaScript 또는 Python)
output_parser | 상위 에이전트의 출력을 구조화된 형태로 파싱/검증
sub_workflow | 다른 워크플로우를 중첩된 서브 그래프(sub-graph)로 실행하고 그 출력을 반환
condition | 양방향 IF, true/false에 따라 방출
switch | 표현식 결과에 따라 키가 지정되는 다방향 분기
merge | 팬인(Fan-in) 배리어 — 실행 전 연결된 모든 선행 노드를 기다림
split_out | 팬아웃(Fan-out) — 리스트의 각 요소당 하나의 아이템을 방출
transform | 실행 상태(run state)에 대한 순수 표현식 기반 필드 매핑
데이터는 { json, binary?, paired_item? } 형태의 아이템 배열로서 노드 간에 흐릅니다. 이는 단순한 함수 합성 DAG(Directed Acyclic Graph)보다는 n8n의 아이템 기반 모델에 더 가깝습니다. 또한 노드 설정은 =item.name과 같이 = 접두사가 붙은 표현식을 사용하여 실행 스코프(run scope)를 참조할 수 있습니다.
제가 실제로 이야기하고 싶은 부분: 호스트 불가지론(host-agnosticism)
이 엔진이 누구와 통신할지 — 어떤 LLM을 사용할지, 어떤 통합 제공자를 사용할지, HTTP 요청이 실제로 어떻게 나갈지, 상태가 어디에 저장될지 —에 대해 통상적으로 결정을 내려야 하는 모든 지점은 대신 임베딩 애플리케이션이 구현하는 Rust 트레이트(trait)로 대체됩니다:
LlmProvider
ToolInvoker
HttpClient
CodeRunner
StateStore
크레이트(crate) 자체는 특정 벤더를 하드코딩하지 않으며, 스스로 실제 네트워크 호출을 수행하지도 않습니다. 테스트 용도(및 아래의 hello_workflow 예제)를 위해, mock cargo feature를 통해 다섯 가지 트레이트 모두에 대한 결정론적인 인메모리(in-memory) 구현체를 제공합니다.
이는
이것은 레포지토리의 hello_workflow 예제입니다 — cargo run --example hello_workflow --features mock.
무엇이 완료되었고, 무엇이 솔직히 아직 완료되지 않았는지
완료된 사항 (Phase A): 전체 노드 카탈로그, 구조적 유효성 검사(structural validation), 실행별 컴파일(per-run compilation), =-표현식 기반의 아이템 기반 데이터 흐름(item-based data flow), 선형/조건부/병렬 분기(linear/conditional/parallel-fan-out)/병합 장벽 라우팅(merge-barrier routing), 노드별 오류 처리(per-node error handling), 인간 개입 루프 승인 게이팅(human-in-the-loop approval gating), 추적 관측 가능성(tracing observability), 불투명 자격 증명 참조(opaque credential references), 그리고 업그레이드를 위한 마이그레이션 프레임워크를 갖춘 버전 관리 와이어 포맷(schema_version + per-node type_version)입니다. 이는 #![orbid(unsafe_code)], MSRV 1.85, Rust 2024 edition으로 작성되었으며, 레퍼런스 워크플로우 E2E 스위트 뒤의 목업 기능들을 대상으로 엔드투엔드로 실행됩니다.
아직 완료되지 않은 사항은 말씀드리느니 차라리 말하는 편이 나을 것 같습니다:
진정한 jq/jaq 스타일의 표현식 엔진 (Expression engine) — 현재는 과도기적 단계로, 최소한의 점 표기법 경로 평가기 (dotted-path evaluator)가 =item.name 스타일의 표현식을 처리합니다.
재시도 백오프 타이밍 (Retry backoff timing) 및 노드별 타임아웃 (per-node timeouts).
지속 가능하고 체크포인트가 생성되는 슈퍼 스텝 재실행 (Durable, checkpointed super-step replay) — 현재는 저장된 실행 중간 체크포인트에서 재개하는 대신 결정론적으로 (deterministically) 재실행합니다.
시각적이고 에이전트 우선적인 저작 도구 (Visual and agent-first authoring tools) (이는 호스트 측의 관심사이며, OpenHuman 제품 레이어가 이 엔진 위에서 수행하는 역할입니다).
OpenHuman 호스트 통합 자체 — 이 엔진을 실제 LLM 및 실제 통합 환경에 실제로 연결하는 부분 — 는 Phase B에 해당하며, 아직 공개되지 않은 별도의 리포지토리(repo)에 존재합니다.
라이선스 (License)
GPL-3.0-or-later. 폐쇄 소스 (closed-source)로 출시할 계획이 있는 프로젝트를 위해 이 엔진을 검토 중이라면 미리 알아둘 가치가 있습니다.
만약 워크플로우/자동화 엔진을 구축하거나, 이와 같은 시스템에서 "역량 특성 (capability trait)"의 경계가 어디에 위치해야 하는지에 대한 의견을 가진 분이라면, 저희가 무엇을 잘못했는지 진심으로 듣고 싶습니다: github.com/tinyhumansai/tinyflows.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기