kitt-stt 的 Agent 驗證與效能分析平台

最值得導入的是一個完整的驗證流程:agent 能找到功能、啟動自己的服務、以正式協定驅動、保存原始證據,再讀取小型結構化結果。kitt-stt 已有大部分工具;目前的問題是這些工具分散,功能測試、效能量測與 trace 的界線沒有在同一入口說清楚。

本次已在獨立 worktree 導入專案內的 verify-kitt-stt skill、Docker 證據出口、既有硬體 profiler 的整合,以及 Perfetto SQL 查詢。圖表沿用既有工具,沒有新增 observability server 或修改 STT 推論邏輯。這是一個可執行的平台起點,尚不是自動判定效能回歸或自主調參的系統。

研究基準為本機 main67160fab;分支為 research/agent-verification-20260912,目錄為 隔離研究工作樹。外部來源查閱日期為 2026-09-12。下文區分程式已提供的能力、實跑結果與尚未實作的建議。

1. pstack 哪些流程值得採用

這裡的 pstack 指 Cursor 公開的工程 workflow 集合。它的價值是把工作拆成有證據門檻的流程;不同 playbook 的交付物不同,不能用同一個「測試綠燈」代替所有結論。1

公開流程 核心做法 在 kitt-stt 的落點
Create verification skill 從 repo 找出介面、啟動方式、驅動方式、證據與隔離條件;至少實跑一個功能 專案內 skill + 五個 feature map,沿用真實 WS/WAV harness
Maintain verification skill 同時核對程式與真實操作;地圖列出的功能都要覆蓋 後續用 $maintain-verification-skill,單個功能通過不能代表全地圖通過
Perf issue 先量 baseline,再提出由 trace 支持的修正,最後比較前後結果 同一輸入、環境、pacing 與暖機下重跑;不憑讀碼推算加速百分比
Runtime forensics 針對正在發生的症狀取樣,再對應到程式位置 CPU、RSS 或 GPU 症狀分別選工具;避免同時開啟所有 profiler
Trace forensics 對既有 artifact 查詢、縮小範圍、對應來源;有配對 capture 才比較 官方 Trace Processor + 本次 SQL;保留原始 gzip,不把大 JSON 塞進 context
Hillclimb 固定工作負載與指標,一次一項變更,量測後決定保留或撤回 待基線具備重複樣本、品質守門與可信比較條件後,再引入逐次實驗記錄

上述流程分別來自建立/維護 skill 與各 playbook。234567 採用的是驗證原則;pstack 的特定編輯器安裝方式、模型配置、開 PR/合併流程不會自動成為這個 repo 的操作授權。

對 agent 最重要的介面是「給定問題,應執行哪一條命令;結果在哪裡;哪些數字能支持結論」。讓它看懂更多圖像有幫助,但若缺少輸入雜湊、量測邊界、樣本數與退出狀態,一張漂亮圖表仍然容易導致錯誤歸因。

2. 目前 repo 已經有哪些能力

flowchart TD
    A[Feature map:選擇功能與證據] --> B[Docker harness:獨立 image / container / localhost port]
    B --> C[Doctor:health / build / model / target]
    C --> D[Live tests:真實 WAV + WS frames]
    D --> E{功能是否通過}
    E -->|是,且要求效能量測| F[既有 hardware_profile:bulk + realtime]
    E -->|否,或不做效能量測| G[保留退出碼與證據]
    F --> G
    G --> H[確認 driver 結束後的新 trace 快照]
    H --> I[停止並匯出 logs / config / trace]
    I --> J[清除本次 container ID]
    J --> K[JSON / CSV 給 agent;HTML / Perfetto 給人]
