모델 라우트 및 기능

“이 모델은 도구 호출을 지원합니까?”는 모델에 대한 질문처럼 들립니다. 하지만 그렇지 않습니다. 이는 모델 과 그 모델을 호출하는 엔드포인트에 대한 질문이며, 같은 모델이라도 한쪽에서는 예, 다른 쪽에서는 아니오라고 답할 수 있습니다. 이 페이지에서는 그 이유와, Entity Enricher가 카탈로그를 믿는 대신 직접 측정하여 이 질문에 답하는 방식을 설명합니다.

기능을 지원하면서도 거부하는 모델

OpenAI의 gpt-6 계열에 기존 /v1/chat/completions 엔드포인트로 함수 도구가 포함된 요청을 보내면 요청이 곧바로 거부됩니다:

400 Bad Request
Function tools with reasoning_effort are not supported.
Use /v1/responses or set reasoning_effort to 'none'.

같은 모델, 같은 도구, 같은 프롬프트를 /v1/responses로 보내면 정상적으로 응답합니다. 두 구조화된 출력 채널 모두에서, 추론 강도 설정 여부와 관계없이 작동합니다. 모델에서 바뀐 것은 없습니다. 주소만 바뀌었을 뿐입니다.

그 결과

기능은 모델만의 속성이 아닙니다. (모델, 엔드포인트) 쌍의 속성입니다. 따라서 모델당 참/거짓 하나만 저장하는 카탈로그는 실제로는 확인할 수 없는 질문에 답하고 있는 셈입니다.

라우트란 무엇인가

라우트란 단순히 요청이 전송되는 엔드포인트입니다. 같은 공급자, 같은 모델, 같은 API 키이지만 전송 형식이 다르고 요청 구조가 다르며 무엇을 조합할 수 있는지에 대한 규칙도 다릅니다. OpenAI는 두 가지를 제공하며, 업계 대부분은 더 오래된 쪽을 따라 했습니다.

라우트주고받는 형식어떤 제공업체가 지원하는가
Chat Completions
/v1/chat/completions
2023
상태를 저장하지 않습니다. 전체 메시지 목록을 보내면 다음 메시지를 받습니다. 호출 사이에 서버에 남는 것은 없습니다.OpenAI가 만든, 거의 모든 곳이 따라 하는 사실상의 업계 표준입니다 — xAI, DeepSeek, Alibaba, Groq, Together, Ollama 및 대부분의 OpenAI 호환 게이트웨이.
Responses API
/v1/responses
2025
타입이 지정된 항목 목록을 반환하며 — 추론 항목, 메시지, 함수 도구 호출, 호스팅 도구 호출 — 상태를 서버 측에 유지하고 한 턴의 추론을 다음 턴으로 이어갈 수 있습니다.OpenAI 전용입니다. Chat Completions 형식을 사용하는 유사 엔드포인트라고 해서 자동으로 이 엔드포인트를 제공하지는 않습니다.

그래서 오늘날 “the OpenAI API”라는 표현은 모호합니다. 두 가지가 존재하고, 서로 겹치며, 동일한 규칙을 적용하지 않습니다.

애초에 API가 두 개인 이유

추론 모델은 메시지 모델을 무너뜨렸습니다. 모델의 내부 추론은 메시지가 아닙니다. 모델이 사용자에게 한 말도, 사용자가 모델에게 한 말도 아니기 때문입니다. Chat Completions에는 메시지 목록만 있어서 추론을 담을 곳이 없으며, 표현할 수 없는 것은 턴 사이에서 버려집니다.

Responses API는 바로 그 간극을 염두에 두고 설계되었습니다. 추론은 반환된 목록에서 일급 항목이며, 암호화된 상태로 반환되어 다음 턴에 다시 전달될 수 있으므로 모델은 자신의 사고 과정을 재구성하지 않고 그대로 이어서 진행합니다.

위 거부가 발생하는 이유

함수 도구 호출은 왕복 과정입니다. 모델이 도구를 요청하고, 여러분의 코드가 응답하고, 모델이 이어서 진행합니다. Chat Completions에는 이 왕복 동안 추론 내용을 보관할 곳이 없으므로, 이어지는 처리는 추론 없이 조용히 재개됩니다. 모델은 이미 비용을 지불한 사고 과정을 다시 수행해야 하고, 그 결과도 달라질 가능성이 큽니다.

그래서 제공자는 조용히 품질을 떨어뜨리는 대신 이 조합을 거부합니다. 오류 메시지는 모델의 한계가 아니라, 이 모델이 만들어내는 결과를 담을 자리가 없음을 구형 API가 인정하는 것입니다.

기능들이 서로 다른 방향을 가리킵니다

모든 기능이 같은 엔드포인트를 선호한다면 라우트는 아무도 신경 쓸 필요 없는 구현 세부 사항일 것입니다. 하지만 그렇지 않습니다.

