Gateway
OpenAI 채팅 완성
Gateway는 소규모 OpenAI 호환 Chat Completions 인터페이스를 제공할 수 있습니다. 이 기능은 기본적으로 비활성화되어 있습니다.
활성화하면 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)을 복원합니다. 채팅 턴을 소유자가 보낸 턴으로 취급합니다. |
신뢰할 수 있는 ID 포함 HTTP(신뢰 프록시 인증 또는 비공개 인그레스의 gateway.auth.mode="none") |
x-openclaw-scopes가 있으면 적용하고, 없으면 기본 운영자 범위 집합을 사용합니다. 호출자가 범위를 명시적으로 축소하고 operator.admin을 제외한 경우에만 소유자 의미 체계가 사라집니다. x-openclaw-model과 같은 소유자 수준 제어에는 operator.admin이 필요합니다. |
인증
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" |
구성된 ID 인식 프록시를 통해 라우팅합니다. 프록시가 필요한 ID 헤더를 삽입합니다. 동일 호스트의 local loopback 프록시에는 명시적으로 gateway.auth.trustedProxy.allowLoopback = true를 설정해야 합니다. |
gateway.auth.mode="none" |
인증 헤더가 필요하지 않습니다(비공개 인그레스 전용). |
참고:
trusted-proxyGateway에서 프록시를 우회하는 동일 호스트 호출자는gateway.auth.password/OPENCLAW_GATEWAY_PASSWORD를 직접 사용하는 방식으로 대체할 수 있습니다. 단,Forwarded,X-Forwarded-*또는X-Real-IP헤더의 흔적이 있으면 요청은 계속 신뢰 프록시 경로를 사용합니다.gateway.auth.rateLimit이 구성되어 있고 인증 시도가 너무 많이 실패하면 엔드포인트는Retry-After헤더와 함께429를 반환합니다.
이 엔드포인트를 사용해야 하는 경우
- 통합이 동일한 Gateway를 위한 또 하나의 운영자/클라이언트 인터페이스에 불과하다면 새 내장 채널을 추가하는 대신 이 엔드포인트를 사용하는 것이 좋습니다.
- 원격 Gateway에 직접 연결되는 네이티브 모바일 클라이언트에는 WebChat 또는 페어링된 기기 부트스트랩/기기 토큰 흐름을 사용하는 Gateway 프로토콜을 권장합니다. 그러면 기기에 공유 HTTP 토큰/비밀번호가 필요하지 않습니다.
- 자체 사용자, 대화방, Webhook 전달 또는 발신 전송 기능을 갖춘 외부 메시징 네트워크를 통합하는 경우에는 채널 Plugin을 구축하십시오. Plugin 구축을 참조하십시오.
에이전트 우선 모델 계약
OpenClaw는 OpenAI의 model 필드를 원시 제공자 모델 ID가 아닌 에이전트 대상으로 취급합니다.
model 값 |
라우팅 대상 |
|---|---|
openclaw |
구성된 기본 에이전트 |
openclaw/default |
구성된 기본 에이전트(안정적인 별칭이며, 환경에 따라 실제 기본 에이전트 ID가 변경되더라도 안전하게 하드코딩 가능) |
openclaw/<agentId> 또는 openclaw:<agentId> |
특정 에이전트 |
agent:<agentId> |
특정 에이전트(호환성 별칭) |
선택적 요청 헤더:
| 헤더 | 효과 |
|---|---|
x-openclaw-model: <provider/model-or-bare-id> |
선택한 에이전트의 백엔드 모델을 재정의합니다. 공유 비밀 Bearer 호출자는 이를 직접 사용할 수 있습니다. ID 포함 호출자(신뢰 프록시 또는 x-openclaw-scopes를 사용하는 인증 없는 비공개 인그레스)는 operator.admin이 필요하며, 그렇지 않으면 403 missing scope: operator.admin이 반환됩니다. |
x-openclaw-agent-id: <agentId> |
에이전트 선택을 위한 호환성 재정의입니다. |
x-openclaw-session-key: <sessionKey> |
명시적으로 세션을 라우팅합니다. 예약된 내부 네임스페이스(subagent:, cron:, acp:)를 사용하면 400 invalid_request_error와 함께 거부됩니다. |
x-openclaw-message-channel: <channel> |
채널을 인식하는 프롬프트/정책을 위한 합성 인그레스 채널 컨텍스트를 설정합니다. |
/v1/models는 백엔드 제공자 모델이나 하위 에이전트가 아니라 최상위 에이전트 대상(openclaw, openclaw/default, openclaw/<agentId>)을 나열합니다. 하위 에이전트는 내부 실행 토폴로지로 유지됩니다. x-openclaw-model을 생략하면 선택한 에이전트는 평소 구성된 모델로 실행됩니다.
/v1/embeddings는 동일한 에이전트 대상 model ID를 사용합니다. 특정 임베딩 모델을 선택하려면 공유 비밀 호출자 또는 operator.admin 권한이 있는 ID 포함 호출자에서 x-openclaw-model을 전송하십시오. 그렇지 않으면 요청은 선택한 에이전트의 일반 임베딩 설정을 사용합니다.
세션 동작
기본적으로 엔드포인트는 요청별로 상태를 유지하지 않습니다(호출할 때마다 새 세션 키 생성).
요청에 OpenAI user 문자열이 포함되면 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(활성화하지 않으면 URL에서 가져오는 image_url 부분이 거부됨) |
images.maxBytes |
이미지당 10MB |
images.maxRedirects |
3 |
images.timeoutMs |
10초 |
HEIC/HEIF image_url 소스는 허용되며, 공유 OpenClaw 이미지 프로세서(Rastermill)를 통해 제공자에게 전달되기 전에 JPEG로 정규화됩니다. 외부 코덱 지원이 필요한 형식에는 시스템 변환기(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가 반환됩니다. |
모든 샘플링 및 토큰 상한 필드는 동일한 에이전트 스트림 매개변수 채널을 통해 전달되며 최선형으로 전달됩니다.
- 토큰 상한: 전송 필드 이름은 제공자 전송 계층에서 선택합니다. OpenAI 계열 엔드포인트에는
max_completion_tokens, 레거시 이름만 허용하는 제공자(Mistral, Chutes)에는max_tokens를 사용합니다. stop은 전송 계층의 중지 필드에 매핑됩니다. Chat Completions 백엔드에는stop, Anthropic에는stop_sequences를 사용합니다. OpenAI Responses API에는 중지 매개변수가 없으므로 Responses 기반 모델에는stop이 적용되지 않습니다.- ChatGPT 기반 Codex Responses 백엔드는 서버 측 고정 샘플링을 사용하며 요청이 해당 백엔드에 도달하기 전에
temperature/top_p를 제거합니다(max_output_tokens,metadata,prompt_cache_retention,service_tier도 함께 제거).
지원되지 않는 변형
다음 경우 400 invalid_request_error를 반환합니다.
- 배열이 아닌
tools, 함수가 아닌 도구 항목 또는 누락된tool.function.name allowed_tools및custom같은tool_choice변형- 제공된 도구와 일치하지 않는
tool_choice.function.name값
tool_choice: "required" 및 함수가 고정된 tool_choice의 경우, 엔드포인트는 노출되는 클라이언트 함수 도구 집합을 좁히고 런타임에 응답 전에 클라이언트 도구를 호출하도록 지시하며, 에이전트 응답에 일치하는 구조화된 클라이언트 도구 호출이 없으면 오류를 반환합니다. 이는 모든 내부 OpenClaw 에이전트 도구가 아니라 호출자가 제공한 HTTP tools 목록에 적용됩니다.
비스트리밍 도구 응답 형식
에이전트가 도구를 호출하면 응답은 다음을 사용합니다.
choices[0].finish_reason = "tool_calls"id,type: "function",function.name,function.arguments(JSON 문자열)를 포함하는choices[0].message.tool_calls[]항목- 도구 호출 전 어시스턴트 설명은
choices[0].message.content에 포함됩니다(비어 있을 수 있음).
스트리밍 도구 응답 형식
stream: true이면 도구 호출은 증분 SSE 청크로 도착합니다. 초기 어시스턴트 역할 델타, 선택적 어시스턴트 설명 델타, 도구 식별 정보 및 인수 조각을 전달하는 하나 이상의 delta.tool_calls 청크, 그다음 finish_reason: "tool_calls"가 포함된 최종 청크와 data: [DONE] 순서입니다.
stream_options.include_usage=true이면 [DONE] 전에 마지막 사용량 청크가 전송됩니다.
도구 후속 루프
tool_calls를 수신한 후 요청된 함수를 실행하고, 이전 어시스턴트 도구 호출 메시지와 일치하는 tool_call_id를 가진 하나 이상의 role: "tool" 메시지를 포함하는 후속 요청을 전송합니다. 그러면 동일한 에이전트 추론 루프가 계속되어 최종 답변을 생성합니다.
스트리밍(SSE)
Server-Sent Events를 수신하려면 stream: true로 설정합니다.
Content-Type: text/event-stream- 각 이벤트 줄은
data: <json>형식입니다. - 스트림은
data: [DONE]으로 종료됩니다.
Open WebUI 빠른 설정
- 기본 URL:
http://127.0.0.1:18789/v1 - macOS에서 Docker를 사용할 때의 기본 URL:
http://host.docker.internal:18789/v1 - API 키: Gateway 베어러 토큰
- 모델:
openclaw/default
예상 동작: GET /v1/models는 openclaw/default를 나열하며, Open WebUI는 이를 채팅 모델 ID로 사용합니다. 특정 백엔드 제공자/모델을 사용하려면 에이전트의 일반 기본 모델을 설정하거나 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으로 문자열 또는 문자열 배열을 지원합니다.