能力 現有來源 適用範圍與限制
自有容器啟動 tests/docker-test.sh 既有 health gate、CPU fallback、模型掛載與測試入口;本次補上證據保存
主要使用介面 src/server.py:create_stt_processorsrc/html_server.py WebSocket frame 協定;status page 並非語音體驗的主要驗證路徑
功能重播 tests/functional/live/conftest.py:_run 真實音訊與控制 frame,但每個 20 ms chunk 只等待 3 ms,屬加速驗證
單使用者效能 tests/batch_decode/hardware_profile.py:run_feed_series bulk/realtime 分開;每個 feed 一條連線,預設三次暖機;已有 JSON、CSV 與互動 SVG 圖表
多使用者效能 tests/batch_decode/concurrency_profile.py 已有多座位、重疊送音量測;適合下一階段驗證 shared recognizer 的排隊成本
ASR 分段成本 src/asr/batch_asr_manager.py preprec_lock_waitdecodeget_resitnpost,部分事件帶 final/interim phase
服務端延遲 src/kitt_stt_service.py:1679:1747 final frame 的 latency、TTFT、RTF、interim 成本;trace 另有 final_tm_breakfinal_utt
使用者負載 src/kitt_stt_service.py:_emit_seat_load audio_lagocc;後者是 handler 佔用比例,不是 GPU utilization
系統資源 utils/sys_diag.py:create_periodic_metric_recorder 約每 2 秒 CPU/RSS/GPU 記憶體取樣;部分為整機、部分為單 process
Trace 留存 utils/perfetto_trace.py:write_tracesrc/server.py:298 原子寫入 gzip、旋轉檔案、600 秒滑動保留窗;旋轉快照可能重疊
連線 log src/server.py:debug_logssrc/html_server.py:_handle_connection WS trace_id 對應 HTTP log 查詢;目前並非所有 live case 都輸出這種關聯資料
TurnSense 時間 src/turnsense/runtime.py:analyze log 已區分 inference 與 semaphore queue;目前沒有同等完整的 Perfetto domain spans

因此,新增另一套 benchmark driver 或另一套 chart renderer 的收益不高。先把既有資料保存、標記邊界,再提供可查詢形式,能以較小改動讓下一個 agent 直接使用。

3. 指標必須先定義量測邊界

指標 現有定義/來源 可以回答 不能直接推論
server_latency_ms final latency_msBatchASRManager.run_offline_inference 的整段 wall time final ASR 路徑是否變慢,包含準備、等待與後處理 純 GPU kernel 耗時、整個 EOT 等待
decode span recognizer 解碼的 duration event 解碼區段的 wall time GPU 上所有 kernel 的獨立成本與佔用率
rec_lock_wait recognizer lock 取得前的等待 多使用者競爭是否拖慢 final/interim executor queue、網路排隊或所有 event-loop stall
server_rtf 累計 decode time ÷ 有效音訊長度 推論計算成本相對語音長度的比例 一定能即時回應;RTF 不包含所有等待成本
server_ttft_ms 服務端第一個 interim 的時間;沒有 interim 時可退回 final 首個辨識輸出的等待 第一個正確可用 token;fallback 與真正 interim 應分開
client_final_latency_ms driver enqueue VAD stop 到 client 收到 final 的同一 monotonic clock 差 應用協定端 final 到達延遲 聲學說完話到 UI paint,或 authoritative EOT commit
ttfs_ms 服務端 wall clock 相對 VAD stop 時間與 stop_secs 補償 現有服務定義下的 final segment 時間 與 client monotonic 指標無條件相減或互換
max_interim_gap_s client 相鄰兩個 interim 的最大間距 使用者在中途看到文字停頓多久 首次 interim 前/最後 interim 後的尾端空窗
proc_mem (MB) process RSS 的週期樣本 長時間或多輪操作的記憶體趨勢 哪個 Python object retained,或 CUDA allocation 根因
GPU memory 平台可取得的整機/process counter 記憶體容量與趨勢 CUDA kernel 時序、是否 compute-bound;Jetson 的共享記憶體也不能照搬獨立 VRAM 解釋

hardware_profile.py 的 HTML 另把 server_rtf × duration_s 顯示為累計運算時間。它是由比值回推的量,不是新的端到端量測,而且報表 duration_s 與服務端包含 preroll 的有效音訊分母可能不同。需要精確分解時,讀 final metrics 或 trace 的原始時間。

