門店服務漏接感知 Agent

2026 Agentic AI on the Edge 黑客松決賽作品說明。隊伍:老闆好痛。實證場域:自家的拉麵店(台北市文山區),實際營業中。內容更新到 2026-10-22,數字都是在真實營業的店裡量的,每一節標了出處文件。

這一頁給評審和其他參賽隊伍看。它說明我們用了哪些技術、系統怎麼接、資訊怎麼流,以及為什麼這件事要放在邊緣做。

只有三分鐘的話,看這四節:

  1. 一句話:我們做了什麼
  2. 評分項對照:每一個評分項,我們怎麼做到、證據是什麼
  3. 系統架構與資訊流:一張圖看完整套系統
  4. 9/20 那則客訴:一個真實的例子,28 秒找到

想追問的話,最後一節〈評審最可能問的問題〉可以點開。

一句話

在店裡既有的監視器上,加一層不用 AI 模型的影像算法整天守著;有可疑狀況時,才叫醒關在沙箱裡的 Nemotron Agent,讓它查 POS、查現場訊號,再決定要不要通知人。

它盯的是「客人有沒有被照顧到」,不是「哪個員工在偷懶」。老闆接到客訴時,也可以打一句話問它,它會從一整天的紀錄裡找出那一刻。

整套系統 10-21 在主辦現場的 DGX Spark 上裝好、跑通:模型、沙箱、即時判定、看片網頁都在這台機器上。

出處:企劃書草稿、交接-2026-10-21、部署-2026-10-21

評分項對照

這張表照主辦的評分項排列。「證據」欄的數字都是實測,括號裡是出處文件。

第一階段企劃書評分

評分項我們怎麼做到證據
邊緣技術與部署 35%
量化、記憶體
用 NVIDIA 官方的 NVFP4-QAD 量化版 Nemotron。常駐層不用模型,只用 CPU。沒有做剪枝。模型檔 BF16 26.4 GB → FP8 15.4 GB → NVFP4 10.6 GB;載入 9.95 GiB。常駐四路 CPU 0.05 核、GPU 0%、334 MB(企劃書第 8 頁、測試報告)
推論速度、延遲模型只在有候選或有客訴時才跑;其餘時間只有常駐層在跑8 張畫面一次判斷:中位數 4.34 秒、第 95 百分位數 4.56 秒(30 次)。輸出約 11.6 tokens/秒(8 張畫面,共用機)。回查層多輪 13.1 秒(沙箱內)(硬體測試報告、測試報告、部署-2026-10-21)
離線、弱網推論、決策、紀錄都在店內這一台;三種斷網保證分開驗攔截對外連線:零次。關掉 Wi-Fi 後模型從零啟動約 225 秒,流程照常。即時判定容器沒有網路介面(硬體測試報告、企劃書第 8 頁)
Agentic 機制創新 25%
自主決策、工具調用
兩個 Agent:回查層(5 個工具)、客訴 agent(4 個唯讀查詢工具+紀錄)。模型自己決定查什麼、查幾次、要不要通知7 個候選各跑一次:7/7 多輪(3–5 輪)、7/7 得出結論。9/13 那筆,模型查完 POS 覺得不夠,自己再去查現場訊號(企劃書第 4 頁)
創新度「當下提醒」和「事後回頭找」分開:前者怕誤報,只讓測得準的訊號開口;後者怕漏,多找幾段給人看。規則判日期和客訴類型,模型負責選工具和寫結論9/20 一則真實負評,28.08 秒從 71,815 張影格交出 4 個時刻,要找的那一次在裡面(決賽簡報素材-2026-10-22)
場景落地與價值 30%
隱私、即時、無網
原始影格加密存放、金鑰不落硬碟;模型只看數字;網頁要登入、有期限。即時警示延遲 1–2 秒。斷網照常回放 9/13:客人 11:00:55 進來,11:01:25 準時跳警示(交接-2026-10-21)
使用體驗、應用潛力不換攝影機、不加感測器,接店裡現有的監視器主機。老闆從手機網頁看每天的狀況、問客訴36 天每日摘要全部算完,0 天失敗;同一套判定換到第三台機器,數字一個都沒變(交接-2026-10-21、部署-2026-10-21)
文件可讀性 10%就是這一頁:先講結論、用詞表、每節標出處,限制寫在明處—

第二階段決賽評分要件

