jim800121chen cff9236699 docs: migrate Autoflow shared documents to docs/autoflow/
Move PRD, design specs, architecture docs, and TDD from .autoflow/
(personal/per-branch layer) to docs/autoflow/ (shared layer that
goes into git) per the new Autoflow workspace layout.

Files moved:
- 02-prd/PRD.md
- 03-design/design-review.md
- 03-design/user-flow-cross-system.md
- 04-architecture/TDD.md
- 04-architecture/design-doc.md
- 04-architecture/security.md

The originals were never tracked, so git mv reduced to a filesystem
rename with no history to preserve. .autoflow/ remains for personal
notes (progress.md, review reports, testing logs).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 10:59:21 +08:00

70 KiB
Raw Blame History

Kneron Model Converter - 產品需求文件 (PRD)

文件性質:此 PRD 為從既有程式碼反向整理,尚待產品負責人確認。 標記 [推測] 的部分為從程式碼推斷但無法確認的內容,請使用者審閱時特別留意。

最後更新2026-04-25原始模型上傳路徑變更visionA-backend 直接 multipart 上傳到 Converter不經過 File Access Agent

變更歷程

2026-04-25第二次更新原始模型上傳路徑變更

  • 變更內容原始模型的上傳路徑由「visionA-backend → File Access Agent使用者模型庫→ Converter 用 S2S 從 File Access Agent 拉下來」改為「visionA-backend 直接把原始模型以 multipart 上傳到 Converter跟現有 Web UI 一樣)」。
  • 變更原因:先前 PRD 基於誤解,把使用者模型庫設計為「原始模型的來源」;使用者已澄清,正確設計是「模型庫只在使用者按『加進模型庫』後才存入轉檔結果」。原始模型上傳是從 visionA-backend 直接推給 Converter。
  • 影響章節
    • §4.3F-28 刪除、F-23 描述重寫)
    • §4.4US-08 前置條件與驗收標準重寫)
    • §5.5POST /api/v1/jobs 描述改為 multipart
    • §5.6OAuth2 Client 讀檔相關 scope 移除)
    • §9.2.1POST /jobs 的 p95 目標調整,標註大檔上傳時間不計入)
    • §10路線圖移除「從 File Access Agent 取原始模型」)
    • §14Phase 1 對 File Access Agent 只剩 PUTpromote不需要 GET、HEAD
    • §15Phase 1 Scope 表移除「從 File Access Agent 取原始模型」)
    • §12.2(大檔 promote 風險表述維持;新增 multipart 上傳相關風險)
    • 附錄 A補充本次變更造成的新問題
  • 不影響章節
    • 既有 Persona A / B 定義
    • 既有 US-01 ~ US-07
    • 既有 [推測] 標記
    • US-13promote 流程)
    • US-14Phase 2 delegated download
    • 既有「Crash 即 Reset」設計哲學

2026-04-25首次更新新增 L 級功能(對外 API

將 Kneron Model Converter 從「僅有 Web UI 的內部工具」擴展為「對外提供 OAuth2 保護 REST API 的服務」,讓 Innovedus 生態中的其他服務(首個消費者為 VisionA能以程式化方式呼叫轉檔能力。

新增章節:

  • §1.2 新增 Persona C — 服務消費者visionA-backend
  • §4.3 API 消費者功能總覽Phase 1 / Phase 2 切分)
  • §4.4 新增的 User StoriesUS-08 ~ US-14
  • §5.5 新增 API 端點預告(對外 API / v1
  • §8.1 RICE 新增項目API 對外開放
  • §9.1 新增成功指標API SLA、採用度、錯誤率
  • §14 相依服務(新增章節)
  • §15 Phase 1 / Phase 2 Scope 切分(新增章節)

保留不變:

  • 既有 Persona A / B、既有 User Stories US-01 ~ US-07
  • 既有 Web UI 行為Phase 1 不改 Web UI 流程)
  • 既有「Crash 即 Reset」設計哲學
  • 既有 [推測] 標記(本次不清除,留待使用者決定)

1. 產品策略

1.1 產品願景

一句話描述:讓 AI 工程師能透過 Web 介面,輕鬆地將 AI 模型轉換為可部署到 Kneron AI 晶片的格式,並透過任務佇列機制解決高併發下的效能瓶頸。

背景問題Kneron Toolchain 的模型轉換流程ONNX → BIE → NEF在單一 VM / 單一 Toolchain instance 運行時,高併發場景下會造成 CPU 爆滿與 Crash。現有的轉換方式需要工程師手動操作 CLI 或 Python API缺乏視覺化介面與任務管理能力。

解決方案:建構一個 Web-based 的模型轉換服務採用「Crash 即 Reset」的設計哲學將轉換流程拆分為可水平擴充的 Worker Pool由 Task Scheduler 統一派工與狀態管理,提供即時任務追蹤與結果下載。

1.2 目標用戶Persona

Persona AAI 應用工程師 — 小明

  • 角色AI 應用開發工程師,負責將訓練好的模型部署到 Kneron 晶片
  • 背景:熟悉 Python、ONNX 模型格式,但不一定熟悉 Kneron Toolchain 的底層細節
  • 目標:快速將 ONNX/TFLite 模型轉換為 NEF 格式,部署到 Kneron KDP 系列晶片
  • 痛點
    • 手動使用 Toolchain CLI 操作繁瑣,容易出錯
    • 多人同時轉換時系統容易當機
    • 轉換過程耗時,無法即時掌握進度
  • 技術素養:高
  • 一句話描述:「我希望能一鍵上傳模型就自動完成轉換,這樣我就可以專注在模型調校而非部署工具的操作」

Persona B[推測] 團隊主管 / 技術經理 — 大華

  • 角色:管理多位 AI 工程師的技術主管
  • 目標:提供團隊穩定的模型轉換服務,減少因工具問題導致的開發阻塞
  • 痛點
    • 單人佔用 Toolchain 時其他人無法使用
    • Crash 後需要 IT 介入重啟
    • 缺乏任務可見性,無法掌握團隊的轉換排隊情況
  • 技術素養:高
  • 一句話描述:「我希望團隊能同時使用轉換服務不互相干擾,這樣就不會因為工具問題拖延專案進度」

Persona C服務消費者 — visionA-backend非人類 Persona

注意:這不是一個「使用者」,而是一個「服務」。 Persona C 代表所有以程式化方式呼叫 Kneron Model Converter API 的下游服務。首個消費者為 Innovedus 旗下的 VisionAvisionA-backendGo 服務,路徑:~/visionA/visionA-backend/)。未來可擴展至 Innovedus 生態的其他 vertical 應用。

  • 角色Innovedus 生態中需要「模型轉檔」能力的下游後端服務
  • 當前代表visionA-backendGo / Gin目前處於 Phase 0 雛形,近期進入 Phase 1 將導入 OAuth2/OIDC
  • 目標
    • 讓 VisionA 的終端使用者Edge AI 應用開發者)能在 VisionA 平台內直接觸發模型轉檔,無需離開平台
    • 把轉檔結果自動納入使用者的 VisionA 模型庫(長期儲存於 NAS
    • 不需要自己重新實作 Kneron Toolchain 的封裝
  • 痛點
    • 目前 Kneron Model Converter 只有 Web UI無法以程式化方式整合
    • 沒有標準的 auth 機制,無法對齊 Innovedus 統一的 Member Center OAuth2 體系
    • 沒有檔案搬運 API下游服務無法把轉檔結果搬到自己的長期儲存
    • 缺乏「同使用者同時一個轉檔」的保護,容易讓使用者搞混
    • 沒有 job recovery 能力,使用者離開頁面後回來看不到未完成的任務
  • 技術素養:不適用(服務對服務)
  • 關鍵特性
    • 以 OAuth2 client_credentials 取得 service token 呼叫 Converter API
    • 在 request 中帶 user_idVisionA 端的使用者 IDConverter 信任不驗證;僅用於業務邏輯,非授權邊界);建 job 時 user_id 作為 multipart field查詢 API 作為 query string
    • 直接將原始模型以 multipart 上傳給 Converter(不經過任何中間檔案庫)
    • 透過 polling非 webhook取得轉檔進度
    • 轉檔完成後呼叫 promote API 將結果搬進模型庫
  • 一句話描述:「作為服務,我希望能用標準的 OAuth2 service token 呼叫 Converter API讓我的使用者能在我的平台內完成模型轉檔同時不用自己處理 Kneron Toolchain 的複雜度」

間接使用者VisionA 終端使用者

雖然他們不直接接觸 Converter API但他們是最終受益者

  • 角色VisionA 平台上的 Edge AI 應用開發者
  • 感受到的能力:在 VisionA 模型庫內可以「把模型送去轉檔」、「看進度」、「把結果加進模型庫」
  • 他們不會知道背後是另一個服務Kneron Model Converter在處理也不會直接和它溝通
  • 關鍵體驗要求
    • 同時只能有一個轉檔進行中(避免搞混)
    • 離開頁面再回來能看到未完成的任務
    • 轉檔失敗時能看到具體原因

