複雜的情境 會需要動態使用不同的 prompt、不同的 tool functions
大概長怎樣呢 我想看個感覺
輸出內容
=== Dynamic Routing - 動態路由 ===特點:根據當前狀態動態提供可用工具,AI 只看得到當前可用的功能
【場景 1:登入問題 - 密碼錯誤】
客戶:你好,我無法登入
[執行:record_issue]
[狀態:phase=recorded, type=, resolved=]
[執行:classify_issue]
[狀態:phase=classified, type=login, resolved=]
助手:請您提供您的帳號和錯誤訊息,以便我能夠協助您解決登入問題。
客戶:帳號是 [email protected],說密碼錯誤
[執行:handle_login]
[狀態:phase=done, type=login, resolved=1]
助手:您的登入問題已解決。我已經將密碼重置連結發送至您的信箱,請按照郵件中的指示重置密碼。如果還有其他問題,請隨時告訴我!
客戶:謝謝
助手:不客氣!如果您還有其他問題或需要進一步的協助,隨時可以聯繫我。祝您有美好的一天!
--- 檢視記錄的狀態資料 ---
登入資料:{
"username": "[email protected]",
"error_message": "密碼錯誤",
"timestamp": "2026-02-12 15:11:36"
}
【場景 2:登入問題 - 需要升級】
客戶:我的帳號被鎖定了
[執行:record_issue]
[狀態:phase=recorded, type=, resolved=]
[執行:classify_issue]
[狀態:phase=classified, type=login, resolved=]
助手:請提供您的帳號名稱及收到的錯誤訊息,以便我幫您處理登入問題。
客戶:帳號是 [email protected],錯誤是 Account Locked
[執行:handle_login]
[狀態:phase=classified, type=login, resolved=]
[執行:escalate]
[狀態:phase=escalated, type=login, resolved=]
[執行:create_ticket]
[狀態:phase=done, type=login, resolved=]
助手:我已為您的帳號問題創建了一個工單 (TKT-20260212-4929)。客服團隊將在24小時內與您聯繫並協助解鎖您的帳號。如有其他問題,請隨時告訴我!
客戶:好的
助手:謝謝您的理解!如果您有任何其他問題或需要進一步的協助,隨時可以聯繫我。祝您有美好的一天!
--- 檢視記錄的狀態資料 ---
登入資料:{
"username": "[email protected]",
"error_message": "Account Locked",
"timestamp": "2026-02-12 15:11:43"
}
工單號碼:TKT-20260212-4929
(工單中包含的登入資訊已傳遞給人工客服)
【場景 3:帳務問題】
客戶:我需要發票
[執行:record_issue]
[狀態:phase=recorded, type=, resolved=]
[執行:classify_issue]
[狀態:phase=classified, type=billing, resolved=]
[執行:handle_billing]
[狀態:phase=done, type=billing, resolved=1]
助手:您的問題已處理。已確認您的付款,發票將於 3 天內寄出。如果您還有其他問題,請隨時告訴我!
客戶:謝謝
助手:不客氣!如果您還有其他需要幫忙的地方,隨時告訴我。祝您有美好的一天!
--- 檢視記錄的狀態資料 ---
帳務資料:{
"request_type": "invoice",
"timestamp": "2026-02-12 15:11:51"
}
=== 完成 ===
重點說明:
- 工具函數會將收集到的資料儲存在 $state 中
- 後續工具(如 create_ticket)可以使用這些資料
- 這些資料可以保存到資料庫供後續分析
Dynamic Routing 的優勢:
✓ System prompt 簡潔(降低 token 消耗)
✓ AI 不可能呼叫錯誤工具(只看得到可用的)
✓ 流程控制嚴格(在程式端控制)
✓ 代碼簡單直覺(容易理解維護)
✓ 靈活彈性(工具自己決定流程)
適用場景:
- 需要根據狀態限制 AI 可用功能
- 希望降低 API 成本(減少 token)
- 追求代碼簡潔性和可維護性
- 大多數實際的 LLM 應用場景
原始碼
system prompt 其實內容很短、也沒說明怎麼分類客戶需求
但是 classify_issue 這個工具函數 用 description 說明了如何分類
並且參數用 'enum' => ['login', 'billing', 'technical'] 定義了有限分類
光是這樣就能用 llm 完成分類 只能說真的要把 llm 當成一位聰明的助理
狀態機 記錄宏觀狀態(目前在哪個 routing 裡面)、各情境的具體資料(每個 routing 各自需要的狀態)
get_available_tools 函數 會利用 phase + issue_type 提供需要的 tool functions 給 llm 使用
這樣做 更清楚也更好理解、llm 跟維護者都更不會出錯
每個動作執行完 接著該執行什麼 是記錄在 tool function 的回傳值裡面
而且還不一定寫得很清楚 就只是自然對話指定下一步而已
return [
'success' => true,
'message' => '問題已記錄',
'next_step' => '請判斷問題類型',
];
return [
'success' => true,
'type' => $type,
'message' => "已分類為 {$type} 問題",
'next_step' => '請處理該類型問題',
];
return [
'success' => true,
'resolved' => false,
'message' => '此問題需要人工處理',
'next_step' => '請使用 escalate 升級',
];
光是這樣就能讓 llm 去跑類似流程圖的邏輯 真神奇