추론 모델

추론 모델 (Reasoning models)

**추론 모델(reasoning models)**은 응답을 만들기 전에 내부 **추론 토큰(reasoning tokens)**을 사용해요. 이 추론 과정 덕분에 모델은 계획을 세우고, 툴을 효과적으로 사용하고, 대안을 검토하고, 모호함에서 벗어나며, 더 어려운 다단계 작업을 해결할 수 있어요. 추론 모델은 복잡한 문제 해결, 코딩, 과학적 추론, 다단계 에이전트 워크플로에서 특히 뛰어나요. 또한 가벼운 코딩 에이전트인 Codex CLI를 위한 최고의 모델이기도 해요.

출처: 공식문서

대부분의 추론 작업에는 gpt-6-astra로 시작하는 것을 권장해요. 비용을 줄이려면 gpt-5.6-terra를, 가장 낮은 비용과 지연을 원한다면 gpt-5.6-luna를 고려하세요. GPT-5.6 모델을 사용한다면 아래 추론 모드pro 옵션을 확인하세요.

추론 모델은 Responses API와 함께 사용할 때 더 잘 동작해요. Chat Completions API도 여전히 지원되지만, Responses를 사용하면 더 나은 모델 지능과 성능을 얻을 수 있어요.

추론 시작하기 (Get started with reasoning)

Responses API를 호출해 추론 모델과 추론 노력을 지정해볼게요:

Responses API에서 추론 모델 사용하기

import OpenAI from "openai";

const openai = new OpenAI();

const 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.
`;

const response = await openai.responses.create({
  model: "gpt-6-astra",
  reasoning: { effort: "low" },
  input: [
    {
      role: "user",
      content: prompt,
    },
  ],
});

console.log(response.output_text);
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)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	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, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: "gpt-6-astra",
		Reasoning: responses.ReasoningParam{
			Effort: responses.ReasoningEffortLow,
		},
		Input: responses.ResponseNewParamsInputUnion{
			OfString: openai.String(prompt),
		},
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(response.OutputText())
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.Reasoning;
import com.openai.models.ReasoningEffort;
import com.openai.models.responses.ResponseCreateParams;

String 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.
    """
        .strip();

ResponseCreateParams params =
    ResponseCreateParams.builder()
        .model("gpt-6-astra")
        .input(prompt)
        .reasoning(Reasoning.builder().effort(ReasoningEffort.LOW).build())
        .build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);

string 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.
    """;
CreateResponseOptions options = new()
{
    Model = "gpt-6-astra",
    ReasoningOptions = new ResponseReasoningOptions
    {
        ReasoningEffortLevel = ResponseReasoningEffortLevel.Low,
    },
};
options.InputItems.Add(ResponseItem.CreateUserMessageItem(prompt));

ResponseResult response = await client.CreateResponseAsync(options);

Console.WriteLine(response.GetOutputText());
require "openai"

client = OpenAI::Client.new
prompt = <<~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.
PROMPT

response = client.responses.create(
  model: "gpt-6-astra",
  reasoning: { effort: :low },
  input: prompt
)

puts(response.output_text)
curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ***" \
  -d '{
    "model": "gpt-6-astra",
    "reasoning": {"effort": "low"},
    "input": [
      {
        "role": "user",
        "content": "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."
      }
    ]
  }'

추론 노력 (Reasoning effort)

reasoning.effort 파라미터는 작업을 수행할 때 모델이 얼마나 많이 생각할지 안내해요.

지원되는 값은 모델에 따라 다르며 none, minimal, low, medium, high, xhigh, max가 될 수 있어요. 낮은 노력은 속도와 낮은 토큰 사용량을 favoring하고, 높은 노력에서는 모델이 더 완전하게 생각해 더 높은 품질의 응답을 제공해요. 모델은 추론 노력에 걸쳐 적응형으로 추론해서, 단순한 작업에는 더 적은 토큰을, 복잡한 작업에는 더 열심히 생각해요.

GPT-6 Astranone 추론 노력을 지원하지 않아요. reasoning.effort(Responses) 또는 reasoning_effort(Chat Completions)를 none으로 설정하면 HTTP 400을 반환해요.

함수 호출에는 Responses API를 사용하세요. Chat Completions는 GPT-6 Astra와의 함수 호출을 지원하지 않아요.

기본값도 보편적이 아니라 모델에 따라 달라요. gpt-5.5medium 추론 노력을 기본값으로 해요. 이는 gpt-5.5의 품질, 신뢰성, 성능의 완전한 균형을 위한 최고의 출발점이에요.

노력 가장 적합한 용도
none 어떠한 추론이나 다중 체인 툴 호출도 필요 없는 지연 시간에 민감한 작업. gpt-5.5의 지연 시간에 민감한 사용 사례에서는 low로 시작한 뒤 필요 시 none으로 이동하는 것을 권장해요.

일반적인 사용 사례: 음성, 빠른 정보 검색, 분류.
low 적당한 지연 증가로 효율적인 추론. 툴 사용, 계획, 검색 또는 다단계 의사 결정이 필요하면서 속도와 비용을 최적화하려는 사용 사례에 이상적.

일반적인 사용 사례: 데이터 분석, 초안 작성, 실행 중심 코딩, 고객 지원 / 채팅 어시스턴트 워크플로.
medium 품질과 신뢰성이 중요하고 작업에 계획, 복잡한 추론, 판단이 포함될 때. 대부분 워크로드의 기본 구성이며 지연, 성능, 비용의 파레토 곡선에서 균형 잡힌 지점.

일반적인 사용 사례: 에이전트 코딩, 연구, 스프레드시트 & 슬라이드 작업, 장기 작업 위임.
high 어려운 추론, 복잡한 디버깅, 깊은 계획, 지연보다 품질과 지능이 더 중요한 고가치 작업. 복잡한 워크플로와 에이전트 작업에 권장.

일반적인 사용 사례: 에이전트 코딩, 장기 연구, 지식 작업. 작업 복잡성에 따라 mediumhigh를 모두 평가하세요.
xhigh 깊은 연구, 비동기 워크플로, 긴 실행이 필요한 에이전트 작업. 추가 지연과 비용을 정당화하는 명확한 이점이 있을 때만 eval에서 확인된 경우에만 사용.

일반적인 사용 사례: 보안 및 코드 리뷰, 엔터프라이즈 생산성, 더 깊은 연구 작업, 어려운 코딩 워크플로.
max 가장 복잡한 작업을 위한 최대 추론. 현재 xhigh를 사용 중이라면 max가 더 강한 성능을 내는지 평가하세요

지연에 민감한 애플리케이션에서 첫 가시 토큰까지의 시간을 빠르게 하려면, 더 깊은 추론을 시작하기 전에 모델에게 짧은 서문(preamble)을 생성하라고 요청하세요.

일부 모델은 이 값들의 일부만 지원하므로, 설정을 선택하기 전에 관련 모델 페이지를 확인하세요.

추론 모드 (Reasoning mode)

GPT-5.6 모델은 Responses API에서 standardpro 추론 모드를 지원해요. standard가 기본값이에요. 더 많은 모델 작업이 필요하고 더 높은 지연과 토큰 사용을 견딜 수 있는 어려운 작업에는 reasoning.modepro로 설정하세요.

추론 모드와 추론 노력은 독립적이에요. 모드는 standard 또는 pro 실행을 선택하고, reasoning.effort는 그 모드 안에서 모델이 적용하는 추론량을 제어해요. reasoning.effort를 생략하면 GPT-5.6은 두 모드 모두에서 medium을 기본값으로 해요.

pro 추론 모드 사용하기

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 모드는 표준 모드보다 더 많은 모델 작업을 수행해서 토큰 사용량과 비용이 증가해요. 기존 Pro 모델 ID는 현재 동작과 가격을 유지해요.

추론이 동작하는 방식 (How reasoning works)

추론 모델은 입력·출력 토큰에 더해 추론 토큰을 도입해요. 모델은 이 추론 토큰들로 "생각"하며, 프롬프트를 분해하고 응답 생성을 위한 여러 접근 방식을 고려해요. gpt-5.5gpt-5.4 같은 우리의 추론 모델은 **교차 사고(interleaved thinking)**를 지원해서, 생각하기 전과 사이에 가시적인 출력 토큰을 생성하고 툴 호출 사이에서도 생각할 수 있어요.

GPT-5.6 이전에 출시된 모델의 경우 다단계 대화의 기본 동작은 각 단계의 입력·출력 토큰을 이월하되 이전 턴의 추론을 다음 샘플에 렌더링하지 않는 것이에요. 반면 GPT-5.6 모델은 이전 턴의 사용 가능한 추론을 렌더링하는 것이 기본값이에요. 지원 모델에서 두 동작 중 하나를 선택하려면 reasoning.context를 사용하세요.

Reasoning tokens with current-turn context

추론 토큰은 API로는 볼 수 없지만, 여전히 모델의 컨텍스트 창에서 공간을 차지하고 출력 토큰으로 청구돼요.

비용 제어하기 (Controlling costs)

추론 모델의 비용을 관리하려면, 추론 토큰, 가시 출력 토큰, 비가시 포맷팅 토큰을 포함해 모델이 생성하는 총 토큰 수를 max_output_tokens 파라미터로 제한할 수 있어요. 생성된 토큰이 usage와 출력 제한에 어떻게 반영되는지는 출력 토큰 수를 참고하세요.

컨텍스트 창 관리하기 (Managing the context window)

응답을 만들 때 컨텍스트 창에 추론 토큰을 위한 충분한 공간이 있는지 확인하는 것이 중요해요. 문제의 복잡성에 따라 모델은 수백 개에서 수만 개의 추론 토큰을 생성할 수 있어요. 사용된 정확한 추론 토큰 수는 응답 객체의 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
  }
}

컨텍스트 창 길이는 모델 참조 페이지에서 찾을 수 있고, 모델 스냅샷별로 다를 수 있어요.

추론 공간 할당하기 (Allocating space for reasoning)

생성된 토큰이 컨텍스트 창 제한이나 설정한 max_output_tokens 값에 도달하면, statusincomplete이고 incomplete_detailsreasonmax_output_tokens로 설정된 응답을 받게 돼요. 이는 가시 출력 토큰이 생성되기 전에 발생할 수 있어서, 가시 응답 없이 입력·추론 토큰 비용이 발생할 수 있어요.

이를 방지하려면 컨텍스트 창에 충분한 공간을 확보하거나 max_output_tokens 값을 더 높게 조정하세요. OpenAI는 이 모델들로 실험을 시작할 때 추론과 출력에 최소 25,000 토큰을 예약할 것을 권장해요. 프롬프트가 필요한 추론 토큰 수에 익숙해지면 이 버퍼를 그에 맞게 조정할 수 있어요.

불완전 응답 처리하기

import OpenAI from "openai";

const openai = new OpenAI();

const 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.
`;