1.3 核心問題與價值主張

核心問題 價值主張
單一 Toolchain instance 無法承受高併發 Worker Pool 水平擴展,多任務平行處理
模型轉換操作繁瑣CLI / Python API Web UI 提供視覺化操作介面
轉換進度不透明 SSE 即時推送任務狀態
Crash 後恢復困難 「Crash 即 Reset」哲學無狀態設計重啟即恢復服務
多人共用時互相干擾 任務佇列隔離,每個 Worker 獨立處理

1.4 OKR [推測]

Objective提供穩定、高效的 AI 模型轉換服務

  • KR1系統可同時處理 N 個轉換任務(透過 Worker 水平擴展)
  • KR2單一任務的轉換成功率 > 95%(排除模型本身問題)
  • KR3系統 Crash 後 < 30 秒恢復服務能力

1.5 北極星指標與指標體系 [推測]

北極星指標:每日成功轉換任務數
  ├── 驅動指標:任務提交數、轉換成功率、平均轉換時間
  │     ├── 輸入指標Web UI 使用率、API 呼叫次數
  │     ├── 輸入指標各階段ONNX/BIE/NEF失敗率
  │     └── 輸入指標Worker 利用率
  └── 護欄指標Worker Crash 率、Redis 記憶體使用量、佇列堆積長度

2. 市場分析 [推測]

2.1 市場定位

此產品為 內部工具 / 企業內部服務,主要服務 Kneron 內部或其客戶的 AI 工程團隊。非面向公開市場的 SaaS 產品。

2.2 競品對照

方案 類型 優勢 劣勢 與本產品差異
Kneron Toolchain CLI 原生 CLI 工具 功能完整、官方支援 無 GUI、不支援併發、操作門檻高 本產品是其 Web 化包裝
Kneron Toolchain Web GUI原版 官方 Web GUI 有介面 單一 instance、Crash 問題 本產品解決了其效能與穩定性瓶頸
Edge Impulse 雲端 ML 平台 完整 MLOps 流程 不支援 Kneron 特定格式 本產品專注 Kneron 晶片生態
TensorFlow Lite Converter Google 官方工具 生態完整 只支援 TFLite 格式 本產品支援 Kneron 特有的 BIE/NEF 格式

2.3 差異化策略

  • 唯一性:唯一支援 Kneron KDP 系列晶片完整轉換流程ONNX → BIE → NEF的 Web 服務
  • 護城河:與 Kneron Toolchain 深度整合,封裝其 Python API
  • 關鍵優勢Worker Pool 架構解決了原生 Toolchain 的併發瓶頸

3. 用戶研究

3.1 用戶旅程地圖

階段 用戶行為 想法/感受 痛點 機會點
模型準備 訓練好模型,匯出 ONNX/TFLite 「模型訓練完成,該部署了」 需要確認模型格式相容性 [推測] 提供模型格式驗證
上傳模型 透過 Web UI 上傳模型檔 + 參考圖片 「介面還算直覺」 大檔案上傳可能較慢(上限 500MB 上傳進度顯示
設定參數 選擇平台、填寫 Model ID / Version 「這些參數是什麼意思?」 參數含義不夠直覺 [推測] 提供參數說明 / 預設值
等待轉換 觀察 SSE 即時進度更新 「大概還要多久?」 只有階段進度,無時間預估 [推測] 加入預估剩餘時間
下載結果 下載 BIE/NEF 產出檔 「轉換完成,可以部署了」 - -
失敗處理 看到失敗訊息,需要重新提交 「為什麼失敗?該怎麼修?」 錯誤訊息可能不夠友善 [推測] 提供更詳細的錯誤診斷

4. 功能需求

4.1 功能總覽與狀態

# 功能 狀態 說明
F-01 模型檔案上傳 已實作 支援 ONNX、TFLite 格式,上限 500MB
F-02 參考圖片上傳 已實作 BIE 量化用的參考圖片(最多 100 張)
F-03 完整轉換流程ONNX → BIE → NEF 已實作 固定三階段序列化流程
F-04 單階段轉換ONNX 優化) UI 已實作,後端部分實作 Web UI 有獨立 ONNX 表單,但後端 API 僅有完整流程端點
F-05 單階段轉換BIE 量化) UI 已實作,後端部分實作 同上
F-06 單階段轉換NEF 編譯) UI 已實作,後端部分實作 同上
F-07 任務狀態即時更新SSE 已實作 Server-Sent Events + Polling 備援
F-08 任務狀態查詢REST API 已實作 GET /jobs/:jobId
F-09 任務列表查詢 已實作 GET /jobs
F-10 結果檔案下載 已實作 GET /jobs/:jobId/download/:filename
F-11 Worker 水平擴展 已實作 docker-compose --scale
F-12 Stub Worker 開發模式 已實作 WORKER_MODE=stub 模擬處理
F-13 IP 評估(可選) 已實作 enable_evaluate 旗標
F-14 浮點 E2E 模擬 未完成 enable_sim_fp 旗標已定義,邏輯未接線
F-15 定點 E2E 模擬 未完成 enable_sim_fixed 旗標已定義,邏輯未接線
F-16 硬體 E2E 模擬 未完成 enable_sim_hw 旗標已定義,邏輯未接線
F-17 健康檢查 API 已實作 GET /health
F-18 [推測] 任務取消 未實作 目前無法中途取消進行中的任務
F-19 [推測] 任務重試 未實作 符合「Crash 即 Reset」哲學失敗需手動重送
F-20 [推測] 歷史任務持久化 未實作 Redis 重啟即清空,無持久化

4.2 User Stories

US-01上傳模型並執行完整轉換

作為 AI 應用工程師, 我希望 上傳 ONNX/TFLite 模型檔和參考圖片,設定目標平台後一鍵啟動轉換, 以便 自動完成 ONNX 優化 → BIE 量化 → NEF 編譯的完整流程,取得可部署到 Kneron 晶片的 NEF 檔。

驗收標準

  • 支援上傳 .onnx 和 .tflite 格式檔案
  • 必填參數model_id、version、platform
  • 支援平台KDP520、KDP720、KDP530、KDP630、KDP730
  • 上傳成功後自動進入 ONNX → BIE → NEF 流程
  • 狀態:已實作

US-02即時追蹤轉換進度

作為 AI 應用工程師, 我希望 在提交任務後能即時看到目前處於哪個階段ONNX/BIE/NEF以及進度百分比 以便 掌握任務狀態,不需要反覆手動刷新。

驗收標準

  • 透過 SSE 即時推送狀態更新
  • SSE 斷線時自動降級為每 3 秒 Polling
  • 顯示當前階段名稱與進度百分比
  • 任務完成或失敗時顯示對應通知
  • 狀態:已實作

US-03下載轉換結果

作為 AI 應用工程師, 我希望 轉換完成後能直接從 Web UI 下載產出的 NEF 檔(或中間產物 BIE 以便 取得可部署的模型檔案。

驗收標準

  • 任務 COMPLETED 後提供下載按鈕
  • 支援下載 out.onnx、out.bie、out.nef
  • 狀態:已實作

US-04選擇單階段處理

作為 AI 應用工程師, 我希望 能選擇只執行某一個階段(例如只做 ONNX 優化,或只做 BIE 量化), 以便 在除錯時逐步確認每個階段的輸出正確性。

驗收標準

  • Web UI 提供四種工作流程選擇ONNX 優化 / BIE 量化 / NEF 編譯 / 完整流程
  • 各流程有獨立的參數表單
  • 狀態:UI 已實作,後端 API 部分實作Web UI 的前端表單呼叫的 API 端點如 /api/onnx/upload/api/bie/process 尚未在 Task Scheduler 中實作,後端目前僅支援 POST /jobs 建立完整流程任務)

US-05水平擴展 Worker

作為 系統管理員, 我希望 能透過簡單的指令增加 Worker 數量, 以便 在任務量大時提升系統處理能力。

驗收標準

  • 透過 docker-compose up --scale bie-worker=N 即可擴展
  • 新 Worker 自動加入 Consumer Group 分配任務
  • 不需修改任何設定檔或重啟其他服務
  • 狀態:已實作

US-06[推測] 查看失敗原因

作為 AI 應用工程師, 我希望 任務失敗時能看到具體的錯誤原因與失敗階段, 以便 判斷是模型問題還是系統問題,並採取對應措施。

驗收標準

  • 失敗任務顯示失敗的階段ONNX/BIE/NEF
  • 顯示錯誤原因文字
  • 狀態:已實作job record 中有 error.step 和 error.reason

US-07開發與測試用 Stub 模式

作為 開發人員, 我希望 能在不安裝 Kneron Toolchain 的情況下啟動整套系統進行開發測試, 以便 快速迭代 Scheduler、Web UI 和佇列邏輯。

驗收標準

  • 設定 WORKER_MODE=stub 即可啟用
  • Stub Worker 模擬處理時間2-3 秒)並產生假輸出檔
  • 完整流程可走通SSE 通知正常運作
  • 狀態:已實作

