콘텐츠로 이동

Reasoning Effort 파라미터

이 문서는 Continuum Router가 다양한 LLM 백엔드에서 reasoning_effort 파라미터를 어떻게 처리하는지 설명합니다. 토큰 예산 변환 및 지원되는 effort 레벨을 포함합니다.

개요

reasoning_effort 파라미터는 모델이 응답을 생성하기 전에 추론에 사용하는 계산 노력의 양을 제어합니다. 각 백엔드는 이 기능을 다르게 구현합니다:

  • OpenAI: O-series 및 GPT-5.x reasoning 모델에 대한 네이티브 reasoning_effort 파라미터
  • Anthropic: 확장 사고(extended thinking)를 지원하는 Claude 모델의 thinking.budget_tokens로 변환, 또는 auto effort에 대해 {"type": "adaptive"}로 변환
  • Gemini: OpenAI 호환 엔드포인트를 통한 thinking 모델에 대한 네이티브 reasoning_effort
  • 기타 백엔드: 패스스루 (변환 없음)

파라미터 형식

Continuum Router는 두 가지 입력 형식을 지원하며 내부적으로 정규화됩니다:

평면 형식 (Chat Completions API)

{
  "model": "o3-mini",
  "reasoning_effort": "high",
  "messages": [...]
}

중첩 형식 (Responses API)

{
  "model": "o3-mini",
  "reasoning": {
    "effort": "high"
  },
  "input": "..."
}

두 형식 모두 처리 전에 평면 reasoning_effort 형식으로 자동 정규화됩니다. 둘 다 존재하는 경우 평면 형식이 우선합니다.

GPT-5.6 네이티브 Responses 제어

백엔드가 네이티브 Responses API를 제공하면 Continuum Router는 새로운 GPT-5.6 요청 표면을 그대로 보존합니다:

  • reasoning.mode(standard 또는 pro)와 reasoning.context(auto, current_turn, all_turns)
  • text.verbosity, safety_identifier, include
  • prompt_cache_key, prompt_cache_options, 그리고 input_text·input_image·input_file의 명시적 prompt_cache_breakpoint
  • Programmatic Tool Calling 도구와 재생 항목(program, program_output, caller가 연결된 함수 출력)
  • 베타 Multi-agent 설정과 출력 항목
{
  "model": "gpt-5.6-sol",
  "input": "조사를 계속하세요.",
  "previous_response_id": "resp_123",
  "reasoning": {
    "mode": "pro",
    "effort": "max",
    "context": "all_turns"
  },
  "text": {
    "verbosity": "high"
  },
  "safety_identifier": "usr_privacy_preserving_hash"
}

네이티브 previous_response_id는 변경하지 않고 전달하므로 OpenAI가 저장된 reasoning을 재사용할 수 있습니다. 변환 백엔드는 계속 라우터의 로컬 세션 확장을 사용합니다. 네이티브 전용 필드가 있는 요청이 변환 전략으로 라우팅되면 필드를 조용히 버리지 않고 unsupported_request_parameter 오류로 실패합니다. 상태 기반 요청과 네이티브 전용 요청은 라우터의 로컬 응답 캐시를 우회합니다.

Multi-agent raw HTTP 클라이언트는 OpenAI-Beta: responses_multi_agent=v1을 보내야 합니다. 라우터는 클라이언트 자격 증명과 전송 헤더는 계속 필터링하면서 이 헤더는 업스트림으로 전달합니다.

토큰 예산 직접 지정

고급 사용 사례의 경우, reasoning_effort 레벨 대신 토큰 예산을 직접 지정할 수 있습니다:

Anthropic: thinking 파라미터 직접 사용

{
  "model": "claude-sonnet-4-5-20250929",
  "thinking": {
    "type": "enabled",
    "budget_tokens": 16000
  },
  "messages": [...]
}

적응형 사고(Adaptive Thinking)의 경우 (모델이 사고의 시점과 정도를 결정):

{
  "model": "claude-opus-4-6",
  "thinking": {
    "type": "adaptive"
  },
  "messages": [...]
}

Gemini: extra_body를 통한 thinking_budget 직접 지정

{
  "model": "gemini-2.5-pro",
  "extra_body": {
    "google": {
      "thinking_config": {
        "thinking_budget": 10000,
        "include_thoughts": true
      }
    }
  },
  "messages": [...]
}

우선순위

reasoning_effort와 직접 토큰 지정이 모두 있는 경우, Anthropic에서는 직접 지정(thinking 파라미터)이 우선합니다. Gemini의 경우 둘 다 공존할 수 있지만 extra_body의 thinking_budget이 세밀한 제어에 사용됩니다.


파생된 Reasoning Effort 정규화

Anthropic Messages 인그레스(POST /anthropic/v1/messages)는 요청을 OpenAI 와이어 백엔드로 라우팅할 때 클라이언트의 thinking과 output_config.effort에서 reasoning_effort를 도출합니다. 도출된 레벨은 요청을 보내기 전에 선택된 대상이 허용하는 값으로 맞춰지며, Chat Completions 와이어(reasoning_effort)와 Responses 와이어(reasoning.effort) 모두에 적용됩니다. /v1/chat/completions로 전송되는 네이티브 Anthropic thinking 요청의 디스패치 측 변환에도 같은 정규화가 동작합니다.

어휘는 다음 순서로 조회하며, 먼저 답하는 소스가 사용됩니다.

  1. 백엔드 선언: backends[].model_configs[].metadata.reasoning_efforts. 모델을 실제로 서빙하는 엔진에 대한 운영자의 선언입니다.
  2. 모델 메타데이터: model-metadata.yaml 또는 model-metadata.d/ 드롭인의 metadata.reasoning_efforts입니다.
  3. 백엔드 타입 기본값:
    • openai와 azure는 내장 OpenAI reasoning 패밀리 테이블을 사용합니다. 테이블에 없는 모델은 도출된 값을 그대로 유지합니다.
    • generic, gemini, vllm, ollama, llamacpp, mlxcel, lmstudio, sglang, tensorrtllm은 low, medium, high를 사용하며, high와 xhigh는 모두 high로 전송합니다.
  4. Passthrough: 대상을 설명하는 소스가 없으면 도출된 값을 수정하지 않고 전달합니다.

정규화로 값이 바뀌면 라우터는 디버그 레벨로 vocabulary_source 필드에 backend_model_config, model_metadata, backend_type_default 중 하나를 기록하며, backend, model, effort_field, 정규화된 reasoning_effort도 함께 남깁니다. Passthrough로 처리된 요청도 같은 필드를 vocabulary_source=passthrough로 기록합니다.