要件我們怎麼做到證據
應用建構與代理機制單一應用、兩個 Agent,共用同一個工具迴圈程式,工具不同。回查層:候選進來,查原因、建議分級。客訴 agent:老闆打一句話,查那一天10-21 現場跑四次回查層 demo,四次抓到同一筆真漏接;客訴 agent 驗過 3 題(9/20 那題問了兩次),11–30 秒(部署-2026-10-21、交接-2026-10-21)
企業級技術與平台整合
Nemotron、NeMo、NemoClaw、DGX Spark
Nemotron Nano 12B v2 VL 跑在 vLLM 上;NeMo Guardrails 檢查提醒內容;兩個 Agent 都在 NemoClaw/OpenShell 的 BYOC 沙箱裡,白名單收緊到零外部端點;全部在主辦現場的 DGX Spark 上,從隨身碟裝起來NemoClaw onboard 8 步全過;沙箱內連外部網站全被擋(15 毫秒回錯誤,不是逾時);沙箱內直連模型服務回 403,只能走受控推論路徑(部署-2026-10-21)

NeMo 框架我們用的是 NeMo Guardrails。工具迴圈是自己寫的,沒有用 NeMo Agent Toolkit。Jetson 沒有測過;NVFP4 需要 Blackwell 架構,Orin 跑不了。

Agent 的四項能力:真實發生的例子

主辦列的四項能力,每一項舉一個系統裡真的發生過、有紀錄的例子。

能力真實的例子出處
01 目標與任務分解目標是「判斷這位客人有沒有被漏接、該通知誰」。拆成四步,後一步依賴前一步:結帳區有人超過 30 秒 → 同一段時間收銀機前沒有店員 → 回查原因(POS、現場訊號) → 分級處置。前兩步是常駐層,後兩步是模型。客訴 agent 也一樣:先用規則判日期和類型,再由模型選工具查,最後寫成固定三段的結論企劃書第 4 頁
02 工具與系統調用9/13 11:00:55 那筆的軌跡:① 查 POS(query_pos):那 3 分鐘有 1 張內用單;② 寫下判斷理由(audit);③ 查現場訊號(detect_entry);④ 通知店長(notify)。5 輪、4 次調用、21.6 秒。工具碰的是 POS 資料、桌況、鏡頭訊號和通知裝置企劃書第 4 頁(逐字節錄)
03 狀態與動態調整上面第 ③ 步是模型自己加的:查完 POS 覺得證據不夠,再去看現場。另一個例子:9/18 實測時,模型連續四輪送出同一個錯的呼叫。之後程式改成「同樣的工具、同樣的參數只准失敗一次」,再試就回它「改參數、換工具,或直接給結論」;連續兩輪沒有進展,就安全中止、標成降級。前場裝置送不出去,也退回「只記錄」src/agent/loop.py、notify.py
04 權限與風險控制提醒沒有「自由文字」這個參數,模型只能選三個固定句型之一。送出前先過護欄:「A 桌碗盤還沒收」放行,「那個店員今天很混」(測試句)擋下。分三級:前場直接送、店長級掛起來等人按確認、只記錄。10-21 12:15 那次,模型選了店長級,系統回「待人工確認」,沒有自動送出。每一步寫進只能往後加的軌跡notify.py、guard.py;部署-2026-10-21

誠實的一點:模型這一半不穩定。同一筆候選,重啟後有時不呼叫 notify、只把分級寫在文字裡,分級也會在店長和前場之間變。詳見〈已知限制〉。

用了哪些技術

技術做什麼用實測或狀態
NVIDIA Nemotron
Nemotron Nano 12B v2 VL,NVFP4-QAD 量化
回查層和客訴 agent 的大腦:讀工具回來的數字,決定下一步查什麼、寫結論。用 NVIDIA 官方的量化檢查點模型檔 10.6 GB;10-21 現場啟動 236 秒就緒
vLLM模型的推論服務,用 NVIDIA 官方容器。工具調用用 NVIDIA 的 Nemotron 解析器(我們修了介面)記憶體預算壓在 24 GB 內
NeMo Guardrails提醒送出前的內容檢查:擋對人的評價字眼和人名。規則寫死,不叫模型判斷一次檢查 3.4 毫秒。它預設會回傳使用統計,我們在程式裡關掉
NemoClaw/OpenShell 沙箱兩個 Agent 都跑在裡面。沙箱裡的每一條連線都要經政策代理,照白名單放行onboard 8 步全過;用自己的映像(BYOC);白名單收緊到零外部端點
BYOC 自帶映像官方底加上我們的程式和設定,打成沙箱映像,不從網路裝套件映像 11 步、88 秒建好
DGX Spark邊緣節點。開發期一台錄影;決賽一台跑模型、沙箱、即時判定、網頁10-21 在主辦現場從隨身碟裝起來
影像算法層(常駐層)整天守著監視器,不用 AI 模型:桌上碗盤用 Canny 邊緣密度,結帳區有沒有人用「和空店畫面比」。找出候選才叫醒模型四路 CPU 0.05 核、GPU 0%、334 MB
AES-GCM 加密每一張影格寫進硬碟前先加密,讀的時候在記憶體裡解開開發機硬碟上的明文影格:0
YOLOv8s-pose找人和人的關鍵點,從關鍵點推頭在哪,在頭上貼一隻小青蛙遮住。用 OpenCV 跑 ONNX 檔,不另外裝套件1,491 張貼了 4,106 隻;仍然會漏
YuNet抓臉,和姿勢模型的結果取聯集,補漏只用它的話,俯拍鏡頭漏很多
Docker --network none即時判定跑在一個沒有網路介面的容器裡警示延遲 1–2 秒

