콘텐츠로 이동
ABTO 가이드
앱토(ABTO) 홈
무료로 시작

연동 가이드

Chat Completions

POST /v1/chat/completions 에서 Gateway가 받는 필드와 제공사별 차이를 설명합니다.

POST /v1/chat/completions는 OpenAI Chat Completions 형식으로 요청을 받습니다. 미지원 필드와 표에 없는 필드는 Gateway가 400으로 거절합니다. “제공사별 차이”가 비어 있는 필드는 OpenAI, Anthropic, Gemini, DeepSeek, Kimi 중 어디로 배정되어도 동작이 같습니다. Vertex AI로 부르는 Gemini는 이 페이지의 Gemini와 같게 동작합니다.

공통 규칙과 오류 출처는 Gateway 개요에 있습니다. OpenAI Responses 형식은 Responses에 있습니다.

  • Anthropic은 최대 토큰이 필수입니다. max_completion_tokens와 max_tokens를 모두 생략하면 그 모델의 출력 상한을 넣습니다. 모델별 상한은 GET /v1/models의 max_output_tokens에서 확인하고, 긴 응답이 필요하면 직접 지정하세요.
  • Anthropic은 json_schema의 모든 object에 additionalProperties: false를 추가합니다. 스키마에 선언하지 않은 속성은 응답에 나오지 않습니다.
  • Anthropic에는 스키마 없는 JSON 모드가 없습니다. Gateway가 자체적으로 json_output이라는 도구를 요청에 넣어 호출하게 한 뒤, 결과를 content 문자열로 되돌립니다. json_object는 tools와 함께 쓸 수 없으며, 도구 이름 json_output도 쓸 수 없습니다.
  • Kimi는 생성 파라미터를 모델이 정한 값으로 고정합니다. 다른 값을 보내면 Kimi가 거절하며, 그 응답을 그대로 돌려받습니다.
  • DeepSeek과 Kimi는 OpenAI 형식을 그대로 받으므로 요청 모양이 같습니다. 받지 않는 값은 아래 표에 필드별로 적습니다.
필드지원제공사별 차이
model지원
messages[].role: system, developer지원 (텍스트만)Anthropic, Gemini: 이어 붙여 맨 앞 하나로 보냅니다
DeepSeek, Kimi: developer를 system으로 보내며 위치는 그대로입니다
messages[].role: user지원 (문자열 또는 파트 배열)
messages[].role: assistant지원 (텍스트만)
messages[].content[].image_url.url지원 (base64 data URL 또는 http(s) URL)Gemini: URL은 주소 끝의 확장자로 종류를 판단하므로 확장자가 없으면 거절합니다
Kimi: http(s) URL을 받지 않습니다
DeepSeek: 이미지를 읽는 모델과 읽지 않는 모델이 있습니다
messages[].content[].image_url.detail지원 (auto, low, high, original)Gemini: low, high만 반영합니다
Anthropic: 반영되지 않습니다
messages[].content[].file.file_data지원 (base64 PDF data URL만)DeepSeek, Kimi: PDF를 받지 않습니다
messages[].content[].file.filename지원Gemini: 보내지 않습니다
  • content 형태: user 메시지의 content는 문자열 또는 text, image_url, file 파트 배열입니다. assistant 메시지는 tool_calls와 reasoning_details가 모두 없으면 content가 있어야 합니다.
  • 미디어 파트: 이미지와 PDF는 user 메시지에서만 받으며, 이미지는 png, jpeg, webp, gif를 지원합니다.
  • 이미지 URL: 이미지는 base64 data URL 대신 http(s) URL로도 보낼 수 있습니다. Gateway는 주소를 그대로 전달하고 제공사가 직접 내려받으므로, 제공사가 닿을 수 있는 공개 주소여야 합니다. PDF는 base64 data URL만 받습니다.
  • 시스템 프롬프트: 노드에 시스템 프롬프트 사용을 허용한 경우, 시스템 프롬프트를 지정한 옵션에 배정된 요청은 system과 developer 메시지 대신 옵션의 시스템 프롬프트를 사용합니다. 허용하지 않은 노드의 요청과 원본 옵션에 배정된 요청은 원본 요청의 메시지를 그대로 사용합니다.
  • 모델 이름: 라우팅을 설정하기 전에는 요청이 OpenAI로 전달되므로 model에 OpenAI 모델 이름을 보내야 합니다. 라우팅을 설정하면 배정된 옵션이 제공사와 모델을 정하고, 옵션이 그 노드의 설정을 바꾸지 않았으면 요청에 보낸 값을 그대로 씁니다. 사용할 수 있는 이름은 모델 목록에서 확인하세요.