정규화는 /v1/chat/completions에서 클라이언트가 직접 보낸 reasoning_effort를 다시 쓰지 않습니다. Anthropic 인그레스와 디스패치 측 변환에서 라우터가 도출한 값에만 적용됩니다.


백엔드별 동작

OpenAI 백엔드

OpenAI 모델은 reasoning_effort 파라미터를 네이티브로 지원합니다. 라우터는 값을 OpenAI API에 직접 전달합니다.

지원되는 Effort 레벨

Effort 레벨 지원 모델 설명
none 이를 제공하는 GPT-5.x 모델 추론 비활성화
minimal 원래 GPT-5 계열 최소 추론 effort
low O-series, GPT-5.x reasoning 최소 추론, 빠른 응답
medium O-series, GPT-5.x reasoning 균형 잡힌 추론 노력
high O-series, GPT-5.x reasoning 깊은 추론, 느린 응답
xhigh GPT-5.2부터 GPT-5.6 reasoning 티어, GPT-6 Astra 매우 높은 추론 노력
max GPT-5.6 계열과 GPT-6 Astra 최대 추론 노력

reasoning_effort를 지원하는 모델

O-series 모델 (low, medium, high 지원):

  • o1, o1-mini, o1-preview
  • o3, o3-mini, o3-pro
  • o4-mini

GPT-6 모델:

  • gpt-6-astra (low, medium, high, xhigh, max). none은 OpenAI가 400으로 거절하므로 추론을 끌 방법이 아예 없는 첫 OpenAI reasoning 모델입니다.
  • gpt-6-sol, gpt-6-luna (none부터 max까지, 기본값 medium). Astra와 달리 none을 받습니다.

GPT-5.x reasoning 모델 (세대별 정확한 레벨은 다름):

  • gpt-5.6, gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna (none부터 max)
  • gpt-5.2부터 gpt-5.5 reasoning 티어 (none, low, medium, high, xhigh)
  • gpt-5.1 reasoning 티어 (none, low, medium, high)
  • gpt-5, gpt-5-mini, gpt-5-nano (minimal, low, medium, high)
  • gpt-5-pro (high만 지원, Responses API 전용)
  • gpt-5.2-pro, gpt-5.4-pro, gpt-5.5-pro (medium, high, xhigh, Responses API 전용)

정확한 모델별 검증

스트리밍과 비스트리밍 Chat Completions 요청은 같은 모델별 검증을 사용합니다. GPT-5 + xhigh, GPT-5.5 + max, OpenAI 모델 + auto처럼 지원하지 않는 조합은 400 invalid_request_error로 거절합니다. 라우터는 요청된 OpenAI effort를 조용히 다른 값으로 바꾸지 않습니다.

type: openai로 선언된 자체 호스팅 엔진

알려진 OpenAI reasoning 계열이 아닌 모델에 대해서는, 백엔드가 OpenAI 클라우드(api.openai.com)이거나 type: azure일 때만 라우터가 reasoning과 reasoning_effort를 제거합니다. 두 곳은 해당 필드를 거부하기 때문입니다. 그 외 URL의 type: openai 백엔드(vLLM, SGLang, llama.cpp 등)는 스트리밍과 비스트리밍 모두에서 클라이언트 값을 그대로 받습니다. 제거가 일어나면 info 수준으로 로그를 남깁니다.

함수 도구와 reasoning effort 조합

OpenAI는 일부 모델에서 요청에 함수 tools가 있고 실제 적용되는 reasoning effort가 none이 아니면 /v1/chat/completions를 거절합니다.

400 Function tools with reasoning_effort are not supported for gpt-5.6-sol in
    /v1/chat/completions. To use function tools, use /v1/responses or set
    reasoning_effort to 'none'.

이 제약은 계열 단위가 아니라 모델 단위이며 영향을 받는 두 세대의 규칙도 서로 다릅니다.

모델 tools + effort 생략 tools + low/medium/high tools + none tools 없음
gpt-6-astra 거절 거절 모델이 거절 허용
gpt-6-sol, gpt-6-luna 거절 거절 허용 허용
gpt-5.6-sol (별칭 gpt-5.6), gpt-5.6-terra, gpt-5.6-luna 거절 거절 허용 허용
gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.4-nano 허용 거절 허용 허용
gpt-5.2 이하, O-시리즈 허용 허용 허용 허용

gpt-5.6 행이 다른 이유는 이 계열의 업스트림 기본 effort가 medium이기 때문입니다. 필드를 생략해도 reasoning 없음을 뜻하지 않으므로 생략한 경우에도 거절이 발생합니다.

GPT-6 Astra는 한 단계 더 엄격합니다. tools 유무와 관계없이 reasoning_effort: "none" 자체를 거절하므로 OpenAI 오류 메시지가 안내하는 두 번째 해결책이 이 모델에는 존재하지 않습니다. 따라서 함수 도구를 실은 Chat Completions 요청은 전부 우회 대상이며, 항목의 chat_completions_default_reasoning_effort: "medium"은 OpenAI가 생략 시 기본 effort를 공개하지 않아 넣어 둔 비-none 자리표시자입니다.

GPT-6 Sol과 Luna는 gpt-5.6 계열과 같이 동작합니다. none을 허용하고 OpenAI 문서상 Chat Completions에서는 none일 때만 함수 도구를 받으며 기본 effort가 medium이므로 effort를 생략한 요청도 우회 대상입니다.

위 표에서 GPT-6 행을 제외한 모든 셀은 2026-09-03에 라이브 API로 측정한 결과이며, GPT-6 행은 OpenAI 모델 문서와 거절 메시지에서 확인한 값입니다. 구분 기준이 이름 접두사를 따르지 않으므로(GPT-5.4 세대는 mini·nano까지 모두 영향받지만 GPT-5.2 이하는 영향 없음) 계열 검사가 아니라 각 모델 항목의 데이터로 규칙을 관리합니다.

라우터는 거절되는 요청만 골라 우회합니다. 해석된 모델 메타데이터에 chat_completions_tools_require_none_reasoning이 있고 요청에 비어 있지 않은 tools 배열이 있으며 실제 적용될 effort가 거절 대상이면, 요청을 /v1/responses로 보내고 응답을 다시 Chat Completions 형태(스트리밍 포함)로 변환합니다. 요청한 effort는 reasoning.effort로 전달되고 생략한 effort는 생략된 채로 유지되며, 클라이언트는 일반 chat.completion 또는 chat.completion.chunk 스트림과 tool call을 그대로 받습니다.

