使用工具呼叫、人工作業核准與執行限制,建立 LangGraph 客戶支援代理
以實務導向的 LangGraph 模式建構客戶支援分流:路由請求、呼叫查詢工具、暫停退款流程等待人工核准,並限制圖形執行範圍。
文章目錄
設計決策:讓代理可以查找,但不能自行完成退款
支援代理應該可以收集購買詳細資料並找出相符的紀錄,但不應被允許自行發放退款。在 LangGraph 中,可以在工作流程中表達這項區分:先路由請求,視需要呼叫唯讀查詢工具,接著在退款操作前暫停流程,讓人員核准或拒絕。
本教學以客戶支援分流為核心,建構這種模式。它使用 LangGraph 進行編排、使用支援工具呼叫的聊天模型進行查詢、在具影響性的節點前加入人工檢查點,並以遞迴限制約束圖形執行。這段程式碼是可供調整的模式,不是經過測試的 OneMux 整合。
本文引用的 LangSmith 教學,使用分開的查詢與退款子圖,建構數位音樂商店支援機器人。該教學說明如何擷取客戶與購買詳細資料、詢問缺少的資訊,以及評估最終回覆、工具軌跡和個別步驟。其退款範例使用資料庫刪除,並明確略過身分驗證及其他正式環境安全措施。請勿將該示範的破壞性行為複製到實際的支援系統中。 閱讀 LangSmith 複雜代理評估教學。
先決條件與界線
安裝 LangGraph,以及所選模型供應商所需的 LangChain 整合套件。來源教學使用 langgraph 與 langchain[openai],但以下範例刻意不指定模型初始化方式,讓其由供應商決定。你也需要一個資料庫或服務,提供唯讀的購買查詢,以及由應用程式控制的退款操作。
在連接模型前,先定義每個工具能做什麼:
- 查詢: 僅回傳通過身分驗證的客戶獲授權查看的紀錄。
- 退款準備: 識別確切的交易與金額;不得變更紀錄。
- 退款執行: 在應用程式程式碼中執行已核准的操作,並加入授權與稽核記錄。
請將客戶身分驗證、授權、冪等性及退款政策置於模型決策範圍之外。模型產生的客戶名稱或發票 ID 不是身分證明。
建立包含人工檢查點的圖形
此範例使用支援工具呼叫的模型、查詢工具,以及獨立的退款節點。請將標記的應用程式函式替換成你自己的授權服務呼叫。模型與工具結構描述必須受到你所設定端點的支援;相容性取決於端點及參數是否有文件明確支援。此程式碼片段不代表特定模型或 OneMux 設定已經過測試。
from typing import Annotated, Literal
from langchain.tools import tool
from langchain_core.messages import AnyMessage
from langgraph.graph import END, START, StateGraph
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import interrupt
from typing_extensions import TypedDict
# Replace with your provider's documented LangChain model setup.
# Confirm that the chosen endpoint supports tool calling and the parameters used.
model = make_your_chat_model().bind_tools([]) # bind the tools below in your application
class State(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
refund_request: dict | None
approval: str | None
@tool
def find_purchases(customer_reference: str) -> list[dict]:
"""Find purchases for an already authenticated customer."""
return authorized_purchase_lookup(customer_reference)
tools = [find_purchases]
model = make_your_chat_model().bind_tools(tools)
def assistant(state: State):
return {"messages": [model.invoke(state["messages"])]}
def prepare_refund(state: State):
# Build this from validated application data, not model-invented values.
request = build_validated_refund_request(state["messages"])
decision = interrupt({
"type": "refund_approval",
"request": request,
"instruction": "Approve or reject this exact refund request.",
})
if decision != "approve":
return {"approval": "rejected", "refund_request": request}
return {"approval": "approved", "refund_request": request}
def execute_refund(state: State):
if state.get("approval") != "approved":
return {"messages": [{"role": "assistant", "content": "The refund was not approved."}]}
result = issue_refund_safely(state["refund_request"])
return {"messages": [{"role": "assistant", "content": format_refund_result(result)}]}
builder = StateGraph(State)
builder.add_node("assistant", assistant)
builder.add_node("tools", ToolNode(tools))
builder.add_node("prepare_refund", prepare_refund)
builder.add_node("execute_refund", execute_refund)
builder.add_edge(START, "assistant")
builder.add_conditional_edges("assistant", tools_condition)
builder.add_edge("tools", "assistant")
builder.add_edge("prepare_refund", "execute_refund")
builder.add_edge("execute_refund", END)
graph = builder.compile(checkpointer=MemorySaver())
這是結構範例,不是完整的路由圖形:你的應用程式必須將已驗證的退款意圖路由至 prepare_refund,並將一般問題路由至助理/查詢路徑。interrupt() 呼叫會暫停圖形,並將核准內容傳回呼叫端。人工審查介面應在傳送決定前,顯示客戶、交易、金額及政策內容。使用 LangGraph 的 Command(resume=...) 機制及相同的執行緒識別碼,恢復同一個執行緒。適當持久化檢查點;記憶體內檢查點適合開發,不適合需要持久性的正式工作流程。
一項關鍵的控制流程細節是:interrupt 是暫停,不是權限系統。在退款執行節點再次強制檢查核准值,並確保退款服務本身驗證授權、交易資格及重複請求。
限制執行範圍,並讓錯誤清楚可見
呼叫圖形時傳入遞迴限制。它會限制圖形的 superstep;不會限制模型 token 數量、工具執行時間、資料庫查詢成本或使用者請求數量。請另外為模型呼叫與工具設定逾時及資源限制。
from langgraph.errors import GraphRecursionError
config = {
"configurable": {"thread_id": "support-case-123"},
"recursion_limit": 12,
}
try:
result = graph.invoke(
{"messages": [{"role": "user", "content": "I need help with a purchase."}]},
config=config,
)
except GraphRecursionError:
# Return a safe handoff or ask for clarification; log the trace for review.
result = {"status": "needs_human_review"}
根據預期工作流程選擇限制值,然後測試正常完成及容易形成迴圈的輸入。不要默默重試已耗盡限制的圖形:除非工具具備冪等性,否則重試可能重複呼叫工具。唯讀查詢工具比具有副作用的操作更適合重試。
評估執行路徑,而不只是答案
引用的 LangSmith 教學指出三個實用的評估目標:最終回覆(客戶得到的答案是否合適?)、軌跡(代理是否採取預期的工具呼叫路徑?)以及單一步驟(針對特定決策,它是否選擇了正確工具?)。針對退款分流,請建立缺少身分資料、多筆相符購買紀錄、查詢無結果、核准遭拒及退款獲核准等案例。
確認代理會要求必要資訊,而不是自行捏造;確認查詢不會觸發退款;並確認未經核准無法執行。評估時使用模擬或測試服務,避免測試修改真實客戶紀錄。來源教學針對資料庫操作使用模擬模式,但描述的是其示範設定,不是正式環境的安全保證。
使用 OneMux 取得模型存取能力
OneMux 透過單一 OpenAI-compatible API 提供領先 AI 模型的存取能力。若你希望使用單一 API 介面來存取模型,請參閱 OneMux 快速入門、API 文件 及可用模型。此工作流程的相容性取決於所選模型端點文件中說明的工具呼叫支援與接受的參數。部署前請確認這些細節;本文不宣稱 LangGraph 範例已針對 OneMux 進行測試。
限制與疑難排解
- 模型沒有呼叫工具: 確認所選端點支援工具呼叫,且工具結構描述以其文件指定的格式傳入。
- 圖形形成迴圈: 檢查助理與工具之間的轉移,限制圖形步驟,並確保完成的工具結果會改變下一個決策。
- 核准後恢復到錯誤案例: 使用與支援案例綁定的穩定執行緒識別碼,並在恢復前驗證檢查點。
- 退款執行兩次: 在服務邊界加入冪等性,並記錄已核准的請求及結果。
- 代理暴露其他客戶的紀錄: 修正查詢服務中的授權;提示指令不是存取控制。
結論
LangGraph 能將支援分流表達為明確的工作流程步驟,而不是相信單一模型回覆同時做出決定並採取行動。讓查詢保持唯讀、在退款前暫停、於執行時驗證核准,並限制圖形步驟。接著評估答案以及代理採取的路徑。這些控制措施讓工作流程更容易檢查,但正式環境的安全性與政策執行仍由應用程式負責。
來源
- LangSmith:評估複雜代理 — 音樂商店支援範例、查詢/退款結構、模擬模式及三種評估目標的來源。
常見問題
如何要求人工核准後,LangGraph 代理才能發放退款?
在退款執行節點前使用 LangGraph interrupt 暫停圖形,將經過驗證的請求呈現給審查人員,並僅在取得明確決定後恢復同一個檢查點。此外,也要在執行節點內再次檢查核准狀態,並在退款服務中強制執行政策。
LangGraph 的遞迴限制會限制工具執行時間或模型 token 嗎?
不會。它限制的是圖形 superstep,不是模型 token 使用量、工具執行時間、資料庫成本或傳入請求量。請另外加入獨立的逾時與資源限制。
模型可以決定客戶是否有資格獲得退款嗎?
不可以。請將模型輸出視為不受信任的輸入。在應用程式與服務程式碼中驗證客戶身分,並確認交易存取權與退款資格。
應該如何評估客戶支援代理?
評估最終回覆、工具呼叫順序,以及個別的工具選擇步驟。加入缺少資訊、購買紀錄不明確、核准遭拒及退款獲核准等案例,並使用測試服務處理副作用。
相關文章
指南
打造具有限制執行步數、可驗證結構化資料的 LangGraph Agent
建立 LangGraph 工作流程,讓 Agent 在需要時呼叫工具、在預設執行預算內停止,並回傳符合 Pydantic schema 驗證的結構化資料。
指南
LangGraph Agentic RAG:工具呼叫、來源歸屬與有界執行
建立 LangGraph 文件問答代理,讓它決定何時擷取資料、評估上下文、重試效果不佳的搜尋,並在不進行無限執行的情況下,返回附有來源歸屬的答案。
指南
建立具備人工核准與測試驗證的 n8n 程式碼變更工作流程
設計 n8n 工作流程,提出程式碼儲存庫變更、請人工核准寫入,並以測試驗證產生的提交。
指南
使用 OpenAI-Compatible Provider 的 Cline:需人工核准的支援分流
設定 Cline 搭配 OpenAI-compatible provider 與 OneMux,用於客戶支援分流,同時確保所有面向客戶的操作都必須經過人工核准。