---
read_when:
    - การวินิจฉัยการหมุนเวียนโปรไฟล์การยืนยันตัวตน คูลดาวน์ หรือพฤติกรรมการสำรองไปใช้โมเดลอื่น
    - การอัปเดตกฎการสลับไปใช้ตัวสำรองสำหรับโปรไฟล์การยืนยันตัวตนหรือโมเดล
    - ทำความเข้าใจว่าการกำหนดโมเดลทับสำหรับเซสชันทำงานร่วมกับการลองใหม่แบบทางเลือกสำรองอย่างไร
sidebarTitle: Model failover
summary: วิธีที่ OpenClaw หมุนเวียนโปรไฟล์การยืนยันตัวตนและสลับไปใช้ตัวเลือกสำรองระหว่างโมเดลต่าง ๆ
title: การสลับไปใช้โมเดลสำรอง
x-i18n:
    generated_at: "2026-04-30T09:47:40Z"
    model: gpt-5.5
    provider: openai
    source_hash: af8c343186105256cb2e1a65cdfc3e0042ce8d3d14d21cd007d90174e35b98e7
    source_path: concepts/model-failover.md
    workflow: 16
---

OpenClaw จัดการความล้มเหลวเป็นสองขั้นตอน:

1. **การหมุนเวียนโปรไฟล์การยืนยันตัวตน** ภายในผู้ให้บริการปัจจุบัน
2. **การใช้โมเดลสำรอง** ไปยังโมเดลถัดไปใน `agents.defaults.model.fallbacks`

เอกสารนี้อธิบายกฎขณะรันไทม์และข้อมูลที่รองรับกฎเหล่านั้น

## โฟลว์ขณะรันไทม์

สำหรับการรันข้อความปกติ OpenClaw จะประเมินตัวเลือกตามลำดับนี้:

<Steps>
  <Step title="Resolve session state">
    แก้ไขสถานะเซสชันที่ใช้งานอยู่และค่ากำหนดโปรไฟล์การยืนยันตัวตน
  </Step>
  <Step title="Build candidate chain">
    สร้างเชนตัวเลือกโมเดลจากการเลือกโมเดลปัจจุบันและนโยบายการใช้สำรองสำหรับแหล่งที่มาของการเลือกนั้น ค่าเริ่มต้นที่กำหนดไว้ โมเดลหลักของงาน cron และโมเดลสำรองที่เลือกอัตโนมัติสามารถใช้ค่าสำรองที่กำหนดไว้ได้ ส่วนการเลือกเซสชันโดยผู้ใช้อย่างชัดเจนจะเข้มงวด
  </Step>
  <Step title="Try the current provider">
    ลองใช้ผู้ให้บริการปัจจุบันพร้อมกฎการหมุนเวียน/คูลดาวน์โปรไฟล์การยืนยันตัวตน
  </Step>
  <Step title="Advance on failover-worthy errors">
    หากผู้ให้บริการนั้นใช้ตัวเลือกหมดแล้วด้วยข้อผิดพลาดที่ควรสลับไปใช้สำรอง ให้ย้ายไปยังตัวเลือกโมเดลถัดไป
  </Step>
  <Step title="Persist fallback override">
    บันทึกค่าทับซ้อนสำรองที่เลือกไว้ก่อนเริ่มลองใหม่ เพื่อให้ตัวอ่านเซสชันอื่นเห็นผู้ให้บริการ/โมเดลเดียวกับที่ตัวรันกำลังจะใช้ ค่าทับซ้อนโมเดลที่บันทึกไว้จะถูกทำเครื่องหมายเป็น `modelOverrideSource: "auto"`
  </Step>
  <Step title="Roll back narrowly on failure">
    หากตัวเลือกสำรองล้มเหลว ให้ย้อนกลับเฉพาะฟิลด์ค่าทับซ้อนเซสชันที่เป็นของการสำรอง เมื่อฟิลด์เหล่านั้นยังตรงกับตัวเลือกที่ล้มเหลวนั้น
  </Step>
  <Step title="Throw FallbackSummaryError if exhausted">
    หากตัวเลือกทั้งหมดล้มเหลว ให้โยน `FallbackSummaryError` พร้อมรายละเอียดรายความพยายามและเวลาสิ้นสุดคูลดาวน์ที่เร็วที่สุดเมื่อทราบ
  </Step>
</Steps>

นี่ตั้งใจให้แคบกว่า “บันทึกและกู้คืนทั้งเซสชัน” ตัวรันการตอบกลับจะบันทึกเฉพาะฟิลด์การเลือกโมเดลที่เป็นเจ้าของสำหรับการใช้สำรอง:

- `providerOverride`
- `modelOverride`
- `modelOverrideSource`
- `authProfileOverride`
- `authProfileOverrideSource`
- `authProfileOverrideCompactionCount`

