콘텐츠로 이동

OpenResponses API로 Gateway 연결하기

여러 API 규격을 맞추느라 고생한 적 많으시죠? 새로운 도구를 도입할 때마다 매번 다른 요청 형식을 익히는 건 정말 번거로운 일이에요. OpenClaw는 이런 불편함을 줄이기 위해 OpenResponses와 호환되는 API 엔드포인트를 제공하고 있습니다.

OpenClaw의 Gateway는 OpenResponses와 호환되는 POST /v1/responses 엔드포인트를 제공할 수 있어요. 이 엔드포인트는 기본적으로 비활성화되어 있으니, 사용하기 전에 설정에서 먼저 활성화해야 합니다.

  • POST /v1/responses
  • Gateway와 동일한 포트 사용 (WS + HTTP 멀티플렉싱): http://<gateway-host>:<port>/v1/responses

내부적으로 요청은 일반적인 Gateway 에이전트 실행과 동일하게 처리됩니다(openclaw agent와 동일한 코드 경로 사용). 따라서 라우팅, 권한, 설정 등이 여러분의 Gateway 설정과 그대로 일치해요.

인증, 보안 및 라우팅 (Authentication, security, and routing)

섹션 제목: “인증, 보안 및 라우팅 (Authentication, security, and routing)”

작동 방식은 OpenAI Chat Completions와 동일합니다.

  • 일반적인 Gateway 인증 설정을 사용하여 Authorization: Bearer <token>을 사용하세요.
  • 이 엔드포인트를 Gateway 인스턴스에 대한 전체 운영자 권한(full operator access)으로 취급합니다.
  • 공유 비밀번호 인증 모드(token 및 password)의 경우, Bearer 토큰에 선언된 좁은 범위의 x-openclaw-scopes 값은 무시하고 일반적인 전체 운영자 기본값을 복원합니다.
  • 신뢰할 수 있는 ID 기반 HTTP 모드(예: 신뢰할 수 있는 프록시 인증 또는 gateway.auth.mode="none")의 경우, 요청에 선언된 운영자 범위를 그대로 따릅니다.
  • 에이전트 선택 시 model: "openclaw", model: "openclaw/default", model: "openclaw/<agentId>" 또는 x-openclaw-agent-id를 사용하세요.
  • 선택한 에이전트의 백엔드 모델을 오버라이드하고 싶을 때는 x-openclaw-model을 사용하세요.
  • 명시적인 세션 라우팅을 위해 x-openclaw-session-key를 사용하세요.
  • 기본값이 아닌 합성 인그레스 채널 컨텍스트를 원할 때는 x-openclaw-message-channel을 사용하세요.

인증 매트릭스:

  • gateway.auth.mode="token" 또는 "password" + Authorization: Bearer ...
    • 공유된 Gateway 운영자 비밀 키를 소유하고 있음을 증명합니다.
    • 더 좁은 범위의 x-openclaw-scopes를 무시합니다.
    • 전체 기본 운영자 범위 세트를 복원합니다.
    • 이 엔드포인트에서의 채팅 턴을 소유자-발신자(owner-sender) 턴으로 취급합니다.
  • 신뢰할 수 있는 ID 기반 HTTP 모드 (예: 신뢰할 수 있는 프록시 인증, 또는 프라이빗 인그레스에서의 gateway.auth.mode="none")
    • 선언된 x-openclaw-scopes 헤더를 따릅니다.
    • 선언된 범위 내에 operator.admin이 실제로 존재할 때만 소유자 의미론(owner semantics)을 가집니다.

이 엔드포인트는 gateway.http.endpoints.responses.enabled 설정으로 활성화하거나 비활성화할 수 있어요.

동일한 호환성 범위에는 다음 항목들도 포함됩니다.

  • GET /v1/models
  • GET /v1/models/{id}
  • POST /v1/embeddings
  • POST /v1/chat/completions

에이전트 대상 모델, openclaw/default, embeddings 패스스루, 백엔드 모델 오버라이드가 어떻게 연동되는지에 대한 자세한 설명은 OpenAI Chat Completions 및 Model list and agent routing 문서를 참고해 주세요.

기본적으로 이 엔드포인트는 요청당 상태를 유지하지 않습니다(stateless). 즉, 호출할 때마다 새로운 세션 키가 생성됩니다.

