1. 页面概览

1.1 是什么

MLOps 模型平台是 LightFoundry 的「模型全生命周期管理」页面(对应设计文档 TAD-07,源码 action/web/src/views/MLOpsPage.vue,约 1065 行)。它面向数据科学团队与业务运营人员,提供从模型注册版本管理部署/回滚在线预测预测历史追溯的一站式界面。页面顶部注释块明确写出它的职责:「模型列表/创建/详情(版本上传、部署、下线)、预测测试(JSON 输入 → predict)、预测历史」,后端 API 前缀为 /api/v1/ml,由 Vite 代理分流到 Foundry 后端(端口 18081)。

与一般「模型仓库」不同,该页面与 Foundry 的本体论引擎深度绑定:模型可以按「对象属性」组织输入特征(PredictForObject),预测输出可以注册为对象的计算属性is_calculated=trueformula 记录 ml:<modelName>),模型还可以作为本体动作被业务应用(低代码应用构建器)调用。也就是说,MLOps 不只是「训练完放个文件」,而是把模型能力编织进企业的对象、应用与工作流体系。

MVP 阶段的推理引擎只有两类,页面上的「格式 format(推理引擎)」下拉框是理解整个系统的钥匙:

其余格式(onnx / pmml / pickle / docker_image 等)在代码中可以注册、可以上传版本,但执行预测时会明确报错「推理引擎暂不支持(MVP 支持 rule 与 external_api,ONNX/PMML/Python 子进程留远期)」。

1.2 核心价值

维度说明
模型登记造册api_name(唯一)登记模型,区分类型/框架/格式/负责人/标签/描述
版本控制同一模型可挂多个语义化版本(如 1.0.0 / 1.1.0),首个版本自动成为当前版本
部署与回滚一键部署指定版本为当前版本、一键回滚到历史版本、一键下线全部部署
在线预测「预测测试」Tab 提供 JSON 输入框,rule / external_api 两类引擎同步返回结果与置信度
全量审计每次预测都落 ml_prediction_logs 日志表,「预测历史」Tab 可追溯输入/输出/置信度/操作者
本体集成预测输出可注册为对象计算属性,模型可被低代码应用当作动作调用

1.3 一句话总结

在 Foundry 里把模型当作「可注册、可版本化、可部署、可在线预测」的一等公民,前端负责建模生命周期操作,后端 rule / external_api 双引擎负责推理,每次预测自动留痕。

2. 访问入口

2.1 路由与菜单

2.2 认证与权限

2.3 端口与 API 前缀

3. 界面布局

页面是一个单屏 Tab 页,顶部是标题与操作结果提示,下面是三个 Tab 面板,文字框图如下:

