Reasoning 모델
Reasoning 모델 (Reasoning models)
Reasoning 모델은 응답을 만들기 전에 내부 reasoning 토큰을 사용해요. 그래서 계획을 세우고, 도구를 효과적으로 쓰고, 대안을 검토하고, 모호함에서 복구하며, 더 어려운 다단계 과업을 풀 수 있어요. 복잡한 문제 해결, 코딩, 과학적 추론, 다단계 에이전트 워크플로에 특히 잘 맞아요. 가벼운 코딩 에이전트인 Codex CLI에도 가장 좋은 모델이에요.
출처: 문서
본문
대부분의 reasoning 워크로드에는 gpt-6-astra로 시작해요. 비용을 줄이려면 gpt-5.6-terra를, 가장 낮은 비용·지연을 원하면 gpt-5.6-luna를 고려해요. GPT-5.6 모델을 쓴다면 reasoning mode의 pro 옵션을 보세요.
Reasoning 모델은 Responses API와 더 잘 맞아요. Chat Completions API도 여전히 지원되지만, Responses를 쓰면 모델 지능과 성능이 개선돼요.
Reasoning 시작하기
Responses API를 호출하고 reasoning 모델과 reasoning effort를 지정해요.
from openai import OpenAI
client = OpenAI()
prompt = """
Write a bash script that takes a matrix represented as a string with
format '[1,2],[3,4],[5,6]' and prints the transpose in the same format.
"""
response = client.responses.create(
model="gpt-6-astra",
reasoning={"effort": "low"},
input=[{"role": "user", "content": prompt}],
)
print(response.output_text)
Reasoning effort
reasoning.effort 파라미터는 모델이 과업을 수행할 때 얼마나 많이 생각할지를 안내해요. 지원 값은 모델에 따라 다르고 none, minimal, low, medium, high, xhigh, max를 포함할 수 있어요. 낮은 effort는 속도와 낮은 토큰 사용을 선호하고, 높은 effort에서는 모델이 더 완전하게 생각해서 더 높은 품질의 응답을 제공해요. 모델은 effort 전반에 걸쳐 적응적으로 reasoning해서, 간단한 과업에는 더 적은 토큰을 쓰고 복잡한 과업에는 더 열심히 생각해요.
GPT-6 Astra는 none reasoning effort를 지원하지 않아요. reasoning.effort(Responses)나 reasoning_effort(Chat Completions)를 none으로 설정하면 HTTP 400을 반환해요. 함수 호출에는 Responses API를 쓰세요. Chat Completions는 GPT-6 Astra에서 함수 호출을 지원하지 않아요.
기본값도 보편적이지 않고 모델에 따라 달라요. gpt-5.5는 기본적으로 medium reasoning effort를 써요. 이것은 gpt-5.5의 품질·신뢰성·성능 균형에 가장 좋은 시작점이에요.
| Effort | 가장 적합한 경우 |
|---|---|
none |
어떤 reasoning이나 다중 체인 도구 호출도 필요 없는 지연 민감 과업. gpt-5.5의 지연 민감 용도에서는 low로 시작해 필요하면 none으로 옮기는 걸 권장해요. 음성, 빠른 정보 검색, 분류가 흔한 예시예요. |
low |
적당한 지연 증가로 효율적인 reasoning. 속도·비용을 최적화하면서 도구 사용, 계획, 검색, 다단계 의사결정이 필요한 용도에 이상적이에요. 데이터 분석, 초안 작성, 실행 중심 코딩, 고객 지원/채팅 어시스턴트 워크플로가 흔한 예시예요. |
medium |
품질·신뢰성이 중요하고 과업이 계획·복잡한 추론·판단을 포함할 때. 대부분 워크로드의 기본 설정이고, 지연·성능·비용의 파레토 곡선에서 균형 잡힌 지점이에요. 에이전트 코딩, 연구, 스프레드시트·슬라이드 작업, 장기 과업 위임이 흔한 예시예요. |
high |
어려운 reasoning, 복잡한 디버깅, 깊은 계획, 지연보다 품질·지능이 중요한 고가치 과업. 복잡한 워크플로와 에이전트 과업에 권장돼요. 에이전트 코딩, 장기 연구, 지식 작업이 흔한 예시예요. 과업 복잡성에 따라 medium과 high를 모두 평가하세요. |
xhigh |
깊은 연구, 비동기 워크플로, 긴 실행이 필요한 에이전트 과업. evals가 추가 지연·비용을 정당화하는 명확한 이득을 보여줄 때만 쓰세요. 보안·코드 리뷰, 엔터프라이즈 생산성, 더 깊은 연구, 어려운 코딩 워크플로가 흔한 예시예요. |
max |
가장 복잡한 과업을 위한 최대 reasoning. 현재 xhigh를 쓴다면 max가 더 강한 성능을 내는지 평가해 보세요. |
지연 민감 앱에서 첫 표시 토큰까지 더 빠르게 하려면, 더 깊은 reasoning 전에 짧은 preamble을 생성하게 하세요. 일부 모델은 이 값들의 일부만 지원하므로, 설정을 고르기 전에 관련 모델 페이지를 확인하세요.
Reasoning mode
GPT-5.6과 GPT-6 모델은 Responses API에서 standard와 pro reasoning 모드를 지원해요. standard가 기본값이에요. 더 많은 모델 작업이 필요하고 높은 지연·토큰 사용을 감당할 수 있는 어려운 과업에는 reasoning.mode를 pro로 설정하세요.
Reasoning mode와 reasoning effort는 독립적이에요. mode는 standard 또는 pro 실행을 선택하고, reasoning.effort는 그 모드 안에서 모델이 얼마나 많이 reasoning할지 제어해요. reasoning.effort를 생략하면 GPT-5.6은 두 모드 모두에서 medium을 기본값으로 써요. GPT-6 Sol과 Luna도 medium reasoning effort를 기본으로 해요.
curl https://api.openai.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ***" \
-d '{
"model": "gpt-5.6",
"reasoning": {
"mode": "pro",
"effort": "medium"
},
"input": "Review this database migration plan and identify potential failure modes."
}'
Pro 모드는 최종 답을 만드는 데 수행된 모델 작업을 집계하고, 선택한 모델의 표준 토큰 요금으로 청구해요. Pro 모드는 standard보다 모델 작업을 더 많이 수행하므로 토큰 사용과 비용이 증가해요. 기존 Pro 모델 ID는 현재 동작과 가격을 유지해요.
Reasoning은 어떻게 동작하나요
Reasoning 모델은 입력·출력 토큰 외에 reasoning 토큰을 도입해요. 모델이 이 reasoning 토큰으로 "생각"해서 프롬프트를 분해하고 응답 생성에 여러 접근을 고려해요. gpt-5.5나 gpt-5.4 같은 reasoning 모델은 interleaved thinking을 지원해, 생각하는 사이와 도구 호출 사이에 보이는 출력 토큰을 생성할 수 있어요.
GPT-5.6 이전에 출시된 모델의 기본 동작은 다단계 대화에서 각 단계의 입력·출력 토큰을 이어 가되 이전 턴의 reasoning을 다음 샘플에 렌더링하지 않는 거예요. GPT-5.6 모델은 대신 이전 턴의 사용 가능한 reasoning을 렌더링하는 걸 기본으로 해요. 지원 모델에서는 reasoning.context로 두 동작 중 하나를 선택할 수 있어요.
reasoning 토큰은 API로 보이지 않지만 모델의 컨텍스트 윈도우 공간을 차지하고 출력 토큰으로 청구돼요.
비용 제어하기
reasoning 모델의 비용을 관리하려면 max_output_tokens 파라미터로 모델이 생성하는 총 토큰 수(reasoning 토큰, 보이는 출력 토큰, 보이지 않는 서식 토큰 포함)를 제한할 수 있어요. 생성 토큰이 usage·출력 한도에 어떻게 반영되는지 자세한 내용은 출력 토큰 수를 참고하세요.
컨텍스트 윈도우 관리하기
응답을 만들 때 reasoning 토큰을 위한 컨텍스트 윈도우 공간이 충분한지 확인하는 게 중요해요. 문제 복잡성에 따라 모델은 수백 개에서 수만 개의 reasoning 토큰을 생성할 수 있어요. 사용된 정확한 reasoning 토큰 수는 응답 객체의 usage 객체의 output_tokens_details에서 볼 수 있어요.
{
"usage": {
"input_tokens": 75,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 1186,
"output_tokens_details": {
"reasoning_tokens": 1024
},
"total_tokens": 1261
}
}
컨텍스트 윈도우 길이는 모델 참조 페이지에서 찾을 수 있고, 모델 스냅샷마다 달라요.
reasoning 공간 할당하기
생성된 토큰이 컨텍스트 윈도우 한도나 설정한 max_output_tokens 값에 도달하면, status가 incomplete이고 incomplete_details의 reason이 max_output_tokens인 응답을 받게 돼요. 이것은 보이는 출력 토큰이 생성되기 전에 발생할 수 있어서, 보이는 응답 없이 입력·reasoning 토큰 비용이 발생할 수 있어요.
이를 막으려면 컨텍스트 윈도우에 충분한 공간이 있는지 확인하거나 max_output_tokens 값을 더 높이세요. OpenAI는 이런 모델 실험을 시작할 때 reasoning과 출력용으로 최소 25,000 토큰을 예약할 것을 권장해요. 프롬프트에 필요한 reasoning 토큰 수에 익숙해지면 버퍼를 그에 맞게 조정할 수 있어요.
from openai import OpenAI
client = OpenAI()
prompt = """
Write a bash script that takes a matrix represented as a string with
format '[1,2],[3,4],[5,6]' and prints the transpose in the same format.
"""
response = client.responses.create(
model="gpt-6-astra",
reasoning={"effort": "medium"},
input=[{"role": "user", "content": prompt}],
max_output_tokens=300,
)
if (
response.status == "incomplete"
and response.incomplete_details.reason == "max_output_tokens"
):
print("Ran out of tokens")
if response.output_text:
print("Partial output:", response.output_text)
else:
print("Ran out of tokens during reasoning")
호출 간 reasoning 보존하기
대화 상태와 reasoning 상태는 다른 목적을 가져요. 호출 간에 메시지를 전달하면 모델에 보이는 대화 기록이 제공돼요. 지원 모델에서 persisted reasoning은 모델이 이전 턴의 호환 가능한 reasoning 항목을 다음 컨텍스트에 렌더링하게 해요.
Persisted reasoning은 연속성을 제공하지만, 모델의 원시 reasoning을 노출하지는 않아요. reasoning 항목은 불투명하게 유지되고 API가 그 reasoning 텍스트를 반환하지 않아요. 모델이 사용할 수 있는 사용 가능한 reasoning 항목을 제어하려면 reasoning.context를 설정하세요.
GPT-5.6 모델 계열은 all_turns를 지원하고 기본으로 써요. 이전 모델은 current_turn을 기본으로 해요. reasoning.context를 생략하거나 auto로 설정하면 선택한 모델의 기본값을 써요.
| 값 | 동작 |
|---|---|
auto |
선택한 모델의 기본값을 사용해요. reasoning.context를 생략하면 auto와 같아요. |
current_turn |
활성 턴의 reasoning은 사용 가능하지만, 이전 턴의 reasoning을 다음 샘플에 렌더링하지 않아요. |
all_turns |
이전 턴의 사용 가능하고 호환되는 reasoning 항목을 다음 샘플에 렌더링해요. GPT-5.6 모델이 이 값을 지원해요. |
응답의 reasoning.context 필드에는 유효 모드(current_turn 또는 all_turns)가 들어 있어요. 각 응답에서 이 필드를 확인해서 모델이 어떤 모드를 사용했는지 확인하세요. 이 설정은 이미 사용 가능하지 않은 reasoning 항목을 만들지 않아요.
all_turns는 요청이 이전 응답 항목에 접근할 수 있을 때만 효과가 있어요. previous_response_id를 쓰거나, 응답을 대화에 연결하거나, 완전한 응답 기록을 수동으로 리플레이하세요. 첫 요청에서는 이전 reasoning이 없으므로 current_turn과 all_turns가 동일하게 동작해요.
Persisted reasoning은 같은 모델 계열 안에서만 재사용할 수 있어요. 예를 들어 gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna는 서로의 reasoning을 재사용할 수 있지만, reasoning은 GPT-5.6과 GPT-5.5 계열 사이로는 옮겨지지 않아요. 모델 계열을 전환하면 reasoning.context가 all_turns여도 API가 호환되지 않는 reasoning을 모델 컨텍스트에서 생략해요.
저장된 응답으로 reasoning 계속하기
가장 짧은 상태 있는 통합을 위해 previous_response_id를 쓰세요.
from openai import OpenAI
client = OpenAI()
model = "gpt-5.6"
first = client.responses.create(
model=model,
input="Inspect this repository and identify the likely bug.",
reasoning={"context": "current_turn"},
)
second = client.responses.create(
model=model,
previous_response_id=first.id,
input="Now patch the bug and explain the change.",
reasoning={"context": "all_turns"},
)
print(second.output_text)
모델이 더 이상 필요로 하지 않는 오래된 응답 항목을 리플레이할 때는 current_turn을 쓰세요. 그 reasoning 항목은 연속성을 위해 API 페이로드에 남아 있을 수 있지만, 서비스는 새 샘플에 렌더링하지 않아요. 이렇게 하면 장기 실행 워크플로의 렌더링 컨텍스트를 줄일 수 있어요.
저장된 응답 없이 reasoning 보존하기
상태 없는(stateless) 모드에서 응답을 만들면, 응답 output 배열의 reasoning 항목에는 기본적으로 encrypted_content 속성이 포함돼요. stateless 모드는 store가 false이거나 조직이 Zero Data Retention(ZDR)을 사용할 때 적용돼요. API는 호환성을 위해 레거시 reasoning.encrypted_content 값을 include에서 계속 받지만 요구하지 않아요.
store: false에서 all_turns를 쓰려면 모든 출력 항목을 보존하고, 다음 사용자 메시지를 덧붙이며, 완전한 기록을 리플레이해요.
from openai import OpenAI
client = OpenAI()
model = "gpt-5.6"
history = [
{
"role": "user",
"content": "Inspect this repository and identify the likely bug.",
}
]
first = client.responses.create(
model=model,
store=False,
input=history,
reasoning={"context": "current_turn"},
)
# Keep every output item, including encrypted reasoning and assistant phase.
history.extend(item.model_dump() for item in first.output)
history.append(
{
"role": "user",
"content": "Now patch the bug and explain the change.",
}
)
second = client.responses.create(
model=model,
store=False,
input=history,
reasoning={"context": "all_turns"},
)
print(second.output_text)
context에 reasoning 항목 유지하기
Responses API에서 reasoning 모델로 함수 호출을 할 때는, 마지막 함수 호출과 함께 반환된 모든 reasoning 항목(함수 출력과 함께)을 다시 전달할 것을 강력히 권장해요. 모델이 연속으로 여러 함수를 호출하면, 마지막 user 메시지 이후의 모든 reasoning 항목·함수 호출 항목·함수 호출 출력 항목을 다시 전달해야 해요. 그래야 모델이 reasoning 과정을 이어가 토큰 효율적으로 더 나은 결과를 낼 수 있어요.
가장 간단한 방법은 이전 응답의 모든 reasoning 항목을 다음 응답에 전달하는 거예요. 시스템이 함수와 무관한 reasoning 항목은 똑똑하게 무시하고 관련 있는 것만 컨텍스트에 유지해요. previous_response_id 파라미터를 쓰거나, 과거 응답의 모든 output 항목을 새 응답의 input에 수동으로 전달할 수 있어요. 컨텍스트 윈도우의 일부를 잘라 최적화하는 고급 용도에서는, 마지막 사용자 메시지와 함수 호출 출력 사이의 모든 항목을 다음 응답에 그대로 전달하세요. 수동 컨텍스트 관리에 대한 자세한 내용은 이 가이드를 참고하세요.
대화 중 reasoning 변경하기
어려운 작업에는 reasoning effort를 높이거나 일상적인 후속 작업에는 낮추기 위해 configuration_update를 쓰세요. 요청 수준의 reasoning.effort는 그대로 두고 응답 사이에 업데이트를 추가해요. 이렇게 하면 프롬프트 캐싱을 위해 원래 프롬프트 prefix를 보존할 수 있어요.
설정 업데이트는 GPT-6 모델 계열에서 standard, 단일 에이전트 모드로 지원돼요. reasoning effort만 바꿔요. HTTP Responses 요청이나 WebSocket response.create 요청의 input 배열에서, 다음 사용자 메시지 앞에 다음 항목을 추가하세요.
{
"type": "configuration_update",
"reasoning": {
"effort": "high"
}
}
예를 들어 대화가 요청 수준 effort low로 시작했다면, 이 업데이트는 다음 응답과 이후 응답에 high를 선택해요(다른 업데이트가 덮어쓸 때까지).
from openai import OpenAI
client = OpenAI()
model = "gpt-6-astra"
response = client.responses.create(
model=model,
reasoning={"effort": "low"},
input="Draft a database migration plan.",
store=True,
)
print(response.output_text)
response = client.responses.create(
model=model,
previous_response_id=response.id,
reasoning={"effort": "low"},
input=[
{
"type": "configuration_update",
"reasoning": {"effort": "high"},
},
{
"role": "user",
"content": "Analyze the failure modes and propose rollback steps.",
},
],
store=True,
)
print(response.output_text)
업데이트는 previous_response_id로 보존하거나, 대화 상태를 수동으로 관리할 때 원래 위치에 리플레이하세요. 응답의 reasoning.effort는 업데이트가 선택한 effort가 아니라 요청 수준 설정을 계속 보고해요. 대화 기록에서 두 configuration_update 항목을 서로 바로 옆에 두지 마세요. API가 인접한 업데이트를 거부해요. 구성 업데이트를 자동 컴팩션·자동 잘라내기와 결합하지 마세요. 독립형 /responses/compact 엔드포인트도 이 업데이트를 포함한 기록을 거부해요. /responses 요청에 compaction_trigger 항목을 포함해 명시적으로 컴팩트할 수는 있어요. 컴팩트 후에는 다음 사용자 메시지 앞에 원하는 effort로 새 configuration_update를 추가하세요. 일반적인 프롬프트 캐싱 요구사항은 여전히 적용돼요. 응답이 실행되는 동안 사용자 지시를 보내려면 Mid-turn steering을 쓰세요.
Reasoning 요약 (Summaries)
모델이 내보내는 원시 reasoning 토큰은 노출하지 않지만, summary 파라미터로 모델 reasoning의 요약을 볼 수 있어요. 어떤 reasoning 모델이 요약을 지원하는지 모델 문서에서 확인하세요. 모델마다 지원하는 reasoning 요약 설정이 달라요. 예를 들어 컴퓨터 사용 모델은 concise summarizer를, o4-mini는 detailed를 지원해요. 모델에 가장 상세한 summarizer를 쓰려면 auto로 설정하세요. 현재 대부분의 reasoning 모델에서 auto는 detailed와 같지만, 앞으로 더 세밀한 설정이 있을 수 있어요.
Reasoning 요약 출력은 reasoning 출력 항목의 summary 배열에 속해요. 명시적으로 옵트인하지 않으면 이 출력은 포함되지 않아요.
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-6-astra",
input="What is the capital of France?",
reasoning={"effort": "low", "summary": "auto"},
)
print(response.output)
이 요청은 어시스턴트 메시지와 함께, 그 응답을 생성할 때의 모델 reasoning 요약을 포함한 output 배열을 반환해요. 최신 reasoning 모델에서 summarizer를 쓰기 전에는 안전한 배포를 보장하려고 조직 검증을 완료해야 할 수 있어요. 플랫폼 설정 페이지에서 검증을 시작할 수 있어요.
phase 파라미터
Responses API의 GPT-5.5·GPT-5.4로 장기 실행·도구 중심 흐름을 만들 때는, assistant 메시지 phase 필드를 써서 조기 중단(early stopping) 같은 오작동을 피하세요. phase는 API 수준에서 선택 사항이지만 OpenAI는 사용을 권장해요. 도구 호출 전 preamble 같은 중간 assistant 업데이트에는 phase: "commentary"를, 완성된 답변에는 phase: "final_answer"를 쓰세요. 사용자 메시지에는 phase를 추가하지 마세요. previous_response_id를 쓰면 이전 assistant 상태가 보존되므로 보통 가장 간단한 경로예요. assistant 기록을 수동으로 리플레이한다면 각 원래 phase 값을 보존하세요. phase가 빠지거나 빠뜨려지면 그 워크플로에서 preamble이 최종 답변으로 취급될 수 있어요.
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-6-astra",
input=[
{
"role": "assistant",
"phase": "commentary",
"content": "I'll inspect the logs and then summarize root cause and remediation.",
},
{
"role": "assistant",
"phase": "final_answer",
"content": "Root cause: cache invalidation race.",
},
{
"role": "user",
"content": "Great—now give me a rollout-safe fix plan.",
},
],
)
print(response.output_text)
프롬프팅 조언
Reasoning 모델을 프롬프팅할 때는 이런 차이를 고려하세요. Reasoning이 가능한 GPT-5 모델은 모든 중간 단계를 규정하지 않고 명확한 목표, 강한 제약, 명시적인 출력 계약을 줄 때 보통 가장 잘 작동해요.
- 모델에 과업, 제약, 원하는 출력 형식을 주세요.
reasoning.effort를 품질을 회복하는 기본 수단이 아니라 조정 손잡이로 취급하세요.- 에이전트·연구 중심 워크플로에서는 무엇이 완료인지, 모델이 작업을 어떻게 검증해야 하는지 정의하세요.
Reasoning 모델 사용 모범 사례에 대한 자세한 내용은 이 가이드를 참고하세요.
프롬프트 예시
코딩(리팩토링) — o 시리즈 모델은 복잡한 알고리즘을 구현하고 코드를 만들 수 있어요. 아래 프롬프트는 특정 기준에 따라 React 컴포넌트를 리팩토링하도록 요청해요. 코드만 반환하고 markdown 코드 블록 같은 추가 서식은 넣지 말고, 네 칸 탭을 쓰며 80열을 넘지 않게 지시하는 식으로 출력 계약을 명확히 해요.
코딩(계획) — o 시리즈 모델은 다단계 계획을 만드는 데도 뛰어나요. 사용자 질문을 데이터베이스에서 찾아 답을 매핑하는 Python 앱을 만들면서, 필요한 디렉터리 구조 계획을 세우고 각 파일을 전체로 반환하도록 요청하는 예시예요. reasoning은 코드 전체가 아니라 시작과 끝에만 제공하게 해요.
STEM 연구 — o 시리즈 모델은 STEM 연구에서 우수한 성능을 보여요. 기초 연구 과업을 지원하는 프롬프트는 강한 결과를 보여야 해요.