그 밖의 요청(reasoning_effort: "none" + tools, tools가 없는 요청, 영향을 받지 않는 모든 모델)은 모두 /v1/chat/completions로 직행하므로 비용과 지연이 달라지지 않습니다. 검증이 먼저 실행되므로 모델이 지원하지 않는 effort는 우회 이전에 라우터 자체의 400으로 거절됩니다. 라우터는 모델 동작이 조용히 바뀌지 않도록 요청된 effort를 none으로 덮어쓰지 않습니다.

동작을 결정하는 메타데이터 키는 responses_only 옆에 놓이는 두 개입니다.

키 타입 의미
chat_completions_tools_require_none_reasoning bool (기본값 false) 이 모델은 /v1/chat/completions에서 함수 도구와 none이 아닌 effort의 조합을 업스트림이 거절합니다.
chat_completions_default_reasoning_effort string (선택) 요청이 reasoning_effort를 생략했을 때 업스트림이 적용하는 effort입니다. gpt-5.6과 GPT-6 항목에 medium으로 지정해 생략한 경우에도 우회하도록 하고 gpt-5.4와 gpt-5.5에는 지정하지 않습니다. 라우터가 이 값을 전송하지는 않습니다.

두 키는 영향을 받는 항목(gpt-6-astra, gpt-6-sol, gpt-6-luna, gpt-5.6-sol과 별칭 gpt-5.6, gpt-5.6-terra, gpt-5.6-luna, gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.4-nano)에 내장 OpenAI 레지스트리와 model-metadata.yaml 양쪽에 이미 설정되어 있습니다. 일반 메타데이터이므로 OpenAI가 제약을 해제하면 라우터 릴리스를 기다리지 않고 model-metadata.d/ 드롭인으로 해제할 수 있습니다.

# model-metadata.d/90-lift-tools-reasoning-bridge.yaml
models:
  - id: gpt-5.6-sol
    metadata:
      chat_completions_tools_require_none_reasoning: false

운영자는 responses_bridge_total 메트릭에서 이 구분을 볼 수 있습니다. reason 레이블이 tools_with_reasoning과 무조건 우회되는 responses_only_model을 나눕니다.

responses_only: true와의 상호작용

이 모델들 중 하나에 responses_only: true를 지정하면 tools가 없는 일반 대화까지 포함해 그 모델의 모든 요청이 /v1/responses를 거치게 됩니다. continuum-router config validate는 backends[].model_configs[]에 이 설정이 걸려 있으면 chat_completions_tools_require_none_reasoning을 가리키는 경고를 출력합니다.

reasoning_effort를 지원하지 않는 모델

다음 모델들은 reasoning 파라미터를 지원하지 않습니다 (파라미터가 제거됨):

  • GPT-4o, GPT-4o-mini, GPT-4-turbo, GPT-4
  • GPT-5.2-chat-latest, GPT-5.2-instant (non-thinking 변형)
  • GPT-3.5-turbo
  • 임베딩 모델, 이미지 모델

Anthropic 백엔드 (Claude)

Anthropic Claude 모델은 모델 세대에 따라 다른 메커니즘을 사용합니다:

  • Claude Fable 5와 Mythos 5 (Mythos급; Mythos 5는 Fable 5에서 안전장치를 해제한 한정 출시 버전): Opus 4.8과 동일하게 적응형 사고({"type": "adaptive"})와 output_config.effort를 사용합니다(레거시 budget_tokens는 HTTP 400 거부, temperature/top_p/top_k 자동 제거, max effort 지원). 또한 명시적 thinking.type == "disabled"도 HTTP 400으로 거부되므로 라우터는 thinking 파라미터를 전달하지 않고 생략합니다.
  • Claude Opus 5.5 (claude-opus-5-5): 적응형 사고와 output_config.effort(low~max, 기본값은 Opus 5보다 한 단계 낮은 medium)를 사용하며 thinking이 항상 켜져 있습니다. 명시적 thinking.type: "disabled"와 레거시 budget_tokens 형식 모두 모든 effort에서 HTTP 400으로 거부되므로 비활성 thinking 설정은 생략하고 enabled는 adaptive로 정규화합니다. 강제 도구 호출은 Fable 5.1과 동일하게 제거되었습니다(아래 참고).
  • Claude Sonnet 5.5 (claude-sonnet-5-5): 적응형 사고와 output_config.effort(low~max)를 사용하며 xhigh는 max로 매핑됩니다. 명시적 thinking.type: "disabled"와 강제 도구 호출(tool_choice의 any 또는 tool)을 거부하므로 라우터는 비활성 thinking 설정을 생략하고 강제 선택은 전달 전에 거부합니다.
  • Claude 4.8+ 모델 (Opus 4.8): 적응형 사고({"type": "adaptive"})와 output_config.effort로 사고 깊이를 제어합니다. 레거시 thinking.type: "enabled" + budget_tokens 형식은 HTTP 400으로 거부되며, temperature, top_p, top_k는 라우터가 자동으로 제거합니다. Effort 기본값은 high입니다.
  • Claude Haiku 5.5 (claude-haiku-5-5, -latest 별칭 없음): 기본으로 켜져 있는 적응형 사고({"type": "adaptive"})와 output_config.effort(low~max, Anthropic 기본값은 medium)를 사용합니다. Haiku 5.5는 레거시 thinking.type: "enabled" + budget_tokens 형식과 temperature, top_p, top_k를 HTTP 400으로 거부합니다. 따라서 라우터가 전자는 적응형으로 변환하고, 후자는 제거합니다. xhigh는 max로 매핑되며, 명시적 thinking.type: "disabled"는 허용되므로 그대로 전달합니다.
  • Claude Haiku 4.5 (claude-haiku-4-5-*): Sonnet 4.x처럼 확장 사고에 thinking.budget_tokens를 사용합니다. effort 파라미터는 지원하지 않습니다.
  • Claude Sonnet 5 (claude-sonnet-5-*, 별칭 claude-sonnet-5-latest): 적응형 사고({"type": "adaptive"})와 output_config.effort를 사용합니다. 레거시 thinking.type: "enabled" + budget_tokens 형식은 HTTP 400으로 거부되며 temperature, top_p, top_k는 자동으로 제거됩니다. xhigh는 high로 다운그레이드되며(max는 Opus/Mythos급 전용) 기본값은 high입니다.
  • Claude 4.6+ 적응형 모델 (Opus 4.6, Sonnet 4.6, Opus 4.7): 적응형 사고({"type": "adaptive"})와 output_config.effort로 사고 깊이를 제어합니다. Claude Opus 4.7은 이 API가 필수이며 레거시 budget_tokens 형식을 보내면 HTTP 400 오류가 발생합니다.
  • 4.6 이전 모델 (Opus 4.5, Sonnet 4 등): 확장 사고에 thinking.budget_tokens를 사용합니다.