EOT 尤其需要獨立處理。src/eot.py:apply 的 WAIT 可以先送 final text,再繼續等待;COMMIT 有 final 時把 EOT metadata 附在 transcription,沒有 final 時才送明確的 semantic stop。只看「收到 final」或某個 stop callback,無法證明使用者的 turn 已正確結案。

4. 需要補哪些指標與圖表

以下是後續增量的優先順序。只有表中的第一列已在本次導入;其餘是有來源落點的建議。

優先序 增量 建議落點 交付形式/判讀方式
P0,已導入 保存身分、輸入與輸出、provider path、錯誤;可查詢 trace tests/docker-test.shtests/verification_evidence.py manifest、input SHA-256、XML、JSON/CSV、原始 trace、SQL 摘要
P1 connection/turn/segment/run 關聯鍵 live driver、UserSession/turn state、trace args 用同一 key 串 input、final、EOT、log、trace;UID 單獨不足以區分多條連線
P1 vad_stop → finalvad_stop → authoritative commit 分開量 接收器觀察 EOT metadata;src/eot.py:_commit 各自的樣本表及依 commit reason 分組的延遲分布;timeout 另外計數
P1 timeout/error/空 final/重複 commit 的分母 driver collector 與 live assertions 成功率、漏失率與錯誤率;不要只留下成功樣本的低 latency
P1 每 workload 的重複試驗與公平比較 既有硬體與 concurrency profiler 周邊 每 feed、長度、座位數的樣本數、median、spread;箱形圖或 ECDF 比單條平均線更能呈現抖動
P1 將 TurnSense frontend、queue、inference 分成 trace spans src/turnsense/runtime.py:analyze 看 ASR 與 TurnSense 並行期間,critical path 到底由哪一段決定
P2 event-loop lag、executor submit→start、trace flush 等待 event-loop 定時 probe、asyncio.to_thread 邊界、PerfettoTracer.write_trace 延遲時間序列與 domain timeline 並排,量到後才決定要不要保留埋點
P2 斷線後的 RSS/VRAM 基線及多輪斜率 既有資源 counters + 重複連線工作負載 以完成 session 數為 x 軸;暖機與 allocator cache plateau 要排除
P2 EOT 品質與 CER/WER 聯合評估 現有 bilingual/wake/EOT cases 與代表性語料 latency–quality 對照;避免以過早結案或辨識品質下降換速度

建議的比較最小單位是「固定一個 workload cell」。例如同一 6 秒音訊、realtime、單座位、相同暖機、同一模型與 provider,先做多次獨立 baseline,再交錯跑 A/B。不同長度或 bulk/realtime 不可混成一個 p95。三輪可作為初步穩定性檢查,但不是統計充分性的保證;尾端指標需要更多樣本與跨輪穩定性。

圖表應由原始資料產生並保留 CSV。對 agent,先給每個 cell 的 JSON 摘要與查詢入口;對人,提供可縮放的 latency/RTF/interim 曲線,再在需要比較時補分布圖。沒有足夠樣本時,圖與文字都標成 smoke measurement。

5. 工具選擇

工具 適合的問題 本次決策
既有 live WS harness 功能正確性、wake/standby/control 保留,作為每次量測前的功能 gate
既有 hardware/concurrency profiler 即時送音、音檔長度與座位數對 latency 的影響 導入 hardware profile;concurrency 作為下一個 workload 維度
Perfetto Trace Processor domain durations、counter、parser diagnostics 的可程式化查詢 已下載官方 v58.2 CLI 到 /tmp、核對官方 manifest SHA-256,實際查詢本次 trace
Perfetto 官方 AI skill 讓 agent 學習 CLI、schema discovery 與 PerfettoSQL 有官方流程可採用;本次先用 CLI + repo SQL,未安裝全域 plugin
py-spy Python CPU 熱點、執行緒堆疊;可選 native frames 有 CPU 症狀再啟用,優先留下 speedscope/raw 格式;須能確認目標 process
Memray Python/native allocation、長時間成長的配置來源 RSS 趨勢確認後,以獨立 process 的 memray run 取證
Nsight Systems CUDA API、kernel、CPU/GPU 同步或 GPU idle gap 明確 GPU 時序問題才使用;目前 domain trace 沒有 CUDA kernels,無法憑空分析
OpenTelemetry 跨 web-ui/gateway/STT 的因果關聯、長期觀測 先補服務內的 correlation;單機證據流程不足時再導入跨服務 spans

