AI 工程面試 · 高頻題拆解

面試官問:意圖識別怎麼做?

如果你張嘴就是「全丟給大模型就好」——這場面試基本上就結束了。
這題真正在考的不是你會不會呼叫 API,而是工程取捨能力

三層漏斗架構規則層 · 上下文層 · 工具層 DST 對話狀態追蹤閾值與拒識成本 / 延遲 / 穩定性

TL;DR一句話標準答案

「意圖識別在生產環境不是一個模型問題,是一個路由問題
我會做成三層漏斗:規則層攔截高頻固定句式(毫秒級、零成本,約 30–40%)、上下文層承接日常請求(微調小模型或語意向量 + 對話狀態,數十毫秒,約 50–60%)、工具層兜底(LLM + function calling,只吃 5–10% 的模糊、多意圖、隱含意圖)。
核心原則是——讓大多數請求在成本最低的那一層被解決。」

這句話為什麼加分?它同時回答了「你懂不懂技術選型」「你有沒有成本意識」「你知不知道要兜底」三件事,而且每一層都留了追問的鉤子,讓你有機會把準備好的深度講出來。

01為什麼不能「全丟給大模型」

面試官心裡有一張表,你只要漏掉其中一格,就會被歸到「只會呼叫 API」那一檔。

⏱ 延遲

LLM 單次推論普遍 500ms – 3s(首 token 延遲 + 生成時間)。使用者打一句「查物流」等兩秒才有反應,體驗直接崩。而規則比對只要 < 5ms,差了 兩到三個數量級

💸 成本

每一次呼叫都在燒錢,而且是隨流量線性成長的。日請求 100 萬的客服系統,全走 LLM 與走三層漏斗,帳單可以差到一個數量級(下面模擬器可以自己拉)。

🛡 穩定性

幻覺、介面逾時、供應商限流(429)、模型版本汰換造成的行為漂移——只要有一個發生,你的核心業務就跟著癱瘓。把 100% 流量壓在單一外部依賴上,是架構上的單點故障

還有兩個大家常漏講的:可測試性與可回溯——規則層的行為是確定性的,出事可以直接指出是哪一條規則;LLM 的判斷難以復現,客訴要追責時說不清楚。 ② 合規與資料落地——把使用者原話整包送到外部 API,在金融、醫療、政府案子裡往往直接違反資料政策。前兩層在自己機房內完成,本身就是一種資安設計。

02三層漏斗架構(互動流量模擬器)

拉動滑桿改變每一層吃掉的流量,即時看平均延遲、P95 延遲與每日成本怎麼變。漏斗的寬度就是還沒被解決、要往下流的請求量。

三層漏斗 · 流量與成本模擬器

預設值取自影片:規則層 35% / 上下文層 55% / 工具層 10%。所有數字都可調,右側指標即時重算。

▼ 全部使用者請求 100% ① 規則層 · 攔截 關鍵詞 / 正則 / 狀態機 3ms ② 上下文層 · 承接 小模型 / 語意向量 + DST 35ms ③ 工具層 · 兜底 LLM + Function Calling 1200ms 35% 55% 10% ↓ 65% 往下流 ↓ 10% 往下流 最終回應 · 逾時則走降級話術 / 轉人工
規則層 上下文層 工具層(LLM)

平均延遲
P95 延遲
每日成本
每月省下
相對「全丟大模型」

成本假設:規則層 NT$0.01/千次(純 CPU)、上下文層 NT$0.6/千次(自建小模型 GPU 攤提)、工具層=上方滑桿值。 LLM 單價換算範例:約 800 input + 150 output token,中階模型約 NT$45/千次、輕量模型約 NT$7/千次。實際請代入你自己的模型報價。

模擬器裡最該注意的一格是 P95。把規則層拉到 35%、上下文層 55%,你會發現平均延遲只有幾十毫秒,但 P95 直接等於 LLM 的延遲——因為前兩層加起來剛好 90%,第 95 百分位必然落在 LLM 那 10% 裡。這就是為什麼「兜底層也要設逾時上限」:平均值會騙人,尾延遲才是使用者實際的痛感。把上下文層再往上推 1%(讓前兩層 ≥ 95%),P95 會瞬間從 1200ms 掉到 35ms——面試時能講出這個轉折,等級立刻不一樣。