변환 테이블: Claude 4.6+ 모델 (적응형 사고)

Claude 4.6+ 적응형 모델(claude-opus-4-6-*, claude-sonnet-4-6-*, claude-opus-4-7-*, claude-opus-4-8-*, claude-sonnet-5-*, claude-haiku-5-5, claude-fable-5-*, claude-mythos-5-*)은 budget_tokens 대신 output_config.effort를 사용합니다:

reasoning_effort thinking output_config.effort 설명
none 비활성화 (생략) Thinking 비활성화
minimal {"type": "adaptive"} "low" Anthropic API에 minimal 없으므로 low로 매핑
auto {"type": "adaptive"} (생략) 모델이 기본 effort(high) 사용
low {"type": "adaptive"} "low" 낮은 사고 깊이
medium {"type": "adaptive"} "medium" 중간 사고 깊이
high {"type": "adaptive"} "high" 높은 사고 깊이
xhigh (Opus 4.6+, Sonnet 5.5+, Haiku 5.5, Fable 5, Mythos 5) {"type": "adaptive"} "max" 최대 사고 깊이
xhigh (Sonnet 4.6, Sonnet 5) {"type": "adaptive"} "high" 다운그레이드 (max는 Opus/Mythos급 전용)

변환 테이블: 4.6 이전 Claude 모델 (Budget Tokens)

4.6 이전 모델은 thinking.budget_tokens를 사용합니다:

reasoning_effort Anthropic thinking 설명
none 비활성화 Thinking 기능 비활성화
minimal {"type": "enabled", "budget_tokens": 1024} 최소 허용 예산
auto {"type": "adaptive"} 모델이 사고의 시점과 정도를 결정
low {"type": "enabled", "budget_tokens": 4096} 가벼운 추론
medium {"type": "enabled", "budget_tokens": 10240} 중간 추론
high {"type": "enabled", "budget_tokens": 32768} 깊은 추론
xhigh {"type": "enabled", "budget_tokens": 32768} high 예산으로 폴백

변환 예시: Claude 4.6+ (적응형 사고 + Effort)

입력 (OpenAI 형식):

{
  "model": "claude-opus-4-6",
  "reasoning_effort": "high",
  "messages": [...]
}

변환됨 (Anthropic 형식):

{
  "model": "claude-opus-4-6",
  "thinking": {
    "type": "adaptive"
  },
  "output_config": {
    "effort": "high"
  },
  "messages": [...]
}

Opus 4.6 또는 Opus 4.7에서 xhigh를 사용하면 output_config.effort가 max로 설정됩니다:

{
  "model": "claude-opus-4-6",
  "thinking": {"type": "adaptive"},
  "output_config": {"effort": "max"},
  "messages": [...]
}

변환 예시: 4.6 이전 Claude (Budget Tokens)

입력 (OpenAI 형식):

{
  "model": "claude-sonnet-4-5-20250929",
  "reasoning_effort": "high",
  "messages": [...]
}

변환됨 (Anthropic 형식):

{
  "model": "claude-sonnet-4-5-20250929",
  "thinking": {
    "type": "enabled",
    "budget_tokens": 32768
  },
  "messages": [...]
}

적응형 사고 (Auto)

reasoning_effort가 auto로 설정되면 라우터는 output_config.effort 없이 {"type": "adaptive"}를 생성합니다. 그러면 Anthropic이 기본 effort 레벨(현재 high)을 사용하고 모델이 언제, 얼마나 추론할지를 동적으로 결정합니다.

입력 (OpenAI 형식):

{
  "model": "claude-opus-4-6",
  "reasoning_effort": "auto",
  "messages": [...]
}

변환됨 (Anthropic 형식):

{
  "model": "claude-opus-4-6",
  "thinking": {
    "type": "adaptive"
  },
  "messages": [...]
}

output_config 직접 전달 (Pass-Through)

요청에 이미 명시적인 thinking 및 output_config 매개변수가 포함되어 있으면 변환 없이 직접 전달됩니다:

{
  "model": "claude-opus-4-6",
  "thinking": {"type": "adaptive"},
  "output_config": {"effort": "medium"},
  "messages": [...]
}

적응형 사고 가용성

output_config.effort 적응형 사고는 Claude 4.6+ 적응형 모델(claude-opus-4-6-*, claude-sonnet-4-6-*, claude-opus-4-7-*, claude-opus-4-8-*, claude-sonnet-5-*, claude-haiku-5-5)과 Mythos급 계열(claude-fable-5-*, claude-mythos-5-*)에서 지원합니다. Claude Opus 4.7/4.8, Sonnet 5, Haiku 5.5, Mythos급 모델은 이 API가 필수이므로 라우터가 레거시 thinking.type == "enabled" 요청을 정규화해 HTTP 400을 방지하며, 4.6 이전 모델은 budget_tokens를 사용합니다.

max Effort 레벨

output_config.effort의 max 레벨은 Opus 4.6 이상, Sonnet 5.5 이상, Claude Haiku 5.5, Mythos급 계열(Fable 5, Mythos 5)에서 사용할 수 있습니다. Sonnet 5 또는 Sonnet 4.6에 xhigh가 요청되면 라우터가 자동으로 high로 다운그레이드하고 info 레벨 로그를 남깁니다.

Claude Opus 4.7/4.8, Sonnet 5, Haiku 5.5 및 Mythos급 샘플링 파라미터 지원 중단

Anthropic은 Claude Opus 4.7, Opus 4.8, Sonnet 5, Haiku 5.5, Fable 5, Mythos 5에 대해 temperature, top_p, top_k를 지원하지 않습니다. 라우터는 claude-opus-4-7-*, claude-opus-4-8-*, claude-sonnet-5-*, claude-haiku-5-5, claude-fable-5-*, claude-mythos-5-* 모델로 전달하기 전에 세 파라미터를 자동으로 제거해 HTTP 400 오류를 방지합니다.

anthropic-version: 2026-10-21과 샘플링 파라미터