도구와 웹 검색에는 Responses API가 필요합니다

도구 채널을 통한 구조화된 출력은 Chat Completions가 추론 모델에서 거부하는 바로 그 조합이며, 제공자가 호스팅하는 웹 검색 도구는 그곳에서만 허용됩니다.

바이너리 오디오는 Chat Completions에서만 동작합니다

원시 오디오 바이트 첨부는 Responses API 경로가 지원하지 않으므로, 오디오를 처리할 수 있는 모델은 더 오래된 엔드포인트를 통해서만 사용할 수 있습니다.

하나의 모델, 두 개의 기능, 서로 다른 두 엔드포인트. 두 경우 모두에 대해 정직한 단일 true/false 값은 존재하지 않습니다. Entity Enricher가 라우트별로 기능 맵을 기록하는 이유이며, 서로 다른 두 라우트에 존재하는 두 기능이 필요한 실행을 조용히 하나를 누락시키는 대신 명시적으로 거부하는 이유입니다.

Entity Enricher가 라우트를 측정하는 방식

기능 프로브는 사람이 직접 작성한 가상의 요청을 보내지 않습니다. 테스트 대상 기능을 강제로 켠 채 실제 에이전트 경로, 즉 보강 실행이 거치는 것과 동일한 코드를 실행하고, 제공자의 응답으로 판정합니다. 따라서 측정되는 것은 API가 이론적으로 허용할 수 있는 것이 아니라 애플리케이션이 실제로 할 수 있는 것입니다.

구조화된 출력 채널, 비전, PDF, 오디오, 웹 검색, 추론 및 요청별 강도 제어에 이르는 전체 단계는 라우터가 선택할 수 있는 라우트마다 한 번씩 실행됩니다. 거의 모든 제공업체는 라우트가 하나뿐이어서 프로브 비용은 이전과 동일하며, 실제로 두 가지 경로로 호출할 수 있는 OpenAI 형태의 제공업체만 두 번 측정됩니다.

첫 일반 텍스트 호출에 응답하지 않는 라우트는 아예 측정되지 않으며, 프로브를 거친 모델은 응답한 라우트로만 라우팅됩니다. 선택 시점에도, 실행이 실패했을 때도 다른 엔드포인트로의 폴백은 없습니다. 어떤 라우트도 응답하지 않는 모델은 사용이 중단되며, 라우트에 구조화된 출력 채널이 하나도 없는 모델도 마찬가지입니다. 텍스트는 결코 폴백이 될 수 없으므로 그런 모델은 단 한 건의 보강도 처리할 수 없습니다. 이후 프로브가 채널을 입증해야만 다시 복귀합니다. 실행이 실패했다는 이유로 기능이 변경되는 일은 없습니다. 기능을 측정하는 것은 오직 프로브뿐입니다.

예

요청이 수락되었고 모델이 예상한 형태의 응답을 생성했습니다.

해당 라우트에 대해 측정된 true로 기록되며, 수집된 모든 주장보다 우선합니다.

아니요

제공업체가 해당 기능을 명시적으로 거부했거나, 클라이언트가 요청 생성 자체를 거부했습니다.

false를 기록할 수 있는 유일한 결과입니다. 거부 역시 무료이며, 절대 과금되지 않습니다.

알 수 없음

그 밖의 모든 경우: 요청 한도 초과, 접근 등급 부족, 시간 초과, 공급자 5xx, 인식되지 않는 오류.

아무것도 기록되지 않으며, 다음 프로브에서 판정할 수 있습니다.

기본값이 “no”가 아니라 항상 “unknown”인 이유

두 가지 오류의 비용은 같지 않습니다. 잘못된 unknown은 재검사 한 번의 비용이면 됩니다. 해당 기능을 나중에 다시 측정하면 그만입니다. 잘못된 no는 조용하고 영구적입니다. 모델을 모든 곳에서 격하시켜 선택기와 라우팅 결정에서 제외하지만, 그 이유는 아무도 알 수 없습니다. 따라서 인식되지 않은 실패는 아무것도 증명하지 못하며, 아무것도 증명하지 못한 것으로 기록됩니다.

수락되었다고 해서 이해한 것은 아닙니다

HTTP 200은 요청이 수락되었음을 증명합니다. 모델이 실제로 첨부 파일을 읽었다는 증명은 아닙니다. 공급자는 이미지를 아무 문제 없이 받아들인 뒤, 그것을 전혀 보지 않는 모델에 넘길 수도 있습니다. 그래서 페이로드를 보내는 모든 프로브는 그 답을 검증할 수 있는 페이로드를 사용합니다:

기능전송된 페이로드제기된 질문
비전단색 빨간 이미지“어떤 색이 주를 이루나요?”
PDF 입력단어가 정확히 하나만 들어 있는 PDF“문서에 어떤 단어가 있나요?”
오디오 입력셀 수 있는 개수의 톤이 담긴 오디오 파일“개별 신호음이 몇 번인가요?”