模型是 VL(看圖)版本,但回查層和客訴 agent 只送給它文字和數字。原本讓它看畫面判斷「有沒有人招呼客人」的那一層,兩次驗證都沒通過(招呼判定和亂猜差不多),所以第一版沒有啟用。

出處:企劃書草稿第 7–9 頁、測試報告、部署-2026-10-21

系統架構與資訊流

結論:影像只在最前面那一段。從常駐層往後,模型和工具看到的只有數字、時刻和文字。一張影格有三條路:回查層(有候選才跑)、每日摘要(一天一次,給網頁和客訴 agent)、即時(影格一進來就判定)。三條路用的是同一套判定程式。

flowchart TD
  subgraph STORE["店裡 既有設備 不改動"]
    CAM["既有監視器 四路"] --> DVR["既有 DVR 快照網址 352x240"]
    POS["POS 結帳紀錄 匯出檔"]
  end
  subgraph REC["錄影主機 DGX Spark"]
    ING["每 0.4 秒取一張"] --> ENC["加密後才寫硬碟"]
    ENC --> DIG["每日摘要 常駐層算法"]
  end
  subgraph SITE["現場 DGX Spark"]
    LIVE["即時判定 無網路容器 常駐層算法"]
    WEB["看片網頁 要登入 有期限"]
    subgraph SB["NemoClaw OpenShell 沙箱 零外部端點"]
      RES["常駐層找候選"] --> TRI["回查層 Agent"]
      CA["客訴 agent"]
    end
    LLM["vLLM 加 Nemotron Nano 12B v2 VL NVFP4"]
    GR["NeMo Guardrails"]
    TIER["分級 前場 店長等確認 只記錄"]
  end
  KEY["金鑰 只在記憶體"]
  DVR --> ING
  ENC -- "加密影格 唯讀拉取" --> LIVE
  ENC -- "加密影格" --> RES
  DIG -- "數字和遮過頭的縮圖" --> WEB
  DIG -- "數字" --> CA
  POS --> TRI
  POS --> CA
  LIVE -- "警示 遮過頭的畫面" --> WEB
  WEB -- "老闆打的一句客訴" --> CA
  CA -- "結論 附相關照片" --> WEB
  TRI -- "受控推論路徑" --> LLM
  CA -- "受控推論路徑" --> LLM
  TRI -- "notify" --> GR --> TIER
  KEY -.-> ENC
  KEY -.-> LIVE
  KEY -.-> RES

三條路

  1. 回查層:常駐層在吧台畫面上找到候選(客人在結帳區超過 30 秒、收銀機前沒有店員),把候選的描述交給回查層 Agent。Agent 呼叫工具查 POS、桌況、現場訊號,最後經 notify 選一個固定句型和分級。提醒先過護欄,再分級。決賽 demo 用 9/13 那段的加密影格,傳進沙箱裡跑。
  2. 每日摘要:在錄影主機上每天跑一次,產出一天的事件、候選、收桌、POS 和遮過頭的縮圖。看片網頁的日曆和單日頁、客訴 agent 的查詢,都讀這份摘要。客訴 agent 不碰影格,也不需要金鑰。
  3. 即時:現場 Spark 每 2 秒從錄影主機拉一次新的加密影格(只能唯讀拉取),在沒有網路的容器裡解開、判定。滿 30 秒、收銀機前沒有店員,就跳一行警示。警示是規則判的,不經模型。

一筆候選進來之後(回查層)