สิ่งนี้ป้องกันไม่ให้การลองใช้สำรองที่ล้มเหลวเขียนทับการเปลี่ยนแปลงเซสชันอื่นที่ใหม่กว่าและไม่เกี่ยวข้อง เช่น การเปลี่ยน `/model` ด้วยตนเอง หรือการอัปเดตการหมุนเวียนเซสชันที่เกิดขึ้นระหว่างที่ความพยายามนั้นกำลังทำงาน

## นโยบายแหล่งที่มาของการเลือก

OpenClaw แยกผู้ให้บริการ/โมเดลที่เลือกออกจากเหตุผลที่เลือก แหล่งที่มานั้นควบคุมว่าจะอนุญาตให้ใช้เชนสำรองหรือไม่:

- **ค่าเริ่มต้นที่กำหนดไว้**: `agents.defaults.model.primary` ใช้ `agents.defaults.model.fallbacks`
- **โมเดลหลักของเอเจนต์**: `agents.list[].model` จะเข้มงวด เว้นแต่วัตถุโมเดลของเอเจนต์นั้นจะมี `fallbacks` ของตัวเอง ใช้ `fallbacks: []` เพื่อทำให้พฤติกรรมเข้มงวดชัดเจน หรือระบุรายการที่ไม่ว่างเพื่อให้เอเจนต์นั้นเลือกใช้การสำรองโมเดล
- **ค่าทับซ้อนสำรองอัตโนมัติ**: การสำรองขณะรันไทม์จะเขียน `providerOverride`, `modelOverride` และ `modelOverrideSource: "auto"` ก่อนลองใหม่ ค่าทับซ้อนอัตโนมัตินั้นสามารถเดินต่อไปตามเชนสำรองที่กำหนดไว้ และจะถูกล้างโดย `/new`, `/reset` และ `sessions.reset`
- **ค่าทับซ้อนเซสชันของผู้ใช้**: `/model`, ตัวเลือกโมเดล, `session_status(model=...)` และ `sessions.patch` จะเขียน `modelOverrideSource: "user"` นั่นคือการเลือกเซสชันแบบตรงตัว หากผู้ให้บริการ/โมเดลที่เลือกล้มเหลวก่อนสร้างคำตอบ OpenClaw จะรายงานความล้มเหลวแทนที่จะตอบจากค่าทดแทนที่กำหนดไว้ซึ่งไม่เกี่ยวข้อง
- **ค่าทับซ้อนเซสชันรุ่นเก่า**: รายการเซสชันรุ่นเก่าอาจมี `modelOverride` โดยไม่มี `modelOverrideSource` OpenClaw ถือว่าสิ่งเหล่านั้นเป็นค่าทับซ้อนของผู้ใช้ เพื่อไม่ให้การเลือกเก่าที่ชัดเจนถูกแปลงเป็นพฤติกรรมสำรองอย่างเงียบ ๆ
- **โมเดลใน payload ของ Cron**: งาน cron `payload.model` / `--model` เป็นโมเดลหลักของงาน ไม่ใช่ค่าทับซ้อนเซสชันของผู้ใช้ โดยจะใช้ค่าทดแทนที่กำหนดไว้ เว้นแต่งานจะระบุ `payload.fallbacks`; `payload.fallbacks: []` ทำให้การรัน cron เข้มงวด

## พื้นที่จัดเก็บการยืนยันตัวตน (คีย์ + OAuth)

OpenClaw ใช้ **โปรไฟล์การยืนยันตัวตน** สำหรับทั้งคีย์ API และโทเค็น OAuth

- ความลับอยู่ใน `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` (รุ่นเก่า: `~/.openclaw/agent/auth-profiles.json`)
- สถานะการกำหนดเส้นทางการยืนยันตัวตนขณะรันไทม์อยู่ใน `~/.openclaw/agents/<agentId>/agent/auth-state.json`
- Config `auth.profiles` / `auth.order` เป็น **เมทาดาทา + การกำหนดเส้นทางเท่านั้น** (ไม่มีความลับ)
- ไฟล์ OAuth รุ่นเก่าสำหรับนำเข้าเท่านั้น: `~/.openclaw/credentials/oauth.json` (นำเข้าไปยัง `auth-profiles.json` เมื่อใช้ครั้งแรก)

รายละเอียดเพิ่มเติม: [OAuth](/th/concepts/oauth)

ชนิดข้อมูลประจำตัว:

- `type: "api_key"` → `{ provider, key }`
- `type: "oauth"` → `{ provider, access, refresh, expires, email? }` (+ `projectId`/`enterpriseUrl` สำหรับผู้ให้บริการบางราย)

## ID โปรไฟล์

การเข้าสู่ระบบ OAuth จะสร้างโปรไฟล์ที่แยกจากกันเพื่อให้หลายบัญชีอยู่ร่วมกันได้