Perfetto 官方文件已直接提供 AI workflow 與 Trace Processor 的 SQL 介面;現有 Chrome JSON trace 可由 CLI 載入,無需先自製另一套 trace database。89 本次 SQL 額外保留 track 與 final/interim phase,輸出樣本數、平均、p50、p95、最大值以及 counter 和匯入診斷。

py-spy 能輸出火焰圖、speedscope 或 raw 資料,也支援部分平台的 native stack。10 Memray 的 run 適合從 process 開始取 allocation profile;native mode 回答的問題比 RSS 數字更深入,但也會增加觀測成本。11 Nsight Systems 提供 CUDA 與系統時序,應在 GPU 假說明確時使用。12 三者都未在本次安裝或執行,不能把它們寫成已得到的診斷證據。

6. 本次實際導入

6.1 一個可重跑的入口

在專案內新增 .agents/skills/verify-kitt-stt/,有 Launch、Doctor、Drive、Evidence、Cleanup、Helpers,並列出 streaming ASR、wake、manual control、forced stop、connection logs 五個功能。skill 裡的命令可直接在這個 worktree 執行,不依賴原先 workspace 共用文件的固定 checkout。

tests/docker-test.sh 增加兩個 opt-in 參數:

EVIDENCE_DIR=/path/to/local-evidence PROFILE_LENGTHS=3,6 \
  IMAGE=kitt-stt:my-verification HOST_PORT=9317 \
  LIVE_TEST_TARGET=tests/functional/live/test_btn_control.py \
  ./tests/docker-test.sh --build -k test_btn_activate

指定全新目錄後才收集證據。PROFILE_LENGTHS 啟用既有硬體 profiler;不指定則維持功能驗證。快取音檔必須存在,避免原本的音檔 generator 在不知情時呼叫外部 TTS。skill 提供以 repository WAV 產生 3/6 秒測試片段的本機步驟。

6.2 證據與失敗語意

Manifest 記錄 Git revision、工作樹狀態、來源檔雜湊、命令、host 與參數;另保存 ASR 模型/輸入 WAV 雜湊、有效設定、實際 image ID 與 port binding。原有 profiler 即使有 timeout row 仍可能 exit 0,因此 wrapper 會讀回 JSON,拒絕錯誤列或缺失/非有限的數值。

容器由 docker create 回傳的 ID 管理。每次 provider attempt 有自己的 artifact 目錄;收集與停止之後才 remove 該 ID。測試失敗保留原 nonzero code;若功能本來成功但證據匯出失敗,整次驗證仍為 nonzero。這些契約已有獨立的可執行檢查,Docker 替身只用來測 harness 的成功/失敗/copy error 路徑;STT 功能驗收則使用真實服務。

6.3 實跑才發現的 shutdown 邊界

src/server.py:322 設定 tracing signal handler,但 src/html_server.py:89serve() 會透過 event loop 重新註冊 SIGINT/SIGTERM。第一次 capture 實際只看到 shutting down ...,沒有 Final trace flushed。Tracing threads 為非 daemon;不能把 docker stop 當成已完成最後 flush 的證據。

本次保留服務端程式,讓收集器在 driver 結束後確認兩次新的週期 trace 寫入,再停止容器。第二次寫入排除第一個 snapshot 在 driver 結束前已開始序列化的可能。capture.json 分別記錄 snapshot_after_driver_exitfinal_flush_logged;後者可以是 false,前者必須有證據。這增加約兩個 flush interval 的等待,預設最多約 20 秒,另加 Docker 停止等待。

這個做法保留的是已完成 driver 工作的證據,並沒有修好服務端 shutdown。下一個獨立 runtime 修正應讓 trace cleanup 綁在 app.serve() 的生命週期 finally,以避免 signal handlers 互相覆蓋;需要另行驗證正常停止、啟動錯誤與重複 cleanup。它也不會把「driver 提早斷線、尚未 commit 的 turn」變成完整 EOT 測試。