anthropic-version이 2026-10-21 이상이면 모든 Claude 모델이 temperature, top_p, top_k를 HTTP 400으로 거부합니다. 이 값은 같은 날 출시된 Anthropic SDK 메이저 버전의 기본값입니다. 네이티브 /anthropic/v1/messages 인그레스는 클라이언트의 anthropic-version을 네이티브 Anthropic 백엔드로 그대로 전달하고, 클라이언트가 보내지 않으면 백엔드의 anthropic_version을 보냅니다. 라우터는 이런 버전으로 보내는 요청에 샘플링 값을 쓰지 않습니다.

  • 정책 값: 샘플링 기본값과 덮어쓰기 값은 계속 라우터 자체 HTTP 400으로 거부합니다. 네이티브 Messages 요청의 모든 후보 백엔드가 클라이언트 샘플링 값을 제거하면, 제한 정책은 해당 필드가 없는 것으로 처리합니다. 서로 다른 제공자가 후보에 섞여 있으면 기존 호환성 검사를 유지하므로, 지원하지 않는 정책 대상 값은 거부됩니다.
  • 클라이언트 값: 네이티브 Messages는 해당 값을 지원하지 않는 Anthropic 홉마다 세 필드를 제거합니다. fallback과 Unix 소켓 경로에도 적용됩니다. 다른 제공자는 클라이언트 값을 유지하며, Bedrock 동작은 바뀌지 않습니다.
  • 변환된 요청: anthropic_version: "2026-10-21"로 설정한 백엔드는 OpenAI 및 Responses 요청을 세 필드 없이 받으며, 이 필드에 대한 정책 값도 같은 방식으로 거부됩니다.
  • 이전 버전: 2023-06-01이거나, 기본값 백엔드에서 anthropic-version 헤더가 없으면 정책 값이 기존대로 적용됩니다.

Mythos급 비활성 thinking 거부

Claude Fable 5, Mythos 5, Claude Opus 5.5 이상, Claude Sonnet 5.5 이상은 모든 effort 수준에서 명시적 thinking: {"type": "disabled"}를 HTTP 400으로 거부합니다. 클라이언트가 이 모델들에 비활성 thinking 설정을 보내면 라우터는 이를 전달하지 않고 thinking 파라미터를 생략합니다. Opus 4.8 이하와 Sonnet 5 이하는 명시적 비활성 thinking 설정을 그대로 허용하며, Opus 5는 effort high 이하에서만 허용합니다(아래 참고).

Claude Opus 5의 high 초과 effort + 비활성 thinking

Claude Opus 5는 output_config.effort가 high 이하일 때만 명시적 thinking: {"type": "disabled"} 설정을 허용합니다. xhigh 또는 max와 함께 보내면 Anthropic이 HTTP 400으로 거부합니다.

  • 인입 검증: 라우터는 업스트림 호출 전에 /v1/chat/completions(스트리밍 및 비스트리밍)와 /anthropic/v1/messages에서 이 조합을 HTTP 400으로 거부합니다. Responses-Anthropic 변환기도 조립된 페이로드에 동일한 가드를 적용하지만 /v1/responses는 thinking 없음을 reasoning.effort: "none"(thinking 파라미터 생략)으로만 표현합니다. 검증은 요청마다 실행되므로 대화 도중 effort만 높인 후속 턴도 감지합니다.
  • 비검사 표면: /anthropic/v1/messages/count_tokens는 토큰을 생성하거나 과금하지 않으므로 검사하지 않으며, Bedrock Converse(endpoint_type: converse)는 설계상 extra_body/additionalModelRequestFields를 그대로 전달합니다.
  • 자동 재작성 없음: 오류 본문은 두 가지 해결책(output_config.effort를 high 이하로 낮추거나 비활성 thinking 설정을 제거해 적응형 사고 사용)을 모두 안내합니다. thinking을 끈 Opus 5에는 도구 호출을 구조화된 tool_use 블록 대신 평문으로 출력하거나 <thinking> 태그가 응답에 노출되는 두 가지 알려진 실패 모드가 있으므로 라우터가 임의로 설정을 변경하지 않습니다.

Mythos급 5.1과 Opus 5.5의 강제 tool_choice 제거

Claude Fable 5.1, Mythos 5.1, Opus 5.5, Sonnet 5.5는 강제 도구 호출(tool_choice: {"type": "any"} 및 {"type": "tool", "name": ...})을 HTTP 400(tool_choice: type "tool" and "any" are not supported for this model.)으로 거부합니다. auto, none, disable_parallel_tool_use는 정상 동작하며 파싱한 계열 버전(Mythos급 >= 5.1, Opus >= 5.5, Sonnet >= 5.5)을 기준으로 검사합니다.

  • 인입 검증: 라우터는 업스트림 호출 전에 강제 호출을 표현할 수 있는 세 인입 경로인 /v1/chat/completions(스트리밍 및 비스트리밍, OpenAI의 "required"와 {"type": "function", ...}이 Anthropic의 any와 tool로 매핑되는 경로), /anthropic/v1/messages, Responses-Anthropic 변환기에서 모두 HTTP 400을 반환합니다.
  • 비검사 표면: /anthropic/v1/messages/count_tokens와 Bedrock Converse(additionalModelRequestFields)는 위와 동일한 이유로 검사하지 않습니다.
  • 자동 다운그레이드 없음: 오류 본문은 모델 이름과 클라이언트가 보낸 표기를 그대로 반환하며 Anthropic이 문서화한 해결책(tool_choice를 auto로 두고 지시문에 도구 명시, 도구 정의에 strict: true 설정, 또는 구조화된 출력 요청)을 안내합니다. 강제 선택을 auto로 임의 변경하면 모델이 평문으로 응답해 도구 호출 보장을 전제로 한 에이전트 루프가 깨질 수 있으므로 라우터는 이를 자동으로 낮추지 않습니다.

확장 사고를 지원하는 모델