- ค่าเริ่มต้น: `provider:default` เมื่อไม่มีอีเมล
- OAuth พร้อมอีเมล: `provider:<email>` (เช่น `google-antigravity:user@gmail.com`)

โปรไฟล์อยู่ใน `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` ภายใต้ `profiles`

## ลำดับการหมุนเวียน

เมื่อผู้ให้บริการมีหลายโปรไฟล์ OpenClaw จะเลือกลำดับดังนี้:

<Steps>
  <Step title="Explicit config">
    `auth.order[provider]` (หากตั้งค่าไว้)
  </Step>
  <Step title="Configured profiles">
    `auth.profiles` ที่กรองตามผู้ให้บริการ
  </Step>
  <Step title="Stored profiles">
    รายการใน `auth-profiles.json` สำหรับผู้ให้บริการ
  </Step>
</Steps>

หากไม่ได้กำหนดลำดับไว้อย่างชัดเจน OpenClaw จะใช้ลำดับแบบ round-robin:

- **คีย์หลัก:** ชนิดโปรไฟล์ (**OAuth ก่อนคีย์ API**)
- **คีย์รอง:** `usageStats.lastUsed` (เก่าสุดก่อน ภายในแต่ละชนิด)
- **โปรไฟล์ที่อยู่ในคูลดาวน์/ถูกปิดใช้งาน** จะถูกย้ายไปท้ายสุด โดยเรียงตามเวลาสิ้นสุดที่เร็วที่สุด

### ความคงตัวของเซสชัน (เป็นมิตรกับแคช)

OpenClaw **ปักหมุดโปรไฟล์การยืนยันตัวตนที่เลือกไว้ต่อเซสชัน** เพื่อให้แคชของผู้ให้บริการยังอุ่นอยู่ ระบบ **จะไม่** หมุนเวียนทุกคำขอ โปรไฟล์ที่ปักหมุดจะถูกใช้ซ้ำจนกว่า:

- เซสชันถูกรีเซ็ต (`/new` / `/reset`)
- Compaction เสร็จสมบูรณ์ (ตัวนับ compaction เพิ่มขึ้น)
- โปรไฟล์อยู่ในคูลดาวน์/ถูกปิดใช้งาน

การเลือกด้วยตนเองผ่าน `/model …@<profileId>` จะตั้งค่า **ค่าทับซ้อนของผู้ใช้** สำหรับเซสชันนั้น และจะไม่ถูกหมุนเวียนอัตโนมัติจนกว่าเซสชันใหม่จะเริ่ม

<Note>
โปรไฟล์ที่ปักหมุดอัตโนมัติ (เลือกโดยเราเตอร์เซสชัน) จะถือเป็น **ค่ากำหนด**: จะถูกลองก่อน แต่ OpenClaw อาจหมุนเวียนไปยังโปรไฟล์อื่นเมื่อเกิด rate limit/timeout โปรไฟล์ที่ผู้ใช้ปักหมุดจะยังล็อกอยู่กับโปรไฟล์นั้น หากล้มเหลวและกำหนดค่าการสำรองโมเดลไว้ OpenClaw จะย้ายไปยังโมเดลถัดไปแทนการสลับโปรไฟล์
</Note>

### ทำไม OAuth อาจ “ดูเหมือนหายไป”

หากคุณมีทั้งโปรไฟล์ OAuth และโปรไฟล์คีย์ API สำหรับผู้ให้บริการเดียวกัน round-robin อาจสลับระหว่างโปรไฟล์เหล่านั้นข้ามข้อความ เว้นแต่จะปักหมุดไว้ หากต้องการบังคับใช้โปรไฟล์เดียว:

- ปักหมุดด้วย `auth.order[provider] = ["provider:profileId"]` หรือ
- ใช้ค่าทับซ้อนต่อเซสชันผ่าน `/model …` พร้อมค่าทับซ้อนโปรไฟล์ (เมื่อ UI/พื้นผิวแชตของคุณรองรับ)

## คูลดาวน์

เมื่อโปรไฟล์ล้มเหลวเนื่องจากข้อผิดพลาดการยืนยันตัวตน/rate-limit (หรือ timeout ที่ดูเหมือน rate limiting) OpenClaw จะทำเครื่องหมายว่าอยู่ในคูลดาวน์และย้ายไปยังโปรไฟล์ถัดไป