4.3 API 消費者功能總覽新增2026-04-25

本節說明本次 L 級更新的新功能範圍。所有新功能都是針對 Persona C服務消費者 設計,並以「讓 VisionA 終端使用者獲得完整模型轉檔體驗」為最終目標。

# 功能 狀態 Phase 說明
F-21 OAuth2 Resource Server驗 visionA-backend 的 service token 未實作 Phase 1 以 Member Center JWKS 驗簽 JWT檢查 aud=kneron_converter_api 與 scope
F-22 OAuth2 ClientConverter 自己取 service token 未實作 Phase 1 client_credentials 向 Member Center 取 token供 PUT 檔案到 File Access Agentpromote 時使用)
F-23 對外 API: 建立轉檔 jobPOST /api/v1/jobs 未實作 Phase 1 multipart/form-data 格式(跟現有 Web UI 一致visionA-backend 直接把原始模型上傳到 Converterbody 帶 user_id + model(原始模型檔)+ ref_images[](可選)+ 參數
F-24 對外 API: 查詢 job 進度(GET /api/v1/jobs/:id 未實作 Phase 1 Polling 模式,回傳 status、stage、progress、error
F-25 對外 API: 查詢 job 列表(GET /api/v1/jobs?user_id=...&status=... 未實作 Phase 1 支援 recovery 場景(使用者離開頁面回來)
F-26 對外 API: 搬檔到模型庫(POST /api/v1/jobs/:id/promote 未實作 Phase 1 Converter 自己用 service token PUT 結果檔到 File Access Agent
F-27 同使用者同時一個轉檔限制 未實作 Phase 1 建 job 時檢查 user_id 是否有 in-progress job有則拒絕
F-29 OpenAPI 規格(對外 API 契約) 未實作 Phase 1 產出 OpenAPI 3.0 spec方便下游服務整合與測試
F-30 使用者下載模型delegated token 直連 File Access Agent 未實作 Phase 2 阻塞Member Center POST /file-access/download-tokens 尚未實作

2026-04-25 變更):原 F-28「從 File Access Agent 取 input 模型」已刪除。Phase 1 的原始模型上傳改為由 visionA-backend 直接 multipart 上傳到 Converter見 F-23不再經過 File Access Agent。

Phase 1 / Phase 2 切分原因Phase 2 的「使用者下載」依賴 Member Center 的 delegated token endpoint但該 endpoint 目前尚未實作。為避免阻塞 Phase 1 整體上線Phase 1 先讓 VisionA 能完成「上傳 → 轉檔 → 搬進模型庫」閉環,下載則等 Member Center 補完後再做。詳見 §15。

4.4 新增 User Stories2026-04-25

US-08visionA-backend 以 service token 建立轉檔 job

作為 visionA-backend服務消費者 我希望 用 OAuth2 service token 呼叫 Converter API 建立轉檔 job 以便 讓我的使用者能在 VisionA 平台內觸發模型轉檔,而不用跳到另一個系統。

前置條件

  • visionA-backend 已取得終端使用者要轉檔的原始模型檔案(由 VisionA 自己的上傳流程收到,保存在 visionA-backend 自己可存取的位置)
  • visionA-backend 已向 Member Center 取得 service tokenaud=kneron_converter_api, scope=converter:job.write

驗收標準

  • POST /api/v1/jobsContent-Type: multipart/form-dataHeader: Authorization: Bearer <service_token>
  • multipart files
    • model(必填,原始模型檔,支援 .onnx / .tflite,單檔 ≤ 500MB
    • ref_images[]可選BIE 量化用參考圖片,最多 100 個)
  • multipart fields
    • user_id必填VisionA 使用者 ID字串
    • model_id必填Integer165535
    • version(必填,字串,如 "0001"
    • platform(必填,字串,"520" / "720" / "530" / "630" / "730"
    • enable_evaluate可選Boolean預設 false
    • enable_sim_fp可選Boolean預設 false未接線
    • enable_sim_fixed可選Boolean預設 false未接線
    • enable_sim_hw可選Boolean預設 false未接線
  • Converter 驗證 token 簽章、audscope,失敗則回 401 / 403
  • 驗證通過後Converter 把原始模型存到 Converter Bucket例如 jobs/{job_id}/input/{filename}),由既有 Worker 流程處理(與現有 Web UI 走 POST /jobs 的儲存路徑一致)
  • 建 job 成功回 201 Createdbody 含 job_idstatus=created
  • 若該 user_id 已有進行中 jobstatus ∈ {created, running}),回 409 Conflictbody 含現有 job_id詳見 US-11
  • 若 multipart 欄位缺漏、檔案超過 500MB、模型格式非 .onnx / .tflite、platform 不支援,回 400 Bad Request
  • 設計備註:此路徑刻意與既有 Web UI 的 POST /jobsPhase 1 內部路徑)走同一份 multipart 上傳行為以最大化重用既有上傳處理邏輯multer memory storage、檔案大小限制、Worker 派工)。差異僅在:/api/v1/jobs 多驗 OAuth token、必填 user_id、多檢查 US-11 的同使用者同時限制。
  • 狀態:未實作Phase 1 必做)

US-09追蹤轉檔進度polling

作為 VisionA 終端使用者(透過 visionA-backend 我希望 在觸發轉檔後能看到目前進度(哪個階段、百分比), 以便 知道還要多久、是否成功。

驗收標準

  • visionA-backend 以固定間隔呼叫 GET /api/v1/jobs/:id(建議 2-5 秒一次)
  • 回傳 body 含:statuscreated / running / completed / failedstageonnx / bie / nefprogress0-100error(失敗時)、result_object_keys(完成時,各輸出檔在 Converter MinIO 的暫存 key
  • visionA-backend 將此資訊轉化為 VisionA UI 要顯示的進度條
  • 不做 Webhook / SSE 對外推送Phase 1 範圍內polling 已足夠)
  • job_id 不存在或不屬於呼叫者的 tenant404
  • 狀態:未實作Phase 1 必做)

US-10轉檔完成後加進模型庫

作為 VisionA 終端使用者(透過 visionA-backend 我希望 轉檔完成後可以選擇「加進我的模型庫」, 以便 結果被長期保存到 NAS而不是留在 Converter 的暫存區等 7 天後被清掉。

驗收標準

  • visionA-backend 呼叫 POST /api/v1/jobs/:id/promotebody 帶目標 object_keyVisionA 端決定命名,例如 visionA/models/{user_id}/{model_id}/v{version}/out.nef
  • Converter 自己用 service tokenscope=files:upload.writePUT 檔案到 File Access Agent
  • 檔案流只在 NAS 側流動Converter → File Access Agent → NAS Bucket不透過 visionA-backend 中轉
  • 成功回 200 OKbody 含已搬檔的 object_key 列表
  • 若 job 尚未 completed 或已 failed409 Conflict
  • 若 promote 過程失敗File Access Agent 不可用、auth 問題等),回 502 Bad Gateway,並可重試
  • Converter Bucket 的暫存檔仍保留直到 7 天 lifecycle 到期(不立即刪除,以利失敗重試)
  • 狀態:未實作Phase 1 必做)

US-11同使用者同時一個轉檔

作為 VisionA 終端使用者(透過 visionA-backend 我希望 系統限制同一個使用者同時只能進行一個轉檔, 以便 我不會被多個同時進行的轉檔搞混,也避免意外消耗 Worker 資源。

驗收標準

  • Converter 在建 job 時檢查該 user_id 是否已有 status ∈ {created, running} 的 job
  • 若有,回 409 Conflictbody 範例:{"error":"user_has_active_job","active_job_id":"..."}
  • 限制作用於 user_idVisionA 使用者),不是 client_id(同一個 VisionA backend 服務可以同時有多個不同使用者的轉檔)
  • 此為「產品面軟限制」非「授權邊界」Converter 只是信任 visionA-backend 傳來的 user_id
  • 狀態:未實作Phase 1 必做)

US-12離開頁面 recovery

作為 VisionA 終端使用者(透過 visionA-backend 我希望 離開轉檔頁面再回來時,能看到我之前未完成的 job 以便 不用重新送一次或擔心轉檔結果遺失。

驗收標準

  • visionA-backend 進入轉檔頁面時呼叫 GET /api/v1/jobs?user_id=...&status=in_progressin_progresscreated + running 的總稱)
  • Converter 回傳該使用者所有進行中的 job 清單Phase 1 同時至多 1 個,但 API 設計為 list 以保彈性)
  • visionA-backend 根據清單決定是否顯示「有未完成的轉檔,是否繼續追蹤?」的 UI
  • 同時支援 status=completed / status=failed(近期完成)、limitoffset 參數
  • 注意Converter 本身仍遵循「Crash 即 Reset」哲學Redis 重啟後 job 會消失。recovery 僅在 Converter 正常運行期間有效,不保證跨 Crash 可恢復
  • 狀態:未實作Phase 1 必做)

US-13Converter 自己搬檔避免大檔跨網段傳輸