漏斗的核心思想,就一句話

能用規則解決的,不走模型;
能用小模型解決的,不走大模型。

03第一層 規則層 · 攔截

< 5ms零邊際成本確定性流量 30–40%

技術手段(由簡到繁)

  • 關鍵詞 / 同義詞表——最直白,用 Aho–Corasick 自動機或 Trie 一次掃完上千個詞,複雜度 O(文字長度),不隨規則數成長。這是規則層能撐住上萬條詞表還不變慢的關鍵。
  • 正規表示式——處理有結構的表達:訂單號 [A-Z]\d{10,}、手機、日期。注意災難性回溯(ReDoS),巢狀量詞的 pattern 要禁掉。
  • 有限狀態機(FSM)——處理「多輪固定流程」:辦卡、實名認證、退貨申請。每個狀態只接受有限的幾種輸入,天生就不需要模型。
  • 快速通道——按鈕 / 卡片 / 選單點擊帶回來的 intent_id,根本不需要「識別」,直接路由。很多團隊忘了算這一塊,它常常就佔了 15–20% 流量。

它該吃哪些請求

只留高頻、明確、不變的意圖:

  • 「查物流 / 我的包裹到哪了 / 貨到哪」→ query_logistics
  • 「退換貨 / 我要退貨 / 怎麼換貨」→ return_request
  • 「我要投訴 / 找人工 / 轉真人」→ to_human這條務必放最前面,是安全閥
  • 敏感詞、辱罵、自傷傾向 → 直接走風控流程,不能讓 LLM 有機會自由發揮

幾十條規則就能蓋住高頻流量——這是長尾分布的必然結果:前 20 個意圖通常佔 70–80% 的請求。

最大的陷阱:規則地獄

什麼都往裡塞,規則就會反噬。三個月後你會擁有 800 條互相衝突、沒人敢動的規則,改一條就有兩個舊功能壞掉,而且沒有人記得第 417 條是為了哪個客訴加的。規則層的維護成本,是你在面試裡必須主動提到的風險。

怎麼治理它(這段講出來很加分)

# 規則設定長這樣,而不是散在 if-else 裡
- id: rule_logistics_001
  intent: query_logistics
  priority: 100
  patterns:
    - kw: ["查物流", "物流", "快遞", "包裹到哪", "貨到哪"]
    - re: "^(我的)?(訂單|包裹|貨).{0,4}(到哪|寄出|出貨)"
  exclude_kw: ["物流費", "運費"]   # 負向詞,擋掉「物流費怎麼算」
  owner: cs-team
  reason: "日均 12k 次,最高頻意圖"
  review_by: 2026-10-01

04第二層 上下文層 · 承接

20–60ms流量主力 50–60%速度與彈性的平衡點

技術選型:兩條路線

路線做法優勢代價
微調小模型
(分類器路線)
DistilBERT / MiniLM / ERNIE-tiny 等,接一個 softmax 分類頭,用自家標註資料微調 準確率高、輸出直接是意圖標籤與機率、單次推論 CPU 上 10–30ms 加一個新意圖就要重新訓練 + 重新評測 + 重新部署;冷啟動需要標註資料
語意向量檢索
(embedding 路線)
把每個意圖的數十條範例句編碼進向量庫,查詢時算相似度取 top-k 投票 加新意圖只要加幾條範例句,零訓練、即時生效;天然支援 few-shot 語意相近的意圖容易混(「改地址」vs「改收件人」);需要維護向量庫與 ANN 索引
實務上多半是混合的:用向量檢索當召回(取 top-20 候選意圖),再用一個輕量 cross-encoder 或分類器做精排。這樣新意圖能快速上線,長期高頻的意圖再逐步「沉澱」成微調樣本,甚至再往上沉澱成規則層的規則——三層之間是會互相流動的,不是靜態的

