Gateway
การเติมเต็มการสนทนาของ OpenAI
Gateway สามารถให้บริการพื้นผิว Chat Completions ขนาดเล็กที่เข้ากันได้กับ OpenAI โดย ปิดใช้งานเป็นค่าเริ่มต้น
เมื่อเปิดใช้งานแล้ว ระบบจะให้บริการรายการทั้งหมดต่อไปนี้บนพอร์ตเดียวกับ Gateway (มัลติเพล็กซ์ WS + HTTP):
| เมธอด | พาธ |
|---|---|
| POST | /v1/chat/completions |
| GET | /v1/models |
| GET | /v1/models/{id} |
| POST | /v1/embeddings |
| POST | /v1/responses |
คำขอจะทำงานในรูปแบบการรันเอเจนต์ Gateway ตามปกติ (ใช้เส้นทางโค้ดเดียวกับ openclaw agent) ดังนั้นการกำหนดเส้นทาง สิทธิ์ และการกำหนดค่าจึงตรงกับ Gateway ของคุณ
การเปิดใช้งานปลายทาง
{ gateway: { http: { endpoints: { chatCompletions: { enabled: true }, }, }, },}ตั้งค่า enabled: false (หรือละไว้) เพื่อปิดใช้งาน
ขอบเขตความปลอดภัย (สำคัญ)
ให้ถือว่าปลายทางนี้เป็น สิทธิ์การเข้าถึงเต็มรูปแบบของผู้ดำเนินการ ต่ออินสแตนซ์ Gateway:
- โทเค็น/รหัสผ่าน Gateway ที่ถูกต้องสำหรับปลายทางนี้เทียบเท่ากับข้อมูลรับรองของเจ้าของ/ผู้ดำเนินการ ไม่ใช่ขอบเขตแบบจำกัดเฉพาะผู้ใช้
- คำขอจะผ่านเส้นทางเอเจนต์ของระนาบควบคุมเดียวกับการดำเนินการของผู้ดำเนินการที่เชื่อถือได้ ดังนั้นหากนโยบายของเอเจนต์เป้าหมายอนุญาตเครื่องมือที่มีความละเอียดอ่อน ปลายทางนี้ก็สามารถใช้เครื่องมือเหล่านั้นได้
- ให้เปิดใช้งานเฉพาะบน local loopback/tailnet/ทางเข้าระบบส่วนตัวเท่านั้น อย่าเปิดเผยต่ออินเทอร์เน็ตสาธารณะ
เมทริกซ์การยืนยันตัวตน:
| เส้นทางการยืนยันตัวตน | ลักษณะการทำงาน |
|---|---|
gateway.auth.mode="token" หรือ "password" + Authorization: Bearer ... |
พิสูจน์การครอบครองข้อมูลลับร่วมของ Gateway โดยไม่สนใจส่วนหัว x-openclaw-scopes ใด ๆ และคืนค่าชุดขอบเขตเริ่มต้นทั้งหมดของผู้ดำเนินการ ได้แก่ operator.admin, operator.approvals, operator.pairing, operator.read, operator.talk.secrets, operator.write และถือว่าเทิร์นแชตเป็นเทิร์นจากผู้ส่งที่เป็นเจ้าของ |
HTTP ที่เชื่อถือได้และมีข้อมูลระบุตัวตน (การยืนยันตัวตนผ่านพร็อกซีที่เชื่อถือได้ หรือ gateway.auth.mode="none" บนทางเข้าระบบส่วนตัว) |
ใช้ x-openclaw-scopes เมื่อมีอยู่ และย้อนกลับไปใช้ชุดขอบเขตเริ่มต้นของผู้ดำเนินการเมื่อไม่มี โดยจะสูญเสียความหมายของการเป็นเจ้าของก็ต่อเมื่อผู้เรียกจำกัดขอบเขตอย่างชัดเจนและละ operator.admin ไว้ ต้องมี operator.admin สำหรับการควบคุมระดับเจ้าของ เช่น x-openclaw-model |
ดู ขอบเขตของผู้ดำเนินการ, ความปลอดภัย และ การเข้าถึงระยะไกล
การยืนยันตัวตน
ใช้การกำหนดค่าการยืนยันตัวตนของ Gateway (ดูรายละเอียดของโหมดดังกล่าวที่ การยืนยันตัวตนผ่านพร็อกซีที่เชื่อถือได้):
| โหมด | วิธีการยืนยันตัวตน |
|---|---|
gateway.auth.mode="token" |
Authorization: Bearer <token> ตั้งค่าผ่าน gateway.auth.token หรือ OPENCLAW_GATEWAY_TOKEN |
gateway.auth.mode="password" |
Authorization: Bearer <password> ตั้งค่าผ่าน gateway.auth.password หรือ OPENCLAW_GATEWAY_PASSWORD |
gateway.auth.mode="trusted-proxy" |
กำหนดเส้นทางผ่านพร็อกซีที่รับรู้ข้อมูลระบุตัวตนซึ่งกำหนดค่าไว้ โดยพร็อกซีจะแทรกส่วนหัวข้อมูลระบุตัวตนที่จำเป็น พร็อกซี local loopback บนโฮสต์เดียวกันต้องตั้งค่า gateway.auth.trustedProxy.allowLoopback = true อย่างชัดเจน |
gateway.auth.mode="none" |
ไม่ต้องใช้ส่วนหัวการยืนยันตัวตน (เฉพาะทางเข้าระบบส่วนตัว) |
หมายเหตุ:
- ผู้เรียกบนโฮสต์เดียวกันที่ข้ามพร็อกซีบน Gateway แบบ
trusted-proxyสามารถย้อนกลับไปใช้gateway.auth.password/OPENCLAW_GATEWAY_PASSWORDโดยตรงได้ หากมีหลักฐานจากส่วนหัวForwarded,X-Forwarded-*หรือX-Real-IPคำขอจะยังคงอยู่บนเส้นทางพร็อกซีที่เชื่อถือได้แทน - หากกำหนดค่า
gateway.auth.rateLimitและมีความพยายามยืนยันตัวตนล้มเหลวมากเกินไป ปลายทางจะส่งคืน429พร้อมส่วนหัวRetry-After
กรณีที่ควรใช้ปลายทางนี้
- เลือกใช้วิธีนี้แทนการเพิ่มช่องทางในตัวใหม่ เมื่อการผสานรวมของคุณเป็นเพียงพื้นผิวผู้ดำเนินการ/ไคลเอนต์อีกแบบหนึ่งสำหรับ Gateway เดียวกัน
- สำหรับไคลเอนต์มือถือแบบเนทีฟที่เชื่อมต่อโดยตรงกับ Gateway ระยะไกล ให้เลือกใช้ WebChat หรือ โปรโตคอล Gateway พร้อมโฟลว์เริ่มต้นอุปกรณ์ที่จับคู่/โทเค็นอุปกรณ์ เพื่อให้อุปกรณ์ไม่จำเป็นต้องใช้โทเค็น/รหัสผ่าน HTTP ร่วม
- ให้สร้าง Plugin ช่องทางแทน เมื่อต้องผสานรวมเครือข่ายรับส่งข้อความภายนอกที่มีผู้ใช้ ห้อง การส่ง Webhook หรือการขนส่งขาออกเป็นของตนเอง ดู การสร้าง Plugin
สัญญาโมเดลที่ให้เอเจนต์เป็นหลัก
OpenClaw ถือว่าฟิลด์ model ของ OpenAI เป็น เป้าหมายเอเจนต์ ไม่ใช่รหัสโมเดลดิบของผู้ให้บริการ
ค่า model |
กำหนดเส้นทางไปยัง |
|---|---|
openclaw |
เอเจนต์เริ่มต้นที่กำหนดค่าไว้ |
openclaw/default |
เอเจนต์เริ่มต้นที่กำหนดค่าไว้ (นามแฝงที่เสถียร สามารถฮาร์ดโค้ดได้อย่างปลอดภัย แม้ว่ารหัสเอเจนต์เริ่มต้นจริงจะเปลี่ยนไประหว่างสภาพแวดล้อม) |
openclaw/<agentId> หรือ openclaw:<agentId> |
เอเจนต์ที่ระบุ |
agent:<agentId> |
เอเจนต์ที่ระบุ (นามแฝงเพื่อความเข้ากันได้) |
ส่วนหัวคำขอที่เลือกใช้ได้:
| ส่วนหัว | ผล |
|---|---|
x-openclaw-model: <provider/model-or-bare-id> |
แทนที่โมเดลแบ็กเอนด์สำหรับเอเจนต์ที่เลือก ผู้เรียกแบบ bearer ที่ใช้ข้อมูลลับร่วมสามารถใช้รายการนี้ได้โดยตรง ส่วนผู้เรียกที่มีข้อมูลระบุตัวตน (trusted-proxy หรือทางเข้าระบบส่วนตัวที่ไม่ต้องยืนยันตัวตนและมี x-openclaw-scopes) ต้องมี operator.admin มิฉะนั้นจะได้รับ 403 missing scope: operator.admin |
x-openclaw-agent-id: <agentId> |
การแทนที่เพื่อความเข้ากันได้สำหรับการเลือกเอเจนต์ |
x-openclaw-session-key: <sessionKey> |
การกำหนดเส้นทางเซสชันอย่างชัดเจน จะถูกปฏิเสธด้วย 400 invalid_request_error หากใช้เนมสเปซภายในที่สงวนไว้ (subagent:, cron:, acp:) |
x-openclaw-message-channel: <channel> |
ตั้งค่าบริบทช่องทางเข้าระบบสังเคราะห์สำหรับพรอมต์/นโยบายที่รับรู้ช่องทาง |
/v1/models แสดงรายการเป้าหมายเอเจนต์ระดับบนสุด (openclaw, openclaw/default, openclaw/<agentId>) ไม่ใช่โมเดลแบ็กเอนด์ของผู้ให้บริการและไม่ใช่เอเจนต์ย่อย โดยเอเจนต์ย่อยยังคงเป็นโทโพโลยีการดำเนินงานภายใน หากละ x-openclaw-model เอเจนต์ที่เลือกจะทำงานด้วยโมเดลที่กำหนดค่าตามปกติ
/v1/embeddings ใช้รหัส model ของเป้าหมายเอเจนต์แบบเดียวกัน ส่ง x-openclaw-model (จากผู้เรียกที่ใช้ข้อมูลลับร่วม หรือผู้เรียกที่มีข้อมูลระบุตัวตนและมี operator.admin) เพื่อเลือกโมเดลการฝังเฉพาะ มิฉะนั้นคำขอจะใช้การตั้งค่าการฝังตามปกติของเอเจนต์ที่เลือก
ลักษณะการทำงานของเซสชัน
โดยค่าเริ่มต้น ปลายทางจะ ไม่มีสถานะในแต่ละคำขอ (สร้างคีย์เซสชันใหม่ทุกครั้งที่เรียก)
หากคำขอมีสตริง user ของ OpenAI Gateway จะสร้างคีย์เซสชันที่เสถียรจากค่านั้น เพื่อให้การเรียกซ้ำสามารถใช้เซสชันเอเจนต์ร่วมกันได้ สำหรับแอปที่สร้างเอง ให้ใช้ค่า user เดียวกันซ้ำต่อเธรดการสนทนา และหลีกเลี่ยงตัวระบุระดับบัญชี เว้นแต่คุณต้องการให้หลายการสนทนา/อุปกรณ์ใช้เซสชัน OpenClaw เดียวกัน ใช้ x-openclaw-session-key เฉพาะเมื่อต้องการควบคุมการกำหนดเส้นทางอย่างชัดเจนระหว่างไคลเอนต์/เธรดหลายรายการ โดยใช้คีย์ที่แอปพลิเคชันเป็นเจ้าของและหลีกเลี่ยงเนมสเปซที่สงวนไว้ข้างต้น
ขีดจำกัดคำขอ (การกำหนดค่า)
สามารถปรับค่าเริ่มต้นภายใต้ gateway.http.endpoints.chatCompletions:
{ gateway: { http: { endpoints: { chatCompletions: { enabled: true, maxBodyBytes: 20000000, maxImageParts: 8, maxTotalImageBytes: 20000000, images: { allowUrl: false, urlAllowlist: ["cdn.example.com", "*.assets.example.com"], allowedMimes: [ "image/jpeg", "image/png", "image/gif", "image/webp", "image/heic", "image/heif", ], maxBytes: 10485760, maxRedirects: 3, timeoutMs: 10000, }, }, }, }, },}ค่าเริ่มต้นเมื่อละไว้:
| คีย์ | ค่าเริ่มต้น |
|---|---|
maxBodyBytes |
20MB |
maxImageParts |
8 (จำนวนส่วน image_url สูงสุดที่อ่านจากข้อความล่าสุดของผู้ใช้) |
maxTotalImageBytes |
20MB (จำนวนไบต์ที่ถอดรหัสสะสมจากส่วน image_url ทั้งหมดในคำขอเดียว) |
images.allowUrl |
false (ส่วน image_url ที่มีแหล่งที่มาจาก URL จะถูกปฏิเสธ เว้นแต่เปิดใช้งาน) |
images.maxBytes |
10MB ต่อภาพ |
images.maxRedirects |
3 |
images.timeoutMs |
10 วินาที |
แหล่งที่มา image_url แบบ HEIC/HEIF ได้รับการยอมรับและปรับให้เป็น JPEG ก่อนส่งไปยังผู้ให้บริการผ่านตัวประมวลผลภาพร่วมของ OpenClaw (Rastermill) ซึ่งจะย้อนกลับไปใช้ตัวแปลงของระบบ (sips, ImageMagick, GraphicsMagick หรือ ffmpeg) สำหรับรูปแบบที่ต้องอาศัยการรองรับตัวแปลงสัญญาณภายนอก
หมายเหตุด้านความปลอดภัย: การเพิ่มชื่อโฮสต์ลงในรายการอนุญาตไม่ได้ทำให้ข้ามการบล็อก IP ส่วนตัว/ภายใน สำหรับ Gateway ที่เปิดให้เข้าถึงจากอินเทอร์เน็ต ให้ใช้การควบคุมทราฟฟิกขาออกของเครือข่ายเพิ่มเติมจากมาตรการป้องกันระดับแอป ดูความปลอดภัย
สัญญาเครื่องมือแชต
/v1/chat/completions รองรับชุดย่อยของเครื่องมือฟังก์ชันที่เข้ากันได้กับไคลเอนต์ OpenAI Chat ทั่วไป
ฟิลด์คำขอที่รองรับ
| ฟิลด์ | หมายเหตุ |
|---|---|
tools |
อาร์เรย์ของ { "type": "function", "function": { ... } } |
tool_choice |
"auto", "none", "required" หรือ { "type": "function", "function": { "name": "..." } } |
messages[*].role: "tool" |
เทิร์นการสนทนาต่อเนื่อง |
messages[*].tool_call_id |
เชื่อมผลลัพธ์ของเครื่องมือกลับไปยังการเรียกเครื่องมือก่อนหน้า |
max_completion_tokens |
ตัวเลข; ขีดจำกัดโทเค็นทั้งหมดที่สร้างต่อการเรียกหนึ่งครั้ง (รวมโทเค็นการให้เหตุผล) เป็นชื่อฟิลด์ปัจจุบัน และจะถูกใช้เมื่อส่งทั้งฟิลด์นี้และ max_tokens |
max_tokens |
ตัวเลข; นามแฝงแบบเดิม ซึ่งจะถูกละเว้นเมื่อมี max_completion_tokens อยู่ด้วย |
temperature |
ตัวเลข 0-2; ใช้ตามความสามารถและส่งต่อไปยังผู้ให้บริการต้นทาง หากอยู่นอกช่วงจะได้ 400 invalid_request_error |
top_p |
ตัวเลข 0-1; ใช้ตามความสามารถ หากอยู่นอกช่วงจะได้ 400 invalid_request_error |
frequency_penalty |
ตัวเลข -2.0 ถึง 2.0; ใช้ตามความสามารถ หากอยู่นอกช่วงจะได้ 400 invalid_request_error |
presence_penalty |
ตัวเลข -2.0 ถึง 2.0; ใช้ตามความสามารถ หากอยู่นอกช่วงจะได้ 400 invalid_request_error |
seed |
จำนวนเต็ม; ใช้ตามความสามารถ ค่าที่ไม่ใช่จำนวนเต็มจะได้ 400 invalid_request_error |
stop |
สตริงหรืออาร์เรย์ของสตริงไม่เกิน 4 รายการ; ใช้ตามความสามารถ หากมีมากกว่า 4 ลำดับ หรือมีรายการที่ไม่ใช่สตริง/เป็นค่าว่าง จะได้ 400 invalid_request_error |
ฟิลด์การสุ่มตัวอย่างและการจำกัดโทเค็นทั้งหมดใช้ช่องทางพารามิเตอร์สตรีมของเอเจนต์เดียวกัน และจะถูกส่งต่อตามความสามารถ:
- ขีดจำกัดโทเค็น: ชื่อฟิลด์บนสายสื่อสารถูกเลือกตามทรานสปอร์ตของผู้ให้บริการ:
max_completion_tokensสำหรับเอนด์พอยต์ตระกูล OpenAI และmax_tokensสำหรับผู้ให้บริการที่ยอมรับเฉพาะชื่อแบบเดิม (Mistral, Chutes) stopจะจับคู่กับฟิลด์หยุดของทรานสปอร์ต:stopสำหรับแบ็กเอนด์ Chat Completions และstop_sequencesสำหรับ Anthropic เนื่องจาก OpenAI Responses API ไม่มีพารามิเตอร์หยุด จึงไม่มีการใช้stopกับโมเดลที่ใช้ Responses เป็นแบ็กเอนด์- แบ็กเอนด์ Codex Responses ที่ใช้ ChatGPT ใช้การสุ่มตัวอย่างคงที่ฝั่งเซิร์ฟเวอร์ และนำ
temperature/top_p(รวมถึงmax_output_tokens,metadata,prompt_cache_retention,service_tier) ออกก่อนที่คำขอจะไปถึงแบ็กเอนด์นั้น
รูปแบบที่ไม่รองรับ
ส่งคืน 400 invalid_request_error สำหรับ:
toolsที่ไม่ใช่อาร์เรย์ รายการเครื่องมือที่ไม่ใช่ฟังก์ชัน หรือไม่มีtool.function.name- รูปแบบ
tool_choiceเช่นallowed_toolsและcustom - ค่า
tool_choice.function.nameที่ไม่ตรงกับเครื่องมือที่ระบุไว้
สำหรับ tool_choice: "required" และ tool_choice ที่ตรึงฟังก์ชัน เอนด์พอยต์จะจำกัดชุดเครื่องมือฟังก์ชันของไคลเอนต์ที่เปิดเผย สั่งให้รันไทม์เรียกเครื่องมือของไคลเอนต์ก่อนตอบกลับ และส่งข้อผิดพลาดหากการตอบกลับของเอเจนต์ไม่มีการเรียกเครื่องมือไคลเอนต์แบบมีโครงสร้างที่ตรงกัน ข้อนี้ใช้กับรายการ HTTP tools ที่ผู้เรียกส่งมา ไม่ใช่เครื่องมือภายในทั้งหมดของเอเจนต์ OpenClaw
รูปแบบการตอบกลับจากเครื่องมือแบบไม่สตรีม
เมื่อเอเจนต์เรียกเครื่องมือ การตอบกลับจะใช้:
choices[0].finish_reason = "tool_calls"- รายการ
choices[0].message.tool_calls[]ที่มีid,type: "function",function.name,function.arguments(สตริง JSON) - คำอธิบายของผู้ช่วยก่อนการเรียกเครื่องมือใน
choices[0].message.content(อาจว่างเปล่า)
รูปแบบการตอบกลับจากเครื่องมือแบบสตรีม
เมื่อ stream: true การเรียกเครื่องมือจะมาถึงเป็นส่วนย่อย SSE แบบต่อเนื่อง: เดลตาบทบาทผู้ช่วยเริ่มต้น เดลตาคำอธิบายของผู้ช่วยที่อาจมีหรือไม่มีก็ได้ ส่วนย่อย delta.tool_calls หนึ่งรายการขึ้นไปที่มีข้อมูลระบุตัวเครื่องมือและส่วนย่อยของอาร์กิวเมนต์ จากนั้นจึงเป็นส่วนย่อยสุดท้ายที่มี finish_reason: "tool_calls" และ data: [DONE]
หาก stream_options.include_usage=true ระบบจะส่งส่วนย่อยข้อมูลการใช้งานปิดท้ายก่อน [DONE]
ลูปการติดตามผลของเครื่องมือ
หลังจากได้รับ tool_calls ให้เรียกใช้ฟังก์ชันที่ร้องขอ แล้วส่งคำขอติดตามผลซึ่งรวมข้อความการเรียกเครื่องมือของผู้ช่วยก่อนหน้า พร้อมข้อความ role: "tool" อย่างน้อยหนึ่งข้อความที่มี tool_call_id ตรงกัน การดำเนินการนี้จะสานต่อลูปการให้เหตุผลของเอเจนต์เดิมเพื่อสร้างคำตอบสุดท้าย
การสตรีม (SSE)
ตั้งค่า stream: true เพื่อรับ Server-Sent Events:
Content-Type: text/event-stream- แต่ละบรรทัดของเหตุการณ์คือ
data: <json> - สตรีมสิ้นสุดด้วย
data: [DONE]
การตั้งค่า Open WebUI อย่างรวดเร็ว
- URL ฐาน:
http://127.0.0.1:18789/v1 - URL ฐานสำหรับ Docker บน macOS:
http://host.docker.internal:18789/v1 - คีย์ API: โทเค็น bearer ของ Gateway ของคุณ
- โมเดล:
openclaw/default
ลักษณะการทำงานที่คาดไว้: GET /v1/models แสดงรายการ openclaw/default และ Open WebUI ใช้ค่านี้เป็นรหัสโมเดลแชต สำหรับผู้ให้บริการ/โมเดลแบ็กเอนด์เฉพาะ ให้ตั้งค่าโมเดลเริ่มต้นตามปกติของเอเจนต์ หรือส่ง x-openclaw-model (ผู้เรียกที่ใช้ข้อมูลลับร่วมกัน หรือผู้เรียกที่มีข้อมูลระบุตัวตนพร้อม operator.admin)
การทดสอบเบื้องต้นอย่างรวดเร็ว:
curl -sS http://127.0.0.1:18789/v1/models \ -H 'Authorization: Bearer YOUR_TOKEN'หากคำสั่งนี้ส่งคืน openclaw/default การตั้งค่า Open WebUI ส่วนใหญ่จะเชื่อมต่อได้ด้วย URL ฐานและโทเค็นเดียวกัน
ตัวอย่าง
เซสชันที่คงที่สำหรับการสนทนาหนึ่งรายการของแอป:
curl -sS http://127.0.0.1:18789/v1/chat/completions \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "model": "openclaw/default", "user": "conv:YOUR_CONVERSATION_ID", "messages": [{"role":"user","content":"Summarize my tasks for today"}] }'ใช้ค่า user เดิมซ้ำในการเรียกครั้งถัดไปสำหรับการสนทนานั้น เพื่อดำเนินเซสชันเอเจนต์เดิมต่อ
แบบไม่สตรีม:
curl -sS http://127.0.0.1:18789/v1/chat/completions \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "model": "openclaw/default", "messages": [{"role":"user","content":"hi"}] }'แบบสตรีม:
curl -N http://127.0.0.1:18789/v1/chat/completions \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -H 'x-openclaw-model: openai/gpt-5.4' \ -d '{ "model": "openclaw/research", "stream": true, "messages": [{"role":"user","content":"hi"}] }'แสดงรายการโมเดล:
curl -sS http://127.0.0.1:18789/v1/models \ -H 'Authorization: Bearer YOUR_TOKEN'ดึงข้อมูลโมเดลหนึ่งรายการ:
curl -sS http://127.0.0.1:18789/v1/models/openclaw%2Fdefault \ -H 'Authorization: Bearer YOUR_TOKEN'สร้างเวกเตอร์ฝังตัว:
curl -sS http://127.0.0.1:18789/v1/embeddings \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -H 'x-openclaw-model: openai/text-embedding-3-small' \ -d '{ "model": "openclaw/default", "input": ["alpha", "beta"] }'/v1/embeddings รองรับ input ในรูปแบบสตริงหรืออาร์เรย์ของสตริง