sequenceDiagram
  participant C as 常駐層
  participant A as 回查層 Agent
  participant T as 工具
  participant G as 護欄
  participant P as 人
  C->>A: 候選 9/13 11:00:55 客人 132 秒 店員 p90 0.042
  A->>T: query_pos 查這 3 分鐘的結帳
  T-->>A: 1 張內用單
  A->>T: audit 寫下判斷理由
  A->>T: detect_entry 再查現場訊號
  T-->>A: 客人區動態可信
  A->>T: notify 店長級 固定句型
  T->>G: 檢查句子
  G-->>T: 放行
  T-->>P: 待人工確認 不自動送出

出處:企劃書草稿第 4 頁(9/13 逐字軌跡)、系統架構與資料流-2026-09-19、交接-2026-10-21

資料不落地:哪些離開、哪些不離開

結論:原始影格在硬碟上只有密文,解密金鑰不寫在任何一台 Spark 的硬碟上。模型和工具只拿到數字和時刻。但網頁上的照片是遮過頭的明文 JPEG,遮臉會漏,所以網頁一定要登入、有期限。

東西存在哪裡、什麼形式會不會離開
原始影格錄影主機的硬碟上,每張都是加密檔(AES-GCM,每張一個隨機數)。讀的時候在記憶體裡解開,解開的畫面不寫回硬碟即時那條路會把加密影格拉到現場 Spark,到了那裡仍是密文,只在無網路容器的記憶體裡解開
解密金鑰不寫在任何一台 Spark 的硬碟上。從店家這一方的筆電經標準輸入送進程式,只在程式的記憶體裡只進錄影程式、即時判定容器、沙箱裡的回查層 demo
每日摘要數字(事件、候選、收桌、POS 對照)加處理過的縮圖這是離開錄影主機的主要東西,送到現場 Spark 給網頁和客訴 agent
網頁上的照片和即時畫面人頭貼了青蛙的明文 JPEG登入的人看得到。網頁每個請求都要帳密,過了期限整個網頁回 403
沒遮的縮圖為了做遮臉,從錄影主機直接串流到店家這一方的筆電,在那台筆電上處理兩台 Spark 都不落地;不放上網頁
模型看到的只有工具回傳的數字、時刻和文字。工具不回影像模型和兩個 Agent 都在零外部端點的沙箱裡
即時判定在 --network none 的容器裡這個容器根本沒有網路介面

邊界:我們不說的話

下面這幾句我們不說,因為它們不成立:

開發期的錄影主機是一台借來的 DGX Spark,放在店外的機房,不在店裡。影格從店裡的監視器主機取來,加密後才寫進它的硬碟。設計上這台應該放在店裡;這一步還沒有在店內實裝。加密防的是有人翻硬碟,防不了有人在程式執行時讀記憶體。

出處:交接-2026-10-21〈晚間追記〉(網頁文字哪些成立)、測試報告第二節、README

為什麼放在邊緣、為什麼舊設備就夠

為什麼放在邊緣

理由性質說明
隱私前提畫面裡有客人和員工的臉。原始影像一旦送上雲端,就是個資風險
斷網前提小店網路不穩。斷網時警示和紀錄不能停
即時需求碗盤沒收、客人在櫃台沒人理,晚十分鐘才知道就沒用了。即時警示延遲 1–2 秒
推理放店內我們的選擇回查層只看文字,技術上可以上雲。我們選在地:POS 營運數據同樣不該離店;不受外部服務影響

延續舊設備就能用

結論:不換攝影機、不加感測器。常駐層只要每秒兩三張低解析度畫面,用很少的運算。

方案每路每秒張數CPU記憶體GPU
影像算法(採用)2.5,跟上0.05 核(20 核的 0.2%)334 MB0%
PeopleNet CPU(對照)1.0,跟不上19.26 核1,387 MB—

CPU 成本差約 385 倍。模型叫醒幾次,由事件數決定,不由影格數決定:9/13 全天 71,817 張影格 → 43 個事件 → 7 個候選。

出處:測試報告第三、五節;企劃書草稿第 7、8 頁(記憶體 334 MB 是 9/21 含吧台背景相減重量的數字)

回查層 Agent

結論:模型決定查什麼、查幾次、選哪一級;程式決定它能做什麼、什麼時候算失敗。

五個工具

工具做什麼
query_pos查一段時間的 POS:進單、內用、外送
query_tables查內場 A、B 桌的桌況
detect_entry查結帳區客人區的動態訊號
notify選一個固定句型、填欄位、選分級。沒有自由文字參數
audit寫下判斷理由到軌跡

迴圈怎麼判斷失敗

