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=true,formula 记录 ml:<modelName>),模型还可以作为本体动作被业务应用(低代码应用构建器)调用。也就是说,MLOps 不只是「训练完放个文件」,而是把模型能力编织进企业的对象、应用与工作流体系。
MVP 阶段的推理引擎只有两类,页面上的「格式 format(推理引擎)」下拉框是理解整个系统的钥匙:
- rule(规则式推理):模型的版本参数
parameters中放一份规则数组(如{"if":{"amount_gt":1000},"then":"high_risk"}),预测时按规则逐条匹配输入特征,命中即输出then值,置信度固定为1.0。 - external_api(HTTP 转发):模型本身不计算,预测时把输入 JSON
POST到部署时配置的第三方模型服务端点,从响应中解析output与confidence字段。
其余格式(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 一句话总结
2. 访问入口
2.1 路由与菜单
- 路由:
/foundry/mlops - 路由名称:
FoundryMLOps - 菜单位置:Foundry 左侧边栏「MLOps 模型」(
FoundryLayout.vue菜单项,位于「数据治理」之后) - 源码文件:
action/web/src/views/MLOpsPage.vue(约 1065 行) - 路由注册:
action/web/src/router/index.js,meta: { title: 'MLOps 模型', requiresAuth: true }
2.2 认证与权限
- 需要登录:是(路由
meta.requiresAuth = true,父路由/foundry同样受保护) - 登录方式:AIP 统一登录;
localStorage.aip_token由client.js请求拦截器自动写入Authorization: Bearer <token> - 页面本身没有额外的角色/对象级权限 UI,所有模型对登录用户可见;权限控制在后端接口层(JWT 校验)。预测日志的
created_by记录当前登录用户(currentUserID(c))。 - 401 排错:若访问
/foundry/mlops被重定向到/login,说明aip_token缺失或过期;重新登录即可。
2.3 端口与 API 前缀
- 后端端口:18081(Foundry)
- 前端 API 客户端:
action/web/src/api/client.js,baseURL = '/api/v1',超时 30 秒 - 本页所有请求路径形如
/api/v1/ml/models,即完整 URL 为http://localhost:18081/api/v1/ml/models(开发态经 Vite 代理)
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 触发 fetchModels | GET /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_prediction | 是 | 空 | name.trim() 非空 | name |
| 「显示名称」 | 展示名,如「客户流失预测」 | 否 | 空 | - | display_name |
| 「模型类型 model_type *」 | 枚举下拉 | 是 | classification | HTML required | model_type |
| 「框架 framework *」 | 训练框架下拉 | 是 | sklearn | HTML required | framework |
| 「格式 format(推理引擎)*」 | 推理引擎下拉 | 是 | pickle | HTML required | format |
| 「负责人 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)) |
- 加载中显示「加载中...」;列表为空显示「暂无模型,请点击"注册模型"创建。」
- 「详情」:把模型 id 设为
selectedModelId并调用loadDetail,在下方展开详情卡片。 - 「删除」:
confirm二次确认(文案「确定删除模型"xxx"吗?(软删除)」),确认后调用DELETE /api/v1/ml/models/:id,成功提示「模型已删除(status=deprecated)」,并清理已选详情。
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 按钮)。
- 「部署」:
openDeploy(v)→ 若模型格式为external_api则弹出预填{"deploy_type": "realtime_api", "endpoint_url": "https://your-model-service.example/predict"}的prompt,否则预填{"deploy_type": "realtime_api"};确认后handleDeployVersion(v, cfg)调POST /api/v1/ml/models/:id/versions/:vid/deploy。 - 「回滚」:
openDeploy(v, true),提示文案不同(「回滚到版本 x(部署后该版本将成为当前版本)」),调同一接口,成功提示「已回滚到版本 x(当前版本已切换)」。 - 「预测」:
testPredictVersion(v)切到预测测试 Tab,自动选中该模型与版本。
部署子块
| 元素 | 含义 | 操作效果 | 后端调用 |
|---|---|---|---|
| 「下线」按钮(红) | 仅当模型 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_url | body.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 触发 fetchPredictions | GET /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:
baseURL: '/api/v1'(Vite 开发代理到 Foundry 18081)timeout: 30000(30 秒)- 请求拦截器:自动附带
Authorization: Bearer ${localStorage.aip_token} - 响应拦截器:401 时清除
aip_token/aip_username并跳转/login - 本页无独立 axios 实例,所有调用走默认
apiClient。
5.2 端点表
| 方法 | 路径 | 请求体要点 | 成功响应 | 备注 |
|---|---|---|---|---|
| GET | /ml/models | query status(可选) | {data: [...]} | 支持状态过滤 |
| POST | /ml/models | name/display_name/description/model_type/framework/format/owner/tags | 201 {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/versions | version/artifact_url/artifact_size/parameters/metrics/input_schema/output_schema | 201 {data:{id}} | 首个版本自动设为当前版本 |
| POST | /ml/models/:id/versions/:vid/deploy | version_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/predictions | query 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.go | MLService:CRUD、版本、部署/下线、预测、日志、本体集成 |
action/products/foundry/ml/rules.go | 规则推理引擎(inferRules/evalRule/parseRuleCond) |
action/products/foundry/server/ml_handlers.go | HTTP handler + RegisterMLRoutes 路由注册 |
action/products/foundry/server/server.go | setupRouter 中 RegisterMLRoutes(protected, NewMLHandler(s.mlSvc)) |
5.5 关键机制
- 模型状态机:registered → deployed(部署任一版本)→ registered(下线);任何状态可被软删除进入 deprecated;错误状态 error 由部署失败等产生。
- 当前版本语义:首个上传的版本自动成为
current_version;部署任意版本会把它切换为当前版本(回滚即部署历史版本);预测未指定版本时使用当前版本。 - 推理引擎判定:
engineKind优先看framework/format是否含rule或external_api,其余格式虽可注册但预测直接报「暂不支持」。 - external_api 端点解析顺序:请求体
endpoint_url(前端「端点覆盖」)→ 该模型+该版本status=active的 realtime_api 部署端点 → 该模型任一 active realtime_api 部署端点 → 报错。 - 预测日志:每次 Predict 都写
ml_prediction_logs,含 input/output/confidence/object_type_id/object_id/created_by;列表按时间倒序、缺省 50 条。 - 本体集成(页面未直接暴露,供审计理解):
RegisterPredictionProperty将预测输出注册为对象计算属性,PredictForObject拉取对象属性当特征并可选写回(write_back)。 - rule 规则语法:
parameters.rules数组,if键支持_gt/_gte/_lt/_lte/_eq/_neq/_contains/_in后缀操作符(如amount_gt→input["amount"] > 1000),全部命中则输出then。
6. 核心流程详解
6.1 主流程一:注册模型
- 进入「模型管理」Tab → 点「注册模型」展开表单。
- 填
name(必填)、display_name、description、下拉选model_type/framework/format,可填owner、tags(逗号分隔)。 - 点「注册」→
handleCreateModel:本地校验 name 非空 →POST /api/v1/ml/models→ 成功提示并自动收起表单、重置、刷新列表 → 若返回 id 则自动selectModel(id)展开详情。 - 失败:顶部 alert 显示
模型注册失败:<error>。
6.2 主流程二:上传版本并部署
- 在模型详情「版本」子块点「+ 上传版本」。
- 填版本号与可选制品信息;rule 模型在「参数 parameters」里贴规则数组,external_api 模型只需版本号即可(端点部署时配)。
- 点「上传」→
POST /api/v1/ml/models/:id/versions→ 成功后收起表单、刷新详情,新版本出现在版本列表;若这是第一个版本,模型current_version自动指向它。 - 点该版本行的「部署」→
prompt预填部署配置 JSON(external_api 需填endpoint_url)→POST .../versions/:vid/deploy→ 成功后该版本成为当前版本,模型状态变为 deployed,部署列表新增一条 active 记录。 - 想切换回旧版本:点旧版本行「回滚」→ 同样走部署接口 → 旧版本成为当前版本(旧 active 部署被停掉、新建 active)。
6.3 主流程三:执行预测
- 切到「预测测试」Tab → 选「模型」(必填)→ 可选选「版本」(缺省当前版本)。
- 在「输入特征 input」贴 JSON 对象(如
{"amount": 2000, "region": "华东"})。 - 若模型是 external_api 且未部署端点,可在「端点覆盖」填第三方端点。
- 点「执行预测」→ 有版本调
POST /ml/models/:id/versions/:vid/predict,否则调POST /ml/models/:id/predict→ 结果卡片展示输出与置信度,同时刷新「预测历史」。 - rule 模型预测语义:逐条规则匹配输入,命中输出
then且confidence=1.0;未命中输出{"matched": false}且confidence=0。 - external_api 语义:
POST {"input": <输入>}到端点,优先取响应output字段(非对象则包一层result),置信度取confidence(缺省 0)。
6.4 主流程四:下线与删除
- 「下线」:仅当模型 deployed 时在部署子块显示;
confirm后POST /ml/models/:id/undeploy,停掉全部 active 部署、状态回 registered。 - 「删除」:列表行或详情中触发;
confirm后DELETE /ml/models/:id,软删除(status=deprecated),列表刷新,若删除的是已选模型则清空详情。
6.5 状态机 / 任务终态语义
┌─────────────┐
注册(POST) │ │ 部署(任一版本)
───────────────▶ │ registered ├───────────────▶ deployed
│ │ ▲
└─────┬───────┘ │ 回滚(部署历史版本)
│ │
删除(DELETE 软删) │ 下线(undeploy) │
▼ │
┌─────────────┐ │
│ deprecated │◀──────────────────┘
└─────────────┘
部署记录状态:deploying → active / failed;下线后 active 变 stopped。预测一律同步执行(HTTP 同步返回),无异步任务轮询;「预测历史」的刷新是简单的列表重拉。
7. 权限与安全
- 认证:全部接口走
/api/v1protected 组,JWT 必需;client.js自动带 Bearer token。 - 数据级安全:页面本身不区分模型可见性(所有登录用户可看全部模型);预测日志的
created_by写当前用户,供审计追溯。 - 写操作防护:删除模型/下线部署/删除前均有
confirm二次确认;上传/注册/部署/预测在busy期间按钮禁用防重复提交。 - 输入校验:前端校验 name/版本号必填、JSON 必须可解析;后端二次校验枚举合法性、name/版本号唯一性、external_api 端点必须可解析。
- external_api 风险提示:预测会把输入转发到用户配置的第三方端点,这是设计内的模型服务调用(区别于 SSRF 场景的 webhook),但端点地址应只配置可信服务。
8. 常见问题与排错
8.1 预测报「推理引擎暂不支持」
- 现象:执行预测返回
推理引擎 "pickle" 暂不支持(MVP 支持 rule 与 external_api...)。 - 原因:模型的
format/framework是 onnx/pmml/pickle/docker_image 等,MVP 推理引擎只实现了 rule 与 external_api。 - 排查:① 查看模型详情确认
format;② 若要可推理,把format改为rule(参数里配 rules)或external_api(部署时配 endpoint_url);③ 或改注册时的「格式 format(推理引擎)」字段。
8.2 external_api 预测报「未部署端点」
- 现象:external_api 模型执行预测报
模型 "xxx" 未部署 external_api 端点,且未指定 endpoint_url。 - 原因:部署记录不存在、非 active,或没有填端点。
- 排查:① 在「部署」prompt 中确认预填了
"endpoint_url": "https://..."(external_api 格式会自动预填);② 在「部署」子块确认存在 active 的 realtime_api 部署;③ 或临时在「预测测试」的「端点覆盖 endpoint_url」填第三方端点。
8.3 JSON 格式错误(上传版本/预测输入)
- 现象:点「上传」或「执行预测」提示
JSON 格式错误:...。 - 原因:
parameters/metrics/input_schema/output_schema或输入特征不是合法 JSON;前端parseJSON直接抛错。 - 排查:① 用
JSON.stringify保证键值双引号;② rule 模型 parameters 必须整体是{"rules":[...]}结构;③ 输入特征必须是 JSON 对象(不能是数组/标量)。
8.4 模型列表一直「加载中...」
- 现象:Tab1 列表卡在加载中,无数据。
- 原因:
GET /ml/models请求失败(网络/401/后端未启动)。 - 排查:① F12 Network 看请求是否 401(重新登录);② 确认 Foundry 后端 18081 已启动;③ 看 alert 是否弹了「加载模型列表失败:...」的错误文案。
8.5 删除后列表仍显示(状态变 deprecated)
- 现象:删除模型后它在列表里还在,只是状态徽标变灰。
- 原因:删除是软删除,
status=deprecated,列表默认不过滤会展示。 - 排查:用「状态筛选」选 deprecated 即可确认已删除;想彻底隐藏可在状态筛选选 registered/deployed。
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,解析失败提示具体错误并保留输入,不再丢弃)。