<AccordionGroup>
  <Accordion title="What lands in the rate-limit / timeout bucket">
    บัคเก็ต rate-limit นั้นกว้างกว่า `429` ธรรมดา: ยังรวมถึงข้อความจากผู้ให้บริการ เช่น `Too many concurrent requests`, `ThrottlingException`, `concurrency limit reached`, `workers_ai ... quota limit exceeded`, `throttled`, `resource exhausted` และขีดจำกัดแบบหน้าต่างการใช้งานตามรอบ เช่น `weekly/monthly limit reached`

    ข้อผิดพลาดด้านรูปแบบ/คำขอไม่ถูกต้อง (เช่น ความล้มเหลวในการตรวจสอบ ID การเรียกเครื่องมือของ Cloud Code Assist) จะถูกถือว่าเหมาะต่อการสลับไปใช้สำรอง และใช้คูลดาวน์เดียวกัน ข้อผิดพลาด stop-reason ที่เข้ากันได้กับ OpenAI เช่น `Unhandled stop reason: error`, `stop reason: error` และ `reason: error` จะถูกจัดประเภทเป็นสัญญาณ timeout/การสลับไปใช้สำรอง

    ข้อความเซิร์ฟเวอร์ทั่วไปก็อาจเข้าไปอยู่ในบัคเก็ต timeout นั้นได้เมื่อแหล่งที่มาตรงกับรูปแบบชั่วคราวที่รู้จัก ตัวอย่างเช่น ข้อความ stream-wrapper แบบเปล่าของ pi-ai `An unknown error occurred` จะถูกถือว่าเหมาะต่อการสลับไปใช้สำรองสำหรับทุกผู้ให้บริการ เพราะ pi-ai ปล่อยข้อความนี้เมื่อสตรีมของผู้ให้บริการจบด้วย `stopReason: "aborted"` หรือ `stopReason: "error"` โดยไม่มีรายละเอียดเฉพาะ payload JSON `api_error` ที่มีข้อความเซิร์ฟเวอร์ชั่วคราว เช่น `internal server error`, `unknown error, 520`, `upstream error` หรือ `backend error` ก็ถูกถือว่าเป็น timeout ที่เหมาะต่อการสลับไปใช้สำรองเช่นกัน

    ข้อความ upstream ทั่วไปเฉพาะ OpenRouter เช่น `Provider returned error` แบบเปล่าจะถูกถือว่าเป็น timeout เฉพาะเมื่อบริบทผู้ให้บริการเป็น OpenRouter จริง ๆ ข้อความสำรองภายในทั่วไป เช่น `LLM request failed with an unknown error.` จะยังคงใช้แนวทางระมัดระวังและไม่กระตุ้นการสลับไปใช้สำรองด้วยตัวมันเอง

  </Accordion>
  <Accordion title="SDK retry-after caps">
    SDK ของผู้ให้บริการบางรายอาจรอเป็นช่วง `Retry-After` ที่ยาวก่อนส่งการควบคุมกลับมายัง OpenClaw สำหรับ SDK ที่ใช้ Stainless เช่น Anthropic และ OpenAI, OpenClaw จะจำกัดการรอ `retry-after-ms` / `retry-after` ภายใน SDK ไว้ที่ 60 วินาทีโดยค่าเริ่มต้น และส่งคืนการตอบสนองที่ลองใหม่ได้ซึ่งยาวกว่านั้นทันที เพื่อให้เส้นทางการสลับไปใช้สำรองนี้ทำงานได้ ปรับแต่งหรือปิดใช้งานขีดจำกัดด้วย `OPENCLAW_SDK_RETRY_MAX_WAIT_SECONDS`; ดู [พฤติกรรมการลองใหม่](/th/concepts/retry)
  </Accordion>
  <Accordion title="Model-scoped cooldowns">
    คูลดาวน์ rate-limit สามารถจำกัดขอบเขตตามโมเดลได้ด้วย:

    - OpenClaw บันทึก `cooldownModel` สำหรับความล้มเหลวจาก rate-limit เมื่อทราบ ID โมเดลที่ล้มเหลว
    - โมเดลพี่น้องบนผู้ให้บริการเดียวกันยังสามารถลองใช้ได้เมื่อคูลดาวน์จำกัดอยู่กับโมเดลอื่น
    - หน้าต่าง billing/ปิดใช้งานยังคงบล็อกทั้งโปรไฟล์ข้ามโมเดล

  </Accordion>
</AccordionGroup>

คูลดาวน์ใช้ exponential backoff:

- 1 นาที
- 5 นาที
- 25 นาที
- 1 ชั่วโมง (เพดาน)

สถานะถูกจัดเก็บใน `auth-state.json` ภายใต้ `usageStats`:

```json
{
  "usageStats": {
    "provider:profile": {
      "lastUsed": 1736160000000,
      "cooldownUntil": 1736160600000,
      "errorCount": 2
    }
  }
}
```

## การปิดใช้งานจาก billing

ความล้มเหลวด้าน billing/เครดิต (เช่น “insufficient credits” / “credit balance too low”) จะถูกถือว่าเหมาะต่อการสลับไปใช้สำรอง แต่โดยปกติไม่ใช่แบบชั่วคราว แทนที่จะใช้คูลดาวน์สั้น OpenClaw จะทำเครื่องหมายโปรไฟล์ว่า **ถูกปิดใช้งาน** (พร้อม backoff ที่ยาวกว่า) และหมุนเวียนไปยังโปรไฟล์/ผู้ให้บริการถัดไป