const response = await openai.responses.create({
  model: "gpt-6-astra",
  reasoning: { effort: "medium" },
  input: [
    {
      role: "user",
      content: prompt,
    },
  ],
  max_output_tokens: 300,
});

if (
  response.status === "incomplete" &&
  response.incomplete_details.reason === "max_output_tokens"
) {
  console.log("Ran out of tokens");
  if (response.output_text?.length > 0) {
    console.log("Partial output:", response.output_text);
  } else {
    console.log("Ran out of tokens during 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")
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	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, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model:           "gpt-6-astra",
		MaxOutputTokens: openai.Int(300),
		Reasoning: responses.ReasoningParam{
			Effort: responses.ReasoningEffortMedium,
		},
		Input: responses.ResponseNewParamsInputUnion{
			OfString: openai.String(prompt),
		},
	})
	if err != nil {
		panic(err)
	}

	if response.Status == responses.ResponseStatusIncomplete {
		fmt.Println("Ran out of tokens")
		if text := response.OutputText(); text != "" {
			fmt.Println("Partial output:", text)
		}
	}
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.Reasoning;
import com.openai.models.ReasoningEffort;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseStatus;

ResponseCreateParams params =
    ResponseCreateParams.builder()
        .model("gpt-6-astra")
        .input(
            "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.")
        .maxOutputTokens(300)
        .reasoning(Reasoning.builder().effort(ReasoningEffort.MEDIUM).build())
        .build();

var response = client.responses().create(params);
if (response.status().filter(ResponseStatus.INCOMPLETE::equals).isPresent()
    && response
        .incompleteDetails()
        .flatMap(Response.IncompleteDetails::reason)
        .filter(Response.IncompleteDetails.Reason.MAX_OUTPUT_TOKENS::equals)
        .isPresent()) {
  System.out.println("Ran out of tokens");
  response.output().stream()
      .flatMap(item -> item.message().stream())
      .flatMap(message -> message.content().stream())
      .flatMap(content -> content.outputText().stream())
      .forEach(text -> System.out.println("Partial output: " + text.text()));
}
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);

