RFQ 引擎架構:可用性預留與取消策略快照為何重要
大多數 RFQ 自動化忽略的問題
當團隊自動化 RFQ 工作流時,他們通常專注於前端:解析買家請求、搜尋目錄、匹配產品、應用定價。這些工作是真實的,也有工具可用——AI 提取需求,而確定性規則處理定價、審批和 SLA 追蹤,正如 GEP 在其採購自動化分析中所述。Ivalua 2026 年採購指南 確認了同樣的模式:AI 處理提取和匹配,規則處理治理。
但兩個問題在生產環境中打破了這個模型,而大多數自動化並未解決:
可用性漂移。 一份需要三天談判的報價,其對應的庫存可能在報價價格下已不存在。如果代理承諾以 $12.40 提供 50 個單位,而買家接受時供應商只剩 12 個,這份報價從一開始就無法交付。代理沒有撒謊——世界在它腳下發生了變化。
策略漂移。 30 天前報價的取消費用可能與預訂時生效的費用不同。如果供應商在談判中途收緊條款,而代理未在報價時捕獲策略,買家後續會爭議這筆費用。爭議是合理的——條款變了。
解決兩者的架構是一個具有兩種機制的 RFQ 引擎:原子性可用性預留,在時間窗口內預留受限庫存;以及取消策略快照,在報價時刻凍結商業條款。這些不是附加到報價工具上的功能,而是資料模型中的結構性承諾——引擎強制執行的欄位、狀態轉換和生命週期操作。
使其運作的實體模型
生產級 RFQ 引擎需要的不僅僅是請求和報價。實體模型必須將買家意圖與供應商響應分開,並且必須獨立於目錄追蹤受限供應。以下實體構成主幹:
Request — 買家意圖:聯絡人、標題、行項目、帳單和收貨地址、有效期、狀態。請求通過定義的狀態機移動:initial → in_progress → confirmed → completed,當報價已存在後項目變更時以 modified 作為重入點。
Item — 買家想要的目錄產品。項目是通用的;有 UUID、類型、定價模式和計量單位。同一項目映射到多個供應商項目。
ProviderItem — 供應商對該項目的特定提供,按計量單位的基礎價格。供應商項目屬於供應商公司,可以有多個批次。
ProviderItemBatch — 受限庫存單位。每個批次有批號、生產日期、過期日期、單位成本、庫存標誌和慢動庫存標誌 slow_move_item。批次是檢查和預留可用性的粒度。
Quote — 供應商對已確認請求的定價響應。報價有供應商、銷售代表、運輸方式和金額、貨幣、匯率和匯率鎖定時間戳、協商輪次(自動計算)以及狀態機:initial → in_progress → confirmed → completed 或 disapproved。
QuoteItem — 報價上的一行,將供應商項目和批次連結到數量、單價、小計、折扣和最終小計。關鍵的是,報價項目攜帶 hold_token、hold_expires_at、guardrail_price_per_uom 和 slow_move_item — 使可用性預留和盈利保障在行級別可見的欄位。
CancellationPolicy — 預訂可取消的條款,包含層級、截止日期和罰金規則,按供應商項目界定。
Installment — 與已確認報價關聯的付款計畫,包含優先級、計畫日期、金額、比例和狀態機:pending → paid 或 cancelled。
這不是一個扁平表。它是一個帶有嵌套解析器的型別化圖——請求解析其報價,報價解析其項目,報價項目解析其供應商項目和批次。引擎使用基於 DataLoader 的批量載入,使得有 20 個行項目的報價不會觸發 20 次順序資料庫查詢。
可用性預留:原子性保留產能
可用性預留是防止可用性漂移的機制。沒有它,代理針對可能已過時的庫存快照報價。有了它,代理在時間窗口內預留產能,報價由真實的、已扣減的供應支援。
預留生命週期有四個狀態和嚴格的轉換規則:
| 狀態 | 含義 | 允許的轉換 |
|---|---|---|
held |
產能已扣減,發放帶 TTL(15 分鐘)的預留權杖 | confirmed, released, expired |
confirmed |
預訂已提交,無第二次產能扣減 | 終態 |
released |
預留已取消,產能已恢復(冪等) | 終態 |
expired |
TTL 已過,產能已恢復(冪等) | 終態 |
關鍵的設計決策在 confirmed 轉換中:無第二次產能扣減。預留已經保留了產能。確認預訂將預留轉為已確認狀態,不會再次觸及庫存計數。這防止了重複計數——即預留扣減產能後確認又扣減一次,導致系統認為可用供應少於實際的 bug。
預留是原子的。acquireAvailabilityHold mutation 扣減可用產能並返回帶 expires_at 時間戳的 hold_token。如果產能不足,操作無副作用地失敗——無部分預留,無髒狀態。releaseAvailabilityHold 和 expireAvailabilityHold mutation 恢復產能並且是冪等的:對同一權杖呼叫兩次返回相同結果。這對容錯很重要——如果網路超時導致重試,系統不會過度恢復產能。
如何映射到報價工作流
考慮一個分銷商向有三個不同過期日期和成本批次的供應商報價 200 台工業泵。代理:
- 呼叫
check_availability,傳入供應商項目 UUID、服務窗口和數量——獲取匹配的批次和可用數量。 - 呼叫
acquire_availability_hold——產能原子性扣減,返回帶 15 分鐘 TTL 的hold_token。 - 報價項目現在攜帶
hold_token和hold_expires_at。買家看到的是由真實庫存支援的報價,而非目錄猜測。 - 如果買家在 15 分鐘內接受,代理呼叫
confirm_availability_hold——預留轉為confirmed,產能鎖定,無第二次扣減。 - 如果買家拒絕或 TTL 過期,代理呼叫
release_availability_hold或讓其過期——產能恢復,下一次報價可以使用。
hold_token 是顯式控制代碼。模型將其作為參數傳遞,而非隱藏的會話狀態。這與 MCP 2026-07-28 release candidate 正式化的顯式控制代碼模式相同:代理跨工具呼叫需要的狀態成為可見的、可稽核的控制代碼,而非傳輸層元資料。
取消快照:凍結條款
取消策略漂移是第二個故障模式。供應商可能在報價和預訂之間更改取消罰金——30 天前 10% 的罰金變成 7 天前 50%。如果代理報價了舊罰金而買家接受了,買家會爭議新費用。爭議是正確的。
架構通過在報價時快照取消策略來解決這個問題。CancellationPolicy 實體有 tiers(帶截止日期和罰金百分比的 JSON 結構)、label、description 和 status。當代理生成報價時,它檢索每個供應商項目的活躍取消策略並將策略條款附加到報價。策略 UUID 及其層級被凍結——即使供應商後續更新策略,報價仍攜帶發出時有效的條款。
search_cancellation_policies 工具按供應商項目和狀態過濾,使代理可以為每個行項目檢索活躍策略。策略然後與報價項目關聯,而非僅通過外鍵參照——快照就是策略,不是指向可變記錄的指標。
這個模式不僅適用於取消。匯率使用相同方法:QuoteType 攜帶 fx_rate 和 fx_rate_locked_at——匯率在報價時鎖定,而非在預訂時查找。如果買家顯示貨幣與供應商報價貨幣不同,鎖定匯率就是買家看到的匯率,不受市場波動影響。
定價層級、分段查找和護欄
定價不是扁平欄位。引擎按客戶分段、數量和供應商項目解析價格層級。get_item_price_tiers 工具接收客戶電子郵件和報價項目列表(每個帶項目 UUID、供應商項目 UUID 和數量),通過分段聯絡人查找客戶分段,並在單次查詢中批量載入所有匹配的價格層級。層級在資料庫層面按數量閾值過濾——只返回 quantity_greater_then 和 quantity_less_then 包含請求數量的層級。
折扣提示以相同方式工作,使用分層範圍系統:GLOBAL(適用於所有報價)、SEGMENT(適用於客戶分段)、ITEM(適用於特定項目)和 PROVIDER_ITEM(適用於供應商對某項目的特定提供)。get_discount_prompts 工具從所有四個範圍載入,去重,並返回帶條件和規則的合併集合。這意味著一份報價可以同時應用批量折扣(分段範圍)、季節性促銷(項目範圍)和供應商特定清倉(供應商項目範圍)——每個有自己的優先級。
報價項目上的 guardrail_price_per_uom 欄位是盈利護欄——從供應商項目批次載入的項目最低可接受價格。如果代理應用使價格低於護欄的折扣,操作不會失敗(代理可能有正當理由),但標誌在報價項目響應中可見。slow_move_item 標誌標記庫存時間過長的項目——代理可以利用此應用更深折扣,但護欄防止不盈利的定價。
防止無效操作的狀態機
沒有狀態強制的 RFQ 引擎只是電子表格。引擎強制執行四個狀態機,每個都有明確的轉換規則和操作守衛:
Request: initial → in_progress → confirmed → completed,以 modified 作為重入點。RequestOperationGuard 強制報價只能從 confirmed 請求建立,項目修改只在 initial、in_progress 或 modified 狀態允許。
Quote: initial → in_progress → confirmed → completed 或 disapproved。QuoteOperationGuard 強制項目修改只在 initial 或 in_progress 允許,分期只能從 confirmed 報價建立。
可用性預留: held → confirmed / released / expired。三個目標狀態都是終態。
Installment: pending → paid 或 cancelled。兩個目標狀態都是終態。
當已確認請求的項目變更且報價已存在時,請求轉為 modified,所有現有報價自動被拒絕——買家必須針對更新後的項目獲取新報價。這防止在生成報價的請求變更後接受過時報價。
當報價上所有未取消分期都已支付時,報價自動轉為 completed。當請求上至少一份報價完成時,請求自動轉為 completed。狀態機不是建議性的——引擎驗證每次轉換,如果操作無效則拋出帶當前狀態和允許轉換的 VALIDATION_FAILED 錯誤。
模組模式:38 個工具,11 個領域 mixin
此架構的參考實作是單個 MCP 模組——mcp_hospirfq_processor——由 11 個領域 mixin 組合的 38 個註冊工具:Request、Item、Availability、Quote、Pricing、Installment、Bundle、Cancellation、File、Segment 和 Catalog。mixin 共享 GraphQLBackedProcessor 基類,提供 GraphQL 客戶端、日誌器和設定。每個 mixin 貢獻自己的工具方法,只存取 self.logger、self.setting 和 self._execute_graphql_query。
工具通過設定區塊(MCP_CONFIGURATION)註冊,宣告每個工具的名稱、描述、輸入 schema(JSON Schema)和模組連結(類名、函數名、返回型別)。MCP runtime 在啟動時載入此設定,將工具呼叫分派到對應的 mixin 方法。@handle_errors 裝飾器用結構化錯誤處理包裝每個工具呼叫,產生帶代碼的型別化錯誤響應,如 GRAPHQL_QUERY_FAILED、VALIDATION_FAILED、HOLD_NOT_FOUND、HOLD_ALREADY_EXPIRED、AVAILABILITY_INSUFFICIENT 和 PRICING_MODE_UNSUPPORTED。
38 個工具涵蓋完整的 RFQ 生命週期:
| 領域 | 工具 | 關鍵操作 |
|---|---|---|
| 請求管理 | 8 | 提交、更新、獲取、搜尋、新增/刪除項目、分配/刪除供應商項目 |
| 項目管理 | 3 | 搜尋項目、獲取項目、獲取帶批次資訊的供應商項目 |
| 報價管理 | 4 | 更新報價、獲取報價、搜尋報價、更新報價項目 |
| 定價 | 3 | 獲取價格層級、獲取折扣提示、計算報價定價 |
| 分期 | 4 | 建立、更新、建立計畫、獲取分期 |
| 可用性 | 5 | 檢查、獲取預留、釋放、確認、過期 |
| Bundle | 3 | 搜尋 bundle、獲取 bundle、搜尋元件 |
| 取消 | 2 | 獲取策略、搜尋策略 |
| 目錄 | 1 | 查詢目錄(知識圖譜搜尋) |
| 分段 | 1 | 獲取分段聯絡人 |
| 檔案 | 2 | 上傳、獲取檔案 |
| 工作流 | 2 | 確認請求+建立報價、確認報價+建立分期 |
兩個工作流工具——confirm_request_and_create_quotes 和 confirm_quote_and_create_installments——是將多個原子工具組合為單次呼叫的便捷操作。前者在一步中確認請求並為選定供應商建立報價。後者在一步中確認報價並建立分期計畫。這減少了代理在最常見多步工作流中需要的往返次數。
inquire_catalog 工具是通往知識圖譜的橋樑。它接收自然語言查詢、可選命名空間(hotel、flight、activity)和限制,從知識圖譜引擎返回排序結果。這就是代理在報價前發現產品的方式——不是對產品表的 SQL 查詢,而是通過知道替代品、相容性和可用性的目錄圖進行語義搜尋。
此架構為何可推廣
參考實作是為旅遊和酒店業構建的——有日期界限的庫存、入住規則、單人定價、bundle、押金、取消條款。這是壓力測試。如果引擎能針對特定日期報價並預訂酒店房間,用 TTL 預留可用性,快照取消策略,鎖定匯率,應用分段特定定價層級,並交付到分期計畫,它就能支援任何具有供應商、買家、受限庫存和商業條款的 B2B RFQ 工作流。
推廣是結構性的:
- 分銷和批發: 用倉庫庫存替換酒店房間,供應商項目替換供應商 SKU,批次替換批號和過期日期。可用性預留預留庫存;取消快照保留退貨條款。
- 採購: 用零件和材料替換旅遊套餐。基於分段的定價層級應用協商合同費率;護欄價格防止不盈利的採購。
- 製造: 用生產槽位替換服務窗口。可用性預留預留生產線產能;取消策略保留重新安排罰金。
- 現場服務: 用預約窗口替換酒店日期。可用性預留預留技術人員的時間槽;分期計畫結構化付款時間表。
實體模型——Request、Item、ProviderItem、ProviderItemBatch、Quote、QuoteItem、CancellationPolicy、Installment——是行業無關的。領域 mixin 是可組合的:採購部署可以去掉 Bundle mixin 並保留其餘。製造部署可以在 Availability 旁新增 ProductionSlot mixin。模組模式、狀態機和顯式控制代碼方法保持不變。
運行 NetSuite、BigCommerce 和三個供應商目錄的分銷商獲得一個代理,它通過郵件或門戶接收 RFQ,針對目錄圖解析產品和替代品,按客戶分段定價,用有效期預留庫存,快照取消條款,鎖定匯率,並將接受的報價寫回 NetSuite——每次工具呼叫都被記錄,每次狀態轉換都被驗證。該構建是四步方法的第 2-3 階段,通常在 5-8 週內上線。
請求範圍確定的構建。 一週 Discovery。您獲得系統清單、工作流圖和固定範圍——無論是否與我們合作。
想為您的系統建構這個嗎?
這裡的每份文件都來自真實的生產工作。如果您有目標系統和工作流程想法,我們可以在一週內確定範圍。
申請客製開發為期一週的發掘階段。您會拿到系統清單、工作流程地圖和固定範圍——無論您最終是否與我們合作開發。