<Note>
ไม่ใช่ทุกการตอบสนองที่มีลักษณะ billing จะเป็น `402` และไม่ใช่ทุก HTTP `402` จะมาที่นี่ OpenClaw จะคงข้อความ billing ที่ชัดเจนไว้ในเลน billing แม้ผู้ให้บริการจะส่งคืน `401` หรือ `403` แทน แต่ตัวจับคู่เฉพาะผู้ให้บริการจะยังจำกัดอยู่กับผู้ให้บริการที่เป็นเจ้าของ (เช่น OpenRouter `403 Key limit exceeded`)

ขณะเดียวกัน ข้อผิดพลาด `402` ชั่วคราวแบบหน้าต่างการใช้งานและข้อจำกัดการใช้จ่ายขององค์กร/เวิร์กสเปซจะถูกจัดประเภทเป็น `rate_limit` เมื่อข้อความดูเหมือนลองใหม่ได้ (เช่น `weekly usage limit exhausted`, `daily limit reached, resets tomorrow` หรือ `organization spending limit exceeded`) สิ่งเหล่านั้นจะยังอยู่บนเส้นทางคูลดาวน์สั้น/การสลับไปใช้สำรอง แทนเส้นทางปิดใช้งานจาก billing ระยะยาว
</Note>

สถานะถูกจัดเก็บใน `auth-state.json`:

```json
{
  "usageStats": {
    "provider:profile": {
      "disabledUntil": 1736178000000,
      "disabledReason": "billing"
    }
  }
}
```

ค่าเริ่มต้น:

- backoff ของ billing เริ่มที่ **5 ชั่วโมง** เพิ่มเป็นสองเท่าต่อความล้มเหลวด้าน billing แต่ละครั้ง และมีเพดานที่ **24 ชั่วโมง**
- ตัวนับ backoff จะรีเซ็ตหากโปรไฟล์ไม่ได้ล้มเหลวเป็นเวลา **24 ชั่วโมง** (กำหนดค่าได้)
- การลองใหม่เมื่อโอเวอร์โหลดอนุญาตให้ **หมุนเวียนโปรไฟล์ผู้ให้บริการเดียวกันได้ 1 ครั้ง** ก่อนการสำรองโมเดล
- การลองใหม่เมื่อโอเวอร์โหลดใช้ **backoff 0 ms** โดยค่าเริ่มต้น

## การใช้โมเดลสำรอง

หากโปรไฟล์ทั้งหมดสำหรับผู้ให้บริการล้มเหลว OpenClaw จะย้ายไปยังโมเดลถัดไปใน `agents.defaults.model.fallbacks` สิ่งนี้ใช้กับความล้มเหลวของการยืนยันตัวตน, rate limit และ timeout ที่ใช้การหมุนเวียนโปรไฟล์จนหมดแล้ว (ข้อผิดพลาดอื่นจะไม่เลื่อนไปยังการสำรอง) ข้อผิดพลาดจากผู้ให้บริการที่ไม่ได้เปิดเผยรายละเอียดเพียงพอยังคงถูกติดป้ายอย่างแม่นยำในสถานะสำรอง: `empty_response` หมายถึงผู้ให้บริการไม่ส่งคืนข้อความหรือสถานะที่ใช้งานได้, `no_error_details` หมายถึงผู้ให้บริการส่งคืน `Unknown error (no error details in response)` อย่างชัดเจน และ `unclassified` หมายถึง OpenClaw เก็บตัวอย่างดิบไว้ แต่ยังไม่มีตัวจัดประเภทใดตรงกับข้อความนั้น

ข้อผิดพลาดจากการใช้งานเกินขีดจำกัดและ rate-limit จะถูกจัดการเชิงรุกมากกว่า cooldown ด้านการเรียกเก็บเงิน ตามค่าเริ่มต้น OpenClaw อนุญาตให้ลองใหม่ด้วยโปรไฟล์การยืนยันตัวตนของผู้ให้บริการเดิมหนึ่งครั้ง แล้วจึงสลับไปยัง fallback ของโมเดลถัดไปที่ตั้งค่าไว้โดยไม่รอ สัญญาณว่าผู้ให้บริการไม่ว่าง เช่น `ModelNotReadyException` จะอยู่ในกลุ่มใช้งานเกินขีดจำกัดนี้ ปรับแต่งได้ด้วย `auth.cooldowns.overloadedProfileRotations`, `auth.cooldowns.overloadedBackoffMs` และ `auth.cooldowns.rateLimitedProfileRotations`