7. 驗證結果與解讀

第一輪已通過單一 control 功能與四個 profile rows,但缺少 final flush 確認,整輪被正確標為失敗,證據仍留在 /path/to/local-evidence。修改收集方式後的完整 skill 重跑使用 /path/to/local-evidence;該輪 exit code 為 0,capture 沒有匯出錯誤,共保留 3,778 events,snapshot_after_driver_exit=true。精確 container ID 的移除與證據留存已核對並寫入 cleanup-check.json

最後將 health 的純文字回應命名為 health.txt 後,又以同一映像重跑單一 control 功能;證據在 /path/to/local-evidence。該輪 1 passed、5 deselected,exit code 0,317 events 保留,容器已移除。前述完整 profile run 仍保留當時名為 health.json 的原始純文字回應,未改寫歷史證據。本次建立的兩個 image tags 亦已清除;重跑 skill 會重新建置。

測試主機為 RTX 4090,driver 580.173.02。ASR startup path 為 cuda (config default),有效設定仍使用 CUDA;TurnSense 在其 runtime 中檢查實際 active provider。ASR 的 label/設定不等於逐節點 provider assignment 證據,因此這裡不宣稱每個 ASR operator 都在 GPU。主機同時有其他既存服務,本次沒有獨占 GPU;數字只驗證量測流程。

重播音訊由 say-lock-all.wav 本機重複/裁切,長度為 3 秒與 6 秒;每種 feed 先暖機三次,表中每格只有一次正式樣本。

Feed 音訊長度 final ASR wall time client final latency RTF interim 數 最大相鄰 interim 間距 實際送音時間
bulk 3 s 32.31 ms 38.51 ms 0.014 1 不適用 0.04 s
bulk 6 s 45.02 ms 50.50 ms 0.009 1 不適用 0.04 s
realtime 3 s 42.15 ms 45.83 ms 0.072 4 1.026 s 3.17 s
realtime 6 s 45.98 ms 49.24 ms 0.079 7 2.550 s 6.34 s

原始 JSON、CSV 與 互動圖表 同時保存。重點是即時模式有 interim 與可量測的停頓;即使 final latency 只有約 49 ms,6 秒樣本中間仍出現約 2.55 秒的更新間隔,因此「final 很快」不足以描述整體體驗。此現象尚未完成重複實驗與根因歸因。

這不是優化前後比較:兩輪服務端程式相同,不能把其差異歸功於效能改善。暖機、OS 排程、音訊 pacing、共享 GPU 與 callback 行為都可能影響數字。查詢整條 trace 時也會包含功能 case、暖機、bulk 和 realtime,必須保留這個混合 workload 標記。

Perfetto v58.2 能載入本次 trace 並執行 repo SQL,但也報告 trace_sorter_negative_timestamp_dropped(1)和 slice_spill_overlapping_complete_event(3)。第一輪原始資料確認負時間戳來自 server_startup:它的開始時間早於 tracer 自己的 time origin。重疊事件使用相同 logical thread track,不能把畫面上的 nesting 當成真實 CPU call stack。這些警告沒有被刪掉或自動「修正」;分析 startup 與 parent/self-time 時必須先修正輸出語意。

SQL 摘要 與 parser log 保留這些診斷。查詢各 track 後加總的 domain event 數量已與原始 JSON 核對:interim decode 48、final decode 11;這包含暖機與功能測試,並非 4 個正式 profile rows 的樣本數。核對結果在 sql-validation.json

驗證 範圍與結果
新增 artifact contract 檢查 python3 tests/test_verification_evidence.py,2 項通過;涵蓋成功、測試失敗、copy 失敗與無效 profile 數值
相關 offline checks verification evidence、live URI、model manager、image build freshness 等,52 passed
規格追溯 tests/test_spec_traceability.py,3 passed;新測試明示屬驗證設施,沒有產品 SW_id
靜態檢查 新增 Python 的 Ruff、shell syntax、Git whitespace 檢查通過
真實功能 test_btn_activate,1 passed、5 deselected;不是整個 live suite
效能 smoke 2 bulk + 2 realtime rows 成功;不是品質 corpus 或統計回歸 gate
全套 regression 本次未執行;服務端推論與對外 frame 行為沒有修改