CreateResponseOptions options = new()
{
    Model = "gpt-6-astra",
    MaxOutputTokenCount = 300,
    ReasoningOptions = new ResponseReasoningOptions
    {
        ReasoningEffortLevel = ResponseReasoningEffortLevel.Medium,
    },
};
options.InputItems.Add(
    ResponseItem.CreateUserMessageItem("Write a bash script that transposes a matrix.")
);

ResponseResult response = await client.CreateResponseAsync(options);
if (
    response.Status == ResponseStatus.Incomplete
    && response.IncompleteStatusDetails?.Reason == ResponseIncompleteStatusReason.MaxOutputTokens
)
{
    Console.WriteLine("The response ended before all output tokens were generated.");
    string partialOutput = response.GetOutputText();
    Console.WriteLine(
        string.IsNullOrWhiteSpace(partialOutput)
            ? "Ran out of tokens during reasoning."
            : $"Partial output: {partialOutput}"
    );
}
else if (
    response.Status == ResponseStatus.Incomplete
    && response.IncompleteStatusDetails?.Reason == ResponseIncompleteStatusReason.ContentFilter
)
{
    Console.WriteLine("The response was interrupted by the content filter.");
}
else if (response.Status == ResponseStatus.Completed)
{
    Console.WriteLine(response.GetOutputText());
}
else
{
    throw new InvalidOperationException($"The response ended with status: {response.Status}");
}
require "openai"

client = OpenAI::Client.new
prompt = <<~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.
PROMPT

response = client.responses.create(
  model: "gpt-6-astra",
  max_output_tokens: 300,
  reasoning: { effort: :medium },
  input: prompt
)

if response.status == OpenAI::Responses::ResponseStatus::INCOMPLETE
  puts("Ran out of tokens")
  puts("Partial output: #{response.output_text}") unless response.output_text.empty?
end

호출 간 추론 보존하기 (Preserve reasoning across calls)

대화 상태와 추론 상태는 서로 다른 목적을 가져요. 호출 간에 메시지를 전달하면 모델에게 가시적인 대화 기록이 제공돼요. 지원 모델에서 지속된 추론(persisted reasoning)은 모델이 이전 턴의 호환 가능한 추론 항목을 다음 컨텍스트에 렌더링하게 해줘요.

지속된 추론은 연속성을 제공하지만, 모델의 원시 추론을 노출하지는 않아요. 추론 항목은 불투명하게 유지되고 API는 추론 텍스트를 반환하지 않아요. reasoning.context를 설정해 모델이 사용할 수 있는 추론 항목을 제어하세요:

GPT-5.6 모델군all_turns를 지원하고 기본값으로 사용해요. 이전 모델은 current_turn을 기본값으로 해요. reasoning.context를 생략하거나 auto로 설정하면 선택한 모델의 기본값을 사용해요.

동작
auto 선택한 모델의 기본값을 사용. reasoning.context를 생략하는 것은 auto와 같은 효과.
current_turn 활성 턴의 추론은 사용 가능하게 하지만, 이전 턴의 추론은 다음 샘플에 렌더링하지 않음.
all_turns 이전 턴의 사용 가능하고 호환 가능한 추론 항목을 다음 샘플에 렌더링. GPT-5.6 모델이 이 값을 지원.

응답의 reasoning.context 필드는 current_turn 또는 all_turns의 유효 모드를 포함해요. 각 응답에서 이 필드를 확인해 모델이 사용한 모드를 확인하세요. 이 설정은 이미 사용 가능하지 않은 추론 항목을 만들지는 않아요.

all_turns는 요청이 이전 응답 항목에 접근할 수 있을 때만 효과가 있어요. previous_response_id를 사용하거나, 응답을 대화에 연결하거나, 완전한 응답 기록을 수동으로 재생하세요. 첫 요청에서는 이전 추론이 없으므로 current_turnall_turns가 동일하게 동작해요.

지속된 추론은 같은 모델군 안에서만 재사용할 수 있어요. 예를 들어 gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna는 서로의 추론을 재사용할 수 있지만, 추론은 GPT-5.6군과 GPT-5.5군 사이를 넘어가지 않아요.

모델군을 전환하면, reasoning.contextall_turns일 때도 API는 호환되지 않는 추론을 모델 컨텍스트에서 생략해요.

저장된 응답으로 추론 이어가기 (Continue reasoning with stored responses)

가장 짧은 상태 기반 통합에는 previous_response_id를 사용하세요:

이전 응답으로 추론 보존하기

import OpenAI from "openai";

const client = new OpenAI();

const first = await client.responses.create({
  model: "gpt-5.6",
  input: "Inspect this repository and identify the likely bug.",
  reasoning: { context: "current_turn" },
});

const second = await client.responses.create({
  model: "gpt-5.6",
  previous_response_id: first.id,
  input: "Now patch the bug and explain the change.",
  reasoning: { context: "all_turns" },
});

console.log(second.output_text);
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)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	model := "gpt-5.6"

	first, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: model,
		Input: responses.ResponseNewParamsInputUnion{
			OfString: openai.String("Inspect this repository and identify the likely bug."),
		},
		Reasoning: responses.ReasoningParam{
			Context: responses.ReasoningContextCurrentTurn,
		},
	})
	if err != nil {
		panic(err)
	}

	second, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model:              model,
		PreviousResponseID: openai.String(first.ID),
		Input: responses.ResponseNewParamsInputUnion{
			OfString: openai.String("Now patch the bug and explain the change."),
		},
		Reasoning: responses.ReasoningParam{
			Context: responses.ReasoningContextAllTurns,
		},
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(second.OutputText())
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.Reasoning;
import com.openai.models.responses.ResponseCreateParams;

var first =
    client
        .responses()
        .create(
            ResponseCreateParams.builder()
                .model("gpt-5.6")
                .input("Inspect this repository and identify the likely bug.")
                .reasoning(
                    Reasoning.builder()
                        .putAdditionalProperty("context", JsonValue.from("current_turn"))
                        .build())
                .build());

var second =
    client
        .responses()
        .create(
            ResponseCreateParams.builder()
                .model("gpt-5.6")
                .input("Now patch the bug and explain the change.")
                .previousResponseId(first.id())
                .reasoning(
                    Reasoning.builder()
                        .putAdditionalProperty("context", JsonValue.from("all_turns"))
                        .build())
                .build());
second.output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
require "openai"

client = OpenAI::Client.new

first = client.responses.create(
  model: "gpt-5.6",
  input: "Inspect this repository and identify the likely bug.",
  reasoning: { context: :current_turn }
)

second = client.responses.create(
  model: "gpt-5.6",
  previous_response_id: first.id,
  input: "Now patch the bug and explain the change.",
  reasoning: { context: :all_turns }
)