만약 요청에 OpenResponses user 문자열이 포함되어 있다면, Gateway는 이를 통해 고정된 세션 키를 유도합니다. 덕분에 반복적인 호출에서도 에이전트 세션을 공유할 수 있어요.

요청 형식 (지원 범위) (Request shape (supported))

섹션 제목: “요청 형식 (지원 범위) (Request shape (supported))”

요청은 아이템 기반 입력을 사용하는 OpenResponses API를 따릅니다. 현재 지원되는 항목은 다음과 같아요.

  • input: 문자열 또는 아이템 객체의 배열입니다.
  • instructions: system prompt에 병합됩니다.
  • tools: 클라이언트 도구 정의(function tools)입니다.
  • tool_choice: 클라이언트 도구를 필터링하거나 필수 사용으로 지정합니다.
  • stream: SSE 스트리밍을 활성화합니다.
  • max_output_tokens: 최선의 노력을 다하는 출력 제한입니다(제공자에 따라 다름).
  • user: 고정된 세션 라우팅에 사용됩니다.

수락되지만 현재는 무시되는 항목:

  • max_tool_calls
  • reasoning
  • metadata
  • store
  • truncation

지원 항목:

  • previous_response_id: 요청이 동일한 에이전트/사용자/요청 세션 범위 내에 있을 때, OpenClaw는 이전 응답 세션을 재사용합니다.

역할(Roles): system, developer, user, assistant.

  • system과 developer는 system prompt 뒤에 추가됩니다.
  • 가장 최근의 user 또는 function_call_output 아이템이 “현재 메시지”가 됩니다.
  • 이전의 user/assistant 메시지는 컨텍스트를 위한 히스토리로 포함됩니다.

도구 실행 결과를 모델에 다시 보낼 때 사용합니다.

{
"type": "function_call_output",
"call_id": "call_123",
"output": "{\"temperature\": \"72F\"}"
}

스키마 호환성을 위해 수락되지만, 프롬프트를 생성할 때는 무시됩니다.

도구 (클라이언트 측 function tools) (Tools (client-side function tools))

섹션 제목: “도구 (클라이언트 측 function tools) (Tools (client-side function tools))”

tools: [{ type: "function", function: { name, description?, parameters? } }] 형식을 통해 도구를 제공할 수 있습니다.

에이전트가 도구를 호출하기로 결정하면, 응답으로 function_call 출력 아이템을 반환합니다. 그 후 여러분은 function_call_output을 포함한 후속 요청을 보내서 대화를 이어가면 됩니다.

이미지 (input_image) (Images (input_image))

섹션 제목: “이미지 (input_image) (Images (input_image))”

base64 또는 URL 소스를 지원합니다.

{
"type": "input_image",
"source": { "type": "url", "url": "https://example.com/image.png" }
}

허용되는 MIME 타입(현재): image/jpeg, image/png, image/gif, image/webp, image/heic, image/heif. 최대 크기(현재): 10MB.

base64 또는 URL 소스를 지원합니다.

{
"type": "input_file",
"source": {
"type": "base64",
"media_type": "text/plain",
"data": "SGVsbG8gV29ybGQh",
"filename": "hello.txt"
}
}

허용되는 MIME 타입(현재): text/plain, text/markdown, text/html, text/csv, application/json, application/pdf.

최대 크기(현재): 5MB.

현재 동작 방식:

  • 파일 내용은 디코딩되어 사용자 메시지가 아닌 system prompt에 추가됩니다. 따라서 세션 히스토리에 저장되지 않고 일시적으로만 유지됩니다.
  • PDF는 텍스트를 추출합니다. 텍스트가 거의 발견되지 않으면 첫 페이지들을 이미지로 래스터화하여 모델에 전달합니다.

PDF 파싱에는 Node.js 친화적인 pdfjs-dist 레거시 빌드(worker 없음)를 사용합니다. 최신 PDF.js 빌드는 브라우저 worker나 DOM 글로벌 객체를 필요로 하기 때문에 Gateway에서는 사용하지 않아요.