필드지원제공사별 차이
max_completion_tokens지원Anthropic: 둘 다 생략하면 모델의 출력 상한
max_tokens지원 (레거시)Anthropic: 둘 다 생략하면 모델의 출력 상한
n다중 응답 미지원 (1만)
stream스트리밍 미지원 (false만)

max_tokens와 max_completion_tokens를 함께 보내면 max_completion_tokens를 사용합니다.

필드지원제공사별 차이
temperature지원Kimi: 모델이 정한 값만 받습니다
DeepSeek: 추론하는 동안에는 반영되지 않습니다
top_p지원Kimi: 모델이 정한 값만 받습니다
frequency_penalty지원Kimi: 모델이 정한 값만 받습니다
DeepSeek: 반영되지 않습니다
presence_penalty지원Kimi: 모델이 정한 값만 받습니다
DeepSeek: 반영되지 않습니다
seed지원Kimi: 반영되지 않습니다
reasoning_effort지원DeepSeek, Kimi: 받는 값이 OpenAI와 다르므로 대시보드에서 확인하세요
verbosity지원DeepSeek, Kimi: 반영되지 않습니다
  • 라우팅을 설정하기 전: 요청에 보낸 값을 그대로 사용하며, 그 구성이 원본 옵션으로 등록됩니다.
  • 라우팅을 설정한 뒤: 배정된 옵션의 값을 사용하고 요청에 보낸 값은 반영되지 않습니다. 옵션이 그 노드의 설정을 바꾸지 않았으면 요청에 보낸 값을 그대로 사용합니다. 옵션에 설정하지 않은 파라미터는 제공사에 전달되지 않고 제공사 기본값이 적용됩니다.
  • 설정 범위: 옵션에 설정할 수 있는 값의 범위는 대시보드가 제공사와 모델별로 보여줍니다. 옵션에는 이 표에 없는 제공사 전용 파라미터도 존재합니다.
필드지원제공사별 차이
response_format: text지원
response_format: json_schema지원Anthropic: additionalProperties: false를 추가합니다
DeepSeek: 받지 않습니다
response_format: json_object지원Anthropic: 도구 호출로 구현합니다
  • 스키마: json_schema에는 json_schema.schema가 있어야 합니다. 스키마 안쪽은 검사하지 않고 그대로 전달합니다.
  • 전달되는 범위: json_schema에서 전달되는 키는 name, description, strict, schema 네 가지이며 그 밖의 키는 제공사에 전달되지 않습니다. 키 이름은 대소문자까지 정확히 일치해야 합니다. Anthropic과 Gemini는 제공사 형식으로 다시 만들며 json_schema.schema만 옮기므로 name, description, strict는 OpenAI에만 전달됩니다.
  • 값 타입: name과 description은 문자열, strict는 불리언입니다. 타입이 다르면 그 키를 알려 주는 400으로 거절합니다.
  • 함께 보내는 규칙: json_object는 tools와 함께 보낼 수 없습니다.
필드지원제공사별 차이
tools지원 (type: function만)
tools[].function.strict지원Gemini: 하나라도 true면 모든 도구를 검증합니다
tool_choice지원 (none, auto, required, 함수 지정)함수를 지정해도 같은 도구를 여러 번 호출할 수 있습니다
tool_choice: allowed_tools지원 (mode는 auto, required만)Anthropic, DeepSeek, Kimi: 허용 밖 도구를 빼고 보냅니다
parallel_tool_calls병렬 호출 끄기 미지원 (true만)
functions지원 (레거시)
function_call지원 (레거시, none, auto, 함수 지정)
messages[].tool_calls[].id지원
messages[].tool_calls[].function.arguments지원 (JSON object 문자열만)
messages[].role: tool지원
messages[].role: function지원 (레거시)
  • 함께 보내는 규칙: tool_choice는 tools와 함께 보내야 합니다. 레거시 functions는 tools, tool_choice와 함께 보낼 수 없고, function_call은 functions가 있어야 합니다.
  • 도구 이름과 스키마: 도구 이름 json_output은 쓸 수 없습니다. tools[].function.parameters 내부는 검사하지 않고 그대로 전달합니다.
  • 결과 되돌리기: tool_calls[].id와 tool_call_id는 응답에서 받은 값을 그대로 보냅니다. 값이 짝을 이루지 않으면 제공사가 거절합니다. role: tool의 content는 문자열 또는 text 파트이고, role: function은 name이 앞선 function_call과 같아야 합니다.
  • 응답 모양: functions로 보낸 요청의 응답은 message.function_call과 finish_reason: "function_call"로 돌아옵니다. 한 응답에 호출이 여럿이면 message.function_call에는 첫 호출만 담기고 나머지는 message.tool_calls에서 확인합니다. 그 밖의 도구 호출 응답은 message.tool_calls와 finish_reason: "tool_calls"로 돌아옵니다.
  • 레거시 권장: 레거시 functions는 한 턴에 호출 하나만 표현합니다. Gemini, DeepSeek, Kimi는 한 응답에 여러 호출을 보내며, 결과를 하나씩 돌려주면 남은 호출을 다시 요청하므로 턴이 늘어납니다. tools를 사용하세요.