這一層真正的難點:對話狀態

使用者說「那個呢?」「然後呢?」「那我要退了」——句子裡沒有任何意圖詞,單句分類器一定崩。你需要 DST(Dialogue State Tracking,對話狀態追蹤):維護一個結構化的對話狀態,記住

面試講法:「意圖識別的輸入不是單句,是 (當前句, 對話狀態)。我會把上一輪意圖、已填槽位、最近 N 輪摘要一起拼進特徵,省略句才接得住。」——這一句話就把你和只會做單句分類的人分開了。

05第三層 工具層 · 兜底

500ms – 3s只吃 5–10%最強理解力最貴

技術上是 LLM + Function Calling:不只判斷意圖,而是直接把意圖識別與工具執行打通——模型輸出的就是「呼叫哪個函式、參數是什麼」,省掉「先分類、再對照到 API」這一層轉譯。

它該處理什麼

意圖模糊

「怎麼會這樣啊」「這個好像怪怪的」——沒有可比對的詞,只能靠語境推。

多意圖混合

「幫我把上個月三筆訂單退掉,然後開發票給我公司」——一句話要拆成多個任務並排序。

隱含意圖

「我上次買的那個不太行,你幫我看看怎麼弄」——隱含售後意圖,要先查訂單,可能導向退換貨。

但是:大模型這一層不能裸奔

只要你在面試裡說「兜底交給 LLM」而沒接下面這幾句,追問一定跟著來。

① 逾時降級

  • 硬性逾時(例如 1.5s),超過就不等了
  • 降級順位:主模型 → 備援模型/備援供應商 → 上下文層的最高分意圖 → 通用兜底話術「我幫您轉接專人」
  • 熔斷器:連續 N 次失敗就整段跳過 LLM,維持一段冷卻期,避免雪崩
  • 成本也要熔斷:設每日呼叫預算上限,超了自動降級,別讓一次爬蟲攻擊燒掉整月預算

② 置信度校驗(別唸成「質性度」)

  • 強制 結構化輸出(JSON Schema / tool schema),拿不到合法 JSON 就當失敗
  • 模型回傳的意圖必須在白名單意圖表內,杜絕它自己發明一個意圖
  • 要求模型同時輸出 confidencereason;低於門檻就轉人工
  • 高風險動作一律要二次確認:退款、取消訂單、改地址這種不可逆操作,模型只能「提議」,執行前要使用者按下確認
// 工具層的輸出契約:不是自由文字,是可驗證的結構
{
  "intents": [
    { "name": "after_sales_consult", "confidence": 0.86,
      "slots": { "order_ref": "上次購買", "issue": "品質不佳" } },
    { "name": "return_request", "confidence": 0.52, "slots": {} }
  ],
  "next_action": { "tool": "query_recent_orders", "args": { "limit": 3 } },
  "needs_human": false,
  "reason": "使用者描述商品問題但未指名訂單,需先取回訂單清單澄清"
}
// 校驗:intents[].name ∈ 白名單、confidence ≥ τ、tool ∈ 已註冊工具、args 符合 schema
// 任一項失敗 → 降級,不進入執行

06請求怎麼流過三層(路由劇場)

點一句使用者的話,看它被哪一層接住、為什麼,以及花了多少時間。

路由劇場

同一套架構,六種輸入,落點完全不同——這就是分層路由在做的事。

使用者輸入
請點選上方任一句話
規則層待命
關鍵詞 / 正則 / FSM 比對
上下文層待命
小模型分類 + 對話狀態
工具層(LLM)待命
LLM + function calling 兜底

07對話狀態追蹤(DST)逐輪演示

「那個呢?」為什麼接得住?因為狀態不在句子裡,在狀態機裡。按「下一輪」逐步看狀態怎麼變。

DST · 對話狀態面板

