亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

LangGraph斷點(diǎn)恢復(fù)與冪等執(zhí)行:生產(chǎn)級(jí)Agent穩(wěn)定性實(shí)踐

LangGraph斷點(diǎn)恢復(fù)與冪等執(zhí)行:生產(chǎn)級(jí)Agent穩(wěn)定性實(shí)踐 做完十幾個(gè) Agent demo 之后你會(huì)發(fā)現(xiàn)一個(gè)殘酷的事實(shí)在 Jupyter Notebook 里跑得挺順的智能體一上生產(chǎn)就原形畢露。用戶刷新一下頁(yè)面任務(wù)重跑一遍錢扣了兩次凌晨三點(diǎn)模型調(diào)用超時(shí)整個(gè)流程從頭再來(lái)前面寫(xiě)進(jìn)數(shù)據(jù)庫(kù)的狀態(tài)全得重建更頭疼的是人工審批環(huán)節(jié)——Agent 運(yùn)行到一半要等領(lǐng)導(dǎo)點(diǎn)個(gè)按鈕結(jié)果進(jìn)程一重啟圖的狀態(tài)沒(méi)了。LangGraph 斷點(diǎn)恢復(fù)和冪等執(zhí)行就是專門治這三類毛病的。這篇文章我把這套東西從原理到落地一次講透代碼能直接抄。在正式動(dòng)手之前有必要先說(shuō)說(shuō) LangGraph 在整個(gè)技術(shù)棧里的位置。現(xiàn)在搜 LangGraph 教程十個(gè)里有八個(gè)會(huì)糾結(jié)它和 LangChain 的區(qū)別。我的理解很簡(jiǎn)單LangChain 是一把瑞士軍刀里面全是工具函數(shù)、模型封裝、Prompt 模板這些零件而 LangGraph 是裝刀的戰(zhàn)術(shù)背心它關(guān)心的是你身上這些裝備怎么按順序掏出來(lái)、掏到一半被打斷能不能塞回去、事后能不能從某個(gè)位置繼續(xù)掏。它通過(guò)狀態(tài)圖的方式組織 Agent 的執(zhí)行流讓每一步都有跡可循、可停可續(xù)而且把狀態(tài)和檢查點(diǎn)作為一等公民內(nèi)置進(jìn)了框架。本文會(huì)從斷點(diǎn)恢復(fù)的底層機(jī)制講起然后進(jìn)入冪等執(zhí)行這個(gè)工程化繞不開(kāi)的命題最后用一個(gè) FastAPI LangGraph 的實(shí)戰(zhàn)項(xiàng)目把它們串起來(lái)。這個(gè)方案適合正在把 Agent 從 Demo 推向生產(chǎn)的開(kāi)發(fā)者也適合被AI 下地干活折磨得懷疑人生的后端工程師。1. 先搞清楚一個(gè)前提LangGraph 到底在解決什么問(wèn)題1.1 LangGraph 和 LangChain 的本質(zhì)區(qū)別很多人問(wèn) LangChain 和 LangGraph 的面試題怎么答其實(shí)就是一行話的事LangChain 提供了與模型、工具、文檔交互的抽象能力LangGraph 則是把這些能力組織成一張可執(zhí)行、可暫停、可恢復(fù)的狀態(tài)圖。LangChain 的 Chain 也有順序執(zhí)行的邏輯但這種執(zhí)行是一把梭的——鏈一旦啟動(dòng)要么跑完要么失敗重來(lái)中間不保留可以被外部干預(yù)的狀態(tài)。LangGraph 則把執(zhí)行過(guò)程建模成由節(jié)點(diǎn)Node和邊Edge構(gòu)成的有向圖每個(gè)節(jié)點(diǎn)就是一次計(jì)算或一個(gè)工具調(diào)用邊定義了流轉(zhuǎn)規(guī)則。關(guān)鍵差異在于LangGraph 里的圖在每次節(jié)點(diǎn)運(yùn)行前后都會(huì)生成一個(gè)狀態(tài)快照也就是 checkpoint你可以通過(guò)它實(shí)現(xiàn)時(shí)間旅行、條件分支重放以及人工介入。這種差異帶來(lái)的直接感受是用 LangChain 寫(xiě) Agent像在流水線上干活從頭到尾一氣呵成用 LangGraph 寫(xiě) Agent像在玩有存檔的游戲任何時(shí)刻都能存一檔、讀一檔、改一檔再繼續(xù)玩。建議學(xué)習(xí)路徑也很直接先用pip install langgraph跑通官方手冊(cè)中文版里的 ReAct 示例理解節(jié)點(diǎn)、邊、狀態(tài)這三個(gè)核心概念再看本篇文章涉及的狀態(tài)持久化和中斷機(jī)制最后再上手真實(shí)業(yè)務(wù)改造。1.2 斷點(diǎn)恢復(fù)的本質(zhì)把圖執(zhí)行變成可中斷事務(wù)斷點(diǎn)恢復(fù)聽(tīng)起來(lái)很高端本質(zhì)上就是數(shù)據(jù)庫(kù)事務(wù)里 Savepoint 和 Rollback 的思想搬到了 Agent 編排層。LangGraph 在執(zhí)行一個(gè)節(jié)點(diǎn)前會(huì)檢查是否有可恢復(fù)的 checkpoint如果有它不會(huì)從頭跑而是直接恢復(fù)到上次中斷后的節(jié)點(diǎn)繼續(xù)執(zhí)行。這里涉及三個(gè)核心概念thread_id、checkpointer、checkpoint_id。thread_id 是會(huì)話標(biāo)識(shí)LangGraph 用它區(qū)分不同的對(duì)話和任務(wù)同一個(gè) thread 的多次執(zhí)行共享狀態(tài)checkpointer 是存儲(chǔ)后端決定 checkpoint 和狀態(tài)持久化到哪里比如內(nèi)存、SQLite、Postgrescheckpoint_id 則是每次圖執(zhí)行生成的狀態(tài)版本號(hào)相當(dāng)于游戲存檔的時(shí)間戳。你可以這樣理解thread_id 是游戲存檔的文件名checkpointer 是硬盤(pán)checkpoint_id 是存檔的時(shí)間點(diǎn)。一個(gè) Agent 應(yīng)用對(duì)應(yīng)多個(gè) thread_id每個(gè) thread 有自己的一系列 checkpoint_id當(dāng)你用同一個(gè) thread_id 再次調(diào)用圖時(shí)LangGraph 會(huì)找最新的 checkpoint 作為起點(diǎn)。這套機(jī)制天然適合 human-in-the-loop 場(chǎng)景Agent 執(zhí)行到需要人工審批的節(jié)點(diǎn)先暫停把狀態(tài)寫(xiě)好存檔然后告訴外部我需要人來(lái)確認(rèn)人類做出決定后應(yīng)用再用同一個(gè) thread_id 調(diào)用續(xù)跑接口LangGraph 會(huì)從斷點(diǎn)接著走而不是把之前的工作推倒重來(lái)。2. 斷點(diǎn)恢復(fù)的落地姿勢(shì)從圖級(jí)斷點(diǎn)到節(jié)點(diǎn)級(jí)中斷2.1 編譯期斷點(diǎn) interrupt_before / interrupt_after用 LangGraph 實(shí)現(xiàn)斷點(diǎn)最直觀的方式是在編譯圖的時(shí)候指定斷點(diǎn)位置。interrupt_before表示進(jìn)入指定節(jié)點(diǎn)前暫停interrupt_after表示離開(kāi)指定節(jié)點(diǎn)后暫停。這種方式適合流程固定的場(chǎng)景比如必須先審核、后下單。代碼層面非常簡(jiǎn)單from langgraph.graph import StateGraph, START, END # 假設(shè)我們定義了一個(gè)簡(jiǎn)單的 Agent 圖 graph StateGraph(MyState) graph.add_node(plan, plan_node) graph.add_node(execute, execute_node) graph.add_node(review, review_node) graph.add_edge(START, plan) graph.add_edge(plan, execute) graph.add_edge(execute, review) graph.add_edge(review, END) checkpointer SqliteSaver.from_conn_string(checkpoints.db) # 編譯時(shí)指定斷點(diǎn) app graph.compile( checkpointercheckpointer, interrupt_before[review], # 進(jìn)入 review 前停住 interrupt_after[execute], # execute 完成且寫(xiě)入狀態(tài)后停住 )這樣編譯完之后你調(diào)用app.invoke(input, config{configurable: {thread_id: order_001}})圖會(huì)一路執(zhí)行到 execute 節(jié)點(diǎn)然后停在進(jìn)入 review 之前。此時(shí)圖的狀態(tài)保存在 checkpoints.db 里進(jìn)程掛了也不怕。要恢復(fù)只需要再次調(diào)用同一個(gè)圖不需要重新傳完整輸入。很多人這里會(huì)踩坑以為恢復(fù)是重新調(diào)用一次原來(lái)的輸入其實(shí) LangGraph 的邏輯是只要 thread_id 一致且該 thread 存在未完成的執(zhí)行調(diào)用就會(huì)嘗試從最近的 checkpoint 續(xù)跑??梢韵胂蟪梢粋€(gè)斷點(diǎn)續(xù)傳的過(guò)程恢復(fù)時(shí)只需要傳你需要注入的外部決定比如審批結(jié)果result app.invoke( None, # 或傳審批結(jié)果取決于業(yè)務(wù)邏輯 config{configurable: {thread_id: order_001}} )執(zhí)行會(huì)從interrupt_before指定的節(jié)點(diǎn)重新開(kāi)始先執(zhí)行 review再繼續(xù)后續(xù)邊。編譯期斷點(diǎn)的缺點(diǎn)是死板一旦編譯就固定了如果業(yè)務(wù)流程是動(dòng)態(tài)的這種方式就不夠靈活。2.2 節(jié)點(diǎn)內(nèi)中斷 interrupt() 與 Command(resume)LangGraph 提供了更靈活的動(dòng)態(tài)中斷方式在節(jié)點(diǎn)內(nèi)部調(diào)用interrupt()函數(shù)。這個(gè)函數(shù)的作用相當(dāng)于在任意指定的執(zhí)行點(diǎn)舉手暫停它會(huì)把一個(gè) payload 暴露給外部系統(tǒng)比如前端頁(yè)面等待外部通過(guò)Command(resume...)把決定塞回來(lái)。說(shuō)一個(gè)真實(shí)業(yè)務(wù)Agent 在幫用戶下單前需要確認(rèn)價(jià)格是否可接受。你在確認(rèn)價(jià)格這個(gè)節(jié)點(diǎn)里寫(xiě)from langgraph.types import interrupt, Command def confirm_price_node(state): # 準(zhǔn)備好給用戶看的報(bào)價(jià)信息 payload { order_id: state[order_id], total_price: state[total_price], items: state[items], } # 中斷把 payload 暴露出去等待用戶確認(rèn) decision interrupt(payload) if decision.get(approved): return {status: approved} else: return {status: rejected, reason: decision.get(reason)}interrupt()被調(diào)用后圖的執(zhí)行立刻暫停不會(huì)繼續(xù)往下走。此時(shí)如果你用app.get_state(config)查看狀態(tài)會(huì)發(fā)現(xiàn)圖處于中斷狀態(tài)且可以拿到interrupt里的 payload。外部應(yīng)用比如 FastAPI 接口把這個(gè) payload 展示給用戶用戶點(diǎn)同意或拒絕應(yīng)用把決定作為參數(shù)傳回from langgraph.types import Command # 用戶點(diǎn)了“同意” app.invoke( Command(resume{approved: True}), config{configurable: {thread_id: order_001}} )Command(resume...)會(huì)喚醒中斷的圖把值傳給interrupt()的返回值。執(zhí)行會(huì)接著 confirm_price_node 往下走。這種方式實(shí)現(xiàn)了真正意義上的動(dòng)態(tài)暫停和外部介入LangGraph 官方叫它 human-in-the-loop是斷點(diǎn)恢復(fù)最強(qiáng)的一個(gè)用法。2.3 狀態(tài)檢查、修改與跳過(guò)執(zhí)行除了暫停和恢復(fù)我們經(jīng)常需要在恢復(fù)前修改圖的狀態(tài)或者臨時(shí)跳過(guò)某個(gè)節(jié)點(diǎn)。LangGraph 提供了get_state和update_state兩個(gè)接口用途很像數(shù)據(jù)庫(kù)里的查詢和 UPDATE。config {configurable: {thread_id: order_001}} # 查看當(dāng)前 state 和 checkpoint snapshot app.get_state(config) print(snapshot.values) # 當(dāng)前狀態(tài)字段 print(snapshot.next) # 下一步會(huì)執(zhí)行哪些節(jié)點(diǎn) # 手動(dòng)修改 state app.update_state(config, {customer_name: 張三}, as_nodeplan)修改 state 的值會(huì)生成一個(gè)新的 checkpoint后續(xù)執(zhí)行基于新的狀態(tài)繼續(xù)。這里有個(gè)細(xì)節(jié)update_state時(shí)你可以通過(guò)as_node指定以哪個(gè)節(jié)點(diǎn)的名義寫(xiě)入這會(huì)影響圖的狀態(tài)更新規(guī)則。如果你希望跳過(guò)某個(gè)節(jié)點(diǎn)可以在中斷后手動(dòng) update_state把該節(jié)點(diǎn)要寫(xiě)入的狀態(tài)直接寫(xiě)進(jìn)去再恢復(fù)執(zhí)行即可。日常開(kāi)發(fā)里我通常把查看狀態(tài) 人工修改 恢復(fù)執(zhí)行三個(gè)動(dòng)作做成三個(gè)獨(dú)立 API方便前端根據(jù)業(yè)務(wù)場(chǎng)景自由組合。從實(shí)踐來(lái)看這種設(shè)計(jì)比把所有邏輯都塞進(jìn)一次 invoke 調(diào)用更可靠。3. 冪等執(zhí)行讓 Agent 重復(fù)跑也不會(huì)出事3.1 為什么 LangGraph 不保證冪等斷點(diǎn)恢復(fù)解決了流程中斷的問(wèn)題但引出了下一個(gè)問(wèn)題既然執(zhí)行可以被暫停、恢復(fù)、甚至重放那么同一個(gè)節(jié)點(diǎn)被重復(fù)執(zhí)行怎么辦LangGraph 本身沒(méi)有內(nèi)置冪等機(jī)制。原因很直接框架層面無(wú)法判斷你的工具調(diào)用是不是冪等的。比如一個(gè)節(jié)點(diǎn)里調(diào)用了發(fā)送短信的接口這個(gè)接口天然不是冪等的但另一個(gè)節(jié)點(diǎn)里只是做一次本地計(jì)算重復(fù)執(zhí)行也沒(méi)關(guān)系??蚣懿恢肋@些所以它選擇把決定權(quán)交給你。但是 LangGraph 提供了實(shí)現(xiàn)冪等的關(guān)鍵信息。每次 invoke 都會(huì)生成一個(gè) runtime run_id每次節(jié)點(diǎn)執(zhí)行后生成 checkpoint_id。你可以把它們當(dāng)作執(zhí)行某段邏輯的流水號(hào)結(jié)合業(yè)務(wù)側(cè)的冪等鍵就能判斷某段副作用是否已經(jīng)執(zhí)行過(guò)。這里強(qiáng)調(diào)一句config里傳入的thread_id是會(huì)話維度不是請(qǐng)求維度同一 session 里有多次 invokerun_id 每次都會(huì)變。所以不要拿 run_id 或 checkpoint_id 當(dāng)業(yè)務(wù)冪等鍵它們只適合做內(nèi)部調(diào)試和狀態(tài)追蹤。3.2 冪等設(shè)計(jì)三件套冪等鍵、副作用登記、唯一約束要讓 Agent 的執(zhí)行變得冪等我的實(shí)戰(zhàn)經(jīng)驗(yàn)是用三件套入口生成冪等鍵、副作用處先登記后執(zhí)行、數(shù)據(jù)庫(kù)加唯一約束。第一步在 Agent 任務(wù)創(chuàng)建時(shí)生成全局唯一的冪等鍵這個(gè)鍵要貫穿整個(gè)執(zhí)行流通常叫run_id但注意是自己生成的業(yè)務(wù) run_id不是 LangGraph 內(nèi)部的 run??梢苑旁?state 最外層一路往下傳。第二步在節(jié)點(diǎn)執(zhí)行副作用發(fā)消息、扣積分、調(diào)用外部下單接口之前先往 operation_log 表插一條記錄字段包括 run_id、操作類型、操作參數(shù)、狀態(tài)。如果插入的時(shí)候拋唯一約束沖突說(shuō)明同一 run 下這個(gè)操作已經(jīng)執(zhí)行過(guò)直接跳過(guò)副作用邏輯并復(fù)用上次的結(jié)果。第三步在數(shù)據(jù)庫(kù)里給(run_id, op_key)建立唯一索引。這里的 op_key 可以是通知用戶扣減庫(kù)存這樣的操作標(biāo)識(shí)也可以是 action 名稱加參數(shù)哈希。這樣即使代碼邏輯漏判了數(shù)據(jù)庫(kù)也會(huì)攔住第二次執(zhí)行。落地到 LangGraph 節(jié)點(diǎn)里基礎(chǔ)設(shè)施可以做成一個(gè)裝飾器def idempotent_node(op_key): def decorator(func): def wrapper(state): run_id state[run_id] log lookup_operation(run_id, op_key) if log: return log[result] # 已執(zhí)行過(guò)直接返回緩存結(jié)果 result func(state) # 首次執(zhí)行副作用 record_operation(run_id, op_key, result) # 寫(xiě)執(zhí)行記錄 return result return wrapper return decorator idempotent_node(deduct_inventory) def deduct_inventory_node(state): # 真正的扣減邏輯 return {inventory_left: state[inventory] - 1}這套方案的巧妙之處在于它把冪等從框架層下沉到了業(yè)務(wù)層。無(wú)論 LangGraph 怎么重放節(jié)點(diǎn)、怎么斷點(diǎn)續(xù)跑只要 run_id 不變?nèi)魏胃弊饔枚紩?huì)被數(shù)據(jù)庫(kù)的唯一約束擋住。3.3 工具調(diào)用層的冪等LangGraph 里最常見(jiàn)的副作用集中在工具調(diào)用上。函數(shù)調(diào)用tool calling模型會(huì)給每個(gè)工具調(diào)用生成一個(gè)唯一的tool_call_id這個(gè) ID 在單輪對(duì)話內(nèi)是唯一的。但問(wèn)題是如果圖執(zhí)行重放同一個(gè)工具調(diào)用可能會(huì)被再次觸發(fā)LangGraph 自帶的 ToolNode 會(huì)再次執(zhí)行該工具。好在 LangGraph 的 ToolNode 有內(nèi)置的消息去重機(jī)制。當(dāng)你用langgraph.prebuilt.ToolNode時(shí)如果某個(gè)tool_call_id已經(jīng)出現(xiàn)在歷史消息里ToolNode 會(huì)直接使用歷史結(jié)果而不會(huì)再次執(zhí)行工具。這個(gè)行為依賴于 checkpointer 保存的消息列表。所以只要你的圖啟用了 checkpointer并且工具節(jié)點(diǎn)用的是官方 ToolNode一定程度上已經(jīng)具備按 tool_call_id 去重的能力。但如果你沒(méi)用 ToolNode而是自己寫(xiě)節(jié)點(diǎn)處理工具調(diào)用那就必須自己實(shí)現(xiàn)冪等。我的做法是在工具執(zhí)行前檢查當(dāng)前 tool_call_id 是否已經(jīng)在狀態(tài)里的 tool_results 字段中出現(xiàn)過(guò)出現(xiàn)過(guò)就直接拿結(jié)果沒(méi)出現(xiàn)過(guò)才執(zhí)行真正的調(diào)用。def smart_tool_executor(state): messages state[messages] last_ai_msg messages[-1] results [] for tool_call in last_ai_msg.tool_calls: existed state[tool_results].get(tool_call[id]) if existed is not None: results.append(existed) # 復(fù)用歷史結(jié)果 continue result real_executor.invoke(tool_call) # 真正執(zhí)行 state[tool_results][tool_call[id]] result results.append(result) return {tool_results: state[tool_results], messages: results}這套邏輯在你需要給工具調(diào)用加緩存、加審計(jì)、加限流的場(chǎng)景下更實(shí)用官方 ToolNode 的自動(dòng)去重就不夠用了。特別是當(dāng)你對(duì)接的資金、積分系統(tǒng)有自己一套冪等憑證體系時(shí)用 tool_call_id 做聯(lián)動(dòng)往往比重新建一套更直接。4. 落地實(shí)戰(zhàn)FastAPI LangGraph 的生產(chǎn)級(jí)斷點(diǎn)恢復(fù)服務(wù)4.1 架構(gòu)與存儲(chǔ)選型從 SQLite 到 Postgres斷點(diǎn)恢復(fù)依賴于 checkpointer所以選什么存儲(chǔ)就決定了你能恢復(fù)到什么程度以及能扛多大并發(fā)。我把常用三個(gè)存儲(chǔ)后端放在一起對(duì)比根據(jù)部署規(guī)模直接挑存儲(chǔ)后端典型場(chǎng)景并發(fā)能力生產(chǎn)可用性備注MemorySaverDemo、本地調(diào)試單進(jìn)程單線程低進(jìn)程重啟狀態(tài)全丟慎用于生產(chǎn)SqliteSaver單機(jī)小規(guī)模服務(wù)受限于單機(jī)中注意線程鎖和文件鎖配套代碼簡(jiǎn)單門檻低PostgresSaver多副本、高可用環(huán)境高高是生產(chǎn)推薦方案需要數(shù)據(jù)庫(kù)連接池和遷移腳本單機(jī)場(chǎng)景直接上 SQLite 就夠了連接字符串傳一個(gè)路徑即可。多副本部署、要做負(fù)載均衡的話建議直接上 Postgres。LangGraph 提供了 AsyncPostgresSaver異步接口配合 FastAPI 的 async 路由非常順滑。需要強(qiáng)調(diào)一點(diǎn)postgres_saver 使用前必須創(chuàng)建表結(jié)構(gòu)官方提供了checkpoint_ddl腳本不要用 SQLite 的表結(jié)構(gòu)去 Postgres 里跑字段類型和索引都對(duì)不上踩一次坑少說(shuō)浪費(fèi)半小時(shí)。4.2 核心代碼構(gòu)建帶審批的人類介入 Agent用 FastAPI LangChain LangGraph 組合做一個(gè)審批后通知的 Agent。業(yè)務(wù)路徑是創(chuàng)建任務(wù) - 模擬扣減積分 - 人工審批 - 審批通過(guò)后發(fā)通知。重點(diǎn)演示斷點(diǎn)恢復(fù)與冪等抑制。# app.py —— 完整示例骨架 import os from typing import TypedDict, Annotated from fastapi import FastAPI from langgraph.graph import StateGraph, START, END from langgraph.checkpoint.sqlite import SqliteSaver from langgraph.types import interrupt, Command import sqlite3 class AgentState(TypedDict): run_id: str user_id: str points_deducted: bool approval: str notified: bool conn sqlite3.connect(agent_state.db, check_same_threadFalse) conn.execute( CREATE TABLE IF NOT EXISTS operation_log ( run_id TEXT, op_key TEXT, result TEXT, PRIMARY KEY (run_id, op_key) ) ) conn.commit() checkpointer SqliteSaver(conn)注意連接池的check_same_threadFalse默認(rèn)的 SQLite 連接不能跨線程用FastAPI 是并發(fā)模型不關(guān)掉會(huì)各種報(bào) thread error。下面定義三個(gè)節(jié)點(diǎn)。第一個(gè)節(jié)點(diǎn)扣積分有工程量第二個(gè)節(jié)點(diǎn)做人工審批中斷第三個(gè)節(jié)點(diǎn)發(fā)通知冪等保護(hù)。def deduct_points_node(state: AgentState): run_id state[run_id] # 冪等查操作日志 row conn.execute( SELECT result FROM operation_log WHERE run_id? AND op_key?, (run_id, deduct_points), ).fetchone() if row: return {points_deducted: True} # 已扣過(guò)不重復(fù)扣 # 真正扣減積分的代碼這里用 print 模擬 print(f真實(shí)扣減積分user{state[user_id]}) conn.execute( INSERT INTO operation_log (run_id, op_key, result) VALUES (?, ?, ?), (run_id, deduct_points, ok), ) conn.commit() return {points_deducted: True} def approval_node(state: AgentState): decision interrupt({ message: 是否允許扣減積分并發(fā)送通知, user_id: state[user_id], run_id: state[run_id], }) return {approval: decision.get(decision, denied)} def notify_node(state: AgentState): if state[approval] ! approved: return {notified: False} run_id state[run_id] row conn.execute( SELECT result FROM operation_log WHERE run_id? AND op_key?, (run_id, send_notify), ).fetchone() if row: return {notified: True} print(f真實(shí)發(fā)送通知user{state[user_id]}) conn.execute( INSERT INTO operation_log (run_id, op_key, result) VALUES (?, ?, ?), (run_id, send_notify, ok), ) conn.commit() return {notified: True}構(gòu)建圖并編譯builder StateGraph(AgentState) builder.add_node(deduct, deduct_points_node) builder.add_node(approval, approval_node) builder.add_node(notify, notify_node) builder.add_edge(START, deduct) builder.add_edge(deduct, approval) builder.add_edge(approval, notify) builder.add_edge(notify, END) app builder.compile(checkpointercheckpointer)FastAPI 路由部分提供三個(gè)接口from fastapi import FastAPI, HTTPException server FastAPI() server.post(/runs) def create_run(user_id: str): import uuid run_id str(uuid.uuid4()) # 啟動(dòng)圖執(zhí)行運(yùn)行到 approval 節(jié)點(diǎn)會(huì)自動(dòng)中斷 app.invoke( {run_id: run_id, user_id: user_id}, config{configurable: {thread_id: run_id}}, ) return {run_id: run_id} server.get(/runs/{run_id}/state) def get_run_state(run_id: str): snap app.get_state({configurable: {thread_id: run_id}}) return { status: snap.next, values: snap.values, interrupts: [i.payload for i in snap.interrupts] if snap.interrupts else [], } server.post(/runs/{run_id}/resume) def resume_run(run_id: str, decision: str): snap app.get_state({configurable: {thread_id: run_id}}) if not snap.interrupts: raise HTTPException(status_code400, detail當(dāng)前狀態(tài)不可恢復(fù)) app.invoke( Command(resume{decision: decision}), config{configurable: {thread_id: run_id}}, ) return {status: resumed}這樣前后端就能完成創(chuàng)建任務(wù) - 查詢審批信息 - 審批 - 恢復(fù)執(zhí)行。整個(gè)生命周期里SQLite 里的 checkpoint 保存了每一步狀態(tài)operation_log 確保了扣減積分和發(fā)通知這兩個(gè)副作用不會(huì)被重復(fù)執(zhí)行。4.3 完整調(diào)用流程演示用 curl 走一遍完整流程你會(huì)很直觀看到斷點(diǎn)恢復(fù)和冪等是怎么協(xié)同的。創(chuàng)建一次任務(wù)圖會(huì)一路跑到 approval 節(jié)點(diǎn)然后自動(dòng)暫停curl -X POST http://localhost:8000/runs?user_idu_100 # 返回 {run_id: abc-123}查詢狀態(tài)你會(huì)看到interrupts里有審批的 payloadnext指向 approval 之后要執(zhí)行的下一個(gè)節(jié)點(diǎn)curl http://localhost:8000/runs/abc-123/state人工審批通過(guò)恢復(fù)執(zhí)行curl -X POST http://localhost:8000/runs/abc-123/resume \ -H Content-Type: application/json \ -d {decision: approved}此刻的關(guān)鍵點(diǎn)來(lái)了如果你再次手動(dòng)調(diào)用扣積分節(jié)點(diǎn)比如誤操作operation_log 里已經(jīng)存在(abc-123, deduct_points)這條記錄節(jié)點(diǎn)會(huì)直接返回{points_deducted: True}不會(huì)真的扣第二次積分。同理send_notify也不會(huì)重復(fù)發(fā)通知。這個(gè)就是業(yè)務(wù)層的冪等兜底。如果把整條鏈路里的每一步都記錄到數(shù)據(jù)庫(kù)你甚至可以做重放審計(jì)——某個(gè) run 到底扣了多少次積分、哪一步是冪等跳過(guò)的、哪一步真實(shí)執(zhí)行了一查便知。5. 實(shí)戰(zhàn)中的坑與排查經(jīng)驗(yàn)5.1 斷點(diǎn)恢復(fù)常見(jiàn)的報(bào)錯(cuò)與解決辦法工程落地會(huì)遇到各種邊界情況我把自己常遇到的幾個(gè)問(wèn)題整理成了速查表報(bào)錯(cuò)/現(xiàn)象根因處理方式Checkpointer required圖里使用了 interrupt 但在 compile 時(shí)沒(méi)傳 checkpointercompile(checkpointer...)恢復(fù)調(diào)用不生效從頭開(kāi)始執(zhí)行thread_id 不一致或使用了不同的 config key確認(rèn) token 不變檢查 config 拼寫(xiě)Cannot update non-existent node...update_state 時(shí) as_node 傳了一個(gè)圖里不存在的節(jié)點(diǎn)名查看圖節(jié)點(diǎn)列表確保 as_node 合法resume 后狀態(tài)不是預(yù)期值Command(resume) 傳參結(jié)構(gòu)不對(duì)檢查 interrupt() 返回值的接收語(yǔ)義SQLitedatabase is locked多線程并發(fā)寫(xiě)同一個(gè) SQLite 文件開(kāi)啟 WAL 模式或改用 PostgresSaver恢復(fù)后節(jié)點(diǎn)重復(fù)執(zhí)行業(yè)務(wù)副作用沒(méi)有做冪等保護(hù)用 3.2 節(jié)的三件套去攔截SQLite 的鎖是最常見(jiàn)的坑尤其是 FastAPI 多 worker 部署時(shí)。建議在初始化連接后執(zhí)行PRAGMA journal_modeWAL;能明顯減少并發(fā)讀寫(xiě)的鎖沖突。但說(shuō)到底多 worker 部署就別用 SQLite 了上 PostgresSaver 是正道。5.2 冪等沒(méi)生效的幾個(gè)隱蔽原因冪等邏輯看著簡(jiǎn)單實(shí)際有幾種隱蔽情況會(huì)導(dǎo)致失效。最常見(jiàn)的是冪等鍵沒(méi)有貫穿整個(gè)調(diào)用鏈。比如你的 run_id 在 create_run 接口生成了但某個(gè)工具節(jié)點(diǎn)內(nèi)部又自己 new 了一個(gè) uuid那節(jié)點(diǎn)側(cè)查 operation_log 時(shí)主鍵永遠(yuǎn)對(duì)不上每次都會(huì)執(zhí)行真實(shí)副作用。建議把冪等鍵放到 state 的頂層字段節(jié)點(diǎn)里只管 read不許 write。第二個(gè)隱蔽原因是副作用執(zhí)行成功但記錄寫(xiě)入失敗。比如真實(shí)扣減積分接口調(diào)用成功了但 operation_log 的 INSERT 因?yàn)槟撤N異常沒(méi)提交此時(shí) Agent 拋錯(cuò)重試業(yè)務(wù)邏輯發(fā)現(xiàn)日志里沒(méi)有記錄又扣了一次。解決辦法是把副作用執(zhí)行和副作用登記放在同一個(gè)事務(wù)邊界里最好的方式是把扣減積分與記錄日志放到同一個(gè)數(shù)據(jù)庫(kù)事務(wù)要么都成功要么都失敗。第三個(gè)隱蔽原因是參數(shù)變化導(dǎo)致的冪等繞過(guò)。比如 op_key 只取了操作名但操作里包含了金額參數(shù)第一次扣 100第二次改成扣 50唯一約束認(rèn)為這是同一條記錄直接跳過(guò)了扣 50 的請(qǐng)求。這就要求 op_key 的設(shè)計(jì)要包含關(guān)鍵的參數(shù)指紋一般是用action hashlib.md5(sorted_params)。5.3 生產(chǎn)部署檢查清單最后給一份我每次上線 Agent 服務(wù)前都會(huì)過(guò)一遍的清單照著做能少走很多彎路生產(chǎn)環(huán)境 checkpointer 是否選擇了 PostgresSaver并創(chuàng)建了正確的 checkpoint 表所有有外部副作用的節(jié)點(diǎn)是否都經(jīng)過(guò)冪等裝飾器或等效邏輯保護(hù)operation_log表是否建了(run_id, op_key)唯一索引關(guān)鍵工具調(diào)用是否用 tool_call_id 做了去重或緩存恢復(fù)接口是否做了并發(fā)控制避免同一個(gè) thread_id 被兩個(gè)人同時(shí) resume是否對(duì)get_state、update_state做了操作審計(jì)方便排查人工干預(yù)的記錄是否有兜底超時(shí)機(jī)制比如 Agent 長(zhǎng)期處于中斷狀態(tài)或恢復(fù)失敗時(shí)有守護(hù)任務(wù)負(fù)責(zé)清理或告警關(guān)于第 4 條里提到的并發(fā)控制簡(jiǎn)單做法是在恢復(fù)接口層加一把 Redis 鎖鎖的 key 是resume:{thread_id}保證同一時(shí)刻只有一個(gè) resume 請(qǐng)求真正驅(qū)動(dòng)圖繼續(xù)執(zhí)行。否則兩個(gè)請(qǐng)求同時(shí)Command(resume...)狀態(tài)會(huì)亂成一鍋粥。6. 斷點(diǎn)狀態(tài)設(shè)計(jì)與冪等鍵命名的一些心得這里講一個(gè)容易被忽略的細(xì)節(jié)斷點(diǎn)恢復(fù)時(shí)interrupt()的返回值本質(zhì)上是從Command(resume)里透?jìng)鬟^(guò)來(lái)的它不會(huì)自動(dòng)做校驗(yàn)。如果你在審批節(jié)點(diǎn)里期望收到一個(gè) dict但恢復(fù)端傳了字符串節(jié)點(diǎn)代碼可能直接報(bào)TypeError。所以我習(xí)慣在 interrupt 節(jié)點(diǎn)里加一層簡(jiǎn)單的 schema 校驗(yàn)比如用 Pydantic 解析解析失敗就拋一個(gè)自定義異常FastAPI 層捕獲后返回 400。這能避免生產(chǎn)環(huán)境出現(xiàn)匪夷所思的恢復(fù)錯(cuò)誤。冪等鍵命名同樣有講究。業(yè)界慣例會(huì)區(qū)分request_id客戶端發(fā)起請(qǐng)求時(shí)生成的 ID用于端到端全鏈路追蹤。idempotency_key專門用于冪等控制的業(yè)務(wù)鍵同一業(yè)務(wù)動(dòng)作多次重試時(shí)保持不變。run_idAgent 任務(wù)內(nèi)部流轉(zhuǎn)用的標(biāo)識(shí)可以就是idempotency_key但注意它不是 LangGraph 框架的 runtime run_id。我通常直接讓入口生成的 UUID 同時(shí)充當(dāng)request_id、idempotency_key和thread_id三合一減少概念數(shù)量降低溝通成本。你可以在日志里同時(shí)打印這個(gè)值和 LangGraph 內(nèi)部的 checkpoint_id方便追蹤狀態(tài)對(duì)應(yīng)關(guān)系。# 日志示例 [RUN abc-123] checkpoint 9f2e... 到達(dá)人工審批 [RUN abc-123] checkpoint 9f2e... 恢復(fù)執(zhí)行審批結(jié)果 approved [RUN abc-123] 冪等跳過(guò) send_notify原因已執(zhí)行最后再分享一個(gè)我在實(shí)戰(zhàn)中堅(jiān)持的習(xí)慣所有 LangGraph 節(jié)點(diǎn)都寫(xiě)成純函數(shù)風(fēng)格不直接操作外部全局狀態(tài)只通過(guò) state 的輸入輸出做數(shù)據(jù)流轉(zhuǎn)。副作用統(tǒng)一收斂到獨(dú)立的工具層或服務(wù)層節(jié)點(diǎn)只做編排。這樣做的好處是當(dāng)你要加斷點(diǎn)、加冪等、加審計(jì)時(shí)改動(dòng)面非常小每個(gè)節(jié)點(diǎn)就像積木一樣可以自由插拔組合。這套理念配合 LangGraph 的 checkpointer基本能滿足絕大多數(shù)生產(chǎn)級(jí) Agent 服務(wù)的需求。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
daxiangjiao你懂的| 欧洲视频在线| www网站黄| 午夜性刺激视频免费观看| 中文字幕高清20页视频| 国产亚洲中文不卡二区| 少妇一区二区三区| 欧美国产有色电影| 2024人人操人人摸| 男插女青青影院| 先锋音影AV| av资源在线观看少妇| 国产精品日日摸夜夜添骚逼| 久久久久久久久国产| 色色色综合网| 亚洲av综合色区无码一| 少妇久久久久久久久| 国产成人主播| 欧美日韩夜夜| 看日韩美女二区三区免费操逼视频| 91国产操逼视频| 97亚洲国产| 蜜桃色色网站视频三区| 高清一区AV无码| 久艹日日日| 婷婷九月国产| 天天综合网1| 亚洲情色第一页| 免费看欧美美女黄色大片 | 手机在线观看不卡无码av| 国产91精品在线免费| 99福利社| 国产吹潮女在线观看| 天天操女人| 亚洲免费人妻在| 亚洲欧美在线观看无码| A级片日韩欧美国产欧美视频精选观看 | 人人扣人人操| 欧美日韩国产中文精品字幕自在自线| 操b在线观看| 亚洲国产日韩精品久久久| 999九九九九国产动| 亚洲色图综合网| 色 亚洲 91| 亚洲中文字幕乱码无码一区二区| 色999人与兽| 色综合久久久久| 亚洲AV成人无码一二三久久| 内射老妇BBWX0C0CK| 人妻少妇精品视频一区二区三区| 激情欧美97| 国产三级中文字幕粉嫩| 94色色电影网| 国内亚洲高清无码| 国产一区二区三三视频| 2017人人操,人人摸| 另类小说综合网| 国产女同在线观看视频| 色就色综合| AA级电影三区| 国产免费一区在线观看| 久久丁香五月婷婷| 日韩一级久久毛片| 久久久久久久91| 久草在| 老熟妇一区二区三区啪啪| 传媒免费一区二区三区| 精品999日本| 樱花草社区www中国| 大肉棒导航| 一区二区亚州激情久婷婷欧美| 另类视频在线| 九九九九精品在线| 久久在肏| 三上悠亚在线毛片91| 欧美一二三| 久久性爱精品一区| 亚洲国产日韩欧美熟妇在线| 日韩AV电影网站| 99抽插| 欧美综色欧| 锕锕好爽 死我在线观看| 9997se| 中文乱码字幕观看视频| 成人精品久久久午夜福利| 国产精品一区二区校花| 五月婷婷六月天| 影音综合网| 高清肉丝中文无码| 午夜美女福利视频| 欧美 亚洲 偷拍自拍| 91亚·色| 久久久久人| 欧美 亚洲 第一页| 伊人久久大香线蕉无码| 久久久一级| 亚洲视频一二区| 91情色在线| 性久久久| 97精品国产97久久久久久免费| 亚熟hd视频在线| 亚洲精品电影| 久久毛卡| 2019午夜福利视频| 国产乱伦搜索结果91P| 亚洲av影音先锋| 亚洲天堂区| 妇女视频网站| 99色热国产视频精品| 啊灬啊灬啊灬好深灬快高潮了动漫-国产字幕国产在线观看-B049AV | 玖玖爱视频网站| 熟女色综合久久| 台湾佬激情综合| 色老久久| 97久久久久| 国产2.3.4区| 久久久一区二区三区四区五区| 伊人丁香五月婷婷| www鬼畜国产男人的天堂| 久久动漫精品视频这里只有精品| 蜜臀中文字幕| 久久久一区二区三区四曲免费听| 蜜臀99久久精品久久久久久| 九九性爱网| 丰满精品人妻少妇久久字幕| 操操逼视频| 偷拍欧美综合| 一区二区三区四区理论片| 激情久久久| 啊啊啊啊啊啊啊啊要喷了| 精品一区二区三区国产| 国产青一二三| 国产一区二区三区白丝| 60秒免费小视频| 久久久精品中文字幕爱豆| 欧美中文字幕男人天堂久久精品| 清纯唯美亚洲综合| 91狠狠色丁香婷婷综合久久精品| 久久噜噜噜精品国产亚洲综合| 台湾成人无码AV| 五月天婷婷成人网| 好属操| 一区二区 韩日AV| 99re欧美| 欧美色图亚州激情| 人人玩人人添人人澡免费| 日本天堂网| 日韩熟女无码| 国产肏屁眼视频| 欧美日韩性爱操大逼| 人人妻天天做天天爽| 人人干人人搞人人摸| 丝袜高跟澳门91视频| 国产成人精品日本视频| 久久精品国产97欧美精品亚洲| 天堂8在线新版官网| 欧美九九九| 99re这里只有精品中心播放| 国产美女销魂在线观看不卡| 青春草A| 18禁中文字幕| 九九九成人| 亚洲精品一区中文字幕乱码| 欧美人与动性人交a| 成人AV素股で擦久久| 国产日韩精品suv| 91欧美性| 精品视频久久久久九九九九9999| 日本日逼高清| 欧美色人| 一区,二区,三区视频| 一级A啪啪啪啪| 福利视频网站| 精吧天堂| 国产人伦精品一区二区三区| 精品国产一区二区三区在线播出| 快播久久人人aV| 狠狠中文字幕| 自偷自拍的亚洲视频| 亚洲欧美色图片| 中文字幕日韩精品一区二区三区| 99热这里只有精品8| a级免费在线观看| 日本中文字幕一区| 精品久一区免费| 无码高清专| 人妻丝袜一区二区三区在线| 色婷婷淫色网| 97久久精品亚洲中六字幕| 黄片无码在线制服| 岛国激情视频在线观看| 国色综合天| 在线五区| 成人av免费观看| 婷婷五月天无码 | 97一区二区蜜臀| 久久久青草青青国产亚洲免观精品高清完整版_97久久综合区小说区图片区,国精品 | 99热在线不卡| 中国AV美女| 伊人97超碰| 97伦综合| 荡小穴在线观看| 欧美一级在线观看成人| 亚洲综合码| 亚洲学生妹高清av| 蜜桃中文字日产乱幕4区| 天天拍夜夜| 丰满欧美少妇| 国产家庭乱伦性爱视频| 日本一二区不卡| 日本操逼视频在线| 91色碰| 17c嫩草51久久91嫩草| 99热超碰| 成人网站 免费观看| 久久久成人免费av电影| 日韩三级视频一区二区三区| 成人精品在线免费视频| 人人妻天天做天天爽| 在线国产一区二区av| 91精品久久久久| 97视频观看| 黑人狂躁日本妞一区二区三区| 久久大陆| 国产精品无码av在线| 97久久精品不卡| 日韩精品99999| 亚洲精品乱码线路中文字幕| 深爱伊人影院| 欧美综合在线91| 国内偷拍精品一区二区| 免费观看网黄| 97精品久久| 中文字幕一区二区三区四五区| 青青青青草av在线观看| 男人兔费天堂| 男人天堂2019亚洲| 97超碰中文在线| 久热大香蕉| 青椒国产97在线熟女| 亚洲欧美激情在线视频| 久操91视频| 欧美性爱三区二区| 蜜桃中文字日产乱幕4区| 九九九精品一区二区无码| 欧美高清色| av资源在线播放天堂| 天天舔天天日天天射| 欧美日韩在线视频网站| 天天插夜夜爽| 91丨九色丨东北熟女| 神马九九九| 色情综合| 国产成人欧美精品在线| 亚洲综合性网址| 日夜精品| 91红杏| 天天看夜夜看日日干| 99激情| 亚洲精品99999| 欧美最婬乱婬爆婬性视频| 久久大黄片| 玖玖爱综合| 日韩黄片影院| 99精品无码| 亚洲天堂,男人| 男女性无套 免费九一| 亚洲性少妇| 六月婷婷综合| 国产97色在线| 亚洲av综合色区无码一| 中文字幕第2页| 99国内精品| 日本高清一区二区在线| 国产亚洲色停停久久99精品91| 啊啊啊啊啊在线视频| 99精品久久久久久久婷婷蜜桃| 超碰97 线线 在现| 视频在线97| AV在线资源| 黄色性爱网网| 爽极品影院| 诱惑网综合| 亚洲成人妻日韩在线| 亚洲午夜福利视频| 色情乱伦AV| 国产一级舔足在线观看| 秋霞午夜成人福利片片| 久久超碰av在线| 330dv亚洲成年视频网| 夜夜操中文字幕| 手机久操欧美综合色码| 久久99草| 97网站在线观看 | 超碰97色色| 天天添天天干电影| 亚洲欧美另类少妇精品| 麻豆人妻精品一区二区| 91GD.COM| 青青草精品| 狠狠爱AV| 2023天天操夜夜操| 370p日韩欧美亚洲精品| 大香蕉视频一二三区| 亚洲日韩久久精品一区| 99热国产精品| 男人天堂2030| av天堂精品久久| 国产精品久久99日日| 国产免a费看黄片在线| 国产精品嫩草久久久久| 91足交| 亚洲情色一区二区三区| 激情文学小说一区二区| 国产伊人精品在线| 啪啪资源网| 人妻av在线| 亚洲1区| 中文字幕视频免费| 蜜臀视频网站| 国产在线激情视频| 久久人妻丝袜一区二区三| 91强热人妻| 亚洲 日韩 欧美 国产综合体| 91人人爽人人爽人人人,gav福利视频导航,日韩欧美亚洲国产字幕四区 | 97欧美久久久久久久| 91女优在线观看 | 亚洲一区二区精品福利| 宅男午夜在线视频| 欧美91变态| 99久久久久| 综合情欲网| 午夜性生活av免费在线看| 秋霞一级A片黄色视频| 国产AV毛片| 九九在线视频| 91精品在线播放| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 欧美日韩狠狠爱| www.黄色在线| 春色综合免费| 国产91久久九九免费精品无码| 日本一久是| 又大又大又大又粗爽高潮观看 | 成人怡红院| 蜜桃视频精品一区二区| 久久区| 久操视频免费在线观看| 翔田千里无码一区| 后入式999| 亚洲成人免费中文字幕| 欧美91在线+|+欧美| 秋霞怕怕片| 欧美亚洲20p| 内射老妇BBWX0C0CK| 国产精品熟女AV中文字幕在线播放| 九九九九九九综合| 人人操人人狠狠操| 91AV入口| 亚洲欧洲中文日韩女优乱码| 色臀aV| 日韩三级一区| 偷看洗澡一二三区美女| 天天操天天日天天干| 一区二区三区高清天码| 干超碰碰熟女| 精品久久大胆人体| 97国产成人精品免费视频| 欧亚韩国999| 亚洲精品一区中文字幕乱码| www.伪伪| 女沟厕偷窥piss小便| 男人干美女| 黑人操一区二区| 国产强奸乱伦无码视频| 91n处女在线观看| 神马久久久久久久久久久久| 蜜桃视频精品一区二区三区| www.色操逼| 综合欧美激情网| 亚欧毛片基地国产毛片基地| 国产馆| 亚洲伊人久久精品影院| 麻豆国产成人精品| 久久国模av| 蜜桃精品一区二区三区ww| 男女真人网18| 久久精品性| 国产精品久久久久久久黄无码| 91香蕉视频在线观看免费| 黄片www视频免费| 欧美一区二区男人天堂| 操逼视频国产无套| 国产亚洲福利第一页丝袜| 欧洲视频在线| 97精品97| 亚洲欧美视| 亚欧操逼片在线观看| 美国三级日本三级久久99| 91狠婷| 久久久久久99AV无码免费网站| 国产又大又粗又色生活片亚洲国产精品成人久久久综合免费 | 久久国产乱子伦精品免费女,网站| 三级激情网站| 加勒比东京热五月天天堂网| 久久久久久久久久久999| 在线无码网站| 国产精品人妻熟女aⅴ| 美女操逼A A| 日韩有码专区| 亚洲久久久久| 成人一二| 国产高清自拍| 青娱乐福利99| 日本免费人成视频播放120秒| 亚洲在线| xxxx网站亚洲精品| 精品中文字幕第一页| 亚洲精品性爱片| 午夜一区二区三区国产| 91精品国产日韩欧美综合| 日韩一级二级三级免费看完整版国语版| 新版天堂中文资源8在线| 色婷婷电影网| 精品妇女一区二区三区| 色一射色一射| 1024亚洲中文字幕久在线看片你懂的 | 黄骗免费网站| 天天激情综合站| 18禁中文字幕| 国内精品伊人久久久久影院会| 在线啊v一区| 亚洲天堂,男人| 91丝袜美女国产| 91视频国品一二三区| 久久免费看高潮毛片韩国| 国产精品乱码久久久久久| 久久久青青草| 国产极品99热在线播放69| 婷婷伊人綜合中文字幕| 磁力99AV| 超碰97欧美| 可以免费观看的日韩av毛片| 91色综合激情| 亚洲色人阁| 亚洲国产精品成人无码久久久| 婷婷三区| 女人久久久| 日本一区二区不卡精品| 极品内射| 草草电影院| 操婷婷逼| 任我爽在线视频免费观看| 国内外内射高清视频| 1024人妻熟女一区二区三区| 69综合网| 蜜乳AV免费观看| 色综合天天| 亚州欧美综合| AV男人天堂网| 东京热,男人的天堂| 九九热久久99精品re| 亚洲国产第一页综合视频| 大香蕉伊然在亚洲91| 亚洲激情在线观看一区| 欧美香蕉视xxx| 亚洲91色| 欧美黑人性猛交91| 久草午夜| 精品人妻二区三区| 91精品人| 嗯嗯啊啊啊好舒服| 99999精品| 一区二区三区精品黑丝白丝酒店对鸡| 情色五月天就去干| 久久久精品视频免费观看| 亚州 综合 色图| 无码一区二区精品视频久久久春药 | 日韩不卡av一二三| 伊人久久亚洲色欲综合网站| h无码动漫在线观看| 干B| 家庭乱伦国产| 99热18这里只有精品| 国产精品一级毛片不卡视| 成人在线视频一区| 国产女人高潮嗷嗷嗷叫小说| 四虎在线观看网站| 欧美久久伊人| 天天欧美| 中文字幕一区 二 区 三 四 五 区日 日 骚 | 久草精品国产99| 一区二区三区 丝袜 高跟 美腿| 97亚洲精品超碰| 大香蕉伊人色偷偷在线| 伊人国产成人av网站| 日本一级黄色电影| 乱伦熟女论坛| 人人操人人大香蕉| AV色五月| 天天看少妇| 欧美日韩 强奸乱伦| 玖玖无码超碰| 夜夜操天天肏| 成人八戒网站| 99国内熟女露脸视频| 无码天天操| 天美传媒精品一区二区三区| 午夜天堂精品久久久久91| 啊啊啊啊啊啊在线观看| 国产女同性恋视频| 欧美人妻一区| 欧美亚洲情色| 久草精品一区| 综合网,亚洲,欧美| 日美免费黄片| 精品蜜乳AV免费观看| 另类视频在线| 野狼激情网| 国产乱伦亚洲| 熟妇色99| 精彩久久中文| 涩爱AV在线| 无码少妇精品一区二区60岁老人| 青娱乐国产剧情av一区| 久久九九久精品国产尤物|国产精品爽黄69天堂A片潘金莲,国产亚洲精品第一综合 | 97超碰色情| 欧美A√综合网| 激情AV| 99久久久无码国产精品性啊聊| 嗯嗯啊啊啊啊轻点视频| 91久久国产综合久久| 99国产精品视频尤物| 日本色日夜干| 色网亚洲人| 欧美另类自拍 | 美女的肌被草喷水视频| 91精品久久久久久综合五月天| 69少妇一区二区| 97视频免费播放| 欧美色图亚洲色,麻豆| 偷窥自拍亚洲色图| av在线一区二区三区| 翔田千里AV无码秘 三区| 九热超碰| 亚洲国产中文字幕| a片亚洲一本通视频| 色老汉色| 性欧美体内射精| 天天摸,夜夜摸| 欧美久热| 嗯嗯啊中文字幕| 最新国产精品久久精品| 国产A v无码专区| 成人97人人超碰人人| 男人天堂网站| 国产精品久久久久婷婷二区次| 久久精品成人一区二区三区蜜臀| 东京热熟女亚洲视频网站| 日韩影片中文字幕一区二区三区| 色色丁香| 95人妻爽爽人人做人人澡| 欧美性爱在线无码| www…国产操逼| 午夜高清成人在线视频| 国产一区二区三区导航| 国产激情在线| 婷婷中文字幕| 91久久精品国产| 人妻日日夜夜精品| 射欧美综合| 欧美青青视频| 亚洲色棕合| 蜜臀99久久精品| 男人的天堂com| 亚洲欧美黄| 久久大黄片| 久久黄片国产一区二区| 嗯啊抽插大香蕉网页| 久久国内| 激情小说五月天| 国产乱婷婷精品二区三区| 嗯嗯,啊啊,国产精品| 亚洲自拍另类丝袜综合| 欧洲精品久久| 91色宗合| 欧美偷拍区| 囯产操逼片| 淮穴色AV| 亚洲色丰满少妇高潮| 亚洲在钱| 热99这里有精品综合久久 | 强奸乱伦AV网址| 一区操逼日比视频| 色婷婷丁香五月| 免費人妻夜夜爽天天爽爽一区| 啊啊啊啊啊在线视频| 欧美日韩美女精品久草一区二区三区| 日韩欧美三级| 亚洲欧美国产中文视频| 国产精品蜜乳AV| 亚洲有码 欧美精品| 97精品国产手机| 麻豆一区二区三区在线看| 国产辣妈在线视频福利| 岛国成人av在线播放网址| 极品五月天噜噜| 久久久久久裸体| 天天综合亚洲综合| 久久av成人无码免费| 91neishe| WWW美腿丝袜香蕉中文| 国产99999| 十八禁的黄污污免费网站| 啊灬啊灬啊灬好深灬快高潮了动漫-国产字幕国产在线观看-B049AV | 蜜乳中文字幕a在线| 国产欧美亚洲精品a第2页| 美女露胸露屁股| 国产suv精品一区二六| 久久性爱视频99| 五月天激情小说| 久久AV色| 亚洲性爱免费电影| 天天射网| 91 丝袜在线播放| 婷婷亚洲天堂| 香港澳门日本三级网站| 日本国产成人亚洲精品无码| 亚洲成人色情五月天丁香花| 天天综合网日韩| 97在线精品| 人妻素股| 日韩精品黄片免费观看| 久久欧洲| 久久久精品中文字幕爱豆| 日韩久久三区| aV中文麻| 99日精品欧美国产| 亚洲日韩97| 黄片色区软件| 美女黑人91神马| 国产成人99久久亚洲综合| 亚洲国产精品久久久久久久久久| 精品少妇高潮久久| 久久精视频美日韩在线视频| 啊啊啊啊啊啊啊网址在线观看| 无码外流操逼视频| 四虎视频在线观看| 欧美中文字幕日韩在线| 伊人97色天使| 久久在线观看免费视频| 四虎影视在线| 天天干人人看综合| 精品久久久中文字幕不| 一级片视频啪啪| 亚洲乱色视频一区、二区在线| 欧洲久久一二线| 美日韩一卡二卡三卡免费人妻精品| 亚洲天天更新| 精品人妻一区二区三区-国产| 国产一区二区三区高清视频| 日本天堂网| 人妻干天天| 欧美91精彩| 亚洲日韩美女中文字幕乱| 色妇91| 91精品无码人妻系列| 国产精品农村妇女精品| 9 9精品一区二区三区| 清纯唯美亚洲综合| 久久熟妇五十路一区| 欧美激情性久久久久久| 免费超碰97久久| 精品婷婷| 91网九色蝌蚪操熟女| 人妻人人澡人人爽人人| 久久鲁干| 婷婷五月天激情四射| 欧美中文字幕一区 | 色色婷婷五月天| 97免费在线观看| 亚洲精品欧洲精品| 中国东北熟女老太婆内谢| 欧美综合色| 91人妻超碰| 久久成人午夜精品影院| 天美久久久久| 欧美高潮在线| 婷婷色播婷婷| 为用户提供免费看黄网址在线观看| 久久九操在线观看| 蜜臀av在线播放一区二区三区| 亚洲av国产av综合av卡| 亚洲中文字幕一区| 久久这里都是精品| 强奸乱伦中文字幕AV| 国产97视频| 亚洲欲| 蜜臀久久99精品久久久久久久久| 国产成人精品必看| 色香av| 亚洲日韩欧美一区二区| 激情综合97| 国产黄色 A 片免费看| 亚洲三级。日韩三级| 神马久久久久眼| 日韩乱伦影音先锋| 九九九九热| 久操免费视频| 欧美色自拍| 91女神在线视频| 99碰碰| 永久免费发布性爱网| av激情亚洲五月天| 日本不卡中文| 色网综合网| 裸体女人草逼视频播放一区,二区,三区,四区,五区 | 成人草草视频| 亚洲男人的天堂网| 热天堂一区二区| 色丁香久久| 操操逼操操逼操操逼逼| 亚洲成人精品在线一区| 久久久极品| 亚洲偷拍欧美激情| 夜夜人妻爽| 色欲久久99国产精品久久久久久| 大香蕉综合在线| 欧美色图片91| 情色日播放AV| 偷拍伦理视频| 色色色综合网| 717影院理论午夜伦八戒| 丁香六月激情| 免费啪啪av| 青娱乐福利99| 国产精品直播在线观看直播| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 午夜寂寞欧美| japan日本高清乱xxxx| 九九精品99| 吖在线不卡一区二区国产剧情| 夜草网站| 日韩一级性爱无码| 2017av无码免费无线播| 啊啊啊好多水| 人妻精品视频一区二区三区| 探花精品 一区二区| 97爱爱爱| 欧美区亚洲区偷拍区 | 热热热热日日漂亮永久永久国产日| 91红杏| 四虎免费看黄| 欧美色图 人妻| 久久久免费懂色| 久热99999| 国产一区二区在线看| 欧色网址| 88xx成人精品视频| 蜜乳Av成人片网站| 岛国黄色大片网站| 丁香五月综合| 国产日本熟女顶级一区二区三区视频| 人妻精品综合中文字幕在线 | 漂亮人妻被强中文字幕hd| 97久久超碰日韩精品| 人妻丝袜日本| 欧美gv在线观看| 激情网色| 婷婷综合| 日韩99神马视频播放| 欧美日韩亚洲高清不卡一区二区三区| 日本超碰97日韩精品人妻| 一区二区亚州激情久婷婷欧美| 玖玖资源视频一区二区三区| 欧美乱欲| 天天操夜夜嗨| 婷婷综合五月| 黄总AV色图| 亚洲熟女少妇免费视频| 久草资源在线| 欧美性爱18观看| 亚洲Av无码成人精品国产| 亚洲综合色网| 欧美A√综合网| 神马久久免费电影观看| 97这里只有精品| 精品亚洲国产成人av网站| 97干在线| 国产精品亚洲四五区在线观看| 国产中文日韩欧美一区二区三区人妻丝袜美腿 | 欧美一区二区三区互相| 国产真实野战在线视频| 91蜜臀在线久久久久| 亚洲日韩久久精品一区| 天天日天天干少妇日| 久久欲| 激情五月婷| 1.igao73.com 加入收藏 免费专区 国产精品 中文字幕 日韩精品 欧美精品 精彩 | 99热综合| 精人妻无码一区二区三区伊人直播| 综合夜夜| 亚洲av无码成人精品国产| 亚洲成人精品久久久| 夜夜黄| 成人亚欧免费视频| 黄色成品网站| 亚洲成成熟女人综合一区二区| 亚洲国产一区二区入口| 97色冈| 男人的天堂VA| 久久一级无码精品毛片6| 国产嫩草精品A88AV在线| 色色香蕉| 色婷婷综合久久久久中文一区二区| 日韩天天综合| 国产成人无码高清| 免费久久9999| 国产91影院| 久久极品一区二区| 日本在线伊人啪啪| 免费a在线播放v| 日韩78m视频| 国产欧美日本亚洲精品| 国产精品视频电影| 国产精品熟女一区二区三区| 色色激情五月天| 亚洲交换| 欧美中出1| 4tube欧美女厕所| 一个人免费HD91视频| AV中文字幕剧情1区2区3| 青青免费在线视频一区| 亚洲欧美爆| 国产精品白领在线观看| 91超碰人人| 91夜色| 欧美老妇综合网| 翔田千里Av在线| 天天看人人操屄犊摸阴| 国产精品白丝在线播放| 欧美狠狠弄| 国产成人精品必看 | 女沟厕偷窥piss小便| 96AV精品| 九九视频黄色片| 五十路熟女工口| 操逼国产免费| Aa东京男人的天堂| 中国探花熟女| 免费在线视频97| 色噜噜人妻av 中文字幕| 超碰97久久| 欧美性暴力猛交XXXX | 久久不卡一区二区| 日韩欧美午夜一区二区| 欧美日动态视频| 色综合久久88色综合久久天天| 91激情国产| www.色婷婷| 欧美18老人禁| 国产一区二区久久| 欧美日韩国内不卡| 97色综合中文网| 啊啊啊好湿久久| 中文字幕乱在线伦视频中文字幕乱码在线 | 91精品丝袜久久久久久| 99丝袜福利在线播放| 内射小黄片| 国内一区二区三区| 极品色社| 国产成年免费大片黄在线观看| 99精品在线| 婷婷四五区| 欧美性爱日韩性爱| 加勒比综合在线| 美日韩一卡二卡三卡免费人妻精品| 国产在线激情视频| 人妻夜爽夜夜爽| 色女综合| 丁香婷婷久久 | 青青草色情网站视频| 午夜福利视频在线一区| 欧美天天综合网| 久噜噜| 天天干,天天日| 中国一级特黄大片护士| 91丰满| 久久女同性恋一二区| 天天日天天插| 操逼逼中文字幕| 97综合在线| 九色 蝌蚪 熟女自| 国产性刺激| 一起草AV| 欧美专区日本专区| 少妇熟女1区2区3区| av2014 日韩在线中文字幕| 美女97超碰| 天天爱天天韩国日本牛牛牛牛| 操逼国产免费| 偷拍精品一区二区三区| 亚洲日本大香蕉1| 欧美韩国你懂得在线| 精品一区二区啪啪啪| 国产色呦呦| 一区二区三区亚洲| 欧美后入| 综合久久2017| 9久9久9久9久视频网站| 亚洲色图 图片| 九九热免费在线国产视频伊人五月| 麻豆这里只有精品| 亚洲无吗在线视频| 视频一区二区三区精品| 国产三级片在线观看| 欧美亚洲韩国视频十五区| 操逼精品视频| 久草色悠悠在线视频| 青青草视频久久| 婷婷香蕉| 免费一级视频特黄色大片| 91视频女生| 欧美疯狂做爰xxxx| 啊啊啊轻点在线观看| 加勒比在线视频一区二区三区| 青青伊人这里只有精品| 日韩不卡a级视频专区| 日本999精品| 欧美操逼熟女| 夜夜躁狠狠躁日日躁av| 国产女上位好爽在线| 国产在线能看的你懂的| 狠操91,com| 日韩精品.久久精品.AV女优.天美传媒| 91热| 93人人操人人| 噜噜噜亚洲精| 久操九九九九九九九九九九九九九九九九九九九九九九九九九九九九 | 国产乱不卡| 久久超碰、| 天天操天天舔| 中文字幕一区二区三区四区在线视频| 劲爆欧美人妖三区91| 人妻嗯啊啊在线播放| av一区二区三区不卡| 九九久久久| 清纯唯美综合亚洲| 不卡人妻少妇精品毛片一区23区视频 | 粉嫩av一区二区三区天美传媒| 国产白嫩精品久久| 99欧美| 无遮挡一级毛片视频免费的| 色色九区| 天天干人人乐| 欧美色91| 婷婷精品久久av影视| 九九九九九九九九九九九蜜桃 | 啊啊啊久久久视频| 97超碰精品成| 中文一区二区| 性性欧美| 2026国产精品视频| 丝袜色综合| 青青伊人加勒比海| 岛国不卡超碰护士AV在线播放| 97玖玖超碰| 爱干爱射网啊啊啊| 欧美三级一级| 97国产亚洲中文在线| 熟女高潮合集-永久久久-成人AV| 男人的天堂欧美| 97 九色| 婷婷激情五月综合| 欧美丝袜91| 探花精品 一区二区| 欧美精品69性爱| 极品销魂美女一区二区| 中字幕人妻一区二区三区| A 在线网址| 国产高清精品福利| 91校园春色长篇| 丝袜视频一区二区在线播放国产中文| 精品人妻一区二区三区夜夜| 亚洲综合69| 欧美后入式| 国产 日韩 欧美高清| 国产成人综合网| 五十路熟女工口| 国产9熟妇视频网站| 天天综合-91入口| 日本性爱不卡视频| 老司机久久| 熟女熟妇伦久久影院毛片一区二区| 国产9l 大屁股| 国产视频一区二区免费| 久久99国产综合精品女同| 精品人妻无码一区二区三区不卡-精品人妻无码一区二区...|精品少妇一区二区三 | 欧美制服网站美腿丝袜| 久久久久久裸体| 日韩电影在线观看网址| 日本三级网页| 麻豆AV短剧| 91天天综合| 熟女突然公开看18禁影片| 国产精品久久久久久久久久久久久久久久久久 | 亚洲老熟妇xxx| 91天堂丝袜美腿| 福利伊人玖玖国产| 60秒免费小视频| 亚洲国产91精品一区二区久久| 丰满少妇一区二区三区四区观看| 日韩有码中文字幕女同性恋| 人人射人人操人人摸| 青青草久久| 日本熟妇人妻中出视频| 91欧美丝袜| 色爱三区| 少妇高潮九九九九九九九| 人妻-91porn| 免费在线视频97| 天天综合色| 国产捆绑一区| 91少妇香蕉久久精品| 成人三级片无码| 日韩在线电影| 欧美午夜精品久久久久久3D| 蜜臀99久久精品久久久懂爱| 丝袜狠狠草尤物人妻av91| 青草综合| 中文字幕精品久久久久人妻红杏ⅰ| 日韩精品人妻一| 亚州,欧美在线| 狠狠中文字幕| 国产日韩欧美亚洲精品95 | 中国黄色特级精品一区二区三区片| 人人操人人狠狠操| 国产一进一出视频网站| Julia Annxxxxx| 青青草密桃在线播放| 欧美亚洲尤物久久| 欧美亚洲综合高清在线| 亚洲污污网站| 91N欧美| 国产亚洲日韩在线三区黑人| 91成人无码| 青青草久草AV| 国精品一区二区三| 九九成人视频| 国模无码一区二区三区在线| 91天天| 亚洲婷婷综合网| 婷婷国产精品一区二区| 人妻少妇精品无码专区二区密桃| 国产亚洲一黄| 国产精品久久久久久久毛片1| 日韩一级久久毛片| 青青草好吊色| 色噜噜国产精品视频一区二区| 久久超碰98| 国产又大又粗又色生活片亚洲国产精品成人久久久综合免费 | 午夜成人福利影视| 久9久| 60秒试看最爽10分钟网站| 91狠狠综合久久久久久| 蜜臀av在线播放一区二区三区| 加勒比久久综合网高清| 高清成年美女黄网站免费大全 | 国产粉嫩出水在线播放| 国模艳艳啪啪一区| 人人射人人操人人摸| 久草免费在线一区二区| 欧美性爱五月天| 大香蕉色十月| 综合激情97 | 久久久久亚洲?V片无码V| 欧美日韩操操操| 久/久精品99看9| 99热超碰| 97色97干| 男女激情黄色网址| 992这里有精品| 国产性感在线观看| 久久大精品乱码视频人妻熟女| 夜夜骑天天燥| 99re黄| 少妇xx精品| 精品夜夜澡人妻无码| a片亚洲一本通视频| 综合欧美色图| 精品午夜福利国产一区二区在线观看| 中文字幕一区二区三区视频播放| 五月天综合网| 青青草日韩免费观看高清在线| 婷婷国产精品一区二区| 亚洲,日韩,欧美,成人播放| www.99热| 亚av顶级裸体一区二区三区四区五区 | 高清不卡视频| 99999久久精| 午夜无码精品免费看性色| 乱精品一区字幕二区| 中文字幕AV片| 性夜影院爽黄A爽免费动漫| 天天色播亚洲综合网站| 色五月天AV| 欧美一区二区一级岛国大片| 午夜丁香| 伊人宅男大香蕉| 人妻22p| 欧美视频一区二区三区| 操逼网站地址| 俺去啦自拍| 99ri视频| 一区二区三区四区理论片| 日本精品成人无码| 污电影在线观看| 日本高清有码网址视频| 久久机热| 日韩性爱播放| 欧美日韩人妻精品系列一区二区三区| 黄色网址在线免费观看| 长久操视频| 婷婷六月色| 97色网| 日韩精品人妻中文字有码在线| 中国少妇XXXX做受| 国模91| 天天综合精品| A一区片| 超碰在线成人电影| 日本精品一区三区| 久久无码一区二区二三区性色| 国产精品电影推荐| 狠狠操综合| 亚洲啪啪视频免费| 婷婷九月丁香| 97操97色| 欧美 亚洲 偷拍自拍| 97亚洲中文| 亚洲drav色图| 欧美精品四区| 日本视频在线观看污污污| 亚洲无码精品AV久久久| 韩日精品福利视频一区不卡在线免| 国产欧美一区激情交| 欧美午夜视频免费观看| 久久爱97| 亚洲在钱| 男人的天堂色偷偷青青草视频婷婷网| 亚洲成人福利电影免费| 国产黄色在线播放观看| 国产免费小视频| 91操人| 国产精品密臀网在线观看| 99这里有精品| 99久久无色码| 大香蕉碰碰| 色香阁在线| 欧洲综合视频|