puts(second.output_text)

모델이 더 이상 필요하지 않은 이전 응답 항목을 재생할 때는 current_turn을 사용하세요. 그 추론 항목들은 연속성을 위해 API 페이로드에 남을 수 있지만, 서비스는 새 샘플에 렌더링하지 않아요. 이는 장기 실행 워크플로에서 렌더링된 컨텍스트를 줄여줄 수 있어요.

저장된 응답 없이 추론 보존하기 (Preserve reasoning without stored responses)

무상태 모드에서 응답을 만들면 응답의 output 배열에 있는 추론 항목은 기본적으로 encrypted_content 속성을 포함해요. 무상태 모드는 storefalse이거나 조직이 제로 데이터 보존(ZDR)을 사용할 때 적용돼요. API는 호환성을 위해 include의 레거시 reasoning.encrypted_content 값을 여전히 받지만, 요구하지는 않아요.

다음 요청은 include를 지정하지 않고 암호화된 추론 내용을 반환해요:

curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ***" \
  -d '{
    "model": "gpt-6-astra",
    "store": false,
    "reasoning": {"effort": "medium"},
    "input": "What is the weather like today?",
    "tools": [ ... function config here ... ]
  }'

output 배열의 추론 항목에는 미래 호출에 전달할 수 있는 암호화된 추론 토큰을 담은 encrypted_content 속성이 포함돼요.

store: falseall_turns를 사용하려면 모든 출력 항목을 보존하고 다음 사용자 메시지를 추가한 뒤 완전한 기록을 재생하세요:

응답을 저장하지 않고 추론 보존하기

import OpenAI from "openai";
import { toResponseInputItems } from "openai/lib/responses/ResponseInputItems";

const client = new OpenAI();

/** @type {OpenAI.Responses.ResponseInput} */
const history = [
  {
    role: "user",
    content: "Inspect this repository and identify the likely bug.",
  },
];

const first = await client.responses.create({
  model: "gpt-5.6",
  store: false,
  input: history,
  reasoning: { context: "current_turn" },
});

// Keep replayable output, including encrypted reasoning and assistant phase.
history.push(...toResponseInputItems(first.output));
history.push({
  role: "user",
  content: "Now patch the bug and explain the change.",
});

const second = await client.responses.create({
  model: "gpt-5.6",
  store: false,
  input: history,
  reasoning: { context: "all_turns" },
});

console.log(second.output_text);
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)
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
	"github.com/openai/openai-go/v3/shared"
)

func main() {
	client := openai.NewClient()
	history := []responses.ResponseInputItemUnionParam{
		responses.ResponseInputItemParamOfMessage("Inspect this repository and identify the likely bug.", responses.EasyInputMessageRoleUser),
	}
	first, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model:     "gpt-5.6",
		Store:     openai.Bool(false),
		Input:     responses.ResponseNewParamsInputUnion{OfInputItemList: history},
		Reasoning: shared.ReasoningParam{Context: shared.ReasoningContextCurrentTurn},
	})
	if err != nil {
		panic(err)
	}
	history = append(history, outputAsInput(first.Output)...)
	history = append(history, responses.ResponseInputItemParamOfMessage(
		"Now patch the bug and explain the change.",
		responses.EasyInputMessageRoleUser,
	))
	second, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model:     "gpt-5.6",
		Store:     openai.Bool(false),
		Input:     responses.ResponseNewParamsInputUnion{OfInputItemList: history},
		Reasoning: shared.ReasoningParam{Context: shared.ReasoningContextAllTurns},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(second.OutputText())
}

func outputAsInput(output []responses.ResponseOutputItemUnion) []responses.ResponseInputItemUnionParam {
	input := make([]responses.ResponseInputItemUnionParam, 0, len(output))
	for _, item := range output {
		var converted responses.ResponseInputItemUnion
		if err := json.Unmarshal([]byte(item.RawJSON()), &converted); err != nil {
			panic(err)
		}
		input = append(input, converted.ToParam())
	}
	return input
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.Reasoning;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputItem;
import java.util.ArrayList;

var history = new ArrayList<ResponseInputItem>();
history.add(
    ResponseInputItem.ofEasyInputMessage(
        EasyInputMessage.builder()
            .role(EasyInputMessage.Role.USER)
            .content("Inspect this repository and identify the likely bug.")
            .build()));

var first =
    client
        .responses()
        .create(
            ResponseCreateParams.builder()
                .model("gpt-5.6")
                .inputOfResponse(history)
                .store(false)
                .reasoning(
                    Reasoning.builder()
                        .putAdditionalProperty("context", JsonValue.from("current_turn"))
                        .build())
                .build());
first.output().stream()
    .map(item -> JsonValue.from(item).convert(ResponseInputItem.class))
    .forEach(history::add);
history.add(
    ResponseInputItem.ofEasyInputMessage(
        EasyInputMessage.builder()
            .role(EasyInputMessage.Role.USER)
            .content("Now patch the bug and explain the change.")
            .build()));

client
    .responses()
    .create(
        ResponseCreateParams.builder()
            .model("gpt-5.6")
            .inputOfResponse(history)
            .store(false)
            .reasoning(
                Reasoning.builder()
                    .putAdditionalProperty("context", JsonValue.from("all_turns"))
                    .build())
            .build())
    .output()
    .stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
require "openai"

client = OpenAI::Client.new
history = [
  {
    role: :user,
    content: "Inspect this repository and identify the likely bug."
  }
]

first = client.responses.create(
  model: "gpt-5.6",
  store: false,
  input: history,
  reasoning: { context: :current_turn }
)
history.concat(first.output)
history << {
  role: :user,
  content: "Now patch the bug and explain the change."
}

second = client.responses.create(
  model: "gpt-5.6",
  store: false,
  input: history,
  reasoning: { context: :all_turns }
)

puts(second.output_text)

추론 항목을 컨텍스트에 유지하기 (Keeping reasoning items in context)

Responses API에서 추론 모델로 함수 호출을 할 때, 마지막 함수 호출과 함께 돌아온 추론 항목을 (함수의 출력에 더해) 다시 전달할 것을 강력히 권장해요. 모델이 연속으로 여러 함수를 호출한다면, 마지막 user 메시지 이후의 모든 추론 항목, 함수 호출 항목, 함수 호출 출력 항목을 전달해야 해요. 이렇게 해야 모델이 추론 과정을 계속해 토큰 효율적으로 더 나은 결과를 낼 수 있어요.

가장 간단한 방법은 이전 응답의 모든 추론 항목을 다음 응답에 전달하는 것이에요. 우리 시스템은 함수와 관련 없는 추론 항목을 똑똑하게 무시하고 관련된 것만 컨텍스트에 유지해요. 이전 응답의 추론 항목은 previous_response_id 파라미터를 사용하거나, 과거 응답의 모든 output 항목을 새 응답의 input에 수동으로 전달해서 넘길 수 있어요.

컨텍스트 창의 일부를 잘라내고 최적화한 뒤 다음 응답에 전달하는 고급 사용 사례라면, 마지막 사용자 메시지와 함수 호출 출력 사이의 모든 항목이 손대지 않은 채 다음 응답에 전달되도록 하세요. 이렇게 하면 모델이 필요한 모든 컨텍스트를 갖게 돼요.

수동 컨텍스트 관리에 대해 더 배우려면 이 가이드를 확인하세요.

대화 중간에 추론 변경하기 (Change reasoning mid-conversation)

어려운 작업에는 추론 노력을 높이고, 일상적인 후속 질문에는 줄이려면 configuration_update를 사용하세요. 응답 사이에 업데이트를 추가하고 요청 수준의 reasoning.effort는 그대로 두세요. 이렇게 하면 프롬프트 캐싱을 위한 원래 프롬프트 접두사를 보존해요.

구성 업데이트는 GPT-6 Astra(gpt-6-astra)의 standard, 단일 에이전트 모드에서만 지원돼요. 추론 노력만 변경해요.

HTTP Responses 요청 또는 WebSocket response.create 요청의 input 배열에서 다음 사용자 메시지 앞에 다음 항목을 추가하세요:

{
  "type": "configuration_update",
  "reasoning": {
    "effort": "high"
  }
}

예를 들어 대화가 요청 수준의 노력 low로 시작하면, 이 업데이트는 다음 응답과 그 후속 응답(다른 업데이트로 덮어쓰기 전까지)에 high를 선택해요.

후속 질문에 대한 추론 노력 높이기

import OpenAI from "openai";

const client = new OpenAI();
const model = "gpt-6-astra";

const first = await client.responses.create({
  model,
  reasoning: { effort: "low" },
  input: "Draft a database migration plan.",
});

const next = await client.responses.create({
  model,
  reasoning: { effort: "low" },
  previous_response_id: first.id,
  input: [
    { type: "configuration_update", reasoning: { effort: "high" } },
    {
      role: "user",
      content: "Analyze the failure modes and propose rollback steps.",
    },
  ],
});
console.log(next.output_text);
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)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
	"github.com/openai/openai-go/v3/shared"
)