左邊是對話,右邊是系統內部維護的結構化狀態。注意第 5 輪的省略句與第 7 輪的意圖切換。


        
0 / 8
三個關鍵機制,都藏在上面的演示裡:意圖繼承——本輪分類分數全低時,不要硬選,而是沿用上一輪意圖。 ② 指代消解——「那個」要對照到 entity buffer 裡最近提及的實體;有歧義就反問,不要猜。 ③ 意圖切換偵測——出現新的高分意圖時要判斷是「補充資訊」還是「換題目」;換題目就把舊意圖壓入堆疊而不是丟掉,處理完新意圖再問「剛剛的物流查詢還要繼續嗎?」

08閾值怎麼定?(覆蓋率 × 準確率權衡)

「你怎麼決定什麼時候該往下一層送?」是這題最常見的追問。答案不是拍腦袋,是拉這條曲線。

置信度閾值 τ 調節器

在 2000 筆模擬驗證集上,調整上下文層的接受閾值 τ,看覆蓋率、準確率與下沉到 LLM 的比例怎麼互相拉扯。

覆蓋率(本層接住)
accept rate
接住的準確率
precision @ accepted
答錯率(實際傷害)
錯誤且被執行
下沉到 LLM
=成本來源

資料為固定亂數種子產生的模擬驗證集(正確樣本分數偏高、錯誤樣本分數偏低),僅示意權衡形狀;真實系統請用自家標註集跑同一張圖。

實務上怎麼選 τ

09補充:意圖體系怎麼設計

影片沒講但面試一定追問的——「那你意圖是怎麼定的?」定壞了,後面三層都白搭。

粒度原則

  • 意圖的粒度=可執行動作的粒度。如果兩個意圖最後打的是同一支 API、走同一段話術,它們就該合併。
  • 反過來,如果同一個意圖底下需要走完全不同的流程,它就該拆——通常是槽位沒抽出來。
  • 一般客服系統落在 30–120 個意圖。超過 200 個通常代表你把「槽位」當成「意圖」在做了。

四類一定要有的「非業務意圖」

  • chitchat 閒聊——「你是機器人嗎」「哈囉」
  • out_of_scope 超出範圍——明確說「這我幫不上」比亂答好
  • to_human 轉人工——永遠可用的逃生門
  • unknown 拒識——不是失敗,是正確的行為。沒有拒識類的系統,準確率報表都是假的。

意圖 vs 槽位:最常見的設計錯誤

❌ 錯誤設計✅ 正確設計
意圖:查A商品物流查B商品物流查上月訂單物流……(意圖爆炸) 意圖:query_logistics
槽位:order_idproducttime_range
意圖:退貨退款換貨 混成一個 售後 拆成三個——因為它們的審核流程與 API 不同,粒度該對齊動作
一句可以背的判準:意圖決定走哪條流程,槽位決定流程裡填什麼參數。會讓流程分岔的才是意圖,只是換個值的都是槽位。」

10補充:冷啟動與資料飛輪

「一開始沒有資料,你的第二層拿什麼訓練?」——這題答不好,前面講的架構會被當成紙上談兵。

階段一 · 冷啟動(0 → 1)

  1. 先只上第一層 + 第三層。規則層蓋高頻,其餘全部丟 LLM。這時候貴、慢,但系統是能上線的。
  2. 把 LLM 的判斷結果全部落盤(原話、判定意圖、槽位、信心、使用者後續行為)。這就是你的標註資料——用大模型當標註機
  3. 人工抽檢 LLM 標註(抽 5–10%),修正後成為金標準驗證集。
  4. 累積到每個意圖 200–500 筆,就可以微調第二層小模型了。這在客服場景通常是 2–4 週的事。

階段二 · 飛輪運轉(1 → N)

  • 影子模式(shadow mode):新版第二層先只預測不決策,跟線上 LLM 的判斷比對,準確率達標才切流量。
  • 灰度放量:1% → 5% → 20% → 100%,每一階看業務指標(一次解決率、轉人工率)而不只看離線準確率。
  • 難例回流:置信度落在中間帶、使用者當輪就改口或轉人工的請求,優先送人工標註——這些是資訊量最高的樣本(主動學習)。
  • 規則層反哺:第二層某個意圖若長期以極高信心 + 極固定句式命中,把它「下放」成規則,省下更多算力。
  • 意圖發現:定期把 unknown 與低信心請求做群聚分析,跑出來的新群集就是你該新增的意圖。這是意圖體系持續演進的來源。