เมื่อการรันเริ่มจาก primary เริ่มต้นที่ตั้งค่าไว้, primary ของงาน Cron, primary ของเอเจนต์ที่มี fallback ระบุไว้อย่างชัดเจน หรือการ override fallback ที่เลือกอัตโนมัติ OpenClaw สามารถไล่ไปตามลำดับ fallback ที่ตั้งค่าไว้ซึ่งตรงกันได้ primary ของเอเจนต์ที่ไม่มี fallback ระบุไว้อย่างชัดเจน และการเลือกโดยผู้ใช้โดยตรง (เช่น `/model ollama/qwen3.5:27b`, ตัวเลือกโมเดล, `sessions.patch` หรือการ override ผู้ให้บริการ/โมเดลแบบครั้งเดียวของ CLI) จะเข้มงวด: หากผู้ให้บริการ/โมเดลดังกล่าวเข้าถึงไม่ได้หรือล้มเหลวก่อนสร้างคำตอบ OpenClaw จะรายงานความล้มเหลวแทนที่จะตอบจาก fallback ที่ไม่เกี่ยวข้อง

### กฎของลำดับตัวเลือก

OpenClaw สร้างรายการตัวเลือกจาก `provider/model` ที่ร้องขออยู่ในปัจจุบัน รวมกับ fallback ที่ตั้งค่าไว้

<AccordionGroup>
  <Accordion title="กฎ">
    - โมเดลที่ร้องขอจะอยู่ลำดับแรกเสมอ
    - fallback ที่ตั้งค่าไว้อย่างชัดเจนจะถูกตัดรายการซ้ำออก แต่จะไม่ถูกกรองด้วยรายการอนุญาตของโมเดล โดยถือว่าเป็นเจตนาที่ผู้ดูแลระบุไว้อย่างชัดเจน
    - หากการรันปัจจุบันอยู่บน fallback ที่ตั้งค่าไว้แล้วในตระกูลผู้ให้บริการเดียวกัน OpenClaw จะยังใช้ลำดับที่ตั้งค่าไว้ทั้งหมดต่อไป
    - หากการรันปัจจุบันอยู่บนผู้ให้บริการคนละรายกับค่าตั้งค่า และโมเดลปัจจุบันนั้นไม่ได้เป็นส่วนหนึ่งของลำดับ fallback ที่ตั้งค่าไว้อยู่แล้ว OpenClaw จะไม่ต่อท้าย fallback ที่ตั้งค่าไว้ซึ่งไม่เกี่ยวข้องจากผู้ให้บริการรายอื่น
    - เมื่อไม่มีการส่ง override fallback โดยตรงให้ตัวรัน fallback ระบบจะต่อท้าย primary ที่ตั้งค่าไว้ไว้ท้ายสุด เพื่อให้ลำดับสามารถกลับไปอยู่ที่ค่าเริ่มต้นปกติได้หลังจากตัวเลือกก่อนหน้าถูกใช้จนหมด
    - เมื่อผู้เรียกส่ง `fallbacksOverride` ตัวรันจะใช้เฉพาะโมเดลที่ร้องขอรวมกับรายการ override นั้นเท่านั้น รายการว่างจะปิดการใช้ fallback ของโมเดล และป้องกันไม่ให้ primary ที่ตั้งค่าไว้ถูกต่อท้ายเป็นเป้าหมายการลองใหม่แบบซ่อน

  </Accordion>
</AccordionGroup>

### ข้อผิดพลาดใดที่เลื่อนไปยัง fallback

<Tabs>
  <Tab title="ดำเนินต่อเมื่อ">
    - การยืนยันตัวตนล้มเหลว
    - rate limit และการใช้ cooldown จนหมด
    - ข้อผิดพลาดจากการใช้งานเกินขีดจำกัด/ผู้ให้บริการไม่ว่าง
    - ข้อผิดพลาดแบบ failover ที่มีลักษณะเป็น timeout
    - การปิดใช้งานจากการเรียกเก็บเงิน
    - `LiveSessionModelSwitchError` ซึ่งถูกปรับให้เป็นเส้นทาง failover เพื่อไม่ให้โมเดลที่คงค้างเก่าอยู่สร้างลูปการลองใหม่ภายนอก
    - ข้อผิดพลาดอื่นที่ไม่รู้จัก เมื่อยังมีตัวเลือกเหลืออยู่

  </Tab>
  <Tab title="ไม่ดำเนินต่อเมื่อ">
    - การยกเลิกโดยตรงที่ไม่มีลักษณะเป็น timeout/failover
    - ข้อผิดพลาด context ล้นที่ควรอยู่ภายในตรรกะ Compaction/ลองใหม่ (เช่น `request_too_large`, `INVALID_ARGUMENT: input exceeds the maximum number of tokens`, `input token count exceeds the maximum number of input tokens`, `The input is too long for the model` หรือ `ollama error: context length exceeded`)
    - ข้อผิดพลาดสุดท้ายที่ไม่รู้จัก เมื่อไม่มีตัวเลือกเหลืออยู่

  </Tab>
</Tabs>