flowchart TD
  Q["候選加五個工具說明"] --> A{"模型這一輪回什麼"}
  A -- "工具呼叫" --> T["執行 結果加進對話"]
  A -- "純文字" --> U{"開頭是工具名接括號"}
  U -- "是" --> X1["降級 工具呼叫沒被解析"]
  U -- "否" --> OK["結論"]
  T --> P{"連續兩輪都沒成功"}
  P -- "是" --> X2["降級 沒有進展 安全中止"]
  P -- "否" --> R{"滿 6 輪"}
  R -- "是" --> X3["降級 輪數用完 不編結論"]
  R -- "否" --> A

提醒與護欄

三個固定句型:「有客人進來了」「{桌} 桌等很久了,已經 {分鐘} 分鐘」「今天漏接 {次數} 次,集中在 {時段}…」。參數多一個、少一個都拒絕。句型合法不代表內容合規(欄位是模型填的),所以送出前再過 NeMo Guardrails。護欄在分級之前跑:店長級雖然只是掛起來,掛起來的內容一樣會被人看到。

10-21 現場四次 demo

時間在哪跑端到端工具呼叫分級
12:15沙箱外,第一次啟動33.4 秒query_pos → audit → notify店長,走 notify,待確認
12:17沙箱外,同一次啟動16.1 秒同上,逐字相同同上
13:40沙箱外,重啟後11.3 秒query_pos → audit店長,只寫在文字裡
14:10沙箱內,同一次啟動13.1 秒同上前場,只寫在文字裡

四次都抓到同一筆:11:00:55–11:03:07,客人 132 秒,收銀機前店員訊號的第 90 百分位數 0.042,POS 證實晚結帳。不用模型的那一半,換到第三台機器,數字一個都沒變;用模型的那一半,重啟就會變。

出處:src/agent/loop.py、notify.py、guard.py;部署-2026-10-21 第六節;硬體測試報告-2026-10-13

客訴 agent 與規則試玩

結論:日期、時段、客訴類型用規則判,不交給模型。模型只決定查哪幾樣、怎麼寫結論。它在沙箱裡,只有四個唯讀的查詢工具,加上寫軌跡的 audit。

flowchart TD
  Q["老闆打的一句話"] --> S1{"規則 擋注入 擋離題"}
  S1 -- "擋下" --> B1["回說明 記一筆軌跡 不送模型"]
  S1 -- "通過" --> W["抓日期和時段"]
  W --> D{"有日期 也有這天的摘要"}
  D -- "否" --> NEED["請老闆補日期 不猜"]
  D -- "是" --> K["判客訴類型"]
  K --> H["提示加一行 先用哪個工具"]
  H --> L["模型 最多 6 輪 溫度 0"]
  L --> T["query_bar longest_visits query_tables query_pos audit"]
  T --> L
  L --> S2{"回答裡有程式碼"}
  S2 -- "有" --> B2["不給老闆看"]
  S2 -- "沒有" --> OUT["三段結論 附相關照片"]

為什麼用規則判

試試看:規則怎麼判。這段 JavaScript 照程式裡的三條規則(擋輸入、抓日期時段、判類型)逐條改寫,在你的瀏覽器裡跑,不叫模型。

結論的格式

固定三段:【查到的】只能引用工具回傳的時刻和數字;【判斷】;【查不到的】寫出資料看不到的部分(態度、講了什麼、會員、集點、餐點品質)。不指名、不評價任何員工。

修掉的兩個錯

拿 9/20 那則真實負評測,抓到兩個錯。兩個都是改工具和規則修好的,不是靠提示詞求模型。

錯根因修正
5 筆有店員的事件,模型全講成「收銀機前無店員」工具欄位寫成「收銀機前沒店員:False」。雙重否定,模型整批讀反,而且答得很有自信改成直接寫「有店員」或「沒有店員」
拿「沒店員」的事件去解釋態度客訴模型只會一種查法加 longest_visits;規則判出糾紛,就在提示裡寫「先用 longest_visits 查」

驗過的題目

題目結果時間
9/13 上午 11 點等很久指向 11:00:5511–30 秒
9/13 下午 1 點半桌子沒收B 桌 13:36–13:48,12.4 分鐘
9/20 集點(第一次修正後)指向 19:59 和 19:25 兩次
9/20 集點(從網頁重問)第一名 19:59:35–20:04:5820.3 秒

都經「網頁 → 沙箱」。第一次問約 30 秒(模型暖機)。

出處:src/agent/complaint.py、bench/complaint.py;交接-2026-10-21 第 4 節;工作日誌-2026-10-21 第五節

