Doramagic 项目包 · 项目说明书

model-compose 项目

灵感源自 docker-compose 的可移植 AI 运行时,用一个 YAML 文件即可组合 Agent、RAG 流水线和 MCP 服务端,并随处运行。

项目概述与快速入门

model-compose 是一个面向工作流编排与多组件组合场景的 Python 框架,仓库内的 Python 包名为 mindor,命令行工具名为 compose。它的核心目标是把"模型推理""HTTP 服务""Shell 命令""本地模型加载"等异构能力抽象为可组合的 组件(Component),并通过声明式配置文件把它们串成可执行的工作流,再以 控制器(Control...

章节 4.1 安装

继续阅读本节完整说明和来源证据。

章节 4.2 第一个工作流

继续阅读本节完整说明和来源证据。

章节 4.3 升级到 v0.4.0 的流式能力

继续阅读本节完整说明和来源证据。

1. 项目定位与目标

model-compose 是一个面向工作流编排与多组件组合场景的 Python 框架,仓库内的 Python 包名为 mindor,命令行工具名为 compose。它的核心目标是把"模型推理""HTTP 服务""Shell 命令""本地模型加载"等异构能力抽象为可组合的 组件(Component),并通过声明式配置文件把它们串成可执行的工作流,再以 控制器(Controller) 的形式统一调度与部署。

从代码组织看,框架入口位于 src/mindor/__init__.py,对外暴露的版本号与基础 API 集中在 src/mindor/__init__.pysrc/mindor/version.py 中,便于上层业务以 import mindor 的方式引用。命令行层则通过 src/mindor/cli/compose.py 提供 compose 子命令,是用户与框架交互的最直接入口。

资料来源:src/mindor/__init__.py:1-20src/mindor/version.py:1-10src/mindor/cli/compose.py:1-30

2. 版本演进与里程碑

model-compose 至今已发布四个稳定版本,每一次迭代都聚焦于"组件生态扩展"和"部署形态多样化"两条主线:

版本主要能力关键补充
v0.1.0核心特性落地,基础文档完成首个稳定版,日志信息较为简略
v0.2.0工作流可直接部署为 MCP Server;支持 Shell 组件进入生产可用阶段
v0.3.0新增本地模型推理组件;支持 Docker 化的 Controller 部署离线/自托管场景更友好
v0.4.0引入 event-streamstreaming 两种流式模式;新增 HTTP Server 组件实时交互能力显著增强

资料来源:v0.1.0 Releasev0.2.0 Releasev0.3.0 Releasev0.4.0 Release

3. 整体架构

框架在运行时可以被划分为三层:配置层(YAML/JSON 工作流描述)、执行层(Controller + 组件运行时)、接入层(CLI、HTTP、MCP、Docker 等多种入口)。三者通过 compose CLI 解耦,用户只关心工作流定义,Controller 负责把它们实例化并对外提供服务。

flowchart LR
    A[用户/调用方] --> B[接入层<br/>CLI / HTTP / MCP / Docker]
    B --> C[Controller<br/>src/mindor/cli/compose.py]
    C --> D[Component Runtime<br/>HTTP / Local Model / Shell / ...]
    D --> E[外部依赖<br/>本地模型 / 远端 API / 系统命令]
    C --> F[Event Stream / Streaming<br/>v0.4.0]

资料来源:src/mindor/cli/compose.py:30-80README.md:1-60pyproject.toml:1-40

4. 快速入门

4.1 安装

项目通过 pyproject.toml 管理依赖与打包元数据,使用标准的 PEP 621 方式声明项目名 mindor 以及 CLI 入口 compose。常见的安装步骤如下:

# 克隆仓库
git clone https://github.com/hanyeol/model-compose.git
cd model-compose

# 以可编辑模式安装
pip install -e .

安装成功后,compose 命令即可在终端被识别,它由 src/mindor/cli/compose.py 中的入口点注册而来。

资料来源:pyproject.toml:1-40src/mindor/cli/compose.py:1-30

4.2 第一个工作流

  1. 在项目根目录新建 workflow.yaml,声明一个最简单的 Shell 组件。
  2. 使用 compose run workflow.yaml 启动本地 Controller。
  3. 若希望以 MCP Server 形式暴露(自 v0.2.0 起可用),执行 compose serve workflow.yaml
  4. 需要实时输出时(自 v0.4.0 起可用),可在配置中开启 streaming: trueevent_stream: true

4.3 升级到 v0.4.0 的流式能力

v0.4.0 引入的流式模式主要面向"长耗时推理 + 增量回传"的场景。建议先在 workflow.yaml 中显式指定 mode: streamingmode: event_stream,再通过 CLI 启动,由 Controller 统一将增量事件转发给 HTTP/MCP 客户端。

资料来源:README.md:60-120v0.4.0 Release

5. 适用场景与边界

  • 适用:需要把"模型调用 + 业务胶水代码 + 外部服务"统一编排为可复用工作流的场景;需要 MCP/HTTP 等多种对外暴露形态的场景;希望在本地或 Docker 化环境中自托管推理服务的场景。
  • 暂不适用:跨语言重型微服务编排(推荐使用专用编排引擎);对超低延迟有苛刻要求的实时音视频链路。

6. 下一步阅读

  • 深入组件配置:workflow.yaml 字段说明与组件类型清单。
  • Controller 与部署形态:CLI、Docker、MCP Server 三种入口的差异。
  • v0.4.0 流式协议:event-streamstreaming 模式的事件契约。

资料来源:README.md:1-60src/mindor/__init__.py:1-20src/mindor/version.py:1-10src/mindor/cli/compose.py:1-80pyproject.toml:1-40

资料来源:src/mindor/__init__.py:1-20src/mindor/version.py:1-10src/mindor/cli/compose.py:1-30

核心架构与控制器

model-compose 是一个面向模型工作流的可组合运行时,其核心由 mindor.core 命名空间下两个并列的子系统协同构成:控制器(Controller) 负责单工作流的执行编排,组合器(Compose) 负责跨工作流的部署与生命周期管理。本页聚焦这两层的设计职责、模块边界与协作流程。

章节 Base Controller:controller/base.py

继续阅读本节完整说明和来源证据。

章节 Controller:controller/controller.py

继续阅读本节完整说明和来源证据。

章节 Runner:controller/runner.py

继续阅读本节完整说明和来源证据。

章节 Compose:compose/compose.py

继续阅读本节完整说明和来源证据。

架构概览

整个 mindor.core 下分出两个平行的子包:controllercompose。控制器层聚焦"如何运行一个已经定义好的工作流",组合层聚焦"如何在外部托管多个工作流并将其暴露为服务"。这种分层使单工作流的执行逻辑与多工作流的部署逻辑彻底解耦——新增执行模式时无需触碰部署代码,新增托管形式时也无需重写调度逻辑。

graph TD
    A[Compose / Manager] -->|托管| B[Controller]
    B -->|委派| C[Runner]
    D[Base Controller] -->|继承| B
    E[Validator] -->|校验| A
    F[Compose] -->|实例化| B

模块间的数据流是单向的:组合层向下游控制器层下发"要跑什么",控制器层向上游组合层回报"跑得怎么样"。这一方向性使得 v0.2.0 引入的 MCP 服务器暴露、v0.3.0 引入的 Docker 化部署以及 v0.4.0 引入的事件流/流式模式都可以在不改对方的前提下叠加演进。

资料来源:src/mindor/core/compose/manager.py:1-40, src/mindor/core/controller/base.py:1-30

控制器层

Base Controller:`controller/base.py`

Base Controller 抽象出控制器的最小契约,定义了工作流标识、组件列表、输入输出契约以及生命周期钩子等通用字段。它是所有具体控制器的父类,确保不同执行模式——同步、事件流、流式——共享同一份骨架。社区反馈中提到的"实时交互"能力正是通过在 Base 之上派生不同子类实现的,骨架的稳定保证了派生类的可替换性。

资料来源:src/mindor/core/controller/base.py:15-60

Controller:`controller/controller.py`

controller.py 在 Base 的基础上注入具体执行策略:根据配置选择同步模式、event-stream 模式(v0.4.0 新增)或 streaming 模式(v0.4.0 新增),并将请求路由到 Runner。该模块还承担错误的归一化处理,使上层不必感知底层调度的差异。

资料来源:src/mindor/core/controller/controller.py:30-90

Runner:`controller/runner.py`

Runner 是真正的执行体:负责实例化组件、按拓扑顺序调度、收集结果并向上汇报错误。Controller 决定"以什么姿态跑",Runner 决定"怎么跑",这一职责切分使得新增执行模式时不必重写调度核心。Runner 同时也是 v0.3.0 引入的"本地模型推理组件"的实际承载者——当组件类型为本地推理时,Runner 直接调用本地模型权重完成推理。

资料来源:src/mindor/core/controller/runner.py:20-70

组合层

Compose:`compose/compose.py`

compose.py 是单工作流的部署描述对象,承载来自配置文件的结构并转换为运行时对象。它也是 v0.2.0 起"将工作流直接部署为 MCP 服务器"能力的载体:当 Manager 检测到部署形态为 MCP 时,会以 Compose 为单位暴露协议端点,而非以单个组件为单位。

资料来源:src/mindor/core/compose/compose.py:25-70

Manager:`compose/manager.py`

Manager 聚合多个 Compose 实例,提供统一启停、健康检查与端口分配。v0.3.0 引入的 Docker 化控制器部署由 Manager 协调构建与启动流程;它也是读取环境变量、注入运行参数(如 API 密钥、模型路径)的统一入口。

资料来源:src/mindor/core/compose/manager.py:30-80

Validator:`compose/validator.py`

Validator 在加载阶段校验配置:组件类型是否受支持、依赖是否闭合、端口是否冲突、外部命令(如 v0.2.0 引入的 Shell 组件)是否可执行。它是 Manager 信任下游 Controller 之前的最后一道闸门,所有不合规的配置都会在此阶段被拦截,避免运行时才暴露问题。

资料来源:src/mindor/core/compose/validator.py:15-55

生命周期与执行流

一次典型的请求经历以下阶段:

  1. Manager 读取配置并交由 Validator 进行静态校验。
  2. Validator 通过后,Manager 实例化一个或多个 Compose 对象。
  3. 对每个 Compose,Manager 实例化对应的 Controller。
  4. Controller 选择执行模式,委派给 Runner。
  5. Runner 依次调度组件、收集结果并沿调用栈向上返回。
阶段责任模块关键产物
加载与校验Validator / Manager合规的配置对象
部署与编排Manager / Compose可寻址的服务实例
执行调度Controller / Runner组件调用结果

v0.1.0 发布说明中曾指出"Log messages are insufficient",后续版本在该路径上持续完善可观测性,使每一阶段都能在日志中留下可追踪的痕迹。

资料来源:src/mindor/core/compose/manager.py:90-120, src/mindor/core/controller/runner.py:80-110

小结

控制器层解决"单工作流怎么跑",组合层解决"多个工作流怎么托管"。二者通过 Validator → Manager → Compose → Controller → Runner 的单向数据流协作,既支撑 v0.2.0 的 MCP 服务器暴露、v0.3.0 的本地推理与 Docker 化部署,也支撑 v0.4.0 的事件流与流式响应。理解这条单向链是从源码入手掌握 model-compose 的最佳起点。

资料来源:src/mindor/core/compose/manager.py:1-40, src/mindor/core/controller/base.py:1-30

组件系统

组件系统(Component System)是 model-compose 工作流编排的核心抽象层,位于 src/mindor/core/component/ 目录下,负责将所有可执行单元(智能体调用、外部 API 调用、本地模型推理、Shell 命令等)统一封装为可声明、可配置、可组合的"组件"。整个工作流的 DAG 节点、Job 任务以及 MCP Server 部署入口...

重点 基础抽象层

base.py 提供组件的基类与生命周期接口;

重点 编排层

component.py 实现组件工厂与注册机制;

重点 运行时层

context.py 提供跨组件共享的上下文对象。

一、系统概述

组件系统(Component System)是 model-compose 工作流编排的核心抽象层,位于 src/mindor/core/component/ 目录下,负责将所有可执行单元(智能体调用、外部 API 调用、本地模型推理、Shell 命令等)统一封装为可声明、可配置、可组合的"组件"。整个工作流的 DAG 节点、Job 任务以及 MCP Server 部署入口,本质上都是通过组件系统进行实例化与调度的。

根据目录结构可见,组件系统由三层组成:

  • 基础抽象层base.py 提供组件的基类与生命周期接口;
  • 编排层component.py 实现组件工厂与注册机制;
  • 运行时层context.py 提供跨组件共享的上下文对象。

services/ 子目录中,则按业务形态沉淀了多种内置组件实现(agent.pyhttp_client.pyhttp_server.py 等),遵循统一的接口契约对外暴露。这种"基类 + 服务目录"的拆分使得新增组件只需继承基类并在 services/ 中添加实现即可,无需修改调度核心,符合开闭原则。

资料来源:src/mindor/core/component/component.pysrc/mindor/core/component/base.py

二、组件基类与生命周期

base.py 定义了组件的抽象基类,规定了所有组件必须实现的标准化生命周期方法(典型地包括 setuprunteardown 等)。这一契约保证调度器可以一致地对待不同类型的组件——无论是 LLM Agent 调用还是 HTTP 请求,都通过相同的生命周期推进。

component.py 充当组件工厂(Factory),承担两个关键职责:

  1. 类型注册:根据 YAML/JSON 工作流配置中的 type 字段,从 services/ 子模块动态加载对应的组件类;
  2. 依赖注入:在实例化组件时,将 context.py 中的运行时上下文(全局配置、共享变量、连接池、Logger 等)注入到组件内部。

context.py 则作为组件之间的"共享内存",既携带全局只读配置,也允许在同一执行流程内跨组件传递中间结果(例如 Agent 的输出作为下游 HTTP 组件的请求体)。这种设计避免了在每次调用时重复解析配置,也使流式(streaming)场景下上游增量输出能够被下游实时消费。

flowchart LR
    A[工作流配置] --> B[component.py 工厂]
    B --> C[base.py 基类]
    C --> D[services 子模块]
    D --> D1[agent.py]
    D --> D2[http_client.py]
    D --> D3[http_server.py]
    C --> E[context.py 上下文]

资料来源:src/mindor/core/component/base.pysrc/mindor/core/component/component.pysrc/mindor/core/component/context.py

三、内置服务组件

services/ 目录是组件生态的具体实现层,社区版本演进过程中持续扩展:

组件文件形态关键用途
agent.py智能体服务调用 LLM 完成推理与对话,作为工作流的"大脑"
http_client.py外部 HTTP 调用触发第三方 API、回调 webhook
http_server.pyHTTP 服务端v0.4.0 新增,将工作流作为可被外部调用的 HTTP 服务暴露

每个服务组件都继承自 base.py 中的基类,仅重写与自身业务相关的执行逻辑。以 http_client.py 为例,它封装了请求构造、鉴权、超时与重试等横切关注点;而 http_server.py 则额外引入了 v0.4.0 引入的 event-stream modestreaming mode,使得服务端组件可以以 SSE(Server-Sent Events)等流式协议向客户端增量推送结果。

agent.py 是工作流中最常见的组件,负责接入模型推理后端。结合 v0.3.0 引入的"本地模型推理"能力,它既可以指向远端 LLM 服务,也可以直接加载本地权重文件,再借助 v0.3.0 的 Docker 化 Controller 进行容器化部署。

资料来源:src/mindor/core/component/services/agent.pysrc/mindor/core/component/services/http_client.pysrc/mindor/core/component/services/http_server.py

四、扩展与组合模式

组件系统的扩展遵循三个核心模式:

  1. 新增组件类型:在 services/ 下新建模块,继承 base.py 中的基类并在 component.py 工厂中注册 type 标识符即可被工作流引用;
  2. 组合嵌套:组件的输入/输出以结构化数据形式写入 context.py,下游组件通过模板表达式或字段绑定读取上游结果,从而在 YAML 中以声明式方式串联成复杂流水线;
  3. 部署形态切换:同一组件实现可在不同 Job 中复用,既能作为内部 DAG 节点执行,也能通过 http_server.py 暴露为 MCP Server 端点(v0.2.0 起支持),实现"一次定义、多种部署形态"。

值得关注的已知限制来自 v0.2.0 与 v0.1.0 发布说明:早期版本的日志输出较为粗放,对于组件级排障不够友好;建议在生产使用中结合 Controller 层的结构化日志进行链路追踪。

资料来源:src/mindor/core/component/component.pysrc/mindor/core/component/base.pysrc/mindor/core/component/context.py

资料来源:src/mindor/core/component/component.pysrc/mindor/core/component/base.py

工作流与作业编排

model-compose 的核心抽象由"工作流(Workflow)"和"作业(Job)"两层组成,工作流负责定义顺序、循环与依赖,作业则是真正执行业务逻辑的最小单元。该项目自 v0.2.0 起支持将工作流直接部署为 MCP 服务器,并在 v0.3.0 / v0.4.0 中陆续加入本地模型推理、Docker 控制器、流式输出以及 HTTP 组件,使编排能力覆盖了从本地推理到...

重点 Component Job

调用一个具体的"组件(Component)",是体系内最高频的作业类型,支持将本地模型、HTTP 服务、Shell 命令等统一映射为可编排节点。资料来源:[src/mindor/core/workflow/job/impl/component.py:1-35]()

重点 If Job

根据布尔表达式选择两条分支之一,常用于条件路由与守门逻辑。资料来源:[src/mindor/core/workflow/job/impl/if.py:1-30]()

重点 Switch Job

对表达式做多路分发,按匹配结果选取唯一的下游分支,适合"枚举值 → 处理路径"场景。资料来源:[src/mindor/core/workflow/job/impl/switch.py:1-35]()

重点 HTTP Job

v0.4.0 引入的新组件作业形态,允许工作流直接发起 HTTP 请求,作为外部系统集成点。资料来源:[src/mindor/core/workflow/job/impl/http.py:1-30]()

model-compose 的核心抽象由"工作流(Workflow)"和"作业(Job)"两层组成,工作流负责定义顺序、循环与依赖,作业则是真正执行业务逻辑的最小单元。该项目自 v0.2.0 起支持将工作流直接部署为 MCP 服务器,并在 v0.3.0 / v0.4.0 中陆续加入本地模型推理、Docker 控制器、流式输出以及 HTTP 组件,使编排能力覆盖了从本地推理到远程服务调用的多种场景。资料来源:src/mindor/core/workflow/workflow.py:1-40

工作流的整体结构

工作流以 Workflow 类为入口,持有若干 Job 实例并通过 Runner 驱动执行。Workflow 在初始化时读取配置(id、name、description、jobs 列表),并向 Runner 注入自身作为执行上下文。资料来源:src/mindor/core/workflow/workflow.py:20-60

Runner 是工作流的运行时引擎,封装了"启动—执行—收尾"的生命周期:调用 run() 触发内部循环,逐个调度处于 PENDING 状态的作业,根据其返回结果更新状态机并向下游传递输入参数。资料来源:src/mindor/core/workflow/runner.py:15-55

graph LR
  Config[YAML/JSON 配置] --> Workflow
  Workflow --> Runner
  Runner --> Job1[Component Job]
  Runner --> Job2[If Job]
  Runner --> Job3[Switch Job]
  Runner --> Job4[HTTP / Shell Job]
  Job1 --> Output[聚合输出]
  Job2 --> Output
  Job3 --> Output
  Job4 --> Output

作业的抽象与注册机制

所有作业继承自统一的 Job 基类,该基类定义了 run(inputs)cancel()state 等公共接口,并保存下游 input_keys,用于把上游作业的输出按字段名映射为本作业的入参。资料来源:src/mindor/core/workflow/job/job.py:10-45

项目使用 registry.py 提供基于"类型字符串 → 类"的工厂模式。新增一种作业类型时,只需要在配置中指定 type: xxx,运行时即可通过注册表解析出对应实现,使编排系统具备良好的扩展性。资料来源:src/mindor/core/workflow/job/registry.py:1-30

常见作业类型

  • Component Job:调用一个具体的"组件(Component)",是体系内最高频的作业类型,支持将本地模型、HTTP 服务、Shell 命令等统一映射为可编排节点。资料来源:src/mindor/core/workflow/job/impl/component.py:1-35
  • If Job:根据布尔表达式选择两条分支之一,常用于条件路由与守门逻辑。资料来源:src/mindor/core/workflow/job/impl/if_.py:1-30
  • Switch Job:对表达式做多路分发,按匹配结果选取唯一的下游分支,适合"枚举值 → 处理路径"场景。资料来源:src/mindor/core/workflow/job/impl/switch.py:1-35
  • HTTP Job:v0.4.0 引入的新组件作业形态,允许工作流直接发起 HTTP 请求,作为外部系统集成点。资料来源:src/mindor/core/workflow/job/impl/http.py:1-30

执行模型与流式能力

Runner 在调度作业时,根据作业声明的 mode(普通 / 流式 / 事件流)选择不同的执行路径:普通模式聚合最终结果后返回;流式模式在生成过程中逐步推送增量;事件流模式则按事件粒度向外暴露中间状态,配合 v0.4.0 新增的 streaming modeevent-stream mode 可用于实时交互。资料来源:src/mindor/core/workflow/runner.py:60-120

每个作业内部维护独立的状态机(PENDING → RUNNING → COMPLETED / FAILED / CANCELLED),Runner 借此实现重试、超时与取消传播;同时,作业失败会被冒泡到工作流层面,由 Workflow 决定是否中止整条流水线或继续执行可选分支。资料来源:src/mindor/core/workflow/job/job.py:50-80

与 MCP 部署的衔接

由于 Workflow 本身只暴露 run() / cancel() 等纯 Python 接口,v0.2.0 之后通过适配层将工作流映射为 MCP server 工具,使编排结果可被任意 MCP 客户端直接调用,无需修改作业实现。资料来源:src/mindor/core/workflow/workflow.py:60-90

小结

工作流负责"画图",作业负责"干活",注册表负责"插拔":model-compose 用三层模型把组件、条件、HTTP、Shell、本地模型推理等异构能力拼成统一流水线,并通过 Runner 的状态机与流式通道支撑生产级调度。扩展新作业类型只需实现 Job 子类并在注册表中登记即可。资料来源:src/mindor/core/workflow/job/registry.py:20-40

来源:https://github.com/hanyeol/model-compose / 项目说明书

模型任务与 AI 集成

模型任务与 AI 集成是 model-compose 中负责将外部大语言模型(LLM)能力接入工作流的核心子系统。它以 ModelServiceComponent 为顶层抽象,统一封装了不同推理后端(HuggingFace、LlamaCPP、vLLM、Unsloth 等),并通过可扩展的"任务(Task)"机制提供对话补全、文本生成等多种 AI 能力,使上层工作流组件能够以...

重点 本地开发

使用 LlamaCPPBackend 加载 GGUF 模型,配合 ChatCompletionTask 构建对话原型。

重点 高吞吐生产

使用 VllmBackend 部署在 GPU 服务器上,通过流式模式对接 Web 前端。

重点 微调推理

使用 UnslothBackend 加载 LoRA 微调权重,复用同一任务接口。

概述

模型任务与 AI 集成是 model-compose 中负责将外部大语言模型(LLM)能力接入工作流的核心子系统。它以 ModelServiceComponent 为顶层抽象,统一封装了不同推理后端(HuggingFace、LlamaCPP、vLLM、Unsloth 等),并通过可扩展的"任务(Task)"机制提供对话补全、文本生成等多种 AI 能力,使上层工作流组件能够以统一接口调用本地或远程模型。

v0.3.0 起官方正式引入本地模型推理组件,配合 Docker 化的控制器部署,使用户能够直接在本地加载权重并执行推理;v0.4.0 则进一步扩展了组件生态,并加入流式(streaming)与事件流(event-stream)两种实时交互模式,强化了模型任务在长链路工作流中的可组合性。资料来源:src/mindor/core/component/services/model/model.py:1-40

整体架构

模型任务系统遵循"组件 → 后端 → 任务"三层结构:

层级职责关键对象
组件层(Component)注册模型服务、对外暴露统一入口、串联输入输出ModelServiceComponent
后端层(Backend)与具体推理引擎对接,处理模型加载与生命周期HuggingFaceBackendLlamaCPPBackendVllmBackendUnslothBackend
任务层(Task)定义面向用户的模型能力,如聊天补全ChatCompletionTask
flowchart TD
    A[工作流 Workflow] --> B[ModelServiceComponent]
    B --> C{后端路由}
    C --> D[HuggingFace]
    C --> E[LlamaCPP]
    C --> F[vLLM]
    C --> G[Unsloth]
    D --> H[ChatCompletionTask]
    E --> H
    F --> H
    G --> H
    H --> I[流式 / 非流式 输出]

资料来源:src/mindor/core/component/services/model/model.py:20-60

推理后端集成

model-compose 通过 BaseModelBackend 抽象为多种推理引擎提供一致接口。HuggingFaceBackend 利用 transformers 库在 Python 进程中加载本地或 Hub 上的模型权重,适合通用 Transformer 系列;LlamaCPPBackend 借助 llama.cpp 的 Python 绑定运行 GGUF 量化模型,对消费级硬件友好;VllmBackend 通过 vLLM 提供高吞吐的 PagedAttention 推理;UnslothBackend 则针对 LLaMA 系微调模型提供加速推理能力。v0.3.0 发布说明强调本地推理能力的核心地位,使用户可以在不依赖外部 API 的情况下完成推理。资料来源:src/mindor/core/component/services/model/base/huggingface:1-30、src/mindor/core/component/services/model/base/llamacpp.py:1-30src/mindor/core/component/services/model/base/vllm.py:1-30src/mindor/core/component/services/model/base/unsloth.py:1-30

后端在初始化阶段会读取组件配置中的 model_pathdevicedtype、量化参数等,并在首次任务调用时延迟加载(lazy load),从而避免无谓的显存占用。

模型任务系统

任务层将后端的原始推理能力封装成面向业务的语义操作。ChatCompletionTask 是最典型的任务,它接收对话历史(messages)作为输入,返回模型生成的回复,并在 v0.4.0 起支持流式与事件流两种输出模式:流式模式按 token 增量推送结果,事件流模式则按结构化事件(如工具调用、结束标记)分段投递,便于前端实时渲染。资料来源:src/mindor/core/component/services/model/tasks/chat_completion:1-40

任务的输入输出由统一的 TaskInput / TaskOutput 模型描述,从而保证不同后端在执行同一任务时对外行为一致。这种解耦使得新增后端(如未来的 SGLang、TensorRT-LLM)或新增任务(如 Embedding、Tool-Use)只需分别扩展对应基类即可。

配置与使用模式

在 YAML/JSON 工作流定义中,用户通过声明 type: model-service 引入模型组件,并在其中指定 backendmodel_pathtask 等字段即可完成接入。典型场景包括:

  • 本地开发:使用 LlamaCPPBackend 加载 GGUF 模型,配合 ChatCompletionTask 构建对话原型。
  • 高吞吐生产:使用 VllmBackend 部署在 GPU 服务器上,通过流式模式对接 Web 前端。
  • 微调推理:使用 UnslothBackend 加载 LoRA 微调权重,复用同一任务接口。

由于模型组件本身也是一种工作流节点,它可以被其他组件(如 HTTP 服务组件)包装后部署为 MCP 服务器,正如 v0.2.0 发布说明所述,整个工作流可直接对外暴露为标准接口。资料来源:src/mindor/core/component/services/model/model.py:40-80

总结

模型任务与 AI 集成子系统通过"组件—后端—任务"三层模型,屏蔽了不同推理引擎的差异,并以任务语义向上层工作流暴露稳定 API。借助 v0.3.0 引入的本地推理能力与 v0.4.0 加入的流式输出,开发者既能快速原型本地 LLM 工作流,也能将其无缝扩展到生产级高吞吐部署。后续若需新增后端或任务,仅需分别继承 BaseModelBackendBaseTask,从而保持整个 AI 集成层的可扩展性与一致性。

资料来源:src/mindor/core/component/services/model/model.py:20-60

适配器、协议与运行时

在 model-compose 的分层架构中,"适配器(Adapter)"负责把工作流的内部执行结果以多种外部协议暴露出来,而"协议与运行时"则统一描述这些适配器及其上游触发入口(Listener)的协作方式。Controller 通过 adapter.py 抽象出协议无关的基类,再由 services/ 子包提供具体实现;Listener 则在另一侧等待外部事件并转发到 ...

章节 HTTP Server 适配器

继续阅读本节完整说明和来源证据。

章节 MCP Server 适配器

继续阅读本节完整说明和来源证据。

章节 Queue Subscriber 适配器

继续阅读本节完整说明和来源证据。

概述与定位

model-compose 的分层架构中,"适配器(Adapter)"负责把工作流的内部执行结果以多种外部协议暴露出来,而"协议与运行时"则统一描述这些适配器及其上游触发入口(Listener)的协作方式。Controller 通过 adapter.py 抽象出协议无关的基类,再由 services/ 子包提供具体实现;Listener 则在另一侧等待外部事件并转发到 Controller 内部的执行队列中。这种"控制器多协议出口 + 监听器多入口"的拆分,使得同一个工作流可以被 HTTP、消息队列或 MCP 等不同形态的上游调用,同时保持核心编排逻辑稳定。资料来源:src/mindor/core/controller/adapters/adapter.py:1-40

角色主要职责代表实现
Adapter(出站协议)将工作流执行结果以目标协议形式输出HTTP Server、MCP Server、Queue Subscriber
Listener(入站触发)监听外部请求并转化为内部任务HTTP Trigger

Adapter:多协议出站适配器

Adapter 基类位于 src/mindor/core/controller/adapters/adapter.py,它定义了协议无关的启动、停止与生命周期接口,所有具体实现都遵循同一抽象。资料来源:src/mindor/core/controller/adapters/adapter.py:1-80

HTTP Server 适配器

services/http_server.py 是最早期的稳定实现,它将组件/工作流的产出以标准 HTTP 响应形式对外发布,便于与既有 Web 客户端或网关集成。资料来源:src/mindor/core/controller/adapters/services/http_server.py:1-60

MCP Server 适配器

自 v0.2.0 起,工作流可直接以 MCP(Model Context Protocol)服务器形态部署,services/mcp_server.py 提供了对 MCP 协议的封装,使 Agent 或外部 LLM 工具链可以按 MCP 的标准调用内部组件。资料来源:src/mindor/core/controller/adapters/services/mcp_server.py:1-80

Queue Subscriber 适配器

services/queue_subscriber/queue_subscriber.py 适配面向消息队列的下游消费者模式,常用于异步、解耦与扇出场景,使工作流的输出可以作为其它系统的输入被订阅消费。资料来源:src/mindor/core/controller/adapters/services/queue_subscriber/queue_subscriber.py:1-60

v0.4.0 在此基础上进一步引入了 event-stream 模式streaming 模式,将原本请求-响应式的协议扩展为可实时推送增量片段的流式协议,HTTP Server 与 Queue Subscriber 都可借助此能力向客户端持续输出中间结果。资料来源:src/mindor/core/controller/adapters/adapter.py:40-120

Listener:入站触发与运行时衔接

与 Adapter 对称的 Listener 位于 src/mindor/core/listener/listener.py,负责在出站协议之外承担"事件入口"职责,把外部协议事件翻译成工作流可识别的内部任务,并交给 Controller 执行。资料来源:src/mindor/core/listener/listener.py:1-60

当前主要的具体触发器实现是 services/http_trigger.py,它在 v0.3.0 引入的本地模型与 Docker 化 Controller 之后,提供了与 HTTP Adapter 配套的入站处理路径,使得从外部 HTTP 请求进入到内部编排、再到协议适配输出的链路形成闭环。资料来源:src/mindor/core/listener/services/http_trigger.py:1-80

运行时协作流程

下图展示了 Listener、Controller(含 Adapter)与外部协议消费者之间的事件流向:

flowchart LR
    A[外部请求/HTTP] --> B[Listener.http_trigger]
    B --> C[Controller 编排引擎]
    C --> D{Adapter 选择}
    D -->|HTTP| E[HTTP Server 适配器]
    D -->|MCP| F[MCP Server 适配器]
    D -->|Queue| G[Queue Subscriber 适配器]
    E --> H[Web 客户端/网关]
    F --> I[MCP 工具/Agent]
    G --> J[消息队列下游]

整条链路上,Listener 负责"入站协议到内部事件"的解码,Controller 完成编排与本地推理(v0.3.0 起的本地模型推理组件也在此处生效),再由 Adapter 以"内部事件到出站协议"的编码把结果投递出去。v0.4.0 的 streaming / event-stream 模式则贯穿此链路,使得中间片段可被增量转发。资料来源:src/mindor/core/controller/adapters/adapter.py:80-140 src/mindor/core/listener/listener.py:40-100

已知边界与注意事项

来源:https://github.com/hanyeol/model-compose / 项目说明书

Web UI、网关与隧道

model-compose 提供了三套相互协作的访问入口:Web UI(基于 Gradio 的图形化交互界面)、Gateway(统一 API 网关)以及 HTTP Tunnel(反向通道 / 内网穿透服务)。这三者共同构成了控制器(Controller)层面向用户与外部系统的"门面",分别覆盖了可视化交互、统一路由转发,以及把内网能力暴露到公网(或跨网络边界)这三种典型场景...

重点 入口与生命周期

webui.py 负责 WebUI Controller 的注册、启动与停止;它根据 DSL 中 controller.webui 节点的配置实例化对应的 Gradio 应用,并将其挂接到控制器统一调度框架中。

重点 构建器(Builder)

gradio/builder.py 把 DSL 中声明的组件、输入输出端口、参数等转换成 Gradio 的 Blocks、Component、EventListener 对象,是 DSL → UI 的桥梁。

重点 驱动层(Driver)

gradio/driver.py 处理运行时的请求分发:把 Gradio 事件转换成内部任务调用,把工作流结果回填到 UI 控件,并支持 v0.4.0 起新增的 event-stream mode 与 streaming mode,从而在聊天、推理等场景中实现 token-by-token 的实时推送。

重点 DSL Schema

src/mindor/dsl/schema/controller/webui 定义了用户在 YAML 中描述 WebUI 时的字段(如端口、主题、是否启用流式响应、可暴露的组件列表等)。

model-compose 提供了三套相互协作的访问入口:Web UI(基于 Gradio 的图形化交互界面)、Gateway(统一 API 网关)以及 HTTP Tunnel(反向通道 / 内网穿透服务)。这三者共同构成了控制器(Controller)层面向用户与外部系统的"门面",分别覆盖了可视化交互、统一路由转发,以及把内网能力暴露到公网(或跨网络边界)这三种典型场景。v0.2.0 起项目支持以 MCP server 形式部署工作流,v0.4.0 起新增了流式响应与 HTTP server 组件,本页涉及的网关与隧道模块正是这些能力的承载体。

1. Web UI:基于 Gradio 的可视化控制器

Web UI 模块位于 src/mindor/core/controller/webui 下,使用 Gradio 作为前端框架,使工作流能够以零前端代码的方式暴露为浏览器应用。

  • 入口与生命周期webui.py 负责 WebUI Controller 的注册、启动与停止;它根据 DSL 中 controller.webui 节点的配置实例化对应的 Gradio 应用,并将其挂接到控制器统一调度框架中。
  • 构建器(Builder)gradio/builder.py 把 DSL 中声明的组件、输入输出端口、参数等转换成 Gradio 的 BlocksComponentEventListener 对象,是 DSL → UI 的桥梁。
  • 驱动层(Driver)gradio/driver.py 处理运行时的请求分发:把 Gradio 事件转换成内部任务调用,把工作流结果回填到 UI 控件,并支持 v0.4.0 起新增的 event-stream modestreaming mode,从而在聊天、推理等场景中实现 token-by-token 的实时推送。
  • DSL Schemasrc/mindor/dsl/schema/controller/webui 定义了用户在 YAML 中描述 WebUI 时的字段(如端口、主题、是否启用流式响应、可暴露的组件列表等)。

由于 schema 校验先行,Builder 阶段几乎不会出现"未知字段"类错误;运行期异常则由 Driver 捕获并以 Gradio 的 gr.Error 形式呈现给用户。资料来源:src/mindor/core/controller/webui/webui.py:1-、src/mindor/core/controller/webui/gradio/builder.py:1-、src/mindor/core/controller/webui/gradio/driver.py:1-、src/mindor/dsl/schema/controller/webui:1-。

2. Gateway:统一 API 网关

Gateway 是 controller 层对外提供 HTTP/REST(以及基于 HTTP 的 MCP 协议)能力的统一入口,源码集中在 src/mindor/core/gateway/gateway.py 与同目录下各 services/ 子包。

  • 路由聚合:当用户在 DSL 中声明多种 controller(webui、shell、MCP server 等)时,Gateway 会按统一前缀把所有 controller 的 HTTP 端点聚合成一棵路由树,避免端口冲突和重复监听的资源浪费。
  • 服务插件化:每个具体的协议实现都放在 gateway/services/<name> 下,例如内置的 http_tunnel 子包。Gateway 通过一个注册机制(在 gateway.py 中维护服务列表)按需加载这些子包,从而保持核心网关代码与具体协议解耦。
  • 请求转发与协议适配:Gateway 解析请求路径后,把它转发给对应的内部 controller;同时负责统一处理鉴权、CORS、日志、请求体大小限制等横切关注点,使得下游组件可以使用"纯业务"接口而无需重复实现。

这一层在 v0.3.0 引入的"以 Docker 方式部署 controller"的能力中尤为重要:容器化场景下,用户只需要把 Gateway 端口暴露出来即可访问全部 controller,不必为每个 controller 单独配置端口映射。资料来源:src/mindor/core/gateway/gateway.py:1-。

3. HTTP Tunnel:反向通道服务

http_tunnelgateway/services 下的一个具体服务实现,用于在网络受限的环境下把 controller 的本地端口"穿越"到外部可达的地址。它和 Gateway 是消费关系:Gateway 是路径与策略的调度者,HTTP Tunnel 是其中一种后端服务。

典型工作流如下图所示(仅用于说明请求流向,不涵盖鉴权细节)。

flowchart LR
    Client[外部客户端] -->|公网 HTTPS| GW[Gateway]
    GW -->|/tunnel/* 路径| HT[HTTP Tunnel Service]
    HT -->|内部 HTTP| Srv[内网 controller<br/>(webui / mcp / shell)]
    Srv --> HT --> GW --> Client

能力要点:

  • 会话保持:Tunnel 为每个外部会话维护一条到内网 controller 的长连接,支持多次请求复用同一通道,避免反复建立连接的开销。
  • 流式透传:结合 v0.4.0 的 streaming mode,Tunnel 需要按 text/event-stream 或 chunked transfer encoding 把内网 controller 的流式响应原样回传给客户端,是实现"实时交互"的关键。
  • 容器/本地混合:在 v0.3.0 引入本地模型推理组件后,本地模型可能仅监听在宿主机的 127.0.0.1,Tunnel 可以把它"代理"给经过 Gateway 路由的外部请求,免去复杂的网络配置。

资料来源:src/mindor/core/gateway/services/http_tunnel:1-。

4. 三者协作关系与选型建议

入口适合场景典型用户依赖组件
Web UI交互调试、Demo、面向非技术用户业务人员、测试人员Gradio Builder + Driver
Gateway 直连自动化脚本、内部服务调用、CI/CD开发者、运维任意 HTTP 兼容 controller
HTTP Tunnel跨网络、无公网 IP、容器化部署远程协作者、边缘部署Gateway + http_tunnel 服务

选型上:本地开发优先使用 Web UI 以获得可视化反馈;脚本与系统集成使用 Gateway 直连;当 controller 部署在没有公网入口或被 NAT 隔离时,再叠加 HTTP Tunnel。三层之间遵循"Gateway 调度 → 协议适配 → 驱动执行"的单向链路,便于独立升级与替换。资料来源:src/mindor/core/gateway/gateway.py:1-、src/mindor/core/controller/webui/webui.py:1-。

资料来源:src/mindor/core/gateway/services/http_tunnel:1-。

自定义开发、示例与故障排查

model-compose 是一个基于 YAML/DSL 的工作流编排框架,核心目标是让用户通过声明式配置组合多种"组件(Component)"来构建模型推理、数据处理与服务化流程。本章聚焦于三类进阶内容:自定义组件与驱动的开发规范、典型示例的复用与常见故障的排查路径。在 v0.4.0 中新增的流式输出(event-stream / streaming mode)与 HTT...

章节 组件类型扩展点

继续阅读本节完整说明和来源证据。

章节 存储驱动(Driver)实现模式

继续阅读本节完整说明和来源证据。

章节 通过 MCP Server 部署工作流

继续阅读本节完整说明和来源证据。

章节 Shell 命令作为组件

继续阅读本节完整说明和来源证据。

概述与定位

model-compose 是一个基于 YAML/DSL 的工作流编排框架,核心目标是让用户通过声明式配置组合多种"组件(Component)"来构建模型推理、数据处理与服务化流程。本章聚焦于三类进阶内容:自定义组件与驱动的开发规范典型示例的复用常见故障的排查路径。在 v0.4.0 中新增的流式输出(event-stream / streaming mode)与 HTTP Server 组件,进一步扩展了自定义开发的边界,开发者可以围绕这些新接口进行扩展 资料来源:README.md:1-40

自定义组件与驱动开发

组件类型扩展点

所有组件的类型定义集中在 DSL Schema 中,新增组件需要先在类型枚举与解析器中注册。types.py 维护了内置组件类别(如 http_servershell_commandlocal_model_inference 等 v0.2.0–v0.4.0 陆续引入的组件)的统一映射;扩展时需同步更新该文件以保证 DSL 校验通过 资料来源:src/mindor/dsl/schema/component/impl/types.py:1-80

存储驱动(Driver)实现模式

存储类服务采用"驱动(Driver)"模式进行解耦,三类核心驱动分别位于:

存储类型驱动目录典型场景
File Storecore/component/services/file_store/drivers/本地文件、对象存储读写
Vector Storecore/component/services/vector_store/drivers/Embedding 检索、RAG
Key-Value Storecore/component/services/key_value_store/drivers/会话状态、缓存

新增驱动需实现统一接口(初始化、连接、读写、关闭),并在驱动注册表中声明,从而被 DSL 自动加载 资料来源:src/mindor/core/component/services/file_store/drivers:1-40 资料来源:src/mindor/core/component/services/vector_store/drivers:1-40 资料来源:src/mindor/core/component/services/key_value_store/drivers:1-40。

典型示例与使用模式

通过 MCP Server 部署工作流

v0.2.0 起支持将工作流直接发布为 MCP Server,示例通常包含:mindor.yaml(DSL 定义)→ mindor deploy 命令 → MCP 协议端点暴露。这是"以服务形式复用工作流"的推荐路径 资料来源:README.md:60-120

Shell 命令作为组件

v0.2.0 引入的 shell_command 组件允许把任意 CLI 工具接入流水线,常用于:调用外部脚本、数据预处理、系统命令包装。该模式是开发者最易上手的自定义入口 资料来源:README.md:80-140

本地模型推理与流式输出

v0.3.0 引入本地模型推理组件,v0.4.0 在此基础上提供 streaming mode 与 event-stream mode。典型用法:在 DSL 中将组件 mode 字段设为 streamingevent-stream,以增量方式输出 token 或事件 资料来源:README.md:100-180

flowchart LR
    A[DSL YAML] --> B[Schema 校验<br/>types.py]
    B --> C[组件运行时]
    C --> D[Driver<br/>file/vector/kv]
    C --> E[Tracer 追踪]
    C --> F[Logger 记录]
    C --> G[HTTP / MCP / Streaming 输出]

故障排查与诊断

日志系统

logger.py 提供统一的日志采集与分级输出入口。故障定位时建议先确认日志级别(DEBUG/INFO/WARN/ERROR),并按时间戳 + 组件 ID 过滤;社区反馈的早期版本"日志信息不足"问题在后续版本中已逐步改善 资料来源:src/mindor/core/logger/logger.py:1-60

调用链追踪

tracer.py 负责对组件执行链路进行埋点,记录输入、输出、耗时与异常。当出现"组件未触发"或"上游输出未传到下游"等问题时,应优先查看 tracer 是否生成了对应的 span,并比对 span 之间的数据契约 资料来源:src/mindor/core/tracer/tracer.py:1-80

常见故障清单

  • DSL 解析失败:通常是 types.py 中未声明新组件类型,先校验 schema 版本与组件枚举 资料来源:src/mindor/dsl/schema/component/impl/types.py:20-60
  • 驱动加载异常:检查驱动目录是否存在 __init__.py 注册逻辑,以及驱动是否实现了统一接口 资料来源:src/mindor/core/component/services/file_store/drivers:10-40。
  • 流式输出截断:v0.4.0 引入 event-stream 后,HTTP 代理或网关若不支持分块传输,需要在客户端显式启用 chunked 解析 资料来源:README.md:140-200
  • MCP Server 启动失败:v0.2.0 已知的"日志消息不充分"问题建议结合 logger.py 调高日志级别配合排查 资料来源:src/mindor/core/logger/logger.py:40-80

最佳实践小结

  1. 扩展前先阅读 types.py:保证 DSL 与运行时一致。
  2. 优先复用 Driver 接口:避免重复实现连接、序列化、关闭逻辑。
  3. 示例驱动开发:以 v0.4.0 的 streaming 组件与 v0.2.0 的 shell 组件为模板。
  4. 调试顺序:Logger → Tracer → Schema:自下而上定位问题,避免在 DSL 层盲目试错。
  5. 关注版本变更:v0.1.0 → v0.4.0 的演进带来了组件生态、流式支持与日志完善,每次升级都需查阅 release notes 中的"Known Limitations" 资料来源:README.md:200-260

来源:https://github.com/hanyeol/model-compose / 项目说明书

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

medium 维护活跃度未知

新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。

medium 存在评分风险

风险会影响是否适合普通用户安装。

low issue/PR 响应质量未知

用户无法判断遇到问题后是否有人维护。

Pitfall Log / 踩坑日志

项目:hanyeol/model-compose

摘要:发现 6 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:能力坑 - 能力判断依赖假设。

1. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 证据:capability.assumptions | https://github.com/hanyeol/model-compose | README/documentation is current enough for a first validation pass.

2. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 证据:evidence.maintainer_signals | https://github.com/hanyeol/model-compose | last_activity_observed missing
  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 证据:downstream_validation.risk_items | https://github.com/hanyeol/model-compose | no_demo; severity=medium

4. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 证据:risks.scoring_risks | https://github.com/hanyeol/model-compose | no_demo; severity=medium

5. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 证据:evidence.maintainer_signals | https://github.com/hanyeol/model-compose | issue_or_pr_quality=unknown

6. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 证据:evidence.maintainer_signals | https://github.com/hanyeol/model-compose | release_recency=unknown

来源:Doramagic 发现、验证与编译记录