Doramagic 项目包 · 项目说明书
model-compose 项目
灵感源自 docker-compose 的可移植 AI 运行时,用一个 YAML 文件即可组合 Agent、RAG 流水线和 MCP 服务端,并随处运行。
项目概述与快速入门
model-compose 是一个面向工作流编排与多组件组合场景的 Python 框架,仓库内的 Python 包名为 mindor,命令行工具名为 compose。它的核心目标是把"模型推理""HTTP 服务""Shell 命令""本地模型加载"等异构能力抽象为可组合的 组件(Component),并通过声明式配置文件把它们串成可执行的工作流,再以 控制器(Control...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
1. 项目定位与目标
model-compose 是一个面向工作流编排与多组件组合场景的 Python 框架,仓库内的 Python 包名为 mindor,命令行工具名为 compose。它的核心目标是把"模型推理""HTTP 服务""Shell 命令""本地模型加载"等异构能力抽象为可组合的 组件(Component),并通过声明式配置文件把它们串成可执行的工作流,再以 控制器(Controller) 的形式统一调度与部署。
从代码组织看,框架入口位于 src/mindor/__init__.py,对外暴露的版本号与基础 API 集中在 src/mindor/__init__.py 与 src/mindor/version.py 中,便于上层业务以 import mindor 的方式引用。命令行层则通过 src/mindor/cli/compose.py 提供 compose 子命令,是用户与框架交互的最直接入口。
资料来源:src/mindor/__init__.py:1-20、src/mindor/version.py:1-10、src/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-stream 与 streaming 两种流式模式;新增 HTTP Server 组件 | 实时交互能力显著增强 |
资料来源:v0.1.0 Release、v0.2.0 Release、v0.3.0 Release、v0.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-80、README.md:1-60、pyproject.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-40、src/mindor/cli/compose.py:1-30。
4.2 第一个工作流
- 在项目根目录新建
workflow.yaml,声明一个最简单的 Shell 组件。 - 使用
compose run workflow.yaml启动本地 Controller。 - 若希望以 MCP Server 形式暴露(自 v0.2.0 起可用),执行
compose serve workflow.yaml。 - 需要实时输出时(自 v0.4.0 起可用),可在配置中开启
streaming: true或event_stream: true。
4.3 升级到 v0.4.0 的流式能力
v0.4.0 引入的流式模式主要面向"长耗时推理 + 增量回传"的场景。建议先在 workflow.yaml 中显式指定 mode: streaming 或 mode: event_stream,再通过 CLI 启动,由 Controller 统一将增量事件转发给 HTTP/MCP 客户端。
资料来源:README.md:60-120、v0.4.0 Release。
5. 适用场景与边界
- 适用:需要把"模型调用 + 业务胶水代码 + 外部服务"统一编排为可复用工作流的场景;需要 MCP/HTTP 等多种对外暴露形态的场景;希望在本地或 Docker 化环境中自托管推理服务的场景。
- 暂不适用:跨语言重型微服务编排(推荐使用专用编排引擎);对超低延迟有苛刻要求的实时音视频链路。
6. 下一步阅读
- 深入组件配置:
workflow.yaml字段说明与组件类型清单。 - Controller 与部署形态:CLI、Docker、MCP Server 三种入口的差异。
- v0.4.0 流式协议:
event-stream与streaming模式的事件契约。
资料来源:README.md:1-60、src/mindor/__init__.py:1-20、src/mindor/version.py:1-10、src/mindor/cli/compose.py:1-80、pyproject.toml:1-40。
资料来源:src/mindor/__init__.py:1-20、src/mindor/version.py:1-10、src/mindor/cli/compose.py:1-30。
核心架构与控制器
model-compose 是一个面向模型工作流的可组合运行时,其核心由 mindor.core 命名空间下两个并列的子系统协同构成:控制器(Controller) 负责单工作流的执行编排,组合器(Compose) 负责跨工作流的部署与生命周期管理。本页聚焦这两层的设计职责、模块边界与协作流程。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
架构概览
整个 mindor.core 下分出两个平行的子包:controller 与 compose。控制器层聚焦"如何运行一个已经定义好的工作流",组合层聚焦"如何在外部托管多个工作流并将其暴露为服务"。这种分层使单工作流的执行逻辑与多工作流的部署逻辑彻底解耦——新增执行模式时无需触碰部署代码,新增托管形式时也无需重写调度逻辑。
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
生命周期与执行流
一次典型的请求经历以下阶段:
- Manager 读取配置并交由 Validator 进行静态校验。
- Validator 通过后,Manager 实例化一个或多个 Compose 对象。
- 对每个 Compose,Manager 实例化对应的 Controller。
- Controller 选择执行模式,委派给 Runner。
- 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.py、http_client.py、http_server.py 等),遵循统一的接口契约对外暴露。这种"基类 + 服务目录"的拆分使得新增组件只需继承基类并在 services/ 中添加实现即可,无需修改调度核心,符合开闭原则。
资料来源:src/mindor/core/component/component.py、src/mindor/core/component/base.py
二、组件基类与生命周期
base.py 定义了组件的抽象基类,规定了所有组件必须实现的标准化生命周期方法(典型地包括 setup、run、teardown 等)。这一契约保证调度器可以一致地对待不同类型的组件——无论是 LLM Agent 调用还是 HTTP 请求,都通过相同的生命周期推进。
component.py 充当组件工厂(Factory),承担两个关键职责:
- 类型注册:根据 YAML/JSON 工作流配置中的
type字段,从services/子模块动态加载对应的组件类; - 依赖注入:在实例化组件时,将
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.py、src/mindor/core/component/component.py、src/mindor/core/component/context.py
三、内置服务组件
services/ 目录是组件生态的具体实现层,社区版本演进过程中持续扩展:
| 组件文件 | 形态 | 关键用途 |
|---|---|---|
agent.py | 智能体服务 | 调用 LLM 完成推理与对话,作为工作流的"大脑" |
http_client.py | 外部 HTTP 调用 | 触发第三方 API、回调 webhook |
http_server.py | HTTP 服务端 | v0.4.0 新增,将工作流作为可被外部调用的 HTTP 服务暴露 |
每个服务组件都继承自 base.py 中的基类,仅重写与自身业务相关的执行逻辑。以 http_client.py 为例,它封装了请求构造、鉴权、超时与重试等横切关注点;而 http_server.py 则额外引入了 v0.4.0 引入的 event-stream mode 与 streaming mode,使得服务端组件可以以 SSE(Server-Sent Events)等流式协议向客户端增量推送结果。
agent.py 是工作流中最常见的组件,负责接入模型推理后端。结合 v0.3.0 引入的"本地模型推理"能力,它既可以指向远端 LLM 服务,也可以直接加载本地权重文件,再借助 v0.3.0 的 Docker 化 Controller 进行容器化部署。
资料来源:src/mindor/core/component/services/agent.py、src/mindor/core/component/services/http_client.py、src/mindor/core/component/services/http_server.py
四、扩展与组合模式
组件系统的扩展遵循三个核心模式:
- 新增组件类型:在
services/下新建模块,继承base.py中的基类并在component.py工厂中注册type标识符即可被工作流引用; - 组合嵌套:组件的输入/输出以结构化数据形式写入
context.py,下游组件通过模板表达式或字段绑定读取上游结果,从而在 YAML 中以声明式方式串联成复杂流水线; - 部署形态切换:同一组件实现可在不同 Job 中复用,既能作为内部 DAG 节点执行,也能通过
http_server.py暴露为 MCP Server 端点(v0.2.0 起支持),实现"一次定义、多种部署形态"。
值得关注的已知限制来自 v0.2.0 与 v0.1.0 发布说明:早期版本的日志输出较为粗放,对于组件级排障不够友好;建议在生产使用中结合 Controller 层的结构化日志进行链路追踪。
资料来源:src/mindor/core/component/component.py、src/mindor/core/component/base.py、src/mindor/core/component/context.py
资料来源:src/mindor/core/component/component.py、src/mindor/core/component/base.py
工作流与作业编排
model-compose 的核心抽象由"工作流(Workflow)"和"作业(Job)"两层组成,工作流负责定义顺序、循环与依赖,作业则是真正执行业务逻辑的最小单元。该项目自 v0.2.0 起支持将工作流直接部署为 MCP 服务器,并在 v0.3.0 / v0.4.0 中陆续加入本地模型推理、Docker 控制器、流式输出以及 HTTP 组件,使编排能力覆盖了从本地推理到...
调用一个具体的"组件(Component)",是体系内最高频的作业类型,支持将本地模型、HTTP 服务、Shell 命令等统一映射为可编排节点。资料来源:[src/mindor/core/workflow/job/impl/component.py:1-35]()
根据布尔表达式选择两条分支之一,常用于条件路由与守门逻辑。资料来源:[src/mindor/core/workflow/job/impl/if.py:1-30]()
对表达式做多路分发,按匹配结果选取唯一的下游分支,适合"枚举值 → 处理路径"场景。资料来源:[src/mindor/core/workflow/job/impl/switch.py:1-35]()
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 mode 与 event-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) | 与具体推理引擎对接,处理模型加载与生命周期 | HuggingFaceBackend、LlamaCPPBackend、VllmBackend、UnslothBackend |
| 任务层(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-30、src/mindor/core/component/services/model/base/vllm.py:1-30、src/mindor/core/component/services/model/base/unsloth.py:1-30
后端在初始化阶段会读取组件配置中的 model_path、device、dtype、量化参数等,并在首次任务调用时延迟加载(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 引入模型组件,并在其中指定 backend、model_path、task 等字段即可完成接入。典型场景包括:
- 本地开发:使用
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 工作流,也能将其无缝扩展到生产级高吞吐部署。后续若需新增后端或任务,仅需分别继承 BaseModelBackend 与 BaseTask,从而保持整个 AI 集成层的可扩展性与一致性。
资料来源:src/mindor/core/component/services/model/model.py:20-60
适配器、协议与运行时
在 model-compose 的分层架构中,"适配器(Adapter)"负责把工作流的内部执行结果以多种外部协议暴露出来,而"协议与运行时"则统一描述这些适配器及其上游触发入口(Listener)的协作方式。Controller 通过 adapter.py 抽象出协议无关的基类,再由 services/ 子包提供具体实现;Listener 则在另一侧等待外部事件并转发到 ...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述与定位
在 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
已知边界与注意事项
- 各类 Adapter 共享统一的
Adapter基类协议,新增协议只需在services/下新增实现并接入生命周期管理即可,无需改动核心编排。资料来源:src/mindor/core/controller/adapters/adapter.py:20-60 - v0.2.0 之前日志粒度较粗,对排查 Adapter / Listener 协作问题支持有限;建议在启用新协议时同时提升日志级别。资料来源:src/mindor/core/listener/listener.py:10-30
- MCP Server 与 Queue Subscriber 的启用需要在编排层面显式声明,避免 Listener 触发后无对应 Adapter 消费造成事件丢失。资料来源:src/mindor/core/controller/adapters/services/mcp_server.py:30-70
来源: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 应用,并将其挂接到控制器统一调度框架中。
gradio/builder.py 把 DSL 中声明的组件、输入输出端口、参数等转换成 Gradio 的 Blocks、Component、EventListener 对象,是 DSL → UI 的桥梁。
gradio/driver.py 处理运行时的请求分发:把 Gradio 事件转换成内部任务调用,把工作流结果回填到 UI 控件,并支持 v0.4.0 起新增的 event-stream mode 与 streaming mode,从而在聊天、推理等场景中实现 token-by-token 的实时推送。
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 的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 时的字段(如端口、主题、是否启用流式响应、可暴露的组件列表等)。
由于 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_tunnel 是 gateway/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...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述与定位
model-compose 是一个基于 YAML/DSL 的工作流编排框架,核心目标是让用户通过声明式配置组合多种"组件(Component)"来构建模型推理、数据处理与服务化流程。本章聚焦于三类进阶内容:自定义组件与驱动的开发规范、典型示例的复用与常见故障的排查路径。在 v0.4.0 中新增的流式输出(event-stream / streaming mode)与 HTTP Server 组件,进一步扩展了自定义开发的边界,开发者可以围绕这些新接口进行扩展 资料来源:README.md:1-40。
自定义组件与驱动开发
组件类型扩展点
所有组件的类型定义集中在 DSL Schema 中,新增组件需要先在类型枚举与解析器中注册。types.py 维护了内置组件类别(如 http_server、shell_command、local_model_inference 等 v0.2.0–v0.4.0 陆续引入的组件)的统一映射;扩展时需同步更新该文件以保证 DSL 校验通过 资料来源:src/mindor/dsl/schema/component/impl/types.py:1-80。
存储驱动(Driver)实现模式
存储类服务采用"驱动(Driver)"模式进行解耦,三类核心驱动分别位于:
| 存储类型 | 驱动目录 | 典型场景 |
|---|---|---|
| File Store | core/component/services/file_store/drivers/ | 本地文件、对象存储读写 |
| Vector Store | core/component/services/vector_store/drivers/ | Embedding 检索、RAG |
| Key-Value Store | core/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 字段设为 streaming 或 event-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。
最佳实践小结
- 扩展前先阅读
types.py:保证 DSL 与运行时一致。 - 优先复用 Driver 接口:避免重复实现连接、序列化、关闭逻辑。
- 示例驱动开发:以 v0.4.0 的 streaming 组件与 v0.2.0 的 shell 组件为模板。
- 调试顺序:Logger → Tracer → Schema:自下而上定位问题,避免在 DSL 层盲目试错。
- 关注版本变更:v0.1.0 → v0.4.0 的演进带来了组件生态、流式支持与日志完善,每次升级都需查阅 release notes 中的"Known Limitations" 资料来源:README.md:200-260。
来源:https://github.com/hanyeol/model-compose / 项目说明书
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
风险会影响是否适合普通用户安装。
用户无法判断遇到问题后是否有人维护。
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 发现、验证与编译记录