8. 下一階段如何讓 AI 自主評估

先以目前的入口建立少數代表性 workload:短指令、長句、wake-only、COMPLETE、INCOMPLETE、退出詞以及多座位完全重疊。每個 workload 指定它要觀察的 final/commit/cancel 契約,以及可接受的錯誤率;品質 gate 與效能數字要一起保存。

接著增加 correlation 與多次試驗。每個 observation 至少包含 run ID、connection ID、turn/segment ID、輸入雜湊、feed、長度、座位數、暖機標記、成功/錯誤狀態,以及其時間邊界。再把「前後環境是否相容」做成可檢查的比較前提。當前 manifest 提供追溯材料,但尚未自動阻擋所有不可比的比較。

最後才採用 hillclimb:固定 workload 與品質 gate,提出由 trace 支持的一個假說,每次只改一個因素,保存 before/after/spread/測試結果,決定保留或撤回。若 metric 的波動大於變更效果,就回到量測流程排除干擾,而不是讓 agent 繼續猜測微調。這是本研究建議的最小演進路線。

評估 agent 平台本身

STT latency 是產品指標;驗證平台還需要評估 agent 是否能可靠取得結論。可用固定任務與乾淨 worktree,對比導入前後的操作紀錄,先量下面四項,不把本次導入直接宣稱為 token 或工時節省。

平台指標 可執行的判定方式
從任務到首份有效證據的時間 記錄開始、Doctor 通過、drive 完成、artifact gate 通過的時間;分開建置與服務冷啟動
錯誤成功率 以 timeout row、缺失 metric、copy failure、錯誤 target 等已知失敗注入檢查是否仍被宣告成功;本次已有前三種的 harness 檢查
可重跑與可追溯比例 新 agent 只讀 skill,能否用 manifest 的輸入/設定/revision 重跑並找到原始證據
結論的 context 成本 比較 raw trace 全讀與 SQL 摘要加精準回查的輸入量;摘要也必須能回指相同 artifact 與 query

這些指標比新增 agent framework 更能回答「平台是否真的讓 AI 更有效」。目前已驗證的是操作與證據流程;尚未進行盲測的 agent A/B evaluation。

來源

Repository 來源以本工作樹為準:tests/docker-test.shtests/verification_evidence.pytests/verification_trace.sqltests/functional/live/conftest.pytests/batch_decode/hardware_profile.pytests/batch_decode/concurrency_profile.pysrc/server.pysrc/html_server.pysrc/asr/batch_asr_manager.pysrc/kitt_stt_service.pysrc/eot.pysrc/turnsense/runtime.pyutils/perfetto_trace.pyutils/sys_diag.py


  1. Cursor / pstack,README,公開 workflow 目錄,查閱 2026-09-12。 

  2. Cursor / pstack,Create verification skill,查閱 2026-09-12;本地使用版本由同名已提供 skill 定義。 

  3. Cursor / pstack,Maintain verification skill,查閱 2026-09-12。 

  4. Cursor / pstack,Perf issue,查閱 2026-09-12。 

  5. Cursor / pstack,Runtime forensics,查閱 2026-09-12。 

  6. Cursor / pstack,Trace forensics,查閱 2026-09-12。 

  7. Cursor / pstack,Hillclimb,查閱 2026-09-12。 

  8. Perfetto,Trace Processor,查閱 2026-09-12;CLI 實測版本 v58.2-add693d8b。 

  9. Perfetto,Using AI with Perfetto,查閱 2026-09-12。 

  10. Ben Frederickson / py-spy,README,查閱 2026-09-12。 

  11. Bloomberg / Memray,The run subcommand,查閱 2026-09-12。 

  12. NVIDIA,Nsight Systems User Guide,查閱 2026-09-12。