← 回作品列表

天線場型分析工具

Antenna Pattern Analyzer with AI KPI Audit

把多種格式的天線場型量測(CSV / XLSX / .dat / .aten / .ffs)正規化為統一資料模型與 2D/3D 視覺化,並以 deterministic KPI 計算為基礎、LLM 僅做 grounded 覆核。

rf RF天線場型視覺化LLMKPI 原始碼:私有

問題現場

天線工程師手上的場型量測檔來自好幾種來源與年代:新版 Excel 長表、舊版正規化 workbook,以及 .dat.aten.ffs 等格式。要把它們畫成 2D/3D 圖、算出關鍵指標、再跟廠商規格比對。

我最早以為難點在「格式多」,後來發現真正會出事的是定義對不上:不同來源對「方向角度」的認定不一致——有些量測站把 theta / phi 的語意對調。一旦對調又沒被抓到,畫出來的場型圖漂漂亮亮、看起來完全合理,工程判讀卻是錯的,而且很難一眼看出來。錯的還不只是這張圖,是後面所有判讀和給廠商的回饋。

最小技術背景

  • 天線場型(antenna pattern):天線往各方向收發訊號的強弱分布。
  • theta / phi:描述方向的兩個角度。本工具的約定是 theta = 仰角 0–180°phi = 方位角 0–360°
  • matrix shape:場型資料是一個矩陣,這裡固定為 (len(theta), len(phi))——列對應 theta、行對應 phi。
  • realized gain:天線實際輻射效率納入後的增益;.ffs 提供的是 E-field,需要換算。
  • grounding:讓 AI 的判斷「踩在已確認的事實上」,而不是自己猜。

系統架構與資料流

核心原則:KPI 由確定性程式算,LLM 只做覆核與解釋,永遠不讓模型憑空產出工程數字。形狀驗證是整條鏈的閘門:

flowchart TD
  F["多格式檔案|dat / aten / ffs / excel"] --> P["依副檔名分流 parser"]
  P --> N["正規化成統一 PatternData|釘死 theta/phi 與 shape"]
  N --> V{"matrix shape 驗證"}
  V -->|不符| BLK["擋下,不進視覺化"]
  V -->|符合| K["計算 KPI|peak gain / efficiency / coverage"]
  K --> VIS["2D polar + 3D surface 視覺化"]
  K --> LLM["LLM grounded audit|只覆核,不算數字"]

關鍵設計決策(含取捨)

決策選了什麼否決的替代為什麼
資料模型所有格式先收斂成統一 PatternData每種格式各自一套處理 + 各自畫圖否決:同樣的邏輯散在好幾處,改一個忘一個,遲早不一致
座標語意在 parser 層把 theta/phi 與 row/col 對應釘死當成 UI 細節、畫圖時再調否決:座標語意是「產品對不對」的問題,不是「畫面好不好看」的細節
形狀檢查依檔案實際內容動態驗 shapehard-code 取樣點數量否決:格式一變就靜默失真,圖照畫,只是畫錯的
AI 角色KPI 先 deterministic 算,LLM 只覆核讓 LLM 直接讀原始檔給結論否決:模型很會給那種「看起來很對、其實是錯」的數字

代表性技術證據

統一資料模型與形狀驗證(pseudo-code,示意)

def to_pattern_data(theta, phi, gain):
    # 不寫死數量;拿檔案真正的維度來驗,對不上就擋下、不放行
    assert gain.shape == (len(theta), len(phi)), \
        f"shape {gain.shape} != ({len(theta)}, {len(phi)})"
    return PatternData(theta=theta, phi=phi, gain=gain)  # row=theta, col=phi

舉個具體的:某檔讀進 theta=[0,90,180](3 點)、phi=[0,90,180,270](4 點),那 gain 就必須是 3 × 4。要是拿到 4 × 3,代表來源把 theta/phi 對調了——這時候我寧可直接擋下,也不要默默畫一張看起來沒事的錯圖。