func main() {
	client := openai.NewClient()
	ctx := context.Background()
	first, err := client.Responses.New(ctx, responses.ResponseNewParams{
		Store:     openai.Bool(true),
		Model:     "gpt-6-astra",
		Reasoning: shared.ReasoningParam{Effort: shared.ReasoningEffortLow},
		Input:     responses.ResponseNewParamsInputUnion{OfString: openai.String("Draft a database migration plan.")},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(first.OutputText())
	response, err := client.Responses.New(ctx, responses.ResponseNewParams{
		Model:              "gpt-6-astra",
		PreviousResponseID: openai.String(first.ID),
		// Keep the original request-level setting; the item updates the conversation.
		Reasoning: shared.ReasoningParam{Effort: shared.ReasoningEffortLow},
		Input: responses.ResponseNewParamsInputUnion{OfInputItemList: responses.ResponseInputParam{
			{OfConfigurationUpdate: &responses.ResponseConfigurationUpdateItemParam{
				Reasoning: responses.ResponseConfigurationUpdateItemParamReasoning{Effort: shared.ReasoningEffortHigh},
			}},
			responses.ResponseInputItemParamOfMessage("Analyze the failure modes and propose rollback steps.", responses.EasyInputMessageRoleUser),
		}},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(response.OutputText())
}
import com.openai.models.Reasoning;
import com.openai.models.ReasoningEffort;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseConfigurationUpdateItemParam;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputItem;
import java.util.List;

Response first =
    client
        .responses()
        .create(
            ResponseCreateParams.builder()
                .model("gpt-6-astra")
                .store(true)
                .reasoning(Reasoning.builder().effort(ReasoningEffort.LOW).build())
                .input("Draft a database migration plan.")
                .build());
Response response =
    client
        .responses()
        .create(
            ResponseCreateParams.builder()
                .model("gpt-6-astra")
                .previousResponseId(first.id())
                // Keep the original request-level setting; the item updates the conversation.
                .reasoning(Reasoning.builder().effort(ReasoningEffort.LOW).build())
                .inputOfResponse(
                    List.of(
                        ResponseInputItem.ofConfigurationUpdate(
                            ResponseConfigurationUpdateItemParam.builder()
                                .reasoning(
                                    ResponseConfigurationUpdateItemParam.Reasoning.builder()
                                        .effort(ReasoningEffort.HIGH)
                                        .build())
                                .build()),
                        ResponseInputItem.ofEasyInputMessage(
                            EasyInputMessage.builder()
                                .role(EasyInputMessage.Role.USER)
                                .content(
                                    "Analyze the failure modes and propose rollback steps.")
                                .build())))
                .build());
response.output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
require "openai"

client = OpenAI::Client.new
first = client.responses.create(
  model: "gpt-6-astra",
  store: true,
  reasoning: OpenAI::Models::Reasoning.new(effort: :low),
  input: "Draft a database migration plan."
)
puts(first.output_text)
response = client.responses.create(
  model: "gpt-6-astra",
  previous_response_id: first.id,
  # Keep the original request-level setting; the item updates the conversation.
  reasoning: OpenAI::Models::Reasoning.new(effort: :low),
  input: [
    OpenAI::Models::Responses::ResponseConfigurationUpdateItemParam.new(
      reasoning: OpenAI::Models::Responses::ResponseConfigurationUpdateItemParam::Reasoning.new(
        effort: :high
      )
    ),
    OpenAI::Models::Responses::EasyInputMessage.new(
      role: :user,
      content: "Analyze the failure modes and propose rollback steps."
    )
  ]
)
puts(response.output_text)

업데이트는 previous_response_id로 보존하거나, 대화 상태를 수동으로 관리할 때 원래 위치에 재생하세요. 응답의 reasoning.effort는 업데이트가 선택한 노력이 아니라 요청 수준 설정을 계속 보고해요.

대화 기록에 configuration_update 항목 두 개를 서로 바로 붙여 배치하지 마세요. API는 인접한 업데이트를 거부해요.

구성 업데이트를 자동 압축(compaction)이나 자동 잘림(truncation)과 결합하지 마세요. 독립형 /responses/compact 엔드포인트도 이 업데이트를 포함한 기록을 거부해요.

/responses 요청에 compaction_trigger 항목을 포함해 명시적으로 기록을 압축할 수는 있어요. 압축 후 다음 사용자 메시지 앞에 원하는 노력으로 새 configuration_update를 추가하세요.

일반적인 프롬프트 캐싱 요구사항은 여전히 적용돼요. 응답이 진행되는 동안 사용자 지시를 보내려면 중간 조종(Mid-turn steering)을 사용하세요.

추론 요약 (Reasoning summaries)

모델이 방출한 원시 추론 토큰은 노출하지 않지만, summary 파라미터를 사용해 모델 추론의 요약을 볼 수 있어요. 추론 요약을 지원하는 추론 모델을 확인하려면 모델 문서를 참고하세요.

모델에 따라 지원되는 추론 요약 설정이 달라요. 예를 들어 컴퓨터 사용 모델은 concise 요약기를 지원하고, o4-mini는 detailed를 지원해요. 모델에서 사용 가능한 가장 상세한 요약기에 접근하려면 이 파라미터 값을 auto로 설정하세요. auto는 오늘날 대부분의 추론 모델에서 detailed와 동일하지만, 미래에는 더 세분화된 설정이 있을 수 있어요.

추론 요약 출력은 reasoning 출력 항목summary 배열의 일부예요. 이 출력은 명시적으로 추론 요약 포함을 선택하지 않으면 포함되지 않아요.

아래 예시는 추론 요약을 포함한 API 요청을 만드는 방법을 보여줘요.

API 응답에 추론 요약 포함하기

import OpenAI from "openai";
const openai = new OpenAI();

const response = await openai.responses.create({
  model: "gpt-6-astra",
  input: "What is the capital of France?",
  reasoning: {
    effort: "low",
    summary: "auto",
  },
});

console.log(response.output);
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)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()

	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: "gpt-6-astra",
		Input: responses.ResponseNewParamsInputUnion{
			OfString: openai.String("What is the capital of France?"),
		},
		Reasoning: responses.ReasoningParam{
			Effort:  responses.ReasoningEffortLow,
			Summary: responses.ReasoningSummaryAuto,
		},
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(response.Output)
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.Reasoning;
import com.openai.models.ReasoningEffort;
import com.openai.models.responses.ResponseCreateParams;

ResponseCreateParams params =
    ResponseCreateParams.builder()
        .model("gpt-6-astra")
        .input("What is the capital of France?")
        .reasoning(
            Reasoning.builder()
                .effort(ReasoningEffort.LOW)
                .summary(Reasoning.Summary.AUTO)
                .build())
        .build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.reasoning().stream())
    .flatMap(reasoning -> reasoning.summary().stream())
    .forEach(summary -> System.out.println(summary.text()));
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);

CreateResponseOptions options = new()
{
    Model = "gpt-6-astra",
    ReasoningOptions = new ResponseReasoningOptions
    {
        ReasoningEffortLevel = ResponseReasoningEffortLevel.Low,
        ReasoningSummaryVerbosity = ResponseReasoningSummaryVerbosity.Auto,
    },
};
options.InputItems.Add(ResponseItem.CreateUserMessageItem("What is the capital of France?"));

ResponseResult response = await client.CreateResponseAsync(options);
foreach (ReasoningResponseItem reasoning in response.OutputItems.OfType<ReasoningResponseItem>())
{
    Console.WriteLine(reasoning.GetSummaryText());
}
Console.WriteLine(response.GetOutputText());
require "openai"

client = OpenAI::Client.new

response = client.responses.create(
  model: "gpt-6-astra",
  input: "What is the capital of France?",
  reasoning: {
    effort: :low,
    summary: :auto
  }
)

puts(response.output)
curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ***" \
  -d '{
    "model": "gpt-6-astra",
    "input": "What is the capital of France?",
    "reasoning": {
        "effort": "low",
        "summary": "auto"
    }
  }'