### พฤติกรรมการข้าม cooldown เทียบกับการ probe

เมื่อโปรไฟล์การยืนยันตัวตนทุกโปรไฟล์ของผู้ให้บริการอยู่ใน cooldown อยู่แล้ว OpenClaw จะไม่ข้ามผู้ให้บริการนั้นไปตลอดโดยอัตโนมัติ แต่จะตัดสินใจเป็นรายตัวเลือก:

<AccordionGroup>
  <Accordion title="การตัดสินใจรายตัวเลือก">
    - การยืนยันตัวตนล้มเหลวแบบถาวรจะข้ามผู้ให้บริการทั้งหมดทันที
    - การปิดใช้งานจากการเรียกเก็บเงินโดยทั่วไปจะถูกข้าม แต่ตัวเลือก primary ยังสามารถถูก probe แบบ throttle ได้ เพื่อให้กู้คืนได้โดยไม่ต้องเริ่มใหม่
    - ตัวเลือก primary อาจถูก probe เมื่อใกล้หมด cooldown โดยมี throttle แยกตามผู้ให้บริการ
    - fallback พี่น้องในผู้ให้บริการเดียวกันสามารถถูกลองได้แม้อยู่ใน cooldown เมื่อความล้มเหลวดูเป็นแบบชั่วคราว (`rate_limit`, `overloaded` หรือไม่รู้จัก) เรื่องนี้สำคัญเป็นพิเศษเมื่อ rate limit ผูกกับโมเดล และโมเดลพี่น้องอาจยังกลับมาใช้งานได้ทันที
    - probe สำหรับ cooldown ชั่วคราวจะถูกจำกัดไว้ที่หนึ่งครั้งต่อผู้ให้บริการต่อการรัน fallback เพื่อไม่ให้ผู้ให้บริการรายเดียวทำให้ fallback ข้ามผู้ให้บริการค้าง

  </Accordion>
</AccordionGroup>

## การ override ของเซสชันและการสลับโมเดลสด

การเปลี่ยนโมเดลของเซสชันเป็นสถานะร่วม ตัวรันที่ใช้งานอยู่ คำสั่ง `/model` การอัปเดต Compaction/เซสชัน และการปรับสถานะเซสชันสดให้สอดคล้องกัน ล้วนอ่านหรือเขียนบางส่วนของรายการเซสชันเดียวกัน

นั่นหมายความว่าการลองใหม่ด้วย fallback ต้องประสานกับการสลับโมเดลสด:

- เฉพาะการเปลี่ยนโมเดลที่ผู้ใช้สั่งโดยตรงเท่านั้นที่จะทำเครื่องหมายการสลับสดที่รอดำเนินการ ซึ่งรวมถึง `/model`, `session_status(model=...)` และ `sessions.patch`
- การเปลี่ยนโมเดลที่ระบบขับเคลื่อน เช่น การหมุน fallback, การ override ของ Heartbeat หรือ Compaction จะไม่ทำเครื่องหมายการสลับสดที่รอดำเนินการด้วยตัวเอง
- การ override โมเดลที่ผู้ใช้สั่งจะถูกถือเป็นการเลือกแบบตรงสำหรับนโยบาย fallback ดังนั้นผู้ให้บริการที่เลือกไว้แต่เข้าถึงไม่ได้จะแสดงเป็นความล้มเหลว แทนที่จะถูกซ่อนด้วย `agents.defaults.model.fallbacks`
- ก่อนการลองใหม่ด้วย fallback จะเริ่ม ตัวรันคำตอบจะบันทึกฟิลด์ override fallback ที่เลือกไว้ลงในรายการเซสชัน
- override fallback อัตโนมัติจะยังคงถูกเลือกในรอบถัดไป เพื่อให้ OpenClaw ไม่ต้อง probe primary ที่ทราบว่าเสียในทุกข้อความ `/new`, `/reset` และ `sessions.reset` จะล้าง override ที่มาจากอัตโนมัติและคืนเซสชันกลับไปยังค่าเริ่มต้นที่ตั้งค่าไว้
- `/status` แสดงโมเดลที่เลือก และเมื่อสถานะ fallback แตกต่างกัน จะแสดงโมเดล fallback ที่ใช้งานอยู่พร้อมเหตุผล
- การปรับสถานะเซสชันสดให้สอดคล้องกันจะให้ความสำคัญกับ override ของเซสชันที่บันทึกไว้มากกว่าฟิลด์โมเดล runtime ที่เก่า
- หากข้อผิดพลาดจากการสลับสดชี้ไปยังตัวเลือกถัดไปในลำดับ fallback ที่ใช้งานอยู่ OpenClaw จะข้ามไปยังโมเดลที่เลือกนั้นโดยตรง แทนที่จะไล่ตัวเลือกที่ไม่เกี่ยวข้องก่อน
- หากการลอง fallback ล้มเหลว ตัวรันจะย้อนกลับเฉพาะฟิลด์ override ที่ตนเขียนไว้ และเฉพาะเมื่อฟิลด์เหล่านั้นยังตรงกับตัวเลือกที่ล้มเหลวนั้น

