# Giao diện modelctl: CLI, TUI & MCP

> Ba cách điều khiển bộ công cụ mô hình modelctl — CLI để scripting, terminal UI tương tác, và một MCP server cho các coding agent — cùng lúc nào nên dùng cái nào.

`modelctl` có thể được điều khiển theo ba cách. Cả ba đều chạy **cùng các lệnh CLI
bên dưới** (`convert` / `validate` / `quantize` / `package`), nên kết quả giống nhau —
hãy chọn giao diện khớp với cách bạn làm việc:

| Giao diện | Phù hợp nhất cho | Cài thêm |
| --- | --- | --- |
| **CLI** (`modelctl`) | Scripting, pipeline CI, lệnh một lần | lõi (không cần gì) |
| **TUI** (`modelctl-tui`) | Dùng tương tác — form, output trực tiếp, không phải nhớ flag | `[tui]` |
| **MCP server** (`modelctl-mcp`) | Coding AI agent (Claude Code, Cursor, …) gọi các tool có kiểu | `[mcp]` |

TUI và MCP server là lớp bọc subprocess mỏng trên CLI và dùng chung cùng cơ chế
[tự động định tuyến](#tự-động-định-tuyến-chọn-đúng-môi-trường): chúng phát hiện các môi
trường `venv-torch` / `venv-tf` của bạn và gửi từng lệnh tới môi trường có framework
cần thiết, nên bạn không bao giờ chạy một bước ở môi trường sai. Cả hai đều không tự

Trang này nói về **các giao diện**. Về quy trình chuẩn bị mô hình đầu-cuối
(convert → validate → quantize → package) và chi tiết flag, xem
[Chuẩn bị mô hình với modelctl](/vi/configure/prepare-models/).

## CLI (`modelctl`)

Giao diện chuẩn. Bốn subcommand, exit code rõ ràng, output kiểm tra ✓/✗ —
làm cho shell và CI.

```bash
# Convert một mô hình TorchScript sang ONNX
modelctl convert --source model.pt --format pytorch --output model.onnx \
  --input-shape 1,3,224,224 --opset 18

# Validate (schema · opset so với runtime biên · nạp runtime · inference thử)
modelctl validate --model model.onnx --target-ort 1.18

# Lượng tử hóa Dynamic INT8
modelctl quantize --model model.onnx --output model.int8.onnx

# Đóng gói thành bundle ngoại tuyến có checksum
modelctl package --model model.onnx --name pump-anomaly-v1
```

<figure class="diagram-card">
  <img
    src="/diagrams/modelctl-cli-session-placeholder.svg"
    alt="Placeholder — ảnh chụp terminal một phiên modelctl CLI chạy convert, validate, quantize và package với các dòng kiểm tra ✓"
    width="1042"
    height="360"
  />
  <figcaption>Một phiên CLI điển hình: mỗi lệnh in các kiểm tra ✓/✗ và exit khác 0 khi thất bại.</figcaption>
</figure>

Điểm riêng của CLI:

- **File cấu hình**: `modelctl convert --config model.yaml` đọc một cấu hình YAML;
  thứ tự ưu tiên là **flag CLI > YAML > mặc định**.
- **Exit code** ứng với các giai đoạn thất bại (3 = thiếu phụ thuộc, 4 = convert,
  5 = validate, 6 = package, 7 = quantize) — hãy chặn CI theo chúng.
- **Bundle tái lập được**: truyền `--timestamp` (hoặc set `SOURCE_DATE_EPOCH`) để
  `metadata.json` / `checksums.sha256` byte-identical giữa các lần chạy.

## TUI (`modelctl-tui`)

Một front-end [Textual](https://textual.textualize.io/) tùy chọn: chọn một lệnh,
điền form của nó, và xem output ✓/✗ chảy trực tiếp kèm badge thành công/lỗi.

```bash
pip install 'modelctl[tui]'
modelctl-tui        # chạy từ thư mục chứa venv-torch / venv-tf
```

### Cấu tạo màn hình

```text
┌ modelctl-tui ──────────── envs: venv-torch[core, pytorch, quantize]  venv-tf[core, quantize, tensorflow] ┐
│ Command                          │ Output                                                  │
│  ( ) convert                     │ $ venv-torch/bin/modelctl validate --model model.onnx   │
│  (•) validate                    │ ✓ ONNX schema valid                                     │
│  ( ) quantize                    │ ✓ Opset supported                                       │
│  ( ) package                     │ ✓ ONNX Runtime load successful                          │
│ Options                          │ ✓ Test inference successful                             │
│  --model *   [model.onnx      ]  │                                                         │
│  --target-ort [1.18           ]  │                                                         │
│  [ Run ]                         │                                                         │
│  → will run in: venv-torch [...] │  ● SUCCESS exit 0                                       │
└──────────────────────────── q quit  ctrl+r run  ctrl+e re-detect envs ────────────────────┘
```

- **Header** — các môi trường phát hiện được và năng lực của chúng (`core` / `pytorch` /
  `tensorflow` / `quantize`).
- **Command + Options (bên trái)** — form đổi theo từng lệnh; `*` đánh dấu trường bắt
  buộc.
- **Gợi ý chạy** — dòng dưới **Run** cho biết lệnh sẽ chạy ở môi trường nào, hoặc vì
  sao chưa chạy được.
- **Output (bên phải)** — luồng ✓/✗ trực tiếp, kèm badge `● SUCCESS exit 0` /
  `● FAILED exit N`.

<figure class="diagram-card">
  <img
    src="/diagrams/modelctl-tui-screen-placeholder.svg"
    alt="Placeholder — ảnh chụp màn hình modelctl-tui với danh sách lệnh, form tùy chọn, khung output trực tiếp và badge trạng thái"
    width="1042"
    height="360"
  />
  <figcaption>TUI thật, đang hiển thị một lần chạy validate được định tuyến tới venv-torch.</figcaption>
</figure>

### Phím tắt

| Phím | Hành động |
| --- | --- |
| `ctrl+r` | Chạy lệnh đang chọn (giống **Run**) |
| `ctrl+e` | Phát hiện lại môi trường (sau khi tạo/sửa một venv) |
| `q` | Thoát |

Nếu header ghi `envs: none detected`, hãy khởi chạy `modelctl-tui` từ thư mục chứa
`venv-torch/` / `venv-tf/`, hoặc nhấn `ctrl+e` sau khi tạo chúng.

## MCP server (`modelctl-mcp`)

Một server stdio [Model Context Protocol](https://modelcontextprotocol.io/) tùy chọn,
phơi cùng các lệnh đó cho coding agent dưới dạng **tool có kiểu**, nhờ vậy một agent có
thể chuẩn bị mô hình cho hộp biên mà không cần truy cập shell.

```bash
pip install 'modelctl[mcp]'
```

Đăng ký nó với agent của bạn — với Claude Code là trong `claude.json` (Cursor tương tự):

```json
{
  "mcpServers": {
    "modelctl": {
      "command": "modelctl-mcp",
      "cwd": "/path/with/venv-torch-and-venv-tf"
    }
  }
}
```

`cwd` phải chứa các thư mục `venv-torch/` / `venv-tf/` (gốc tìm kiếm mặc định của
router) — hoặc để agent gọi `list_environments` trước để xác nhận cái gì định tuyến được.

### Các tool

| Tool | Mục đích | Tham số chính |
| --- | --- | --- |
| `list_environments` | Khám phá môi trường và năng lực của chúng | — |
| `convert` | PyTorch / TensorFlow → ONNX | `source`, `format`, `output`, `input_shape` |
| `validate` | Schema, opset, nạp runtime, inference thử | `model`; tùy chọn `target_ort`, `no_runtime` |
| `quantize` | Lượng tử hóa Dynamic INT8 | `model`; tùy chọn `output`, `input_shape` |
| `package` | Validate + đóng gói thành bản phát hành ngoại tuyến có checksum | `model`, `name`; tùy chọn `version`, `quantize`, `out_root` |

Mọi tool đều trả về cùng một dạng kết quả: `command`, `env_label`, `exit_code`,
`ok`, `stdout`, `stderr`, và `artifact_path` (file/bundle tạo ra khi thành công) —
agent nên kiểm tra `ok` rồi mới dùng `artifact_path`.

<figure class="diagram-card">
  <img
    src="/diagrams/modelctl-mcp-agent-session-placeholder.svg"
    alt="Placeholder — ảnh chụp một phiên coding agent gọi các MCP tool list_environments, convert và validate với kết quả JSON"
    width="1042"
    height="360"
  />
  <figcaption>Một phiên coding agent: list_environments → convert → validate, mỗi bước trả về một kết quả có kiểu.</figcaption>
</figure>

## Tự động định tuyến: chọn đúng môi trường

Các extra `quantize` và `tensorflow` không thể dùng chung một môi trường Python (xung
đột phiên bản `ml_dtypes`), đó là vì sao bộ công cụ giữ hai venv. TUI và MCP server dò
năng lực của từng môi trường và định tuyến theo từng lệnh:

| Lệnh | Cần năng lực | Thường định tuyến tới |
| --- | --- | --- |
| `validate`, `package` (không quantize) | core | môi trường nào cũng được |
| `convert --format pytorch` | pytorch | `venv-torch` |
| `convert --format tensorflow` | tensorflow | `venv-tf` |
| `quantize`, hoặc bất kỳ flag `--quantize` | quantize | `venv-torch` |

Có một tổ hợp không thể thỏa mãn do thiết kế: **convert TensorFlow cùng với quantize**.
Cả hai giao diện đều nêu điều này ra thay vì fail giữa đường — TUI vô hiệu hóa **Run**
kèm một gợi ý, MCP trả về lỗi — hãy làm theo hai bước: `convert` (tensorflow) ra
`.onnx` trước, rồi `quantize` chính file `.onnx` đó.

## Bước tiếp theo

  - [Chuẩn bị mô hình với modelctl](/vi/configure/prepare-models/) — Toàn bộ quy trình convert → validate → quantize → package và tham chiếu flag.
  - [Thực hành tốt nhất với modelctl](/vi/configure/modelctl-best-practices/) — Nên/không nên: hồ sơ, cổng validate, bundle tái lập, CI.
  - [Triển khai mô hình](/vi/configure/models/) — Tải bundle ONNX lên và dùng mô hình trong một luồng.