이 API 요청은 어시스턴트 메시지와 그 응답을 생성하는 모델 추론의 요약이 모두 담긴 output 배열을 반환해요.

[
  {
    "id": "rs_6876cf02e0bc8192b74af0fb64b715ff06fa2fcced15a5ac",
    "type": "reasoning",
    "summary": [
      {
        "type": "summary_text",
        "text": "**Answering a simple question**\n\nI\u2019m looking at a straightforward question: the capital of France is Paris. It\u2019s a well-known fact, and I want to keep it brief and to the point. Paris is known for its history, art, and culture, so it might be nice to add just a hint of that charm. But mostly, I\u2019ll aim to focus on delivering a clear and direct answer, ensuring the user gets what they\u2019re looking for without any extra fluff."
      }
    ]
  },
  {
    "id": "msg_6876cf054f58819284ecc1058131305506fa2fcced15a5ac",
    "type": "message",
    "status": "completed",
    "content": [
      {
        "type": "output_text",
        "annotations": [],
        "logprobs": [],
        "text": "The capital of France is Paris."
      }
    ],
    "role": "assistant"
  }
]

최신 추론 모델에서 요약기를 사용하기 전에, 안전한 배포를 보장하기 위해 조직 인증(organization verification)을 완료해야 할 수 있어요. 플랫폼 설정 페이지에서 인증을 시작하세요.

phase 파라미터

Responses API에서 GPT-5.5와 GPT-5.4와 함께 오래 실행되거나 툴이 많은 흐름을 사용할 때, 어시스턴트 메시지의 phase 필드를 사용해 조기 중단·기타 오작동을 피하세요. phase는 API 수준에서 선택 사항이지만 OpenAI는 사용을 권장해요. 중간 어시스턴트 업데이트(예: 툴 호출 전 서문)에는 phase: "commentary"를, 완성된 답에는 phase: "final_answer"를 사용하세요. 사용자 메시지에는 phase를 추가하지 마세요. previous_response_id를 사용하는 것이 보통 가장 간단한 경로인데, 이전 어시스턴트 상태가 보존되기 때문이에요. 어시스턴트 기록을 수동으로 재생한다면 각 원래 phase 값을 보존하세요. phase가 없거나 누락되면 그런 워크플로에서 서문이 최종 답으로 취급될 수 있어요. 모델별 프롬프트 지침은 GPT-5.5 프롬프팅을 참고하세요.

어시스턴트 phase 값 왕복하기 (Round-trip assistant phase values)

어시스턴트 phase 값 왕복하기

import OpenAI from "openai";
const client = new OpenAI();

const response = await 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.",
    },
  ],
});