9/20 那則客訴:28 秒找到

結論:9/20 吧台 9.5 小時、71,815 張加密影格,28.08 秒交出 4 個時刻,要找的那一次就在裡面。一個月後換一支程式重跑,4 筆數字完全一樣。

那天晚上約 20:41,Google 上出現一則 1 顆星評論:客人想用集點兌換飲料,店員要他反覆刷退 LINE 付款才換得到。老闆想知道當時櫃台發生什麼事。

當晚怎麼找到的

在錄影主機上找「客人在結帳區連續 120 秒以上」的時段。只輸出數字和時刻。

時刻客人在結帳區收銀機前店員訊號 p90
18:06:00136 秒0.400
19:25:38312 秒0.554
19:59:35151 秒0.465
20:02:37142 秒0.552

店家看畫面確認:19:59–20:05 那一組(後兩筆,中間只斷 31 秒)就是這則評論。畫面裡客人低頭反覆操作手機。20:05 結束,37 分鐘後貼出評論。

10-21 從看片網頁問客訴 agent

sequenceDiagram
  participant B as 老闆
  participant W as 看片網頁
  participant R as 規則
  participant M as 模型 沙箱內
  participant T as 工具
  B->>W: 9/20 集點換飲料被刁難
  W->>R: 擋輸入 抓日期 判類型
  R-->>W: 日期 9/20 類型 糾紛
  W->>M: 客訴加系統判讀 先用 longest_visits
  M->>T: longest_visits
  T-->>M: 第一名 19:59:35 到 20:04:58 323 秒 店員在場 100%
  M->>T: audit
  M-->>W: 三段結論 附相關照片
  W-->>B: 約 20 秒
排名時段客人待多久店員在場
119:59:35–20:04:58323 秒100%
219:25:38–19:30:50312 秒100%
318:06:00–18:10:28268 秒96%

最有意思的地方:那 5 分鐘裡店員全程在櫃台。系統找出來的是「客人卡在哪」,不是「誰偷懶」。該改的是集點流程和公告。這也是「收銀機前沒有店員」那一套查不到它的原因。

講這個數字時要準的地方

出處:決賽簡報素材-2026-10-22 第一到六節;原始紀錄 bar-誤報核對-2026-09-20 第七節

邊緣實測數字

量化前後

模型/精度模型檔載入佔用
Nemotron VL BF16(基準)26.4 GB—
Nemotron VL FP815.4 GB14.4 GiB
Nemotron VL NVFP4-QAD(採用)10.6 GB9.95 GiB

NVFP4 的延遲:8 張真實營業影格,在共用機上 4.64 秒(10 次);10-13 在主辦的機器上獨占重量,4.34 秒(30 次)。早期用測試影像量的延遲比真實影格低很多,不引用。

速度、記憶體、斷網

項目實測出處
模型單次判斷(8 張畫面)中位數 4.34 秒、第 95 百分位數 4.56 秒(30 次,獨占)硬體測試報告-2026-10-13
輸出速度8 張畫面 11.6 tokens/秒;4 張 15.7;2 張 19.8(共用機)測試報告第四節
一張畫面的提示長度約 1,814 tokens(352×240)測試報告第四節
回查層多輪7 個候選 11.9–25.7 秒,7/7 得出結論;10-21 沙箱內 13.1 秒,第一次暖機 33.4 秒企劃書第 8 頁、部署-2026-10-21
客訴 agent11–30 秒(3 題)交接-2026-10-21
模型服務記憶體10-21 啟動後佔 19,293 MiB。其中大部分是照 24 GB 預算預留的 KV cache,實際需求約 12 GB部署-2026-10-21、企劃書第 8 頁
模型就緒時間236 秒;重啟 232 秒部署-2026-10-21
常駐層四路每路 2.5 張/秒全跟上;CPU 0.05 核、GPU 0%、334 MB測試報告第三節
全天回查71,815 張、28.08 秒決賽簡報素材-2026-10-22
每日摘要36 天全部算完,0 天失敗;每天約 85 秒交接-2026-10-21
斷網:程式攔截攔截所有對外連線,跑完整條鏈路:零次對外連線嘗試。第一次實測攔到一次:NeMo Guardrails 的使用統計,已在程式裡關掉企劃書第 8 頁
斷網:關 Wi-Fi模型從零啟動約 225 秒,和連網時一樣;流程照常硬體測試報告-2026-10-13
斷網:沙箱連外部網站全被擋,15 毫秒回錯誤;直連模型服務 403部署-2026-10-21