의도적으로 분리된 두 개의 결과

응답 내용은 판정 옆에 기록될 뿐 기능 플래그를 뒤집지는 않습니다. 빨간 사각형을 잘못 읽은 소형 모델도 여전히 비전을 지원합니다. 전송은 성공했고 모달리티도 전달되었으며, 단지 모델의 성능이 약했을 뿐입니다. “할 수 없음”과 “잘하지 못함”을 혼동하면 단어 하나가 틀렸다는 이유로 정상 작동하는 기능이 조용히 삭제됩니다. 둘을 구분하면 두 가지를 동시에 알 수 있습니다.

주장과 측정값

LiteLLM이나 PricePerToken 같은 공개 모델 카탈로그는 기능을 엔드포인트 정보 없이 모델에 대한 단순한 사실로 표기합니다. 이는 부주의해서가 아니라 그런 필드 자체가 없기 때문입니다. 하지만 그 결과, 일반적으로는 전적으로 맞는 주장이 실제 실행에 사용되는 엔드포인트에서는 틀릴 수 있습니다.

스크래핑으로 수집한 주장

“이 모델은 도구 호출을 지원합니다.” 어딘가에서는 사실입니다. 어디인지는 말해 주지 않습니다. 아직 아무도 프로브하지 않은 모델의 출발점으로는 유용합니다.

측정값

“이 엔드포인트에서 이 모델은 이 시점에 도구 호출을 수락했습니다.” 라우트를 명시하므로, 실행이 실제로 사용할 라우트와 비교할 수 있습니다.

라우트를 명시하는 것은 시간이 지나도 측정값의 정직성을 유지하는 방법이기도 합니다. 모델이 더 이상 사용하지 않는 엔드포인트에서 내려진 판정은 주장보다 나은 근거가 아니라, 다른 대상에 대한 근거일 뿐입니다. 라우트가 함께 기록되지 않으면 오래된 측정값과 최신 측정값을 구분할 수 없고, 엉뚱한 엔드포인트에 대해 카탈로그보다 우선시됩니다. 라우트가 기록되어 있으면 그 측정값은 단순히 적용되지 않으며, 올바른 엔드포인트에서 측정값이 나와 대체할 때까지 해당 주장이 유효합니다.

제품에서 확인하는 방법

앱 내부의 모델 카탈로그와 공개 모델 카탈로그 모두 필터 옆에 라우트 선택기가 있습니다. 이 선택기는 각 행의 기능 아이콘이 어떤 라우트를 기준으로 답하는지를 바꿉니다.

서비스 라우트(기본값)

각 행은 해당 모델이 실제로 서비스되는 엔드포인트를 기준으로 답합니다. 이 보기는 보강을 실행할 때 얻게 되는 결과와 일치하므로, 특정 엔드포인트를 조사하는 경우가 아니라면 이 보기를 확인하세요.

이름이 명시된 라우트

전체 표를 하나의 엔드포인트에 고정하면 아이콘은 해당 엔드포인트만을 기준으로 표시됩니다. 엔드포인트를 전환할 때 기능이 나타나거나 사라지는 것을 확인하고, 두 모델을 동일한 조건에서 비교하는 방법입니다.

도달 가능한 라우트가 하나뿐인 모델에는 선택기가 아예 표시되지 않습니다. 선택할 것이 없고, 아이콘이 이미 그 유일한 엔드포인트에 대한 답을 보여 주기 때문입니다. 선택기는 모호함이 실제로 존재할 때만 나타납니다.

이것이 의미하는 바

대부분의 경우 아무것도 하지 않아도 되며, 그것이 핵심입니다. 라우트를 직접 고르는 일은 없습니다. 모델을 선택하고 실행 내용을 설명하면, 라우터가 그 실행에 필요한 것을 처리할 수 있는 엔드포인트를 선택합니다. 도구와 웹 검색은 이를 허용하는 곳으로, 오디오 첨부 파일은 오디오를 처리하는 곳으로 전달됩니다.

실제로 마주치게 되는 유일한 경우는 진짜 충돌입니다. 예를 들어 동일한 OpenAI 모델에 웹 검색을 요청하면서 오디오 파일을 첨부하는 경우인데, 두 가지를 함께 처리하는 엔드포인트가 없기 때문입니다. 이때 해당 실행은 둘 중 하나를 조용히 누락한 채 진행되지 않고, 두 기능의 이름과 각 라우트가 처리할 수 있는 항목을 밝히며 명시적으로 거부됩니다. 요구 사항 중 하나를 빼거나 두 가지를 모두 지원하는 모델을 선택하면 실행됩니다.

기능 아이콘이 예상과 다르게 보인다면, 그 설명은 라우트 선택기에 있습니다. 거의 언제나 질문을 어디에서 했는지에 따라 답이 달라지는 모델을 보고 있는 것입니다.