作為 visionA-backend 我希望 呼叫 Converter 搬檔時Converter 能自己把檔案推到 File Access Agent 以便 避免大檔(可能數百 MB跨 AWS ↔ NAS 來回傳輸Converter → visionA-backend → File Access Agent 會慢且貴)。

驗收標準

  • POST /api/v1/jobs/:id/promote 的實作中Converter 直接從自己的 MinIO 讀檔,然後 PUT 到 File Access Agent
  • visionA-backend 不接觸檔案實體,只接收 promote API 的成功/失敗結果
  • Converter 以自己的 OAuth2 client_credentials 向 Member Center 取得 files:upload.write scope 的 tokennon-user-bound service token
  • File Access Agent 以 Member Center JWKS 驗該 token檢查 aud=file_access_apiscope=files:upload.writetenant_id 吻合
  • 狀態:未實作Phase 1 必做)

US-14【Phase 2】使用者下載模型走 delegated token

作為 VisionA 終端使用者, 我希望 從 VisionA 模型庫下載已搬進 NAS 的模型檔時,瀏覽器能直連 File Access Agent帶短效 delegated token 以便 大檔不必經過 visionA-backend 中轉,下載快速且省流量。

前置條件(阻塞)

  • Member Center 已實作 POST /file-access/download-tokens(目前狀態:未實作

驗收標準Phase 2

  • visionA-backend 呼叫 Member Center 的 POST /file-access/download-tokensscope=files:download.delegate),傳入 tenant_iduser_idobject_key
  • Member Center 回傳短效 opaque token建議 exp <= 5 分鐘
  • visionA-backend 把 token 回給瀏覽器,瀏覽器直連 GET https://<file-access-agent>/files/{object_key}?token=<delegated_token>
  • File Access Agent 呼叫 Member Center validation endpoint 線上驗 token驗過才回檔案
  • 此 User Story 不涉及 Converter API 的修改,只是 VisionA ↔ Member Center ↔ File Access Agent 的串接
  • 狀態:未實作Phase 2等 Member Center 補完後啟動)

阻塞觸發條件

  • Member Center owner 確認 POST /file-access/download-tokens 的實作時程,並提供測試環境
  • 或者 VisionA 團隊決定自己暫時 proxy 下載(折衷方案,需另議)

5. 系統架構摘要(從程式碼確認)

5.1 服務元件

元件 技術 職責
Web UI Vue 3 + Vite + Element Plus 使用者操作介面
Nginx Alpine 反向代理、靜態檔案服務、SSE 轉發
Task Scheduler Node.js + Express REST API、Job 狀態管理、Queue 派工、SSE 推送
Redis Redis 7 Alpine不開 persistence Job 狀態儲存、任務佇列Redis Stream
ONNX Worker Python ONNX 優化 / TFLite 轉換
BIE Worker Python 量化分析
NEF Worker Python NEF 編譯
Shared Volume Docker named volume Worker 間的檔案交換

5.2 API 端點(已實作)

方法 路徑 說明
GET /health 健康檢查
POST /jobs 建立新任務(上傳模型 + 參考圖片 + 參數)
GET /jobs 列出所有任務
GET /jobs/:jobId 查詢單一任務狀態
GET /jobs/:jobId/events SSE 事件串流
GET /jobs/:jobId/download/:filename 下載結果檔案

5.3 任務參數