面試金句:「大模型在我的架構裡有兩個角色——線上是兜底,離線是標註機與教師模型。第三層產生的資料會不斷把流量往第二層、第一層推,漏斗的形狀是會隨時間變好看的。」

11補充:怎麼評測(離線 + 線上)

「你怎麼知道它做得好不好?」只講 accuracy 是不夠的。

離線指標

  • Macro-F1(不是 accuracy)——意圖分布極度不平衡,accuracy 會被高頻意圖灌水
  • 每意圖的 P/R——找出哪幾個意圖在互相吃分
  • 混淆矩陣——語意相近的意圖對是規則與樣本要補的地方
  • 拒識品質:該拒識而未拒識(過度自信)/不該拒識卻拒識(過度保守)
  • 槽位 F1 與整輪正確率(joint goal accuracy)——意圖對但槽位錯,任務照樣失敗

線上指標(面試更看重)

  • 一次解決率(不需轉人工、不需重問就完成)
  • 轉人工率使用者重述率(連續兩輪換句話說=識別失敗的強訊號)
  • 各層命中率分布——漏斗有沒有走形,是最重要的健康度指標
  • P50 / P95 / P99 延遲(分層拆開看)
  • 每會話成本(cost per session)——直接對得上財務
  • 降級觸發次數逾時率
報警怎麼設:不要對「準確率下降」報警(延遲太久才看得出來),要對分布變化報警——第一層命中率突然掉 5%、unknown 比例突然翻倍、第三層流量佔比從 10% 爬到 25%。這些幾分鐘內就能發現,而且通常代表上游改版或有人在打爆你的系統。

12補充:兩層快取(最便宜的優化)

精確快取

正規化後的原話(去空白、繁簡、全半形、表情符號)當 key,直接查結果。客服場景的請求重複率高得驚人,命中率 20–35% 很常見。做在最前面,連規則層都省了。

語意快取

用 embedding 找相似度 > 0.95 的歷史請求,複用其意圖判定。務必把對話狀態一起納入 key——同一句「那個呢」在不同上下文意思完全不同,只比對句子會直接答錯。

快取的失效設計是重點:意圖表更新、規則變更、模型換版時要能整批失效;快取 key 帶上 rules_version + model_version 是最省事的做法。沒有這個,你會遇到「規則明明改了但行為沒變」的鬼故事。

13面試答題腳本

同一套架構,兩種長度。先給 30 秒版本讓面試官決定要不要深挖,他一追問你就展開。

⏱ 30 秒版(開場必說)

「我不會把意圖識別當成單一模型問題,會設計成三層漏斗的路由
第一層規則層,關鍵詞、正則、狀態機,處理高頻固定句式,毫秒級、零成本;
第二層上下文層,微調的小模型或語意向量,結合對話狀態,這層是流量主力;
第三層才是 LLM + function calling,只兜底模糊、多意圖、隱含意圖的長尾,配逾時降級和置信度校驗。
設計目標是讓大多數請求在成本最低的那一層被解決,同時保留最終防線,讓使用者不會覺得系統很笨。」

🎯 2 分鐘版(追問後展開的順序)

  1. 先講約束:延遲要求(首次回應 < 300ms)、日請求量、成本上限、合規要求。先講約束再講方案,是資深工程師的講法。
  2. 再講分層與流量預期:35 / 55 / 10,並說明這個比例是觀測出來的、會隨飛輪改變,不是拍腦袋。
  3. 講每層的失敗處理:規則衝突怎麼仲裁、小模型低信心怎麼辦、LLM 逾時怎麼降級。
  4. 講評測與上線:影子模式 → 灰度 → 全量,線上看一次解決率與各層命中率分布。
  5. 講演進:LLM 當標註機 → 沉澱小模型 → 高頻沉澱成規則,漏斗自己會變好。
  6. 最後主動講風險:規則地獄、意圖體系膨脹、模型換版導致閾值失效。主動說出自己方案的弱點,是最強的加分項。