console.log(response.output_text);
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)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	commentary := responses.ResponseInputItemParamOfMessage(
		"I’ll inspect the logs and then summarize root cause and remediation.",
		responses.EasyInputMessageRoleAssistant,
	)
	commentary.OfMessage.Phase = responses.EasyInputMessagePhaseCommentary
	finalAnswer := responses.ResponseInputItemParamOfMessage(
		"Root cause: cache invalidation race.",
		responses.EasyInputMessageRoleAssistant,
	)
	finalAnswer.OfMessage.Phase = responses.EasyInputMessagePhaseFinalAnswer
	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: "gpt-6-astra",
		Input: responses.ResponseNewParamsInputUnion{OfInputItemList: responses.ResponseInputParam{
			commentary,
			finalAnswer,
			responses.ResponseInputItemParamOfMessage("Great—now give me a rollout-safe fix plan.", responses.EasyInputMessageRoleUser),
		}},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(response.OutputText())
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputItem;
import java.util.List;

ResponseCreateParams params =
    ResponseCreateParams.builder()
        .model("gpt-6-astra")
        .inputOfResponse(
            List.of(
                ResponseInputItem.ofEasyInputMessage(
                    EasyInputMessage.builder()
                        .role(EasyInputMessage.Role.ASSISTANT)
                        .phase(EasyInputMessage.Phase.COMMENTARY)
                        .content(
                            "I'll inspect the logs and then summarize root cause and remediation.")
                        .build()),
                ResponseInputItem.ofEasyInputMessage(
                    EasyInputMessage.builder()
                        .role(EasyInputMessage.Role.ASSISTANT)
                        .phase(EasyInputMessage.Phase.FINAL_ANSWER)
                        .content("Root cause: cache invalidation race.")
                        .build()),
                ResponseInputItem.ofEasyInputMessage(
                    EasyInputMessage.builder()
                        .role(EasyInputMessage.Role.USER)
                        .content("Great—now give me a rollout-safe fix plan.")
                        .build())))
        .build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
require "openai"

client = OpenAI::Client.new

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."
    }
  ]
)

puts(response.output_text)

프롬프팅 조언 (Advice on prompting)

추론 모델을 프롬프팅할 때 다음 차이점을 고려하세요. 추론 가능한 GPT-5 모델은 명확한 목표, 강한 제약, 명시적 출력 계약을 주되 매 중간 단계를 일일이 지시하지 않을 때 가장 잘 동작해요.

  • 모델에게 작업, 제약, 원하는 출력 형식을 주세요.
  • reasoning.effort를 품질을 회복하는 주된 수단이 아닌 조정 손잡이로 취급하세요.
  • 에이전트 또는 연구 중심 워크플로에서는 무엇이 완료인지, 모델이 작업을 어떻게 검증해야 하는지 정의하세요.

추론 모델 사용 시 모범 사례에 대한 더 자세한 내용은 이 가이드를 참고하세요.

프롬프트 예시 (Prompt examples)

코딩 (리팩터링)

OpenAI o-시리즈 모델은 복잡한 알고리즘을 구현하고 코드를 만들 수 있어요. 이 프롬프트는 o1에게 특정 기준에 따라 React 컴포넌트를 리팩터링하도록 요청해요.

코드 리팩터링

import OpenAI from "openai";

const openai = new OpenAI();

const prompt = `
Instructions:
- Given the React component below, change it so that nonfiction books have red
  text.
- Return only the code in your reply
- Do not include any additional formatting, such as markdown code blocks
- For formatting, use four space tabs, and do not allow any lines of code to
  exceed 80 columns

const books = [
  { title: 'Dune', category: 'fiction', id: 1 },
  { title: 'Frankenstein', category: 'fiction', id: 2 },
  { title: 'Moneyball', category: 'nonfiction', id: 3 },
];

export default function BookList() {
  const listItems = books.map(book =>
    <li>
      {book.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}
`.trim();

const response = await openai.responses.create({
  model: "gpt-6-astra",
  input: [
    {
      role: "user",
      content: prompt,
    },
  ],
});

console.log(response.output_text);
from openai import OpenAI

client = OpenAI()

prompt = """
Instructions:
- Given the React component below, change it so that nonfiction books have red
  text.
- Return only the code in your reply
- Do not include any additional formatting, such as markdown code blocks
- For formatting, use four space tabs, and do not allow any lines of code to
  exceed 80 columns

const books = [
  { title: 'Dune', category: 'fiction', id: 1 },
  { title: 'Frankenstein', category: 'fiction', id: 2 },
  { title: 'Moneyball', category: 'nonfiction', id: 3 },
];

export default function BookList() {
  const listItems = books.map(book =>
    <li>
      {book.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}
"""

response = client.responses.create(
    model="gpt-6-astra",
    input=[
        {
            "role": "user",
            "content": prompt,
        }
    ],
)

print(response.output_text)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	prompt := `Instructions:
- Given the React component below, change it so that nonfiction books have red text.
- Return only the code in your reply.
- Do not include any additional formatting, such as markdown code blocks.

const books = [
  { title: 'Dune', category: 'fiction', id: 1 },
  { title: 'Frankenstein', category: 'fiction', id: 2 },
  { title: 'Moneyball', category: 'nonfiction', id: 3 },
];`


	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: "gpt-6-astra",
		Input: responses.ResponseNewParamsInputUnion{
			OfString: openai.String(prompt),
		},
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(response.OutputText())
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;

String prompt =
    """
    Instructions:
    - Given the React component below, change it so that nonfiction books have red text.
    - Return only the code in your reply.
    - Do not include any additional formatting, such as markdown code blocks.

    const books = [
    { title: 'Dune', category: 'fiction', id: 1 },
    { title: 'Frankenstein', category: 'fiction', id: 2 },
    { title: 'Moneyball', category: 'nonfiction', id: 3 },
    ];
    """
        .strip();

ResponseCreateParams params =
    ResponseCreateParams.builder().model("gpt-6-astra").input(prompt).build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);

string prompt =
    """
    Instructions:
    - Given the React component below, make nonfiction book titles red.
    - Return only the updated component code in your reply.
    - Do not include any additional formatting, such as markdown code blocks.
    - For formatting, use four space tabs, and do not allow any lines of code to
      exceed 80 columns.

    const books = [
      { title: 'Dune', category: 'fiction', id: 1 },
      { title: 'Frankenstein', category: 'fiction', id: 2 },
      { title: 'Moneyball', category: 'nonfiction', id: 3 },
    ];

    export default function BookList() {
      const listItems = books.map(book =>
        <li>
          {book.title}
        </li>
      );

      return (
        <ul>{listItems}</ul>
      );
    }
    """;