LLM grounded audit(pseudo-code,示意)

kpi = compute_kpi(pattern)                 # 數字先用確定性程式算好,這步不關 AI 的事
audit = llm.audit(kpi, vendor_spec)        # LLM 只負責解釋、挑可疑,絕不讓它算數字
assert_schema(audit, REQUIRED_KEYS)        # 鎖死回傳格式,免得它今天這樣回、明天那樣回

踩過的坑

欄位內容
症狀某舊格式匯入後,3D 主瓣方向看起來合理,卻與量測站報告對不上
初判(猜錯)第一個念頭是繪圖的角度/視角設錯了
驗證印出 matrix shape 與軸對應,發現列、行其實對到了相反的角度
根因該格式的 theta/phi 語意與內部約定相反,且當時沒驗 shape
修法在 parser 層強制依檔案內容對齊(列=theta、行=phi)並驗 shape,不 hard-code
預防新增「theta 與 phi 維度不相等」的 synthetic case,對調時必定失敗

驗證方式

  • 形狀 / 語意:拿刻意讓 theta、phi 點數不同的 synthetic 場型,看對調時會不會乖乖被擋。
  • 報表一致性tests/test_app_gui_frequency_report.py 驗證 axis label、KPI 欄位、矩陣方向一致。
  • AI 回傳tests/test_llm_prompt_schema.py 鎖 prompt / 回傳 schema,防止格式漂移。
  • 驗收標準:同一份資料,圖、KPI 與報表三者方向一致,且 LLM 不得改動數值、只能標註。

可複製 SOP:把外部資料安全接進分析工具

適用情境:要把多來源、語意可能不一致的資料,接進同一個分析或 AI 工具。

不適用情境:單一固定格式、語意已保證一致時,可省略動態驗證。

前置條件

  • 先寫下這個領域「不可妥協的定義」(這裡是 theta/phi 語意與 matrix shape)。
  • 準備至少一組刻意「會出錯」的合成資料(如 theta、phi 點數不同),用來證明驗證真的會擋。

步驟

  1. 收斂模型:不管來源幾種格式,先全部收成同一套內部資料模型。
  2. 入口驗證:在入口就按檔案實際內容驗 shape / 語意,別寫死數量。
  3. 確定性計算:關鍵指標(KPI)一律自己用程式算,不外包給 AI。
  4. AI 只覆核:定義釘死、數字算好了,才輪到 AI 解釋與挑可疑。
  5. 鎖回傳格式:AI 輸出限定固定欄位,再用 schema 測試把漂移擋掉。

停損點

  • shape / 語意驗證不過 → 擋下,不進視覺化(寧可不畫,也不畫錯)。
  • 合成「會出錯」案例沒被擋下 → 驗證本身失效,先修驗證再說。

驗收標準

  • 對調、缺欄、格式變動都會被擋。
  • 同一份資料,圖、KPI、報表三者方向一致。
  • AI 不能竄改任何數值,只能標註。

回滾:parser 對應出錯時,回到最後一次「合成案例全綠」的設定。

可複製到:任何「先確立 domain 事實、再讓 AI 覆核」的資料工具。

決策回放(三個月後回讀用)

  • 背景:把零散、語意不一致的天線量測檔,做成可信、可比對的分析工具。
  • 限制:不可外流內部 LLM 服務憑證、.env、廠商規格與真實客戶量測資料。
  • 考慮過但放棄:讓 LLM 直接讀原始檔給 KPI——被「會給看起來對、其實錯的數字」否決。
  • 證據PatternData shape 驗證、KPI 確定性計算、prompt schema 測試。
  • 未解:要主打哪個格式(.dat / .aten / .ffs);是否加 theta/phi 教學小節。

作者備註: 這案子最容易被低估的一點:座標方向搞反,圖還是很漂亮。所以「定義」一定要放在會擋人的程式檢查裡,不能靠看圖的人自己小心。