常見追問與答法

追問要點
怎麼決定一句話該往下沉?置信度閾值 + top1-top2 margin + 各意圖獨立閾值;中間帶反問澄清而不是硬猜。閾值由業務可接受錯誤率回推。
一開始沒資料怎麼辦?規則層+LLM 先上線,LLM 判斷全落盤當標註,抽檢成金標準,2–4 週後微調第二層。
多意圖怎麼處理?第二層做多標籤(sigmoid 而非 softmax)+ 分數門檻;真正複雜的組合交給第三層拆解成有序任務清單,逐一確認執行。
LLM 掛了怎麼辦?逾時上限 → 備援模型/供應商 → 降回第二層 top1 → 通用話術+轉人工;配熔斷器與每日成本上限。
怎麼加一個新意圖?先在向量層加幾條範例句當天生效,累積真實樣本後再納入下一次微調,最高頻的再下放成規則。三層是有流動路徑的。
怎麼評估這套架構值不值得?算兩個數:每會話成本P95 延遲,跟全 LLM 基線比。順便講「前兩層必須 ≥ 95% 才能把 P95 壓下來」這個非線性效果。
為什麼不直接用 LLM 做 router?那只是把問題往上推一層——router 本身就有延遲與成本。可以用「小模型 router + LLM 執行」,但判定入口一定要便宜。

四種會被扣分的回答

❌「全丟給大模型,讓它判斷就好」——沒有工程取捨。
❌「用 BERT 做個分類就好了」——只有單句視角,沒有對話狀態、沒有拒識、沒有兜底。
❌「寫一堆正則就能解決」——沒有泛化能力,也不知道規則會反噬。
❌ 只講技術不講數字——說不出延遲量級、流量佔比、成本量級,會被認為沒做過線上系統。

14一頁速查表

① 規則層② 上下文層③ 工具層
定位攔截承接兜底
技術關鍵詞 / 正則 / FSM / Aho-Corasick微調小模型(DistilBERT 等)/語意向量檢索 + DSTLLM + Function Calling + 結構化輸出
延遲< 5ms20–60ms500ms – 3s
流量30–40%50–60%5–10%
邊際成本≈ 0極低(自建攤提)高,隨流量線性成長
比的是速度平衡理解力
主要風險規則地獄、維護成本語意相近意圖混淆、需要重訓幻覺、逾時、成本失控
必配機制優先級仲裁、命中率監控、回歸測試閾值+margin 拒識、機率校準、影子模式逾時降級、熔斷、白名單校驗、二次確認

這套架構到底解決了什麼

  • 分層路由——每一層只做自己最擅長的事,規則層拚速度、模型層拚平衡、大模型層拚理解力,互不越界
  • 成本優先——越靠前的層成本越低,90% 的請求在前兩層就解決,根本不需要驚動大模型。
  • 兜底保障——剩下 10% 的複雜場景依然有最終防線,使用者不會覺得這個系統很笨。

15逐字稿勘誤(語音辨識錯字)

原影片是自動字幕,幾個關鍵術語被聽錯了。照著錯字背去面試會很尷尬,這裡一併校正。

字幕寫的正確術語說明
DSG 攔截快速攔截(規則層 fast path)字幕誤植;同段後文出現的 DST 才是真術語
DSTDST = Dialogue State Tracking對話狀態追蹤,這個是對的
DisturbedDistilBERTBERT 的蒸餾版,參數約 40% 少、推論快約 60%
複雜常位請求複雜長尾請求long-tail
逗底響應兜底回應fallback response
質性度較艷置信度校驗confidence validation
語意向量做相似度語意向量(embedding)相似度匹配正確,補上英文
退還貨退換貨