斷網有三種保證,來源不同:沙箱外是程式自己攔截連線;沙箱內是 OpenShell 的政策代理照白名單擋;即時判定是容器根本沒有網路。沙箱和斷網的驗收都是我們自己跑、自己記的,沒有第三方驗證。

已知限制

  1. 模型的判斷不穩定。同一筆候選,重啟後有時不呼叫 notify、只把分級寫在文字裡;分級會在店長和前場之間變。前場是不經人確認就送出的那一級。原因沒有驗證。
  2. 有一種無聲失效還沒攔。模型把 notify 寫成純文字放在結論的結尾,程式只檢查開頭,會當成正常結論收下。
  3. 遮臉會漏。俯拍鏡頭上,抓臉和姿勢模型都不能當隱私保護。所以網頁要登入、有期限,不對外說「已去識別化」。
  4. 結帳區的候選不準。人工核對 10 筆:4 筆候選都不是客人在等(框裡有吧台座位);6 筆 POS 證實的久候,收銀機前都有店員。所以候選只當線索、由人確認,不直接提醒。
  5. 驗證樣本小。9/20 那則只有 1 筆;客訴 agent 驗過 3 題;回查層的結論對不對,沒有系統性驗證。
  6. 桌況只涵蓋 A、B 兩張四人桌。
  7. 模型寫的文字,只有 notify 的句子過護欄。軌跡和客訴結論只有基本的規則檢查。
  8. 只在一家店、DGX Spark 上驗證過。NVFP4 需要 Blackwell 架構,Orin 這類機器跑不了;Jetson 沒有測過。
  9. 開發期的錄影主機不在店裡(見〈資料不落地〉)。即時警示只顯示在網頁上,沒有接到店裡的裝置。

出處:交接-2026-10-21〈還沒決定的〉、工作日誌-2026-10-21〈未解決〉、部署-2026-10-21 第八節

用詞表

這一頁的每一個詞都照這張表的意思用。

詞在本頁的意思
監視器主機(DVR)店裡原本就有的監控錄影設備。我們只向它要快照
錄影主機開發期錄店裡影格的 DGX Spark,也跑每日摘要
現場 Spark主辦在會場借我們的 DGX Spark。跑模型、沙箱、即時判定、看片網頁
影格監視器的一張畫面,352×240 像素的 JPEG,硬碟上存成加密檔
基準空店時的畫面。拿現在的影格和它比,多出來的就是人
存在訊號畫面上一塊區域裡,和基準不一樣的像素比例,0 到 1
事件結帳區有人、持續 30 秒以上的一段時間
候選事件開頭 30 秒裡,收銀機前店員訊號的第 90 百分位數低於 0.10 的事件。可能是漏接,由人確認
漏接客人站在結帳區超過 30 秒,沒有店員來結帳(店家定的判準)
來訪間隔不到 60 秒的幾個事件合成的一段
常駐層整天在跑、不用 AI 模型的影像算法
回查層有候選才被叫醒的 Agent,加上它的五個工具
客訴 agent老闆打一句客訴進來才跑的 Agent,加上它的唯讀查詢工具
工具模型可以呼叫的函式。只回數字和文字,不回影像
提醒回查層經 notify 送出的一句話,固定句型,分三級
警示即時判定用規則產生的一行字。不經模型
護欄提醒送出前的內容檢查(NeMo Guardrails)
降級某一步失敗時,退回「只記錄」,並在軌跡上標明
軌跡每一步一行的紀錄檔,只能往後加
沙箱NemoClaw/OpenShell 的執行環境,連線只能經政策代理、照白名單放行
零外部端點沙箱白名單裡,除了推論路徑和 OpenClaw 自己的回撥,沒有任何外部網域
青蛙貼在人頭上的綠色小圖。會漏,不是隱私保護
回放把過去某天的影格照原本的節奏重播,當成「現在」。畫面上一定標「回放」

評審最可能問的問題

點開看答案。答案都照實測和文件,沒驗過的直接說。

為什麼要放在邊緣,不用雲端?

兩個前提和一個選擇。前提一:畫面裡有客人和員工的臉,原始影像送上雲端就是個資風險。前提二:小店網路不穩,斷網時警示和紀錄不能停。選擇:回查層只看文字,技術上可以上雲;我們選在地,因為 POS 營運數據同樣不該離店,也不想受外部服務影響。

這會不會變成監控員工?