확장 사고는 다음에서 지원됩니다:

  • Claude Fable 5 / Mythos 5 (적응형 사고 + effort; max 지원; 샘플링 파라미터 제거; 명시적 비활성 thinking 생략): claude-fable-5-*(별칭 claude-fable-5-latest), claude-mythos-5-*(별칭 claude-mythos-5-latest, 한정 출시)
  • Claude Sonnet 5.5 (적응형 사고 + effort; max 지원; 샘플링 파라미터 제거; 명시적 비활성 thinking 생략; 강제 도구 선택 거부): claude-sonnet-5-5
  • Claude Opus 4.8 (적응형 사고 + effort; 샘플링 파라미터 미지원; effort 기본값 high): claude-opus-4-8-*, 별칭 claude-opus-4-8-latest
  • Claude Sonnet 5 (적응형 사고 + effort; 샘플링 파라미터 제거; xhigh는 high로 다운그레이드; effort 기본값 high): claude-sonnet-5-*, 별칭 claude-sonnet-5-latest
  • Claude Opus 4.7 (적응형 사고 + effort; 샘플링 파라미터 지원 중단): claude-opus-4-7-*
  • Claude Haiku 5.5 (적응형 사고 + effort; max 지원; 샘플링 파라미터 제거; effort 기본값 medium): claude-haiku-5-5
  • Claude 4.6 계열 (적응형 사고 + effort): claude-opus-4-6-*, claude-sonnet-4-6-*
  • Claude Opus 모델 (budget tokens): claude-opus-4-*, claude-opus-4-5-*
  • Claude Sonnet 4 모델 (budget tokens): claude-sonnet-4-*, claude-sonnet-4-5-*
  • Claude Haiku 4.5 (budget tokens): claude-haiku-4-5-*

Temperature 제한

확장 사고가 활성화되면 Claude는 사용자 정의 temperature 설정을 지원하지 않습니다. 라우터는 thinking이 활성화되면 temperature 파라미터를 자동으로 제거합니다. Claude Opus 4.7, Opus 4.8, Haiku 5.5, Fable 5, Mythos 5의 경우 thinking 활성화 여부와 관계없이 temperature, top_p, top_k가 항상 제거됩니다.

4.6 이전 Claude의 xhigh 폴백

4.6 이전 Claude 모델에 xhigh가 요청되면 라우터가 자동으로 high (32,768 budget_tokens)로 다운그레이드합니다.

Anthropic 외부의 auto

auto effort 레벨은 Anthropic의 적응형 사고에 매핑됩니다. OpenAI에서는 유효한 effort가 아니므로 auto 요청을 거절합니다. Gemini는 공급자별 auto → medium 변환을 유지합니다.

폴백 홉에서의 역방향 변환

위 내용은 모두 OpenAI reasoning_effort를 Claude thinking 설정으로 바꾸는 정방향 변환을 설명합니다. 교차 공급자 폴백 홉에서는 역방향 변환이 필요할 수 있습니다. thinking이나 output_config가 포함된 요청이 OpenAI 와이어 백엔드로 폴백되면, 디스패치는 해당 설정을 대상 백엔드가 허용하는 reasoning_effort 값으로 먼저 변환한 뒤 Anthropic 고유 필드를 제거하여 추론 의도를 유지합니다.

이 역방향 변환에서 output_config.effort는 동일 수준으로 매핑되고(max는 대상 어휘에 있을 때 xhigh로 변환), budget_tokens는 공통 구간표를 따라 매핑됩니다. effort가 없는 적응형 사고와 비활성 thinking은 아무 값도 생성하지 않으며, 클라이언트가 직접 지정한 reasoning_effort가 항상 우선합니다. 전체 구간표와 대상별 어휘 규칙, 로컬 엔진 처리 방식은 모델 폴백을 참고하십시오.

Anthropic Messages API 인그레스(/anthropic/v1/messages)도 Chat Completions 변환과 responses_only 모델용 Responses API 변환 모두에서 동일한 함수를 통해 같은 구간표를 적용합니다. 따라서 budget_tokens 값은 요청이 /anthropic/v1/messages로 유입되었든 폴백 홉을 통해 OpenAI 와이어 백엔드로 전달되었든 라우터 전체에서 동일한 추론 수준으로 해석됩니다.


Gemini 백엔드

Gemini 모델은 OpenAI 호환 엔드포인트를 통해 reasoning_effort를 네이티브로 지원합니다. 라우터는 값을 검증하고 직접 전달합니다.

지원되는 Effort 레벨

Effort 레벨 지원 모델 설명
none rejects_reasoning_effort_none가 붙지 않은 모든 모델 Thinking 비활성화
minimal 모든 thinking 모델 최소 추론
low 모든 thinking 모델 가벼운 추론
medium 모든 thinking 모델 중간 추론
high 모든 thinking 모델 깊은 추론

none을 받는 모델

none은 모델 메타데이터가 업스트림의 거절을 명시하지 않는 한 Gemini로 그대로 전달됩니다. 거절은 deny list이며 model-metadata.yaml의 rejects_reasoning_effort_none입니다. 거절이 측정된 모델에 설정되어 출하됩니다.

  • gemini-3.6-flash
  • gemini-3.5-flash-lite
  • 모든 Gemini Pro 티어

그 외에는 라우터 빌드 이후에 나온 모델을 포함해 전부 전달되고 Gemini가 답하므로, 새 Gemini 마이너 버전이 나와도 라우터 릴리스를 기다리지 않고 none 지원이 유지됩니다.

지원 여부는 계열 접두사를 따르지 않습니다. 2026-09-10에 OpenAI 호환 엔드포인트로 카탈로그 id마다 reasoning_effort: "none" 요청을 한 번씩 보내 측정했습니다. 2.5 Flash, 2.5 Flash-Lite, 3 Flash, 3.1 Flash-Lite, 3.5 Flash, 3.7 Flash, 3.8 Flash는 200, gemini-3.5-flash-lite와 gemini-3.6-flash는 400 INVALID_ARGUMENT, Pro 티어는 400 Budget 0 is invalid. This model only works in thinking mode., 2.0 계열은 업스트림 퇴역으로 404였습니다.

라우터 자체의 400이 필요한 곳은 업스트림 오류가 필드도 모델도 밝히지 않는 두 Flash 티어입니다. Pro 모델은 업스트림 메시지가 이미 구체적이라 플래그의 이득은 주로 왕복 한 번을 아끼는 것입니다. 검사는 /v1/chat/completions 인입에서 백엔드 선택 전에 실행되므로 스트리밍과 논스트리밍을 함께 덮습니다. 특정 행에 동의하지 않는 운영자는 릴리스를 기다리지 않고 model-metadata.d/ 드롭인으로 설정하거나 해제할 수 있습니다.

폴백 홉은 거절이 아니라 맞춤 대상입니다. 인입 검사는 클라이언트가 요청한 모델을 판단하지만 홉은 운영자의 체인이 고른 다른 모델에 착지하고 그 모델의 메타데이터에는 원래 모델에 없던 플래그가 있을 수 있습니다. 그런 홉에서는 라우터가 reasoning_effort: "none"을 떨어뜨리고 로그를 남깁니다. 홉은 이미 모델을 바꾼 상태이므로 실패를 감수하고 다른 모델을 받아들인 클라이언트에게는 오류보다 그 모델이 추론하며 답하는 편이 낫기 때문입니다. 대체 모델이 추론하므로 추론 없는 답변에는 충분하던 작은 max_tokens가 잘릴 수 있습니다.

