Gateway
โมเดลภายในเครื่อง
โมเดลแบบโลคัลทำได้จริง แต่ก็ยกระดับข้อกำหนดด้านฮาร์ดแวร์ ขนาดคอนเท็กซ์ และการป้องกัน prompt-injection ให้สูงขึ้นด้วย การ์ดขนาดเล็กหรือที่ quantize อย่างหนักจะตัดคอนเท็กซ์และทำให้ความปลอดภัยรั่วไหล หน้านี้เป็นคู่มือเชิงแนะนำสำหรับสแตกโลคัลระดับสูงกว่าและเซิร์ฟเวอร์โลคัลแบบกำหนดเองที่เข้ากันได้กับ OpenAI สำหรับการเริ่มต้นใช้งานที่มีแรงเสียดทานต่ำที่สุด ให้เริ่มจาก LM Studio หรือ Ollama และ openclaw onboard
ระดับฮาร์ดแวร์ขั้นต่ำ
ตั้งเป้าให้สูง: Mac Studio รุ่นเต็มสเปกอย่างน้อย 2 เครื่อง หรือชุด GPU ที่เทียบเท่า (~$30k+) เพื่อให้ลูป agent ทำงานได้อย่างสบาย GPU 24 GB เพียงตัวเดียวใช้ได้เฉพาะกับพรอมป์ที่เบากว่าและมี latency สูงกว่าเท่านั้น ให้ใช้ ตัวแปรรุ่นใหญ่ที่สุด / ขนาดเต็มที่สุดที่คุณโฮสต์ได้ เสมอ checkpoint ขนาดเล็กหรือที่ quantize หนักจะเพิ่มความเสี่ยงต่อ prompt-injection (ดู ความปลอดภัย)
เลือกแบ็กเอนด์
| แบ็กเอนด์ | ใช้เมื่อ |
|---|---|
| LM Studio | ตั้งค่าโลคัลครั้งแรก, ตัวโหลด GUI, Responses API แบบเนทีฟ |
| Ollama | เวิร์กโฟลว์ CLI, ไลบรารีโมเดล, บริการ systemd แบบไม่ต้องดูแล |
| MLX / vLLM / SGLang | การให้บริการแบบ self-hosted ที่ throughput สูง พร้อมเอนด์พอยต์ HTTP ที่เข้ากันได้กับ OpenAI |
| LiteLLM / OAI-proxy / พร็อกซีแบบกำหนดเองที่เข้ากันได้กับ OpenAI | คุณวางอีก model API ไว้ข้างหน้าและต้องการให้ OpenClaw ปฏิบัติกับมันเหมือน OpenAI |
ใช้ Responses API (api: "openai-responses") เมื่อแบ็กเอนด์รองรับ (LM Studio รองรับ) มิฉะนั้นให้ใช้ Chat Completions (api: "openai-completions")
แนะนำ: LM Studio + โมเดลโลคัลขนาดใหญ่ (Responses API)
สแตกโลคัลที่ดีที่สุดในปัจจุบัน โหลดโมเดลขนาดใหญ่ใน LM Studio (เช่น build ขนาดเต็มของ Qwen, DeepSeek หรือ Llama) เปิดใช้เซิร์ฟเวอร์โลคัล (ค่าเริ่มต้น http://127.0.0.1:1234) และใช้ Responses API เพื่อแยก reasoning ออกจากข้อความสุดท้าย
{
agents: {
defaults: {
model: { primary: "lmstudio/my-local-model" },
models: {
"anthropic/claude-opus-4-6": { alias: "Opus" },
"lmstudio/my-local-model": { alias: "Local" },
},
},
},
models: {
mode: "merge",
providers: {
lmstudio: {
baseUrl: "http://127.0.0.1:1234/v1",
apiKey: "lmstudio",
api: "openai-responses",
models: [
{
id: "my-local-model",
name: "Local Model",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 196608,
maxTokens: 8192,
},
],
},
},
},
}
เช็กลิสต์การตั้งค่า
- ติดตั้ง LM Studio: https://lmstudio.ai
- ใน LM Studio ให้ดาวน์โหลด build โมเดลที่ใหญ่ที่สุดที่มี (หลีกเลี่ยงตัวแปร "small"/ที่ quantize หนัก) เริ่มเซิร์ฟเวอร์ และยืนยันว่า
http://127.0.0.1:1234/v1/modelsแสดงรายการโมเดลนั้น - แทนที่
my-local-modelด้วย ID โมเดลจริงที่แสดงใน LM Studio - โหลดโมเดลค้างไว้ การโหลดแบบ cold-load จะเพิ่ม latency ตอนเริ่มต้น
- ปรับ
contextWindow/maxTokensหาก build ของ LM Studio ที่คุณใช้แตกต่างออกไป - สำหรับ WhatsApp ให้ใช้ Responses API ต่อไป เพื่อให้ส่งเฉพาะข้อความสุดท้ายเท่านั้น
คงการตั้งค่าโมเดลที่โฮสต์ไว้แม้ขณะรันโลคัล ใช้ models.mode: "merge" เพื่อให้ fallback ยังพร้อมใช้งาน
คอนฟิกแบบไฮบริด: hosted primary, local fallback
{
agents: {
defaults: {
model: {
primary: "anthropic/claude-sonnet-4-6",
fallbacks: ["lmstudio/my-local-model", "anthropic/claude-opus-4-6"],
},
models: {
"anthropic/claude-sonnet-4-6": { alias: "Sonnet" },
"lmstudio/my-local-model": { alias: "Local" },
"anthropic/claude-opus-4-6": { alias: "Opus" },
},
},
},
models: {
mode: "merge",
providers: {
lmstudio: {
baseUrl: "http://127.0.0.1:1234/v1",
apiKey: "lmstudio",
api: "openai-responses",
models: [
{
id: "my-local-model",
name: "Local Model",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 196608,
maxTokens: 8192,
},
],
},
},
},
}
ใช้โลคัลเป็นหลักพร้อม safety net แบบ hosted
สลับลำดับ primary และ fallback คงบล็อก providers เดิมและ models.mode: "merge" เพื่อให้คุณ fallback ไปยัง Sonnet หรือ Opus ได้เมื่อเครื่องโลคัลไม่พร้อมใช้งาน
การโฮสต์ตามภูมิภาค / การกำหนดเส้นทางข้อมูล
- ตัวแปร Hosted MiniMax/Kimi/GLM มีอยู่บน OpenRouter ด้วย พร้อมเอนด์พอยต์ที่ปักภูมิภาคไว้ (เช่น โฮสต์ในสหรัฐฯ) เลือกตัวแปรตามภูมิภาคที่นั่นเพื่อเก็บทราฟฟิกไว้ในเขตอำนาจที่คุณเลือก ขณะยังใช้
models.mode: "merge"สำหรับ fallback ไปยัง Anthropic/OpenAI - แบบ local-only ยังคงเป็นเส้นทางความเป็นส่วนตัวที่แข็งแกร่งที่สุด การกำหนดเส้นทางแบบ hosted ตามภูมิภาคเป็นทางสายกลางเมื่อคุณต้องการฟีเจอร์ของผู้ให้บริการแต่ยังต้องการควบคุมการไหลของข้อมูล
พร็อกซีโลคัลอื่นที่เข้ากันได้กับ OpenAI
MLX (mlx_lm.server), vLLM, SGLang, LiteLLM, OAI-proxy หรือ Gateway แบบกำหนดเองจะทำงานได้หากเปิดเผยเอนด์พอยต์ /v1/chat/completions แบบ OpenAI-style ใช้อะแดปเตอร์ Chat Completions เว้นแต่แบ็กเอนด์จะมีเอกสารรองรับ /v1/responses อย่างชัดเจน แทนที่บล็อก provider ด้านบนด้วยเอนด์พอยต์และ ID โมเดลของคุณ:
{
agents: {
defaults: {
model: { primary: "local/my-local-model" },
},
},
models: {
mode: "merge",
providers: {
local: {
baseUrl: "http://127.0.0.1:8000/v1",
apiKey: "sk-local",
api: "openai-completions",
timeoutSeconds: 300,
models: [
{
id: "my-local-model",
name: "Local Model",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 120000,
maxTokens: 8192,
},
],
},
},
},
}
หากละ api ไว้ใน provider แบบกำหนดเองที่มี baseUrl OpenClaw จะใช้ค่าเริ่มต้นเป็น openai-completions เอนด์พอยต์ loopback เช่น 127.0.0.1 จะได้รับความเชื่อถือโดยอัตโนมัติ ส่วนเอนด์พอยต์ LAN, tailnet และ DNS ส่วนตัวยังต้องใช้ request.allowPrivateNetwork: true
ค่า models.providers.<id>.models[].id เป็นแบบ local ต่อ provider อย่าใส่ prefix ของ provider ไว้ตรงนั้น ตัวอย่างเช่น เซิร์ฟเวอร์ MLX ที่เริ่มด้วย mlx_lm.server --model mlx-community/Qwen3-30B-A3B-6bit ควรใช้ ID แค็ตตาล็อกและ model ref นี้:
models.providers.mlx.models[].id: "mlx-community/Qwen3-30B-A3B-6bit"agents.defaults.model.primary: "mlx/mlx-community/Qwen3-30B-A3B-6bit"
ตั้งค่า input: ["text", "image"] บนโมเดล vision แบบโลคัลหรือผ่านพร็อกซี เพื่อให้แนบรูปภาพเข้าไปในเทิร์นของ agent การ onboarding provider แบบกำหนดเองเชิงโต้ตอบจะอนุมาน ID โมเดล vision ที่พบบ่อยและถามเฉพาะชื่อที่ไม่รู้จัก การ onboarding แบบไม่โต้ตอบใช้การอนุมานเดียวกัน ใช้ --custom-image-input สำหรับ ID vision ที่ไม่รู้จัก หรือ --custom-text-input เมื่อโมเดลที่ดูเหมือนรู้จักเป็น text-only อยู่หลังเอนด์พอยต์ของคุณ
คง models.mode: "merge" ไว้เพื่อให้โมเดล hosted ยังพร้อมเป็น fallback ใช้ models.providers.<id>.timeoutSeconds สำหรับเซิร์ฟเวอร์โมเดลโลคัลหรือรีโมตที่ช้า ก่อนเพิ่ม agents.defaults.timeoutSeconds timeout ของ provider ใช้เฉพาะกับคำขอ HTTP ของโมเดล รวมถึงการเชื่อมต่อ headers การสตรีม body และการ abort ของ guarded-fetch ทั้งหมด
หมายเหตุพฤติกรรมสำหรับแบ็กเอนด์ /v1 แบบโลคัล/ผ่านพร็อกซี:
- OpenClaw ถือว่าสิ่งเหล่านี้เป็น route ที่เข้ากันได้กับ OpenAI แบบ proxy-style ไม่ใช่เอนด์พอยต์ OpenAI แบบเนทีฟ
- การจัดรูปคำขอเฉพาะ OpenAI แบบเนทีฟจะไม่ใช้ที่นี่: ไม่มี
service_tier, ไม่มี Responsesstore, ไม่มีการจัดรูป payload สำหรับ OpenAI reasoning-compat และไม่มี hint ของ prompt-cache - header แสดงที่มาของ OpenClaw แบบซ่อน (
originator,version,User-Agent) จะไม่ถูกแทรกบน URL พร็อกซีแบบกำหนดเองเหล่านี้
หมายเหตุความเข้ากันได้สำหรับแบ็กเอนด์ที่เข้ากันได้กับ OpenAI และเข้มงวดกว่า:
-
บางเซิร์ฟเวอร์ยอมรับเฉพาะ
messages[].contentแบบสตริงบน Chat Completions ไม่ใช่ array ของ content-part แบบมีโครงสร้าง ตั้งค่าmodels.providers.<provider>.models[].compat.requiresStringContent: trueสำหรับเอนด์พอยต์เหล่านั้น -
โมเดลโลคัลบางตัวปล่อยคำขอ tool แบบวงเล็บเดี่ยวเป็นข้อความ เช่น
[tool_name]ตามด้วย JSON และ[END_TOOL_REQUEST]OpenClaw จะยกระดับสิ่งเหล่านั้นเป็น tool call จริงก็ต่อเมื่อชื่อตรงกับ tool ที่ลงทะเบียนไว้สำหรับเทิร์นนั้นอย่างพอดี มิฉะนั้นบล็อกนั้นจะถูกถือเป็นข้อความที่ไม่รองรับและถูกซ่อนจากคำตอบที่ผู้ใช้เห็น -
หากโมเดลปล่อย JSON, XML หรือข้อความสไตล์ ReAct ที่ดูเหมือน tool call แต่ provider ไม่ได้ปล่อย invocation แบบมีโครงสร้าง OpenClaw จะปล่อยไว้เป็นข้อความและบันทึกคำเตือนพร้อม run id, provider/model, pattern ที่ตรวจพบ และชื่อ tool เมื่อมี ให้ถือว่านี่เป็นความไม่เข้ากันของ tool-call ของ provider/model ไม่ใช่การรัน tool ที่เสร็จสมบูรณ์
-
หาก tool ปรากฏเป็นข้อความของ assistant แทนที่จะถูกรัน เช่น raw JSON, XML, syntax แบบ ReAct หรือ array
tool_callsว่างใน response ของ provider ให้ตรวจสอบก่อนว่าเซิร์ฟเวอร์กำลังใช้ chat template/parser ที่รองรับ tool-call สำหรับแบ็กเอนด์ Chat Completions ที่เข้ากันได้กับ OpenAI ซึ่ง parser ทำงานเฉพาะเมื่อบังคับใช้ tool ให้ตั้งค่า override คำขอต่อโมเดลแทนการพึ่งพาการ parse ข้อความ:{ agents: { defaults: { models: { "local/my-local-model": { params: { extra_body: { tool_choice: "required", }, }, }, }, }, }, }ใช้สิ่งนี้เฉพาะกับโมเดล/เซสชันที่ทุกเทิร์นปกติควรเรียก tool เท่านั้น มันจะแทนที่ค่า proxy เริ่มต้นของ OpenClaw คือ
tool_choice: "auto"แทนที่local/my-local-modelด้วย provider/model ref ที่ตรงตามที่แสดงโดยopenclaw models listopenclaw config set agents.defaults.models '{"local/my-local-model":{"params":{"extra_body":{"tool_choice":"required"}}}}' --strict-json --merge -
หากโมเดลแบบกำหนดเองที่เข้ากันได้กับ OpenAI ยอมรับ OpenAI reasoning efforts นอกเหนือจากโปรไฟล์ในตัว ให้ประกาศค่าเหล่านั้นบนบล็อก compat ของโมเดล การเพิ่ม
"xhigh"ที่นี่จะทำให้/think xhigh, ตัวเลือกเซสชัน, การตรวจสอบ Gateway และการตรวจสอบllm-taskเปิดเผยระดับนี้สำหรับ provider/model ref ที่กำหนดค่าไว้:{ models: { providers: { local: { baseUrl: "http://127.0.0.1:8000/v1", apiKey: "sk-local", api: "openai-responses", models: [ { id: "gpt-5.4", name: "GPT 5.4 via local proxy", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 196608, maxTokens: 8192, compat: { supportedReasoningEfforts: ["low", "medium", "high", "xhigh"], reasoningEffortMap: { xhigh: "xhigh" }, }, }, ], }, }, }, }
แบ็กเอนด์ที่เล็กกว่าหรือเข้มงวดกว่า
หากโมเดลโหลดได้เรียบร้อย แต่ agent turn เต็มรูปแบบทำงานผิดปกติ ให้ไล่จากบนลงล่าง ยืนยัน transport ก่อน แล้วค่อยจำกัดพื้นผิวให้แคบลง
-
ยืนยันว่าโมเดลภายในเครื่องตอบสนองได้เอง ไม่มีเครื่องมือ ไม่มีบริบทเอเจนต์:
openclaw infer model run --local --model <provider/model> --prompt "Reply with exactly: pong" --json -
ยืนยันการกำหนดเส้นทางของ Gateway ส่งเฉพาะพรอมป์ที่ระบุเท่านั้น — ข้ามทรานสคริปต์, การบูตสแตรป AGENTS, การประกอบ context-engine, เครื่องมือ และเซิร์ฟเวอร์ MCP ที่รวมมาให้ แต่ยังคงทดสอบการกำหนดเส้นทางของ Gateway, การยืนยันตัวตน และการเลือกผู้ให้บริการ:
openclaw infer model run --gateway --model <provider/model> --prompt "Reply with exactly: pong" --json -
ลองใช้โหมด lean หากโพรบทั้งสองผ่าน แต่รอบการทำงานจริงของเอเจนต์ล้มเหลวด้วยการเรียกเครื่องมือที่มีรูปแบบไม่ถูกต้องหรือพรอมป์ที่ใหญ่เกินไป ให้เปิดใช้
agents.defaults.experimental.localModelLean: trueโหมดนี้จะตัดเครื่องมือเริ่มต้นที่หนักที่สุดสามรายการ (browser,cron,message) ออก เพื่อให้รูปแบบพรอมป์เล็กลงและเปราะบางน้อยลง ดู ฟีเจอร์ทดลอง → โหมด lean สำหรับโมเดลภายในเครื่อง สำหรับคำอธิบายทั้งหมด กรณีที่ควรใช้ และวิธียืนยันว่าเปิดใช้งานอยู่ -
ปิดใช้งานเครื่องมือทั้งหมดเป็นทางเลือกสุดท้าย หากโหมด lean ยังไม่พอ ให้ตั้งค่า
models.providers.<provider>.models[].compat.supportsTools: falseสำหรับรายการโมเดลนั้น จากนั้นเอเจนต์จะทำงานโดยไม่มีการเรียกเครื่องมือบนโมเดลนั้น -
หลังจากนั้น คอขวดอยู่ที่ต้นทาง หากแบ็กเอนด์ยังคงล้มเหลวเฉพาะกับการรัน OpenClaw ขนาดใหญ่หลังจากใช้โหมด lean และ
supportsTools: falseแล้ว ปัญหาที่เหลือมักเป็นความจุของโมเดลหรือเซิร์ฟเวอร์ต้นทาง — หน้าต่างบริบท, หน่วยความจำ GPU, การขับไล่ kv-cache หรือบั๊กของแบ็กเอนด์ ณ จุดนั้นปัญหาไม่ได้อยู่ที่ชั้นการรับส่งข้อมูลของ OpenClaw
การแก้ไขปัญหา
- Gateway เข้าถึงพร็อกซีได้หรือไม่?
curl http://127.0.0.1:1234/v1/models. - โมเดล LM Studio ถูกถอนโหลดอยู่หรือไม่? โหลดใหม่; การเริ่มแบบ cold start เป็นสาเหตุของอาการ "ค้าง" ที่พบบ่อย
- เซิร์ฟเวอร์ภายในเครื่องรายงาน
terminated,ECONNRESETหรือปิดสตรีมกลางรอบหรือไม่? OpenClaw จะบันทึกmodel.call.error.failureKindที่มีคาร์ดินาลิตีต่ำ พร้อมกับสแนปช็อต RSS/heap ของกระบวนการ OpenClaw ใน diagnostics สำหรับภาวะหน่วยความจำตึงตัวของ LM Studio/Ollama ให้เทียบเวลานั้นกับล็อกของเซิร์ฟเวอร์ หรือล็อก crash / jetsam ของ macOS เพื่อยืนยันว่าเซิร์ฟเวอร์โมเดลถูกฆ่าหรือไม่ - OpenClaw คำนวณค่าเกณฑ์ preflight ของหน้าต่างบริบทจากหน้าต่างโมเดลที่ตรวจพบ หรือจากหน้าต่างโมเดลแบบไม่จำกัดเมื่อ
agents.defaults.contextTokensลดหน้าต่างที่มีผลจริงลง ระบบจะเตือนเมื่อต่ำกว่า 20% โดยมีพื้นขั้นต่ำ 8k การบล็อกแบบเด็ดขาดใช้เกณฑ์ 10% โดยมีพื้นขั้นต่ำ 4k และจำกัดไม่เกินหน้าต่างบริบทที่มีผลจริง เพื่อให้ metadata ของโมเดลที่ใหญ่เกินไปไม่ปฏิเสธค่าจำกัดของผู้ใช้ที่ยังถูกต้องอยู่ หากคุณเจอ preflight นี้ ให้เพิ่มขีดจำกัดบริบทของเซิร์ฟเวอร์/โมเดล หรือเลือกโมเดลที่ใหญ่กว่า - เกิดข้อผิดพลาดด้านบริบทหรือไม่? ลด
contextWindowหรือเพิ่มขีดจำกัดของเซิร์ฟเวอร์ของคุณ - เซิร์ฟเวอร์ที่เข้ากันได้กับ OpenAI ส่งคืน
messages[].content ... expected a stringหรือไม่? เพิ่มcompat.requiresStringContent: trueในรายการโมเดลนั้น - การเรียก
/v1/chat/completionsขนาดเล็กโดยตรงทำงานได้ แต่openclaw infer model run --localล้มเหลวบน Gemma หรือโมเดลภายในเครื่องอื่นหรือไม่? ตรวจสอบ URL ของผู้ให้บริการ, อ้างอิงโมเดล, เครื่องหมาย auth และล็อกเซิร์ฟเวอร์ก่อน;model runภายในเครื่องไม่รวมเครื่องมือของเอเจนต์ หากmodel runภายในเครื่องสำเร็จ แต่รอบการทำงานของเอเจนต์ที่ใหญ่กว่าล้มเหลว ให้ลดพื้นผิวเครื่องมือของเอเจนต์ด้วยlocalModelLeanหรือcompat.supportsTools: false - การเรียกเครื่องมือปรากฏเป็นข้อความ JSON/XML/ReAct ดิบ หรือผู้ให้บริการส่งคืนอาร์เรย์
tool_callsว่างหรือไม่? อย่าเพิ่มพร็อกซีที่แปลงข้อความ assistant เป็นการดำเนินการเครื่องมือแบบไม่พิจารณา ให้แก้ chat template/parser ของเซิร์ฟเวอร์ก่อน หาก โมเดลทำงานได้เฉพาะเมื่อบังคับใช้เครื่องมือ ให้เพิ่มการ override รายโมเดลparams.extra_body.tool_choice: "required"ข้างต้น และใช้รายการโมเดลนั้น เฉพาะกับเซสชันที่คาดว่าจะมีการเรียกเครื่องมือทุกครั้ง - ความปลอดภัย: โมเดลภายในเครื่องจะข้ามตัวกรองฝั่งผู้ให้บริการ; จำกัดขอบเขตเอเจนต์ให้แคบและเปิด Compaction ไว้เพื่อลดรัศมีผลกระทบจาก prompt injection