系統盯的是「客人有沒有被照顧到」。提醒只能是固定句型,例如「A 桌等很久了,已經 12 分鐘」,沒有自由文字的參數;送出前護欄擋對人的評價和人名。客訴 agent 的結論規定不指名、不評價員工。9/20 的例子裡,系統找出的反而是「店員全程在櫃台、客人卡在集點流程」。

但技術上管好資料,不等於回答了「憑什麼拍」。員工的告知和同意要另外做,不是這套系統能代替的。

遮臉會漏,怎麼辦?

我們承認會漏。試過三種:和空店比、有差就馬賽克(不漏,但畫面糊到看不出狀況);只抓臉(俯拍鏡頭漏很多);用姿勢模型找頭(現用,1,491 張貼了 4,106 隻,仍會漏)。所以處理方式是:網頁每個請求都要帳密、過了期限整個關閉;原始影格不放上網頁;對外不說「已去識別化」。

誤報怎麼控制?

靠分級,不靠調門檻。測得準的訊號(碗盤在不在桌上)才准當下提醒;測不準的(結帳區有人,但看不出在做什麼)只列成候選,由人確認。人工核對 10 筆結帳區資料,4 筆候選都不是客人在等,所以候選不直接提醒。模型選了「店長」級,也只會掛起來等人確認。

斷網還能不能用?

能。三種證據:程式攔截所有對外連線、跑完整條鏈路,零次對外連線嘗試;關掉 Wi-Fi 後模型從零啟動約 225 秒,流程照常;即時判定容器本來就沒有網路介面。斷網那次,找候選的部分結果一樣;模型的判斷不同,原因是重啟,不是斷網。

模型多大、多快、吃多少記憶體?

Nemotron Nano 12B v2 VL,NVIDIA 官方 NVFP4-QAD 量化版,模型檔 10.6 GB(BF16 是 26.4 GB),載入 9.95 GiB。8 張畫面一次判斷,中位數 4.34 秒;輸出約 11.6 tokens/秒。模型服務照 24 GB 預算啟動,10-21 佔 19,293 MiB,多數是預留的 KV cache。常駐層不用模型:0.05 核、GPU 0%、334 MB。沒有做剪枝。

Agent 真的有自主決策,還是只是 prompt?

模型自己決定呼叫哪些工具、呼叫幾次、選哪個分級。9/13 那筆,它查完 POS 覺得證據不夠,自己再去查現場訊號。程式負責邊界:工具重複失敗就擋、沒有進展就安全中止、工具呼叫沒被解析就算失敗、句型和分級寫死。

也有該說清楚的地方:日期和客訴類型是規則判的,不是模型;模型的分級重啟後會變,這是目前最大的未解問題。

為什麼要用 NemoClaw 沙箱?

Agent 能呼叫工具,就要限制它能碰到什麼。沙箱讓每一條連線都經政策代理、照白名單放行。出廠的白名單會放行 npm、pypi、huggingface 等,零外部端點是我們收緊後的結果,而且每次重建沙箱都要重新收緊。實測沙箱裡連外部網站全被擋;直連模型服務也是 403,只能走受控推論路徑。

換一家店要做什麼?

不換攝影機:只要店裡的監視器主機有快照網址。要做的是:在畫面上畫區域(桌子、客人區、收銀機前),取一段空店畫面當基準,接上 POS 匯出檔,用那家店的真實素材校準門檻,判準(例如「超過 30 秒算漏接」)由店家定。目前只在一家店驗證過,第二家店還沒做。

成本多少?

我們沒有做價格估算。能說的是運算量:不用換監視器、不加感測器;常駐層只要 0.05 核;模型只在有候選或有客訴時才跑,9/13 一整天只叫醒 7 次。硬體只在 DGX Spark 上驗證過,更小的機器沒有測。

28 秒那個數字是怎麼量的?樣本多少?

9/20 吧台一整天 9.5 小時、71,815 張加密影格,在錄影主機上(不是現場 Spark)跑一次「客人在結帳區連續 120 秒以上」的掃描,28.08 秒交出 4 個時刻,其中一組經店家看畫面確認是那則評論。樣本只有 1 筆,不能說召回率 100%。另外 3 個不是這則客訴。一個月後換一支程式重跑,4 筆數字完全一樣。

同樣的問題,系統每次答得一樣嗎?

不用模型的那一半一樣:換機器、斷網、重啟,抓到的事件和數字一個都沒變。用模型的那一半不一樣:10-21 四次 demo,分級一次店長、一次前場,有兩次沒有呼叫 notify。所以我們把「會不會送出」的權限放在分級規則和人工確認上,不放在模型的文字上。