네이티브 thinkingConfig.thinkingLevel: "MINIMAL" 필드는 다른 질문이고 답도 다릅니다. Gemini 3.8 Flash는 이를 거절하고 3.6 Flash는 받아 위 두 행과 정반대입니다. Google이 문서화한 것은 minimal 레벨이지 이 매핑이 아니므로 minimal에 대한 문서 서술로 deny list를 고쳐서는 안 됩니다. id를 직접 측정해야 합니다.

xhigh 자동 폴백

Gemini 모델에 xhigh가 요청되면 라우터가 자동으로 high로 다운그레이드합니다. Gemini는 xhigh를 지원하지 않기 때문입니다.

추가 기능

Gemini thinking 모델의 경우, 라우터는 자동으로 다음 동작을 수행합니다:

  1. reasoning content를 노출하기 위해 include_thoughts: true 설정
  2. 지정되지 않은 경우 기본 max_completion_tokens: 16384 설정
  3. 모델 기능에 대해 effort 레벨 검증

셋 다 스트리밍과 비스트리밍 두 경로 모두에 같은 순서로 적용되므로 거절되는 effort는 어느 쪽이든 동일한 400을 반환합니다.

어떤 모델에 이 주입이 적용되는지는 이름 부분 문자열이 아니라 계열 테이블(src/infrastructure/backends/gemini/transform.rs의 THINKING_FAMILIES)이 결정합니다. 버전, 날짜, preview 접미사는 제거되어 gemini-3.1-pro-preview와 gemini-3.1-pro가 같은 계열로 해석되고 -lite 세그먼트는 Flash와 Flash-Lite가 서로 다른 모델이므로 제거되지 않습니다.

thought 요약 자체는 응답 쪽 처리가 필요합니다. Google은 이를 별도 필드가 아니라 message.content 안에 <thought>...</thought>로 감싸 넣고 extra_content.google.thought: true로 표시해 반환합니다. 라우터는 그 텍스트를 message.reasoning_content로 옮기고 content에는 답변만 남기므로 마크업이 클라이언트에 도달하지 않고 content 키는 항상 존재합니다. 모델이 thought만 내놓은 경우에는 키가 사라지는 대신 빈 문자열이 됩니다.

잘못된 함수 호출

Gemini는 도구 턴을 finish_reason: "function_call_filter: MALFORMED_FUNCTION_CALL"(네이티브 API 표기는 MALFORMED_FUNCTION_CALL)로 끝내는 경우가 간헐적으로 있습니다. HTTP 200 응답이지만 assistant 메시지에 content와 tool_calls가 모두 없고 completion_tokens: 0인 상태로, 모델이 생성한 함수 호출을 공급자가 파싱하지 못한 경우입니다. 2026-09-10 측정 기준 도구 하나를 지정한 gemini-3.1-pro-preview에서 2회 중 1회, 5회 중 1회 발생했고 나머지는 정상 tool_calls를 반환했습니다.

라우터는 이를 성공으로 전달하지 않습니다. 재시도 가능한 업스트림 실패(502, type: upstream_error, 메시지에 malformed_function_call 명시)로 바꾸므로 재시도 루프와 설정된 fallback.fallback_chains 홉이 동작합니다. 관측된 모든 사례에서 재시도가 성공했고 대신 stop으로 답하면 아무것도 생산하지 못했으면서 프롬프트 토큰은 쓴 턴을 숨기게 됩니다. 스트리밍 요청에서는 응답이 이미 커밋된 뒤에 감지되므로 HTTP 상태가 아니라 SSE 오류 이벤트로 전달됩니다.

그 결과 모든 Gemini 경로에서 두 가지 형태 보장이 성립합니다. finish_reason은 항상 OpenAI의 다섯 값(stop, length, tool_calls, content_filter, function_call) 중 하나입니다. 공유 테이블 하나가 공급자 표기를 매핑하고 인식하지 못하는 값은 stop으로 줄이기 때문입니다. assistant 메시지에는 항상 content 키가 있으며 null은 tool_calls가 함께 있을 때뿐이고 그 외에는 빈 문자열입니다.


Generic/HTTP 백엔드

Generic HTTP 백엔드 (Ollama, vLLM, LocalAI, LM Studio 등에 사용)는 변환 없이 요청을 전달합니다.

동작 설명
패스스루 reasoning_effort가 백엔드에 그대로 전달됨
검증 없음 라우터가 effort 레벨을 검증하지 않음
변환 없음 토큰 예산 변환이 수행되지 않음

백엔드 책임

generic 백엔드의 경우, 대상 LLM 서버가 reasoning_effort 파라미터를 처리(또는 무시)할 책임이 있습니다. 서버가 지원하지 않으면 오류를 반환하거나 파라미터를 무시할 수 있습니다.


llama.cpp 백엔드

llama.cpp 백엔드는 패스스루 동작을 사용합니다:

동작 설명
패스스루 파라미터가 변경 없이 전달됨
서버 의존적 지원 여부는 llama-server 설정에 따라 다름

llama.cpp에서의 Thinking 모델 지원

최근 버전의 llama-server는 <think> 태그 처리를 통해 thinking 모델(예: DeepSeek-R1)을 지원합니다. 그러나 reasoning_effort나 budget_tokens에 대한 표준화된 API 파라미터는 없습니다. Thinking 동작은 일반적으로 다음으로 제어됩니다:

  • thinking 태그가 있는 모델의 내장 chat 템플릿
  • 서버 측 구성 (예: --thinking-budget 가능한 경우)
  • temperature 및 top-p 같은 샘플링 파라미터

vLLM 백엔드

vLLM은 OpenAI 호환 API를 제공하지만 reasoning effort 지원은 모델에 따라 다릅니다:

동작 설명
패스스루 generic 백엔드를 통해 파라미터 전달
모델 의존적 모델 유형에 따라 지원이 다름

vLLM에서의 Thinking 모델 지원

vLLM은 thinking 가능 모델(예: DeepSeek-R1, QwQ)을 실행할 수 있지만 reasoning_effort 파라미터 처리는 다음에 따라 다릅니다:

  • 모델이 구조화된 thinking을 지원하는지 여부
  • vLLM 서버 버전 및 구성
  • 모델의 chat 템플릿 구성

DeepSeek-R1 및 유사 모델의 경우, thinking은 명시적인 budget 파라미터로 제어되기보다 모델의 동작에 내재되어 있는 경우가 많습니다.