┌──────────────────────────────────────────────────────────────────┐
│  MLOps 模型平台                                     [操作结果提示] │
├──────────────────────────────────────────────────────────────────┤
│  [模型管理]  [预测测试]  [预测历史]                                 │
├──────────────────────────────────────────────────────────────────┤
│ Tab1 模型管理:                                                    │
│  ┌ 卡片: 状态筛选下拉 + [注册模型/收起] ────────────────────────┐ │
│  ┌ 卡片: 注册模型表单(三列栅格: 名称/显示名/类型/框架/格式/     ┐ │
│  │        负责人/标签 + 描述 textarea + 注册/取消)             │ │
│  ┌ 卡片: 模型列表表格 ────────────────────────────────────────┐ │
│  │  名称 | 类型 | 格式 | 当前版本 | 状态 | 标签 | 操作(详情/删除)│ │
│  ┌ 卡片: 选中模型详情 ────────────────────────────────────────┐ │
│  │  ├ 版本 子块: [标题+计数] [+ 上传版本]                       │ │
│  │  │   上传版本表单(内联) + 版本列表表格(版本/制品/大小/指标/   │ │
│  │  │   上传时间/操作: 部署/回滚/预测)                          │ │
│  │  └ 部署 子块: [标题+计数] [下线]                            │ │
│  │      部署列表表格(版本/部署类型/端点/状态/时间)               │ │
├──────────────────────────────────────────────────────────────────┤
│ Tab2 预测测试:                                                   │
│  ┌ 卡片: 预测测试表单 ─────────────────────────────────────────┐ │
│  │  模型* | 版本(缺省当前) | 输入特征 input(JSON)* | 端点覆盖    │ │
│  │  [执行预测]                                                │ │
│  ┌ 卡片: 预测结果(模型名/版本/置信度/日志# + JSON 输出)───────┐ │
├──────────────────────────────────────────────────────────────────┤
│ Tab3 预测历史:                                                   │
│  ┌ 卡片: 模型下拉 + [刷新] ────────────────────────────────────┐ │
│  ┌ 卡片: 预测日志表格(时间/版本/输入/输出/置信度/关联对象/操作者)┐ │
└──────────────────────────────────────────────────────────────────┘
板块职责
操作结果提示(alert)页面顶部显示成功/失败/信息提示,可点「关闭」按钮手动清除
Tab 栏模型管理 / 预测测试 / 预测历史 三个工作区切换
状态筛选 + 注册模型按 registered/deployed/deprecated/error 过滤模型列表;展开内联注册表单
模型列表表格展示模型概要,行内「详情」「删除」操作
模型详情点「详情」后展开:模型元信息 + 版本子块 + 部署子块
版本子块上传新版本(表单内联展开)、版本列表、每版本「部署/回滚/预测」按钮
部署子块展示该模型全部部署记录,模型已部署时提供「下线」按钮
预测测试表单选模型(+可选版本)→ 填 JSON 输入 → 可选端点覆盖 → 执行预测
预测结果卡片展示模型名、版本、置信度、日志号与格式化 JSON 输出
预测历史表格按模型查看预测日志,含输入/输出/置信度/关联对象/操作者

4. 交互元素详解

4.1 页面级元素

元素位置含义默认值/必填操作效果触发的后端调用
操作结果提示页面顶部显示操作结果(info/success/error)点「关闭」按钮清空 alert.message
Tab「模型管理」Tab 栏切到模型管理默认激活切换 activeTab='models'
Tab「预测测试」Tab 栏切到预测测试切换 activeTab='predict'
Tab「预测历史」Tab 栏切到预测历史切换 activeTab='history'

4.2 Tab1 模型管理

4.2.1 状态筛选与注册入口

元素位置含义默认值/必填操作效果触发的后端调用
状态筛选下拉模型管理顶部按状态过滤模型全部(空串)@change 触发 fetchModelsGET /api/v1/ml/models?status=xxx
选项「全部」下拉不过滤默认选中传空参数GET /api/v1/ml/models
选项 registered下拉仅看已注册模型-status=registered同上带参
选项 deployed下拉仅看已部署模型-status=deployed同上带参
选项 deprecated下拉仅看已下线/归档模型-status=deprecated同上带参
选项 error下拉仅看异常模型-status=error同上带参
按钮「注册模型」/「收起」右侧展开/收起注册表单-切换 showCreateForm

4.2.2 注册模型表单

表单用三列栅格布局,@submit.prevent="handleCreateModel"

元素含义必填默认值前端校验传给后端的字段
「名称(api_name,唯一)*」模型唯一标识,如 churn_predictionname.trim() 非空name
「显示名称」展示名,如「客户流失预测」-display_name
「模型类型 model_type *」枚举下拉classificationHTML requiredmodel_type
「框架 framework *」训练框架下拉sklearnHTML requiredframework
「格式 format(推理引擎)*」推理引擎下拉pickleHTML requiredformat
「负责人 owner」责任人-owner
「标签 tags(逗号分隔)」标签[,,] 拆分并去空tags(数组)
「描述」 textarea模型用途描述-description
按钮「注册」提交--校验必填POST /api/v1/ml/models
按钮「取消」收起表单---

后端合法枚举(源码 ml/models.go):model_type ∈ classification/regression/ranking/clustering/other;framework ∈ sklearn/pytorch/onnx/pmml/custom/external_api/rule;format ∈ onnx/pmml/pickle/docker_image/external_api/rule。前端三个下拉框的选项与后端 valid* 集合逐字一致。

注册成功后提示 模型注册成功 id=xxx,自动收起表单、重置并重新拉取列表,随后 selectModel(id) 自动打开新模型详情。

4.2.3 模型列表表格

显示内容
名称粗体显示 display_name || name,下方灰色小字为 name
类型model_type,空显示 -
格式format,空显示 -
当前版本current_version,空显示 -
状态status-badge 徽标,按状态着色(registered=蓝、deployed=绿、deprecated=灰、error=红)
标签逐个渲染 dim-tag,无标签显示 -
操作「详情」按钮(selectModel(m.id))+「删除」按钮(handleDeleteModel(m)

4.2.4 模型详情卡片

标题区显示 display_name || name,灰字元信息 (name · model_type / framework / format · v当前版本),右侧状态徽标;有描述时以灰色 hint 展示。

版本子块
元素含义操作效果后端调用
「+ 上传版本」/「收起」展开/收起内联上传表单切换 showVersionForm
版本号 *语义化版本,如 1.0.0必填组装到 body
制品地址 artifact_url模型文件路径或 URL,如 s3://models/x.onnx可空artifact_url
制品大小(字节)number 输入可空(默认 0)artifact_size
参数 parameters(JSON)推理参数;rule 模型放规则 rules可空parameters(JSON 对象)
评估指标 metrics(JSON)训练指标,如 {"accuracy": 0.95}可空metrics
输入结构 input_schema(JSON)输入结构定义可空input_schema
输出结构 output_schema(JSON)输出结构定义可空output_schema
按钮「上传」提交版本校验版本号非空,JSON 字段必须可解析,成功后提示「版本上传成功 id=xxx」并刷新详情POST /api/v1/ml/models/:id/versions
按钮「取消」收起表单-

参数占位提示:当模型的 format === 'rule' 时,参数 textarea 的 placeholder 为规则数组示例 {"rules": [{"if": {"amount_gt": 1000}, "then": "high_risk"}]};其他格式为 {"feature": "值"}versionParamPlaceholder computed)。

版本列表表格列:版本(当前版本带蓝色「当前」标签并高亮行 row-current)、制品(cell-code 等宽)、大小(formatBytes 格式化为 B/KB/MB)、评估指标(JSON 压缩串)、上传时间(toLocaleString)、操作(「部署」「回滚」「预测」三个 outline 按钮)。

部署子块
元素含义操作效果后端调用
「下线」按钮(红)仅当模型 status === 'deployed' 时显示confirm 后调下线接口,提示「模型已下线」POST /api/v1/ml/models/:id/undeploy

部署列表表格列:版本(versionLabel 映射版本号)、部署类型、端点(endpoint_url 等宽)、状态徽标、时间。

4.3 Tab2 预测测试

元素含义必填默认值操作效果后端调用
「模型 *」下拉选择模型@change 触发 onPredictModelChange(清版本、清结果、拉详情)GET /api/v1/ml/models/:id
「版本(缺省当前版本)」下拉指定版本空(当前版本 current_version选定 versionId组装到 URL
「输入特征 input(JSON 对象)*」textarea预测输入,如 {"amount": 2000, "region": "华东"}{}解析失败提示「输入 JSON 格式错误」body.input
「端点覆盖 endpoint_url(可选,external_api 未部署时使用)」手动指定转发端点有值时追加 body.endpoint_urlbody.endpoint_url
按钮「执行预测」触发预测--busy 期间禁用并显示「预测中...」有版本 POST /api/v1/ml/models/:id/versions/:vid/predict;无版本 POST /api/v1/ml/models/:id/predict

预测结果卡片:模型名、版本、置信度(confidence)、日志 #log_id 前 8 位);<pre> 展示 JSON.stringify(output, null, 2) 格式化输出。预测成功后还会调用 fetchPredictions 刷新预测历史。

4.4 Tab3 预测历史

元素含义操作效果后端调用
「模型」下拉选择模型@change 触发 fetchPredictionsGET /api/v1/ml/models/:id/predictions
「刷新」按钮手动刷新重新拉取当前模型预测日志同上

表格列:时间、版本(versionLabelByLog 映射)、输入(截断等宽 cell-truncate)、输出(同左)、置信度、关联对象(object_type_id / object_id,无则 -)、操作者(created_by)。空列表提示「暂无预测记录(请先在"预测测试"中执行预测)」。后端缺省每次返回最近 50 条(limit<=0 时缺省 50)。

5. 后端关联

5.1 API 客户端

页面使用 action/web/src/api/client.js

5.2 端点表

方法路径请求体要点成功响应备注
GET/ml/modelsquery status(可选){data: [...]}支持状态过滤
POST/ml/modelsname/display_name/description/model_type/framework/format/owner/tags201 {data:{id}}name 唯一
GET/ml/models/:id-{data: {model, versions, deployments}}详情聚合
PUT/ml/models/:id空字段保留原值{data:{id}}前端未使用
DELETE/ml/models/:id-{data:{deleted:true}}软删除 → deprecated
POST/ml/models/:id/versionsversion/artifact_url/artifact_size/parameters/metrics/input_schema/output_schema201 {data:{id}}首个版本自动设为当前版本
POST/ml/models/:id/versions/:vid/deployversion_id/deploy_type/endpoint_url/config{data:{deployment_id}}部署并切换当前版本
POST/ml/models/:id/undeploy-{data:{undeployed:true}}停掉全部 active 部署
POST/ml/models/:id/versions/:vid/predict{input:{...}, endpoint_url?}{data:{model_id, version, output, confidence, log_id}}指定版本预测
POST/ml/models/:id/predict同上同上当前版本预测
GET/ml/models/:id/predictionsquery limit(缺省 50){data:[...]}预测日志

5.3 响应结构

okData 统一包一层 data。预测结果示例:

{
  "data": {
    "model_id": "5f0a...",
    "version_id": "6b3d...",
    "version": "1.0.0",
    "output": { "matched": true, "result": "high_risk" },
    "confidence": 1.0,
    "log_id": "a9e8...",
    "object_type_id": 0,
    "object_id": ""
  }
}

错误统一走 errorResponse,前端读取 err.response?.data?.error 展示,例如 {"error": "推理引擎 ... 暂不支持(MVP 支持 rule 与 external_api)"}

5.4 关联模块表

后端包/文件职责
action/products/foundry/ml/models.go四张表:ml_models / ml_model_versions / ml_model_deployments / ml_prediction_logs;状态与枚举常量
action/products/foundry/ml/service.goMLService:CRUD、版本、部署/下线、预测、日志、本体集成
action/products/foundry/ml/rules.go规则推理引擎(inferRules/evalRule/parseRuleCond)
action/products/foundry/server/ml_handlers.goHTTP handler + RegisterMLRoutes 路由注册
action/products/foundry/server/server.gosetupRouter 中 RegisterMLRoutes(protected, NewMLHandler(s.mlSvc))

5.5 关键机制

6. 核心流程详解

6.1 主流程一:注册模型

  1. 进入「模型管理」Tab → 点「注册模型」展开表单。
  2. name(必填)、display_namedescription、下拉选 model_type/framework/format,可填 ownertags(逗号分隔)。
  3. 点「注册」→ handleCreateModel:本地校验 name 非空 → POST /api/v1/ml/models → 成功提示并自动收起表单、重置、刷新列表 → 若返回 id 则自动 selectModel(id) 展开详情。
  4. 失败:顶部 alert 显示 模型注册失败:<error>

6.2 主流程二:上传版本并部署

  1. 在模型详情「版本」子块点「+ 上传版本」。
  2. 填版本号与可选制品信息;rule 模型在「参数 parameters」里贴规则数组,external_api 模型只需版本号即可(端点部署时配)。
  3. 点「上传」→ POST /api/v1/ml/models/:id/versions → 成功后收起表单、刷新详情,新版本出现在版本列表;若这是第一个版本,模型 current_version 自动指向它。
  4. 点该版本行的「部署」→ prompt 预填部署配置 JSON(external_api 需填 endpoint_url)→ POST .../versions/:vid/deploy → 成功后该版本成为当前版本,模型状态变为 deployed,部署列表新增一条 active 记录。
  5. 想切换回旧版本:点旧版本行「回滚」→ 同样走部署接口 → 旧版本成为当前版本(旧 active 部署被停掉、新建 active)。

6.3 主流程三:执行预测

  1. 切到「预测测试」Tab → 选「模型」(必填)→ 可选选「版本」(缺省当前版本)。
  2. 在「输入特征 input」贴 JSON 对象(如 {"amount": 2000, "region": "华东"})。
  3. 若模型是 external_api 且未部署端点,可在「端点覆盖」填第三方端点。
  4. 点「执行预测」→ 有版本调 POST /ml/models/:id/versions/:vid/predict,否则调 POST /ml/models/:id/predict → 结果卡片展示输出与置信度,同时刷新「预测历史」。
  5. rule 模型预测语义:逐条规则匹配输入,命中输出 thenconfidence=1.0;未命中输出 {"matched": false}confidence=0
  6. external_api 语义:POST {"input": <输入>} 到端点,优先取响应 output 字段(非对象则包一层 result),置信度取 confidence(缺省 0)。

6.4 主流程四:下线与删除

6.5 状态机 / 任务终态语义

                    ┌─────────────┐
     注册(POST)      │             │   部署(任一版本)
  ───────────────▶  │ registered  ├───────────────▶  deployed
                    │             │                   ▲
                    └─────┬───────┘                   │ 回滚(部署历史版本)
                          │                           │
         删除(DELETE 软删) │  下线(undeploy)           │
                          ▼                           │
                    ┌─────────────┐                   │
                    │ deprecated  │◀──────────────────┘
                    └─────────────┘

部署记录状态:deploying → active / failed;下线后 active 变 stopped。预测一律同步执行(HTTP 同步返回),无异步任务轮询;「预测历史」的刷新是简单的列表重拉。

7. 权限与安全

8. 常见问题与排错

8.1 预测报「推理引擎暂不支持」

8.2 external_api 预测报「未部署端点」

8.3 JSON 格式错误(上传版本/预测输入)

8.4 模型列表一直「加载中...」

8.5 删除后列表仍显示(状态变 deprecated)

9. 已知缺陷与边界

项目说明
推理引擎有限MVP 仅 rule 与 external_api 可执行预测,onnx/pmml/pickle/docker_image 可注册但预测报「暂不支持」
部署为记录式realtime_api 部署仅登记端点/状态,不做真实服务编排;batch_job/ontology_integration 类型仅合法值,无独立实现
回滚语义回滚即「部署历史版本」,新版本成为当前版本;不保留历史部署记录(旧 active 停掉)
版本号唯一性同一模型内版本号必须唯一,重复上传报冲突错误
预测历史条数后端缺省返回最近 50 条,页面无分页/翻页 UI
无批量操作不支持批量删除/批量部署/批量预测(后端有 BatchPredict 但前端未接入)
状态 error页面没有主动设置 error 状态的入口,多由后端部署失败产生
端点信任external_api 转发目标由用户配置,无 SSRF 级校验,仅建议配置可信端点

注:部署配置依赖原生 prompt 输入 JSON 的问题已于 2026-09-06 修复(改为页面弹窗表单,提交前本地预校验 JSON,解析失败提示具体错误并保留输入,不再丢弃)。