參數 必填 類型 說明
model檔案 File ONNX 或 TFLite 模型檔
ref_images檔案 File[] 量化用參考圖片(最多 100 張)
model_id Integer 模型 ID1-65535
version String 模型版本(如 "0001"
platform String 目標平台("520"/"720"/"530"/"630"/"730"
enable_evaluate Boolean 是否執行 IP 評估(預設 false
enable_sim_fp Boolean 是否執行浮點 E2E 模擬(預設 false未接線
enable_sim_fixed Boolean 是否執行定點 E2E 模擬(預設 false未接線
enable_sim_hw Boolean 是否執行硬體 E2E 模擬(預設 false未接線

5.4 任務狀態機

建立 → ONNX → BIE → NEF → COMPLETED
         ↓       ↓       ↓
       FAILED  FAILED  FAILED
  • 流程固定ONNX → BIE → NEF不支援跳過或只跑部分後端限制
  • 任何階段失敗即整體 FAILED不自動重試

5.5 對外 API 端點預告新增2026-04-25待 Architect 產出詳細規格)

本節只列出 PRD 層級 的功能與驗收要點,詳細 API 規格request / response schema、錯誤碼、範例由 Architect Agent 在 04-architecture/TDD.md04-architecture/api/api-external.md 中定義。

Base Path/api/v1(與既有內部 API 區隔,讓 Web UI 繼續用舊的 /jobs,對外走新版)

Auth:所有端點都需要 Authorization: Bearer <service_token>token 需滿足:

  • 簽發者Innovedus Member Center以 JWKS 驗簽)
  • aud=kneron_converter_api
  • 對應 scope下表列出
方法 路徑 Content-Type 用途 必要 scope 對應 US
POST /api/v1/jobs multipart/form-data 建立轉檔 job直接上傳原始模型 converter:job.write US-08, US-11
GET /api/v1/jobs/:id 查詢單一 jobpolling converter:job.read US-09
GET /api/v1/jobs 查詢 job 列表recovery converter:job.read US-12
POST /api/v1/jobs/:id/promote application/json 搬檔到模型庫 converter:job.write US-10, US-13

POST /api/v1/jobs 採 multipart/form-data 是刻意選擇,與既有 Web UI POST /jobs 一致,讓 visionA-backend 直接把原始模型推給 Converter。不使用「body 帶 object_keyConverter 再去 File Access Agent 拉檔」的設計(詳見 §4.4 US-08、§14.2)。

Phase 1 明確不做的端點

  • Webhook 回呼不做polling 已足夠)
  • Cancel job延後到未來既有專案本來就沒有
  • Delegated download 相關Phase 2

scope 命名:上述命名為 PM 建議Architect 需與 Member Center owner 對齊最終名稱。若 Member Center 已有命名慣例則採用其慣例。

5.6 Auth / 身分識別模型新增2026-04-25

本節定義 Converter 在新 API 中的雙重身分與 user_id 傳遞策略。

Converter 作為 OAuth2 Resource Server

  • 驗證 visionA-backend或其他未來消費者送來的 service token
  • 驗證項目JWT 簽章Member Center JWKSissaud=kneron_converter_apiexp、必要 scope
  • 不驗證使用者身分token 是 service-to-serviceclient_credentialsclaim 裡沒有 user_id

Converter 作為 OAuth2 Client

  • 使用自己的 client_id=kneron_converter(需在 Member Center 註冊)
  • client_credentials grant 取得 token
  • 取得後用於:
    • PUT 結果檔到 File Access Agentscope=files:upload.writepromote 時使用,見 US-10 / US-13
  • Phase 1 Converter 完全不從 File Access Agent「讀」任何東西(原始模型改由 visionA-backend 直接 multipart 上傳,見 US-08。因此 Phase 1 不需要 files:download.readfiles:metadata.read 等讀取類 scope。

user_id 傳遞策略(方式 Arequest payload

  • visionA-backend 在對外 API 中以 request payload(非 JWT claim非 HTTP header傳遞 user_id
    • POST /api/v1/jobsuser_id 作為 multipart form field
    • POST /api/v1/jobs/:id/promoteuser_id 作為 JSON body 欄位(若 promote API body 需要;若不需要,由 :id 反查即可)
    • GET /api/v1/jobs?user_id=...listGET /api/v1/jobs/:idsingleConverter 會在內部比對 job 的 user_iduser_id 作為 query string
  • Converter 信任 visionA-backend 送的 user_id不驗證
  • user_id 的用途:
    • 業務邏輯同使用者同時一個轉檔的限制US-11
    • recovery 的 job 列表過濾US-12
  • user_id 不是授權邊界Converter 不負責判斷「某個 user 能不能做某件事」,授權邊界由 visionA-backend 自己管
  • 選擇方式 A 而非「把 user_id 放 token claim」的原因visionA-backend 是 service-to-service token非 user-bound硬塞 user_id 進 claim 會破壞 OAuth2 semantics
  • 選擇方式 A 而非「自訂 header如 X-User-Id」的原因delegation model 跟 payload 一起走、API 審計可讀性較好,且 multipart 本來就要帶其他欄位user_id 放在一起語意一致

重要:不做的事

  • Converter 呼叫 Member Center 驗證 user_id 是否存在(相信 visionA-backend
  • Converter 在 job 上做 user 層級的 ACL例如「user A 不能看到 user B 的 job」這由 visionA-backend 自己管Converter 只是按 user_id 過濾查詢結果

6. 非功能需求

6.1 效能需求

項目 需求 現況
併發任務數 取決於 Worker 數量(每 Worker 一次處理一個任務) 已實作(水平擴展)
檔案上傳上限 500 MB 已實作
API Rate Limit 每 15 分鐘 200 次請求 已實作
SSE 心跳 每 15 秒 已實作

6.2 安全性需求

項目 需求 現況
HTTP 安全標頭 X-Frame-Options, X-Content-Type-Options, X-XSS-Protection 已實作Nginx + Helmet
容器安全 非 root 用戶運行 Task Scheduler 已實作
API Key 認證 [推測] 應有 API Key 或其他認證機制 未實作(開發環境硬編碼)
Redis 認證 Redis 應有密碼保護 未實作
HTTPS 生產環境需 TLS 未實作
輸入驗證 檔案類型/大小驗證 部分實作(大小有限制,類型由前端限制)

6.3 可用性需求

項目 需求 現況
Crash Recovery 服務重啟後自動恢復可用 已實作Crash 即 Reset
容器自動重啟 服務異常時自動重啟 已實作restart: unless-stopped
健康檢查 Redis 連線狀態監控 已實作GET /health
[推測] 監控告警 系統指標監控與告警 未實作
[推測] 日誌收集 集中式日誌管理 未實作(僅 console 輸出)

6.4 可擴展性

項目 需求 現況
Worker 水平擴展 動態增減 Worker 數量 已實作
[推測] 跨主機部署 多台主機分散 Worker 未實作(目前用 Shared Volume未來規劃 MinIO
[推測] Scheduler HA 多個 Scheduler instance 明確列為 Non-goal

7. 系統限制與假設

7.1 設計決策Non-goals從設計文件確認

以下為刻意的設計取捨,不是缺陷

  1. 不做任務持久化 — Redis 重啟即清空所有任務
  2. 不做 Crash 後恢復 — 進行中的任務在 Crash 後消失
  3. 不做 exactly-once / at-least-once 保證 — 任務可能因 Crash 而遺失
  4. 不做 Scheduler HA — 單一 Scheduler instance
  5. 不做自動重試 — 失敗即 FAILED由使用者手動重送
  6. 轉換流程固定 — 必須走完 ONNX → BIE → NEF不支援跳過

7.2 技術假設

  1. 所有 Worker 需掛載相同的 Docker Volume 才能存取共享檔案
  2. Worker 需要 Kneron Toolchain Python 環境(或使用 Stub 模式)
  3. Redis 不開啟 persistence符合「Crash 即 Reset」哲學
  4. [推測] 目標部署環境為 Linux Docker 環境

7.3 已知限制

  1. 前端 UI 的單階段 API 端點(/api/onnx/upload/api/bie/process 等)在後端尚未實作,前後端 API 契約不一致
  2. Simulator 功能(浮點/定點/硬體模擬)旗標已定義但邏輯未接線
  3. 任務列表使用 redis.keys('job:*') 掃描,任務量大時效能可能有問題 [推測]
  4. 檔案上傳使用 memory storagemulter.memoryStorage()),大檔案可能導致記憶體壓力

8. 功能優先排序RICE

以下 RICE 評分為從程式碼推斷的優先級建議Reach 與 Confidence 為推測值Effort 需 Architect 確認。

8.1 RICE 評分表(含 2026-04-25 新增項目)

# 功能 Reach Impact Confidence Effort (人週) RICE 分數 階段
F-21~29 API 對外開放 Phase 1OAuth2 + 對外 API + promote + recovery 100% 3 70% 4 53 本次 Phase 1
F-30 Phase 2 使用者下載delegated token 100% 2 40% 1 80 Phase 2阻塞中
F-14~16 E2E 模擬(浮點/定點/硬體) 80% 2 60% 3 32 Phase 2
F-04~06 單階段轉換 API後端 70% 2 80% 1.5 75 Phase 2
- 前後端 API 契約對齊 100% 3 90% 1 270 急迫
- Redis 認證 + HTTPS 100% 2 90% 1 180 Phase 1
F-18 任務取消 [推測] 50% 1 50% 2 13 Phase 3
F-20 歷史任務持久化 [推測] 60% 1.5 40% 3 12 Phase 3
- 跨主機部署MinIO 30% 2 70% 4 11 Later
- 監控與告警 80% 1.5 70% 2 42 Phase 2
- 錯誤訊息改善 [推測] 80% 1 60% 0.5 96 Phase 1
- 轉換時間預估 [推測] 70% 0.5 40% 1 14 Phase 3

8.2 API 對外開放Phase 1RICE 推論說明

  • Reach = 100%100% 指「所有未來要整合 Converter 的下游服務」都需要此能力不是終端使用者數。Phase 1 首個消費者是 visionA-backend但架構設計為可擴展未來 Innovedus 其他 vertical
  • Impact = 3最高:沒有 APIVisionA 就無法整合,整個合作關係無法成立。屬於「關鍵路徑」。
  • Confidence = 70%OAuth2 / File Access Agent僅 upload 方向)/ Member Center 三邊整合有不確定性(特別是 scope 命名、client 註冊流程、tenant_id 策略),實作細節待與兩個服務 owner 對齊。
  • Effort = 4 人週:涵蓋 OAuth middleware、client 實作、multipart 上傳整合對外 API、promote API、user_id 相關業務邏輯、recovery API、OpenAPI 規格產出、整合測試。待 Architect Agent 在 TDD 中精確估算(2026-04-25 變更後Phase 1 不含「從 File Access Agent 取原始模型」的整合工作Architect 可視情況調低 Effort)。
  • RICE = 53:分數看起來不高是因為 Effort 較大,但此功能屬於「解鎖型」——不做就無法開始整個商業合作,性質上是 P0RICE 分數在此僅作排序參考,不應作為 go/no-go 的唯一依據。

8.3 商業效益(預期)

指標 Phase 1 上線前 Phase 1 上線後(預期) 備註
下游服務整合可能性 0無 API 1+VisionA 未來可擴展
VisionA 使用者轉檔路徑 N/A無法使用 Converter 平台內一站完成 降低切換成本
手動操作步驟(從模型到 NAS 5+ 步(上傳 Web UI → 轉檔 → 下載 → 上傳到 VisionA → 搬到 NAS 2 步(在 VisionA 選模型 → 按轉檔) 使用者體驗大幅改善
服務耦合度 緊耦合(各服務自己做) 鬆耦合(經 OAuth2 契約) 可維護性

注意:上述「預期」為 PM 推論,實際採用率與整合價值需 Phase 1 上線後用 §9 的成功指標追蹤。

RICE 公式

RICE = (Reach x Impact x Confidence) / Effort


9. 成功指標KPI

9.1 既有指標 [推測] 為建議性質,需與產品負責人確認是否適用。 9.2 新增指標2026-04-25專門針對 API 對外開放功能。

9.1 既有成功指標 [推測]

類別 指標 建議目標值 追蹤方式
穩定性 系統 uptime > 99%(工作時段) 健康檢查 API 監控
效率 轉換成功率 > 95% Job COMPLETED / 總 Job
效率 平均轉換時間 視模型大小而定 Job created_at → completed_at
容量 每日處理任務數 視團隊規模而定 Job 計數
體驗 任務佇列等待時間 < 5 分鐘 入 Queue 到 Worker 開始處理
可用性 Crash 後恢復時間 < 30 秒 Docker restart 時間

9.2 API 對外開放 成功指標新增2026-04-25

9.2.1 API SLA品質指標

指標 目標值 護欄(不能低於) 追蹤方式
API 可用率(/api/v1/* 非 5xx 的比率) > 99.5%(工作時段) 99% Nginx access log + 監控
API p95 回應時間GET /jobs/:id < 200ms 500ms APM / 自建時間戳
API p95 server-side 處理時間POST /jobs < 500ms不含 multipart 上傳時間,計算從 Converter 收到整份 body 後的處理時間) 2s APMserver-side 埋點,從 body 完整接收到回 201 的時間)
端到端回應時間POST /jobs含上傳 取決於檔案大小與網路;大檔上傳時間不計入 API p95 SLA 由 visionA-backend 側觀測,作為 UX 指標而非服務 SLA
API p95 回應時間POST /jobs/:id/promote < 3s含 PUT 到 File Access Agent 10s APM
OAuth token 驗證失敗率401 / 403 < 1%(排除 token 過期正常情況) 5% Nginx log 分類統計

2026-04-25 變更):原 POST /jobs p95 目標「< 2s含從 File Access Agent 下載原始模型)」已調整。現行設計為 visionA-backend 直接 multipart 上傳原始模型,因此 API SLA 分兩層:

  • server-side 處理時間Converter 收完 multipart body 後的處理邏輯(驗 token、存檔到 Bucket、建 job record、派工到 Queue— 這是 Converter 可控的 SLA。
  • 端到端上傳時間:包含大檔上傳網路傳輸時間(可能數百 MB受限於 visionA-backend ↔ Converter 網路頻寬與檔案大小,不納入 API p95 SLA改由 visionA-backend 側追蹤作為使用者體驗指標。

9.2.2 API 採用度指標(成長指標)

指標 目標Phase 1 上線後 3 個月) 追蹤方式
每月透過 API 建立的 job 數 由 visionA 的使用量決定,設 baseline job 來源標記API vs Web UI
API job 占總 job 的比例 > 30%Phase 1→ > 60%6 個月) 同上
promote 成功率(搬進模型庫) > 90% promote API 成功/總呼叫
離開頁面 recovery 使用率(有 in-progress 時回來查看) 不設硬目標,但要能觀測 GET /api/v1/jobs?status=in_progress 呼叫次數
同使用者 409 Conflict 比率US-11 觸發) < 5%(表示大多數使用者理解限制) Conflict 回應計數 / 總 POST /jobs

9.2.3 錯誤率護欄

指標 護欄(不能超過) 觸發動作
Auth failure rate 5% 檢查 Member Center JWKS 是否可達、scope 設定
Promote 失敗率5xx 類) 5% 檢查 File Access Agent 連線、Converter service token 有效性
File Access Agent 連線失敗率 2% 跨服務網路問題警報
Converter 自己的 service token 取用失敗率 1% Member Center 連線問題

9.2.4 使用者體驗指標(透過 visionA 間接觀察)

指標 目標 追蹤方式
同使用者同時一個轉檔的限制被使用者理解率(不會重複嘗試) 連續同 user_id 在短時間內的 409 次數
recovery 成功率(使用者離開頁面回來能看到 job > 95%Converter 正常運行期間) visionA 側埋點

追蹤工具建議(待 Architect 決定)

  • API layer 埋點Nginx access log + 自訂結構化 log
  • 指標聚合Prometheus + Grafana與既有監控對齊如有
  • 失敗類別拆分:在 Scheduler 層記錄 error codeauth_failed / promote_failed / input_fetch_failed 等)

注意:上述目標值為 PM 提案,具體數字需 Phase 1 上線前與 SRE / 監控負責人對齊。沒有歷史資料的指標(例如 API p95需在 Phase 1 beta 期間收集 baseline 後再訂正式 SLA。


10. 策略性路線圖

Now當前 — 已實作 / 急需修復)

  • 完整轉換流程ONNX → BIE → NEF
  • Web UI 基本功能
  • SSE 即時狀態推送
  • Worker 水平擴展
  • Stub Worker 開發模式
  • Docker Compose 一鍵啟動
  • 前後端 API 契約對齊Web UI 的單階段端點在後端未實作)

NextPhase 1 — 對外 API + 穩定化與安全性)

本次 L 級新功能主要工作:

  • API 對外開放 Phase 1本次重點
    • OAuth2 Resource Server以 Member Center JWKS 驗 service token
    • OAuth2 ClientConverter 自己取 service tokenpromote 時 PUT 到 File Access Agent
    • 對外 API 路徑:POST /api/v1/jobsmultipartGET /api/v1/jobs/:idGET /api/v1/jobsPOST /api/v1/jobs/:id/promote
    • user_id 業務邏輯同使用者同時一個轉檔、recovery
    • multipart 上傳流程visionA-backend → Converter與現有 Web UI 路徑重用儲存邏輯)
    • 搬結果檔到 File Access Agentpromote
    • OpenAPI 3.0 規格產出與測試
  • 安全性強化Redis 認證、HTTPS原 API Key 由 OAuth2 取代)
  • 錯誤訊息改善(更友善的錯誤描述)
  • 單階段轉換 API後端實作 /api/onnx/process、/api/bie/process、/api/nef/process— 延後至下一波
  • 輸入驗證強化(後端檔案類型驗證)

LaterPhase 2 — 功能擴展)

  • 使用者下載模型走 delegated token(本次 Phase 2阻塞於 Member Center
  • E2E 模擬功能接線(浮點/定點/硬體)
  • 監控與告警系統指標、Worker 狀態、API SLA
  • 日誌收集與集中管理
  • [推測] 批次轉換(多個模型一次提交)
  • Web UI 是否也改走新 OAuth 流程(待決)

FuturePhase 3 — 進階功能)

  • [推測] 任務取消功能
  • [推測] 歷史任務持久化(可選開啟)
  • 跨主機部署MinIO 替換 Shared Volume
  • [推測] 轉換時間預估
  • [推測] 使用者認證與權限管理

11. 支援平台清單(從程式碼確認)

平台代號 平台名稱 備註
520 KDP520 -
720 KDP720 -
530 KDP530 -
630 KDP630 -
730 KDP730 -

12. 風險與緩解

12.1 既有風險(延續)

風險 可能性 影響 緩解措施
Redis Crash 導致所有任務遺失 符合設計哲學,使用者重送即可;未來可考慮 optional persistence
大檔案上傳耗盡 Node.js 記憶體 改用 disk storagemulter.diskStorage替代 memory storage
Worker 處理時間過長佔用資源 [推測] 加入 timeout 機制
前後端 API 不一致造成功能無法使用 優先對齊前後端 API 契約
無認證機制導致未授權存取 Phase 1 以 OAuth2 取代硬編碼
Redis keys 掃描在大量任務時效能劣化 [推測] 改用 Redis Sorted Set 管理任務索引

12.2 本次 L 級新功能風險新增2026-04-25

風險 可能性 影響 緩解措施
Member Center POST /file-access/download-tokens 長期不實作Phase 2 無法啟動 Phase 1 可獨立上線(不依賴此 endpoint定期與 Member Center owner 同步;必要時 VisionA 做 proxy 下載作為 fallback
File Access Agent 部署位置 / tenant_id 未定promote 整合測試被阻塞 盡早與 File Access Agent owner 對齊部署計畫;若必要 Converter 開發環境先接 Stub 做 promote 契約驗證(讀檔已不再依賴 File Access Agent
Member Center OAuth client / audience 註冊延遲 盡早申請;開發初期可用 local Member Center 測試
scope 命名與 Member Center 既有命名慣例衝突 Architect 在 TDD 提案後,走跨團隊 review
visionA-backend 傳來的 user_id 被偽造VisionA 被入侵或誤用) 接受此風險Converter 不做 user 層 ACL責任邊界在 visionA-backend。可加日誌記錄 user_id 變更頻率作為監測
大檔 promote 時 File Access Agent 不可用 Converter Bucket 7 天 lifecycle 保留,使用者可重試 promoteAPI 回清楚的 502
大檔 multipart 上傳失敗或 timeoutvisionA-backend ↔ Converter 之間) 沿用既有 Web UI 的 500MB 上限;若未來需更大檔,與 Architect 討論改用 disk storage 或 chunked uploadAPI 回清楚的 413 Payload Too Large / 408 Request Timeout;由 visionA-backend 做重試邏輯Converter 無 resume upload 能力)
multipart 上傳占用記憶體(既有 multer.memoryStorage() 問題) 此為既有既有風險(見 §12.1L 級新功能後因 API 消費者數量增加可能加劇。建議 Architect 評估是否 Phase 1 同步改 multer.diskStorage();若不改,需明確在 Capacity Planning 中計算記憶體上限
Converter 的 service token 過期未正確刷新 實作 token cache + 主動 refreshexp-60s
同使用者同時一個轉檔對「急用者」造成不便 以 409 + 現有 job_id 回應,讓 VisionA 引導使用者「繼續追蹤」而非重送
對外 API 穩定性承諾OpenAPI修改困難 Phase 1 採保守設計預留未來擴充欄位API 走 /api/v1 版本化
OAuth middleware 阻塞既有 Web UI 走的 /jobs 路徑 API 分兩套Web UI 維持原路徑無 OAuth對外 API 走 /api/v1/* 新路徑

14. 相依服務新增2026-04-25

本次 L 級新功能使 Kneron Model Converter 從「獨立工具」變為「依賴兩個外部服務 + 被一個外部服務呼叫」的生態成員。本章節說明三個相依關係。

14.1 Member Center身分與權限中心

  • 專案位置/tmp/member_center/Innovedus 旗下C# .NET + OpenIddict + PostgreSQL
  • 負責範圍OAuth2 / OIDC authorization server、JWKS 發布、token 簽發、delegated token 簽發與驗證
  • Converter 對它的依賴
    • 驗 token作為 Resource Server:從 GET /.well-known/openid-configuration 與 JWKS 端點拉取公鑰,驗證 visionA-backend 送來的 service token
    • 取 token作為 Client:以 client_credentialsPOST /oauth/token 取得 Converter 自己的 service token
  • 目前狀態
    • 核心 OAuth2 / OIDC 已完成(見 /tmp/member_center/docs/DESIGN.md §7.1
    • POST /file-access/download-tokensPhase 2 需要)尚未實作
  • 本次 Converter 需要 Member Center 做的事(需跨團隊協調):
    • 註冊一個 resource audiencekneron_converter_api(暫定名)
    • 註冊一個 OAuth clientkneron_converter暫定名Converter 自己使用)
    • 在 visionA-backend 的 OAuth client 設定中加入 kneron_converter_api 的 scope 授權(例如 converter:job.write, converter:job.read
    • 在 Converter 的 client 設定中加入 file_access_api 相關 scope 授權:Phase 1 僅需 files:upload.writepromote 時 PUT 檔案用);不需要 files:download.readfiles:metadata.read2026-04-25 變更後Phase 1 Converter 完全不從 File Access Agent 讀取任何東西)
  • 風險任何註冊、scope 命名、client_secret 發放都需要 Member Center owner 配合

14.2 File Access Agent檔案閘道

  • 專案位置/tmp/file_access_agent/Innovedus 旗下C# / ASP.NET Core
  • 負責範圍
    • 代表「tenant 邊界內的所有檔案」的統一存取閘道
    • 所有檔案進出都 proxy 經過 File Access Agent無 presigned URL 模式
    • 單一 tenant per instance啟動時設定 INSTANCE_TENANT_ID
    • 驗 upload 的 JWT向 Member Center JWKS
    • 驗 download 的 delegated token向 Member Center 線上 validation endpoint
  • Converter 對它的依賴Phase 1 簡化版2026-04-25 變更)
    • 僅 PUT 結果到模型庫promote 時 Converter PUT 結果檔到 File Access Agent帶 service tokenscope=files:upload.write
    • Phase 1 Converter 完全不從 File Access Agent「讀」任何東西(原始模型改由 visionA-backend 直接 multipart 上傳到 Converter
    • Phase 1 不需要 GET / HEAD / metadata 類的呼叫
  • 目前狀態
    • 核心功能完成(見 /tmp/file_access_agent/docs/API.mdupload (PUT)、download (GET with delegated token)、metadata、delete
    • MinioFileStorage、MemberCenterDelegatedDownloadTokenValidator 已實作(約 1865 行 C#
  • 本次 Converter 需要 File Access Agent 做的事Phase 1
    • 確認 deployment哪個 instance 服務哪個 tenant、Converter 要連哪個 URL
    • 約定 objectKey 命名(建議:kneron-converter/{user_id}/{model_id}/v{version}/{filename} 或類似結構,需與 VisionA 對齊)
    • 只使用 PUT 端點upload 類),不使用 GET / HEAD / metadata
  • 設計選擇(已確認):沒有 presigned URL 模式 — 所有 promote 流量 都經過 File Access AgentConverter 接受此設計,不爭取改變
  • Phase 2 可能新增的依賴Phase 2 的 delegated download 不經過 Converter見 US-14

14.3 visionA-backend服務消費者

  • 專案位置~/visionA/visionA-backend/Innovedus 旗下Go + Gin
  • 負責範圍
    • VisionA 平台的後端,管理其使用者、模型庫、應用設定
    • Phase 0 雛形階段,近期進 Phase 1 導入 OAuth2/OIDC 與 JWT 認證
  • Converter 對它的關係
    • 是 Converter 的 第一個 API 消費者Persona C 實例)
    • visionA-backend 會以 client_credentials 向 Member Center 取 service tokenaud=kneron_converter_api),然後呼叫 Converter API
  • 職責邊界(明確區分)
    • visionA-backend 的責任:使用者認證、使用者 ACL哪個使用者能看哪些模型、模型庫 UX、將終端使用者的操作轉換為對 Converter API 的呼叫、處理 polling 與 UI 進度顯示、決定 promote 的目標 objectKey
    • Converter 的責任Kneron Toolchain 轉檔執行、job 狀態管理、以自己的 service token 讀寫 File Access Agent、同使用者同時一個轉檔的限制、job 查詢過濾
    • 不能混淆的邊界Converter 驗 user_id 真偽、做使用者層級 ACL、管 VisionA 的模型庫命名規則
  • 目前狀態Phase 0 雛形static auth無 DBLocalFS。Phase 1 將導入 JWT/OIDC 與真實使用者系統
  • 協作時間表假設VisionA 進 Phase 1OAuth2 完成)的時間需與 Converter Phase 1 的整合測試時程對齊

14.4 相依關係圖PRD 層級2026-04-25 更新)

                    [VisionA 終端使用者]
                            │
                            │ (web UI 操作)
                            ▼
                  ┌──────────────────┐
                  │  visionA-backend  │  ← Persona CConverter API 消費者)
                  └───┬──────┬───┬───┘
                      │      │   │
     service token    │      │   │  ① multipart 上傳原始模型
     (client_cred.)   │      │   │    (POST /api/v1/jobs, Phase 1)
                      │      │   │
                      ▼      │   │  delegated tokenPhase 2
              ┌────────────────┐ │
              │ Member Center   │ │
              │ (OAuth2, JWKS,  │ │
              │  delegated tok.)│ │
              └────┬──────┬────┘ │
                   │      │      │
         驗 token  │      │ 驗   │
         取 token  │      │      │
                   ▼      ▼      ▼
            ┌────────────────────────┐
            │     Converter (本專案)   │
            │  - 收 multipart 上傳     │
            │  - 驗 OAuth token       │
            │  - Worker 轉檔流程       │
            │  - Bucket 暫存 (7天)    │
            └──────────────┬─────────┘
                           │
                           │ ② promote 時 PUT 結果檔
                           │   (Phase 1, scope=files:upload.write)
                           ▼
                  ┌──────────────────┐
                  │ File Access Agent │  ← Phase 1 只收寫入
                  │   (檔案閘道)       │     (不處理 Converter 的讀檔)
                  │  無 presigned URL │
                  └─────────┬────────┘
                            │
                            │ NAS長期儲存
                            ▼
                       [模型庫]

Phase 1 檔案流(已確認)

  1. 原始模型:visionA-backend ──multipart──> Converter(不經 File Access Agent
  2. 轉檔結果promote 時):Converter ──PUT──> File Access Agent ──> NAS
  3. 使用者下載結果Phase 1 UX 由 visionA-backend 決定可選方案VisionA proxy、VisionA 存自己的 copy、或等 Phase 2

Phase 2 新增的檔案流(阻塞於 Member Center 4. 使用者下載:瀏覽器 ──GET (delegated token)──> File Access AgentConverter 不參與)


15. Phase 1 / Phase 2 Scope 切分新增2026-04-25

本章節明確界定本次 L 級功能的交付範圍,避免在實作時範圍蔓延或誤砍。

15.1 Phase 1本次必做

目標:讓 visionA-backend 能完成「上傳 → 轉檔 → 搬進模型庫」閉環,不需要使用者直接下載能力。

必須交付

項目 說明 對應 US / F
OAuth2 Resource Server 驗 visionA-backend 的 service tokenJWKS 驗簽、aud、scope F-21, US-08
OAuth2 Client Converter 自己取 service token僅用於 promote 時呼叫 File Access Agent 的 PUT F-22, US-13
POST /api/v1/jobsmultipart 建 jobmultipart filesmodel + ref_images[]multipart fieldsuser_id + model_id + version + platform + 旗標 F-23, US-08
GET /api/v1/jobs/:id Polling 進度 F-24, US-09
GET /api/v1/jobs?user_id=...&status=... Recovery 的 job 列表查詢 F-25, US-12
POST /api/v1/jobs/:id/promote 搬結果到 File Access AgentConverter 自己推) F-26, US-10, US-13
同使用者同時一個轉檔限制 建 job 時檢查 user_id 有無 in-progress job F-27, US-11
OpenAPI 3.0 規格 對外 API 契約visionA-backend 整合用 F-29

2026-04-25 變更):原 Phase 1 Scope 中的「從 File Access Agent 取原始模型F-28」已移除。Phase 1 原始模型來源改為「visionA-backend 直接 multipart 上傳到 Converter」見 F-23 / US-08

明確不做Phase 1 不在範圍):

  • 使用者下載模型的 delegated token 流程(移至 Phase 2
  • Web UI 改走新 OAuth 流程(維持既有 multipart 路徑,另外評估)
  • Webhook / SSE 對外推送polling 已足夠)
  • Job 取消功能(既有專案本來就沒有,不在本次新增)
  • Job 持久化 / Crash 恢復維持「Crash 即 Reset」哲學
  • 單階段轉換 APIF-04~06— 這是既有 backlog 項目,和本次 L 級功能獨立

Phase 1 上線完成的判定標準

  1. visionA-backend 能成功以 service token 呼叫所有四個對外 API
  2. 一個完整 E2E 流程跑通VisionA 使用者上傳模型 → File Access Agent → 觸發轉檔 → polling 進度 → 完成後 promote 到模型庫
  3. 同使用者同時轉檔限制生效(回 409
  4. Recovery 能查到 in-progress job
  5. OpenAPI 規格通過 visionA-backend 整合測試
  6. API SLA 基本指標可觀測可用率、p95 回應時間)

15.2 Phase 2延後做

目標:讓 VisionA 終端使用者能直接從瀏覽器下載 NAS 裡的模型檔,不經 visionA-backend 中轉。

必須交付

項目 說明 對應 US / F
visionA-backend 呼叫 Member Center 取 delegated token scope=files:download.delegate,帶 tenant_id + user_id + object_key F-30, US-14
瀏覽器直連 File Access Agent 下載 GET /files/{object_key}?token=<delegated> US-14
Converter 無變更 Phase 2 對 Converter 本身無直接改動

阻塞條件(必須先解除才能啟動 Phase 2

  1. Member Center 的 POST /file-access/download-tokens 已實作並部署(目前:未實作
  2. Member Center owner 提供測試環境與 scope 授權
  3. File Access Agent 的 MemberCenterDelegatedDownloadTokenValidator 已通過整合測試(目前:程式碼已有,待驗證)

觸發 Phase 2 的條件

  • Member Center owner 確認時程,或
  • VisionA 業務需求強烈要求此時可考慮折衷方案VisionA 自己做 proxy 下載),但這是另一個討論

Phase 2 的 US-14 風險

  • 若 Member Center 長期不實作VisionA 的終端使用者要下載自己的模型就只能「從 VisionA 下載介面(經 visionA-backend proxy」或「連 Kneron Converter 舊的 Web UI此時兩邊資料不同步會混亂」。需提前與 VisionA 產品團隊溝通 UX 取捨。

15.3 Phase 1 / Phase 2 決策原則

  • Phase 1 必須能獨立上線:不能因為 Phase 2 阻塞就拖累 Phase 1。
  • Phase 1 / Phase 2 之間不會互相破壞Phase 2 只新增功能,不修改 Phase 1 的 API 契約。
  • 阻塞透明化Phase 2 的阻塞原因Member Center endpoint 未實作)必須明確記錄在 PRD讓使用者知道是上游依賴不是本專案問題。

16. 附錄

註:本章原為 §13因新增 §14相依服務與 §15Phase 切分)而重編號為 §16。章節內容不變。

16.1 技術堆疊完整列表

層級 技術 版本
前端框架 Vue 3 + Vite Vue 3.3.4, Vite 4.4.5
UI 元件庫 Element Plus -
狀態管理 Pinia -
後端(調度) Node.js + Express Node 18
Worker 框架 Python同步 Python 3.9
佇列 / 狀態 Redis Stream Redis 7 Alpine
模型處理 ONNX 1.14.1, TensorFlow 2.16.2 -
容器化 Docker + docker-compose -
反向代理 Nginx Alpine
測試框架 pytest + pytest-asyncio -

16.2 後端介面層設計

程式碼採用 Protocol + Factory 模式,將 Kneron Toolchain 的呼叫封裝為可替換的後端介面:

  • QuantizationBackendservices/backends/quantization.py)— 量化分析
  • CompilerBackendservices/backends/compiler.py)— NEF 編譯
  • EvaluatorBackendservices/backends/evaluator.py)— IP 評估
  • SimulatorBackendservices/backends/simulator.py)— E2E 模擬(未完成)

此設計使得未來可以替換為不同版本的 Toolchain 後端,或在測試時注入 Mock。

16.3 程式碼品質觀察

  • 模組化設計良好Worker / Consumer / Backend 職責清晰
  • 測試覆蓋6 個測試檔涵蓋 ONNX/BIE/NEF 核心與 E2E 流程
  • 使用 Helmet、Rate Limiting、Compression 等 Express 最佳實踐
  • Graceful shutdown 處理SIGTERM / SIGINT

附錄 A本次更新的 PM 疑問清單2026-04-25

撰寫本次 PRD 更新時遇到以下疑問,列出給 Orchestrator / 使用者裁決。這些問題不阻塞三方交叉審閱,但需在使用者最終審核 PRD 前釐清

A.1 需使用者決定的產品問題

  1. Phase 1 的 Web UI 要不要也改走 OAuth 流程?
    • 傾向不改(維持既有 multipart 行為),未來評估
    • 若決定改,則 Phase 1 範圍會擴大(升級為 L+ 或拆兩個 L
  2. 同使用者同時一個轉檔限制範圍確認
    • 是否真的是「整個 Converter 服務」共用的 user_id 空間?還是不同 client_id(例如未來有 visionA-backend 以外的消費者)各自獨立?
    • 目前 PRD 以「整個服務內 user_id 唯一」設計(預期未來不會出現跨 client 的 user_id 衝突)
  3. tenant_id 策略
    • Member Center 與 File Access Agent 都是多租戶設計,但 PRD 目前未處理「Converter 內部怎麼標記 tenant」
    • 待 Architect Agent 評估Converter 是否要在 job record 上記錄 tenant_id還是只信任 File Access Agent 的 single-tenant-per-instance 保證?
  4. Phase 2 的 fallback 策略
    • 若 Member Center 長期不實作 delegated tokenVisionA 要不要做 proxy 下載作為折衷?
    • 還是完全等 Member Center
  5. API 採用度的 baseline 如何取得?
    • §9.2.2 列的目標值(例如「每月 X 個 job」目前沒有歷史資料
    • 建議Phase 1 上線後跑 1 個月 beta 再訂正式目標
  6. 既有 PRD 中的 [推測] 標記要不要在此次順便確認?
    • 本次 PM 暫不動既有 [推測],保留給使用者決定
    • 建議在使用者最終審核本版 PRD 時一併確認

A.2 需跨團隊協調的問題(給 Orchestrator 記到 progress.md 未解決問題)

  1. Member Center owner 協調:註冊 kneron_converter_api audience、kneron_converter client、設定 scope 授權
  2. File Access Agent owner 協調:確認 Converter 要連的 instance URL、tenant_id、objectKey 命名約定
  3. VisionA 團隊協調:確認 VisionA 的 Phase 1 OAuth 整合時程,對齊 Converter 整合測試時機
  4. Member Center /file-access/download-tokens 實作時程:影響 Phase 2 啟動

A.3 給 Architect Agent 的待確認項

  1. scope 命名converter:job.write / converter:job.read 是否符合 Member Center 慣例?由 Architect 在 TDD 提案後跨團隊 review
  2. Effort 估算RICE 表中 Phase 1 Effort = 4 人週 為 PM 概估,需 Architect 在 TDD 後精確。注意2026-04-25 變更後Phase 1 移除「從 File Access Agent 取原始模型」這條路徑,相對減少 OAuth Client 的讀檔 scope 與整合測試複雜度Architect 可重新估 Effort
  3. OpenAPI 規格的維護策略:自動生成還是手寫?版本變更流程?
  4. user_id 在 job record 的索引設計Redis 現在用 redis.keys('job:*') 掃描,加 user_id 過濾後效能策略?
  5. 新增2026-04-25multipart 上傳的記憶體策略:既有 Web UI 用 multer.memoryStorage(),對外 API 接受相同路徑後,同時多個 visionA-backend 呼叫可能放大記憶體問題。Architect 需評估 Phase 1 是否同步改 diskStorage,或是否需 Capacity Planning 加上明確的上限(例如同時 multipart 上傳數 × 500MB ≤ Node.js heap
  6. 新增2026-04-25POST /api/v1/jobs 與既有 POST /jobs 的路徑實作關係兩者行為近似Architect 需決定是「共享同一個 handler前面加 OAuth middleware + user_id 驗證分支」還是「完全獨立兩個 handler」。這會影響未來維護性

A.4 給 Design Agent 的待確認項

  1. 本次 Phase 1 主要影響「API 層 + visionA-backend 串接」,Kneron Converter 自己的 Web UI 預期不改
  2. Design Agent 需確認:既有 Web UI 的「上傳模型」流程是否在 Phase 1 仍維持 multipart若維持則 Web UI 不受影響
  3. visionA-backend 端的 UI 設計進度條、recovery 提示、promote 按鈕等)不在 Kneron Converter 的 Design Agent 範圍內,由 VisionA 團隊負責

A.5 本次變更2026-04-25 第二次更新)新產生的 Open Questions

  1. VisionA 終端使用者如何下載轉檔結果Phase 1 期間)
    • 由於 Converter 不再從 File Access Agent「讀」原始模型而使用者要看 / 下載 轉檔結果BIE、NEF的流程在 Phase 1 就尚未有 end-to-end 設計
    • 選項:(a) 使用者先等到 promote 完成後從 VisionA UI 下載VisionA 自己 proxy(b) Phase 1 只讓 VisionA 平台顯示「已加進模型庫」,不提供下載鍵,等 Phase 2 delegated token 再開放,(c) VisionA 先不呼叫 promote從 Converter 的 /jobs/:jobId/download/:filename 既有路徑下載(此路徑目前無 OAuth
    • 需 PM + VisionA 產品團隊對齊
  2. visionA-backend 在上傳前是否也存一份原始模型到自己
    • 由於 Phase 1 原始模型不進 File Access Agent若轉檔失敗或使用者要重試visionA-backend 是否需要自己暫存一份?
    • 這是 visionA-backend 內部設計問題,不影響 Converter API 契約,但會影響 VisionA 使用者 UX失敗後能不能一鍵重試
  3. 既有 /jobs/:jobId/download/:filename 端點的對外曝光問題
    • Phase 1 visionA-backend 若走 promote 路徑,下載由 VisionA ↔ File Access Agent 處理Converter 的下載端點不需對外
    • 但若 VisionA 決定「先不 promote、直接從 Converter 拉結果」,此端點就需要加 OAuth 保護
    • 需在 TDD 中決定既有下載端點是否要區分「Web UI 內部用」vs「對外 API /api/v1 用」兩套