URL 페치(fetch) 기본값:

  • files.allowUrl: true
  • images.allowUrl: true
  • maxUrlParts: 8 (요청당 URL 기반 input_file + input_image 파트의 총합)
  • 요청은 보호됩니다 (DNS 확인, 프라이빗 IP 차단, 리다이렉트 제한, 타임아웃).
  • 입력 타입별로 선택적인 호스트네임 허용 목록(allowlist)을 지원합니다 (files.urlAllowlist, images.urlAllowlist).
    • 정확한 호스트: "cdn.example.com"
    • 와일드카드 서브도메인: "*.assets.example.com" (apex 도메인은 일치하지 않음)
    • 허용 목록이 비어 있거나 생략되면 호스트네임 제한이 없음을 의미합니다.
  • URL 기반 페치를 완전히 비활성화하려면 files.allowUrl: false 또는 images.allowUrl: false로 설정하세요.

파일 및 이미지 제한 (설정) (File + image limits (config))

섹션 제목: “파일 및 이미지 제한 (설정) (File + image limits (config))”

기본값은 gateway.http.endpoints.responses 아래에서 조정할 수 있습니다.

{
gateway: {
http: {
endpoints: {
responses: {
enabled: true,
maxBodyBytes: 20000000,
maxUrlParts: 8,
files: {
allowUrl: true,
urlAllowlist: ["cdn.example.com", "*.assets.example.com"],
allowedMimes: [
"text/plain",
"text/markdown",
"text/html",
"text/csv",
"application/json",
"application/pdf",
],
maxBytes: 5242880,
maxChars: 200000,
maxRedirects: 3,
timeoutMs: 10000,
pdf: {
maxPages: 4,
maxPixels: 4000000,
minTextChars: 200,
},
},
images: {
allowUrl: true,
urlAllowlist: ["images.example.com"],
allowedMimes: [
"image/jpeg",
"image/png",
"image/gif",
"image/webp",
"image/heic",
"image/heif",
],
maxBytes: 10485760,
maxRedirects: 3,
timeoutMs: 10000,
},
},
},
},
},
}

생략 시 기본값:

  • maxBodyBytes: 20MB
  • maxUrlParts: 8
  • files.maxBytes: 5MB
  • files.maxChars: 200k
  • files.maxRedirects: 3
  • files.timeoutMs: 10s
  • files.pdf.maxPages: 4
  • files.pdf.maxPixels: 4,000,000
  • files.pdf.minTextChars: 200
  • images.maxBytes: 10MB
  • images.maxRedirects: 3
  • images.timeoutMs: 10s
  • HEIC/HEIF input_image 소스는 수락되며 제공자에게 전달되기 전에 JPEG로 정규화됩니다.

보안 참고 사항:

  • URL 허용 목록은 페치 전과 리다이렉트 단계에서 강제 적용됩니다.
  • 호스트네임을 허용 목록에 추가해도 프라이빗/내부 IP 차단은 우회되지 않습니다.
  • 인터넷에 노출된 Gateway의 경우, 애플리케이션 수준의 보호 외에도 네트워크 이그레스(egress) 제어를 적용하세요. 자세한 내용은 Security를 참고해 주세요.

Server-Sent Events(SSE)를 받으려면 stream: true로 설정하세요.

  • Content-Type: text/event-stream
  • 각 이벤트 라인은 event: <type>과 data: <json>으로 구성됩니다.
  • 스트림은 data: [DONE]으로 종료됩니다.

현재 방출되는 이벤트 타입:

  • response.created
  • response.in_progress
  • response.output_item.added
  • response.content_part.added
  • response.output_text.delta
  • response.output_text.done
  • response.content_part.done
  • response.output_item.done
  • response.completed
  • response.failed (에러 발생 시)

usage 정보는 하위 제공자(provider)가 토큰 사용량을 보고할 때 채워집니다.

에러는 다음과 같은 JSON 객체를 사용합니다.

{ "error": { "message": "...", "type": "invalid_request_error" } }

일반적인 사례:

  • 401 인증 누락 또는 유효하지 않음
  • 400 유효하지 않은 요청 본문
  • 405 잘못된 메소드

비스트리밍 방식:

Terminal window
curl -sS http://127.0.0.1:18789/v1/responses \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-H 'x-openclaw-agent-id: main' \
-d '{
"model": "openclaw",
"input": "hi"
}'

스트리밍 방식:

Terminal window
curl -N http://127.0.0.1:18789/v1/responses \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-H 'x-openclaw-agent-id: main' \
-d '{
"model": "openclaw",
"stream": true,
"input": "hi"
}'

궁금한 점이 있거나 설정에 도움이 필요하신가요? AI Setup Assistant에게 언제든 물어보세요!

OpenClaw

OpenClaw Expert

아직 막혀 있나요?

이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.