สิ่งนี้ป้องกันการแข่งขันแบบคลาสสิก:

<Steps>
  <Step title="Primary ล้มเหลว">
    โมเดล primary ที่เลือกไว้ล้มเหลว
  </Step>
  <Step title="เลือก fallback ในหน่วยความจำ">
    ตัวเลือก fallback ถูกเลือกในหน่วยความจำ
  </Step>
  <Step title="ที่เก็บเซสชันยังบอกว่าเป็น primary เก่า">
    ที่เก็บเซสชันยังสะท้อน primary เก่า
  </Step>
  <Step title="การปรับสถานะสดให้สอดคล้องกันอ่านสถานะเก่า">
    การปรับสถานะเซสชันสดให้สอดคล้องกันอ่านสถานะเซสชันที่เก่า
  </Step>
  <Step title="การลองใหม่ถูกดึงกลับ">
    การลองใหม่ถูกดึงกลับไปยังโมเดลเก่าก่อนที่การลอง fallback จะเริ่ม
  </Step>
</Steps>

override fallback ที่บันทึกไว้จะปิดช่องว่างนี้ และการย้อนกลับแบบแคบจะคงการเปลี่ยนแปลงเซสชันแบบ manual หรือ runtime ที่ใหม่กว่าไว้ครบถ้วน

## การสังเกตการณ์และสรุปความล้มเหลว

`runWithModelFallback(...)` บันทึกรายละเอียดรายครั้งที่ลอง ซึ่งป้อนเข้าสู่บันทึกและข้อความ cooldown ที่แสดงต่อผู้ใช้:

- ผู้ให้บริการ/โมเดลที่ลอง
- เหตุผล (`rate_limit`, `overloaded`, `billing`, `auth`, `model_not_found` และเหตุผล failover ที่คล้ายกัน)
- สถานะ/โค้ดที่มีหรือไม่มีก็ได้
- สรุปข้อผิดพลาดที่มนุษย์อ่านได้

บันทึก `model_fallback_decision` แบบมีโครงสร้างยังรวมฟิลด์ `fallbackStep*` แบบแบน เมื่อมีตัวเลือกที่ล้มเหลว ถูกข้าม หรือ fallback ถัดไปสำเร็จ ฟิลด์เหล่านี้ทำให้การเปลี่ยนผ่านที่ลองไว้ชัดเจน (`fallbackStepFromModel`, `fallbackStepToModel`, `fallbackStepFromFailureReason`, `fallbackStepFromFailureDetail`, `fallbackStepFinalOutcome`) เพื่อให้ตัวส่งออกบันทึกและการวินิจฉัยสามารถสร้างภาพความล้มเหลวของ primary ได้ แม้ fallback สุดท้ายจะล้มเหลวด้วยก็ตาม

เมื่อทุกตัวเลือกล้มเหลว OpenClaw จะโยน `FallbackSummaryError` ตัวรันคำตอบภายนอกสามารถใช้สิ่งนั้นเพื่อสร้างข้อความที่เฉพาะเจาะจงขึ้น เช่น "ทุกโมเดลถูกจำกัดอัตราชั่วคราว" และรวมเวลาหมด cooldown ที่เร็วที่สุดเมื่อทราบ

สรุป cooldown นั้นรับรู้ตามโมเดล:

- rate limit ที่ผูกกับโมเดลที่ไม่เกี่ยวข้องจะถูกละเว้นสำหรับลำดับผู้ให้บริการ/โมเดลที่ลอง
- หากบล็อกที่เหลือเป็น rate limit ที่ผูกกับโมเดลและตรงกัน OpenClaw จะรายงานเวลาหมดอายุล่าสุดที่ตรงกันซึ่งยังคงบล็อกโมเดลนั้นอยู่

## ค่าตั้งค่าที่เกี่ยวข้อง

ดู [การกำหนดค่า Gateway](/th/gateway/configuration) สำหรับ:

- `auth.profiles` / `auth.order`
- `auth.cooldowns.billingBackoffHours` / `auth.cooldowns.billingBackoffHoursByProvider`
- `auth.cooldowns.billingMaxHours` / `auth.cooldowns.failureWindowHours`
- `auth.cooldowns.overloadedProfileRotations` / `auth.cooldowns.overloadedBackoffMs`
- `auth.cooldowns.rateLimitedProfileRotations`
- `agents.defaults.model.primary` / `agents.defaults.model.fallbacks`
- การกำหนดเส้นทาง `agents.defaults.imageModel`

ดู [โมเดล](/th/concepts/models) สำหรับภาพรวมที่กว้างขึ้นของการเลือกโมเดลและ fallback