ResponseResult response = await client.CreateResponseAsync(
    "gpt-6-astra",
    [ResponseItem.CreateUserMessageItem(prompt)]
);
Console.WriteLine(response.GetOutputText());
require "openai"

client = OpenAI::Client.new
prompt = <<~PROMPT
  Instructions:
  - Given the React component below, change it so that nonfiction books have red text.
  - Return only the code in your reply.
  - Do not include any additional formatting, such as markdown code blocks.

  const books = [
    { title: 'Dune', category: 'fiction', id: 1 },
    { title: 'Frankenstein', category: 'fiction', id: 2 },
    { title: 'Moneyball', category: 'nonfiction', id: 3 },
  ];
PROMPT

response = client.responses.create(
  model: "gpt-6-astra",
  input: prompt
)

puts(response.output_text)

코딩 (계획)

OpenAI o-시리즈 모델은 다단계 계획을 만드는 데도 능숙해요. 이 예시 프롬프트는 o1에게 전체 솔루션을 위한 파일시스템 구조와 원하는 사용 사례를 구현하는 Python 코드를 만들도록 요청해요.

Python 프로젝트 계획 및 생성

import OpenAI from "openai";

const openai = new OpenAI();

const prompt = `
I want to build a Python app that takes user questions and looks
them up in a database where they are mapped to answers. If there
is close match, it retrieves the matched answer. If there isn't,
it asks the user to provide an answer and stores the
question/answer pair in the database. Make a plan for the directory
structure you'll need, then return each file in full. Only supply
your reasoning at the beginning and end, not throughout the code.
`.trim();

const response = await openai.responses.create({
  model: "gpt-6-astra",
  input: [
    {
      role: "user",
      content: prompt,
    },
  ],
});

console.log(response.output_text);
from openai import OpenAI

client = OpenAI()

prompt = """
I want to build a Python app that takes user questions and looks
them up in a database where they are mapped to answers. If there
is close match, it retrieves the matched answer. If there isn't,
it asks the user to provide an answer and stores the
question/answer pair in the database. Make a plan for the directory
structure you'll need, then return each file in full. Only supply
your reasoning at the beginning and end, not throughout the code.
"""

response = client.responses.create(
    model="gpt-6-astra",
    input=[
        {
            "role": "user",
            "content": prompt,
        }
    ],
)

print(response.output_text)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	prompt := `I want to build a Python app that takes user questions and looks them up
in a database where they are mapped to answers. If there is a close match, it
retrieves the matched answer. If there is not, it asks the user to provide an
answer and stores the question/answer pair in the database. Make a plan for the
directory structure you will need, then return each file in full.`

	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: "gpt-6-astra",
		Input: responses.ResponseNewParamsInputUnion{
			OfString: openai.String(prompt),
		},
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(response.OutputText())
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;

String prompt =
    """
    I want to build a Python app that looks up user questions in a database where
    they are mapped to answers. If there is a close match, it retrieves the answer.
    Otherwise, it asks the user for an answer and stores the question and answer.
    Plan the directory structure, then return each file in full.
    """
        .strip();

ResponseCreateParams params =
    ResponseCreateParams.builder().model("gpt-6-astra").input(prompt).build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);

string prompt =
    """
    I want to build a Python app that looks up user questions in a database where
    they are mapped to answers. If there is a close match, it retrieves the answer.
    Otherwise, it asks the user for an answer and stores the question and answer.
    Plan the directory structure, then return each file in full.
    Only supply your reasoning at the beginning and end, not throughout the code.
    """;
ResponseResult response = await client.CreateResponseAsync("gpt-6-astra", prompt);

Console.WriteLine(response.GetOutputText());
require "openai"

client = OpenAI::Client.new
prompt = <<~PROMPT
  I want to build a Python app that looks up user questions in a database where
  they are mapped to answers. If there is a close match, it retrieves the answer.
  Otherwise, it asks the user for an answer and stores the question and answer.
  Plan the directory structure, then return each file in full.
PROMPT

response = client.responses.create(
  model: "gpt-6-astra",
  input: prompt
)

puts(response.output_text)

STEM 연구

OpenAI o-시리즈 모델은 STEM 연구에서 뛰어난 성능을 보여줬어요. 기초 연구 작업을 지원하는 프롬프트는 강한 결과를 보여줘야 해요.

기초 과학 연구 관련 질문하기

import OpenAI from "openai";

const openai = new OpenAI();

const prompt = `
What are three compounds we should consider investigating to
advance research into new antibiotics? Why should we consider
them?
`;

const response = await openai.responses.create({
  model: "gpt-6-astra",
  input: [
    {
      role: "user",
      content: prompt,
    },
  ],
});

console.log(response.output_text);
from openai import OpenAI

client = OpenAI()

prompt = """
What are three compounds we should consider investigating to
advance research into new antibiotics? Why should we consider
them?
"""

response = client.responses.create(
    model="gpt-6-astra", input=[{"role": "user", "content": prompt}]
)

print(response.output_text)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	prompt := `What are three compounds we should consider investigating to advance
research into new antibiotics? Why should we consider them?`

	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: "gpt-6-astra",
		Input: responses.ResponseNewParamsInputUnion{
			OfString: openai.String(prompt),
		},
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(response.OutputText())
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;

String prompt =
    """
    What are three compounds we should consider investigating to advance research
    into new antibiotics? Why should we consider them?
    """
        .strip();

ResponseCreateParams params =
    ResponseCreateParams.builder().model("gpt-6-astra").input(prompt).build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);

string prompt =
    """
    What are three compounds we should investigate to advance research into
    new antibiotics? Why should we consider them?
    """;
ResponseResult response = await client.CreateResponseAsync(
    "gpt-6-astra",
    [ResponseItem.CreateUserMessageItem(prompt)]
);
Console.WriteLine(response.GetOutputText());
require "openai"

client = OpenAI::Client.new
prompt = <<~PROMPT
  What are three compounds we should consider investigating to advance research
  into new antibiotics? Why should we consider them?
PROMPT

response = client.responses.create(
  model: "gpt-6-astra",
  input: prompt
)

puts(response.output_text)

사용 사례 예시 (Use case examples)

추론 모델을 실제 사용 사례에 활용한 예시는 쿡북에서 찾을 수 있어요.

추론을 데이터 검증에 사용하기 — 합성 의료 데이터셋에서 불일치 평가하기

추론을 일상 생성에 사용하기 — 헬프 센터 문서로 에이전트가 수행할 수 있는 액션 생성하기

더 알아보기 (Learn more)