응답 필드 정규화

최신 vLLM 버전은 추론 텍스트를 choices[].delta.reasoning(스트리밍) 또는 choices[].message.reasoning(비스트리밍) 필드로 반환합니다. 라우터는 Chat Completions의 모든 릴레이 경로에서 이 필드를 reasoning_content로 정규화하므로, vLLM 버전에 관계없이 클라이언트는 항상 reasoning_content를 받습니다. 이미 reasoning_content를 사용하는 백엔드는 영향을 받지 않습니다.


요약 테이블

백엔드 Effort 레벨 변환 비고
OpenAI none, minimal, low, medium, high, xhigh, max의 모델별 부분집합 없음 (네이티브) 정확한 모델별 검증, 조용한 effort 폴백 없음
Anthropic (Fable 5 / Mythos 5) none, minimal, auto, low, medium, high, xhigh → adaptive + output_config.effort xhigh → max; temperature/top_p/top_k 항상 제거; 명시적 비활성 thinking 생략
Anthropic (Opus 4.8) none, minimal, auto, low, medium, high, xhigh → adaptive + output_config.effort xhigh → max; temperature/top_p/top_k 항상 제거; effort 기본값 high
Anthropic (Opus 4.7) none, minimal, auto, low, medium, high, xhigh → adaptive + output_config.effort xhigh → max; temperature/top_p/top_k 항상 제거
Anthropic (Haiku 5.5) none, minimal, auto, low, medium, high, xhigh → adaptive + output_config.effort xhigh → max; temperature/top_p/top_k 항상 제거; effort 기본값 medium
Anthropic (Sonnet 5.5) none, minimal, auto, low, medium, high, xhigh → adaptive + output_config.effort xhigh → max; temperature/top_p/top_k 제거; 명시적 비활성 thinking 생략
Anthropic (4.6) none, minimal, auto, low, medium, high, xhigh* → adaptive + output_config.effort *xhigh → Opus 4.6은 max, Sonnet 4.6은 high; temperature 제거
Anthropic (4.6 이전) none, minimal, auto, low, medium, high → budget_tokens 또는 adaptive auto는 적응형 사고로 매핑; temperature 제거
Gemini none*, auto**, minimal, low, medium, high 없음 (네이티브) *none은 Flash 모델만; **auto는 medium으로 다운그레이드
vLLM 모델 의존적 패스스루 DeepSeek-R1, QwQ는 암시적 thinking 사용
llama.cpp 모델 의존적 패스스루 chat 템플릿에서 <think> 태그 사용
Generic 모두 패스스루 백엔드가 검증 처리

응답 형식

reasoning/thinking이 활성화되면 응답에 모델의 추론 과정이 포함됩니다:

OpenAI 형식 (reasoning_content 포함)

{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": "답은 42입니다.",
      "reasoning_content": "단계별로 생각해보겠습니다..."
    },
    "finish_reason": "stop"
  }]
}

Claude 확장 사고 (OpenAI 형식으로 변환됨)

라우터는 Claude의 thinking 블록을 reasoning_content 필드로 변환합니다:

{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": "답은 42입니다.",
      "reasoning_content": "여러 요소를 고려해야 합니다..."
    },
    "finish_reason": "stop"
  }]
}

모범 사례

  1. 적절한 effort 레벨 사용: 높은 effort는 추론 품질을 높이지만 응답 지연과 토큰 비용이 증가합니다.
  2. 모델 지원 확인: 모든 모델이 reasoning 파라미터를 지원하는 것은 아닙니다.
  3. 상위 effort 레벨 신중히 처리: GPT-5.2부터 GPT-5.6은 xhigh를 지원하고 GPT-5.6과 GPT-6만 max를 지원하며, 이전 모델에는 라우터가 문서화된 폴백을 적용합니다.
  4. 비용 고려: 확장 사고는 추가 토큰을 소비합니다(특히 Anthropic의 budget_tokens).
  5. 백엔드 테스트: Generic 백엔드는 엔진과 모델에 따라 지원 수준이 다를 수 있습니다.

관련 문서

추론 요청의 stop 시퀀스

백엔드가 숨겨진 추론에서 stop과 일치하는 문자열을 만나면, 사용자에게 보이는 내용을 생성하기 전에 응답을 끝낼 수 있습니다. 추론을 수행하는 요청에서는 최종 업스트림 페이로드에서 stop 시퀀스를 제거하고, debug 로그를 남깁니다. 제거한 stop 시퀀스는 라우터에서도 적용하지 않습니다. 출력이 해당 문자열을 지나 계속될 수 있으며, 일반 토큰 한도는 그대로 적용됩니다.

백엔드 본문 확장을 적용한 뒤, 매 시도의 선택된 백엔드와 모델을 기준으로 판단합니다.

판단 신호 동작
실제 전송되는 enabled/adaptive thinking 또는 추론을 활성화하는 effort stop 시퀀스 제거
실제 disabled thinking, effort none/off, Gemini thinking budget 0 stop 시퀀스 유지
선언된 기본 reasoning effort 명시적 제어가 없으면 해당 기본값 적용
비활성화·기본값 재정의가 없는 reasoning 기능 또는 thinking 패턴 메타데이터 추론 모델로 처리
OpenAI 호환 요청의 적응형 Claude 기본 추론 활성화
thinking을 별도로 켜야 하는 이전 Claude 계열 thinking 활성화 전까지 stop 유지
추론 신호 없음 stop 시퀀스 유지

Gemini의 includeThoughts: false는 추론 표시만 숨기며, 추론 자체를 끄지 않습니다. 네이티브 제공자는 변환기가 실제로 전송한 제어값을 기준으로 판단합니다. 네이티브 Anthropic Messages에서 enabled/adaptive thinking이 없으면 stop을 보존합니다. Responses의 reasoning.effort: none으로 thinking이 생략된 경우도 같습니다. Gemini Responses 변환기는 현재 reasoning.effort를 전달하지 않으므로 해당 필드만으로 추론이 비활성화되지는 않습니다.

HTTP·Unix 소켓의 일반 및 스트리밍 OpenAI 호환 전송, Responses·Anthropic Messages 변환 요청, 네이티브 Gemini 생성 설정에 같은 보호를 적용합니다. 폴백 시도는 새 요청 사본에서 다시 판단하므로, 추론 백엔드에서 제거한 stop이 다음 비추론 백엔드까지 사라지지 않습니다. 이 검사 뒤에 본문 확장이 stop을 다시 추가할 수 없습니다.