필드지원제공사별 차이
messages[].reasoning_details지원OpenAI: 추론을 반환하지 않으므로 보낼 값이 없습니다
  • 응답에 오는 값: 추론하는 모델은 message.reasoning_details에 추론을 반환합니다. 각 항목은 type으로 종류를 구분하며 reasoning.text는 text에 본문을, reasoning.encrypted는 data에 제공사만 읽을 수 있는 값을 담습니다. format은 추론을 만든 제공사를 나타냅니다.
  • 다음 턴으로 잇기: 대화를 이어갈 때는 응답에서 받은 reasoning_details를 assistant 메시지에 고치지 않고 그대로 실어 보냅니다. 항목 순서를 바꾸거나 내용을 편집하면 추론이 이어지지 않습니다. 응답의 message 객체를 그대로 대화 이력에 넣으면 함께 따라갑니다.
  • 같은 대화는 같은 옵션으로: 여러 턴을 이어갈 때는 모든 요청에 같은 x-abto-device-id를 보냅니다. 이 값이 있어야 대화가 같은 옵션으로 배정되어 추론이 이어집니다. 값이 없으면 요청마다 옵션이 따로 정해지며, 제공사가 바뀐 턴부터는 이전 추론을 사용하지 않고 다시 추론합니다.
  • 생략했을 때: Gemini는 도구 호출이 있는 턴의 추론이 빠진 이력을 거절합니다. DeepSeek은 응답에서 받은 tool_calls[].id를 고쳐 보내면서 추론까지 빠뜨린 이력을 거절합니다. Anthropic과 Kimi는 추론 없이도 이어지며 매 턴 다시 추론하므로 추론 토큰이 늘어납니다.
  • 추론 토큰: usage.completion_tokens_details.reasoning_tokens는 추론에 사용한 토큰 수이며 추론 내용과 별개입니다.
  • 도구 없는 대화: 추론은 도구 호출과 무관하게 이어집니다. 도구를 사용하지 않는 여러 턴 대화와 functions를 사용한 대화에서도 같은 방법으로 보냅니다.

아래 필드를 보내면 Gateway가 400으로 거절합니다. 표에 없는 필드도 같습니다.

구분필드
토큰 확률logprobs, top_logprobs, logit_bias
오디오와 그 밖의 입력modalities, audio, messages[].audio, 그 밖의 content 파트(input_audio 등)
파일 참조messages[].content[].file.file_id, messages[].content[].file.file_data의 http(s) URL
제공사 서버 기능store, service_tier, moderation, web_search_options, prediction
프롬프트 캐시prompt_cache_key, prompt_cache_options, prompt_cache_retention
요청 태그와 사용자 식별metadata, user, safety_identifier
그 밖stop, stream_options, messages[].name (role: function 제외), messages[].refusal, messages[].reasoning, messages[].reasoning_content

제공사에 태그를 남기거나 사용자를 식별하는 용도는 대체할 수 없습니다. 분석에 쓰던 식별자는 레퍼런스의 x-abto-feature-id와 x-abto-device-id로 보내며, 이 헤더는 ABTO에 기록되고 제공사에는 전달되지 않습니다.

Gateway는 아래 API 형식으로 요청을 보냅니다. 제공사가 받는 값의 범위와 거절 조건은 각 문서를 확인하세요.