For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
기본 탐색 메뉴
Theme

API 배포 체크리스트

배포 품질과 신뢰성을 높이고 속도와 비용을 개선하는 데 효과적이지만 흔히 놓치는 설계 방법을 소개합니다.

목차 기대 효과
Responses API 사용 품질, 비용, 지연 시간, 신뢰성
워크로드에 맞는 모델 선택 품질, 비용, 지연 시간
reasoning.effort 설정 품질, 비용, 지연 시간
대화 중 추론 수준 변경 품질, 비용, 지연 시간
text.verbosity 설정 품질, 비용, 지연 시간
어시스턴트 메시지의 phase 매개변수 설정 품질, 비용
tool_search 사용 비용, 지연 시간
프로그래밍 방식으로 도구 호출 품질, 비용, 지연 시간
멀티 에이전트로 작업 병렬 처리 품질, 비용, 지연 시간
비동기 도구 호출 사용 지연 시간
내장 도구 활용 품질
컨텍스트 압축 활용 비용
프롬프트 캐싱 최적화 지연 시간, 비용
reasoning.encrypted_content 사용 품질, 지연 시간
작업에 맞게 이미지 세부 수준 설정 품질, 비용, 지연 시간
안전 식별자 전송 안전성, 신뢰성
정렬 이탈 모니터링에 대응 안전성, 신뢰성
트래픽 급증 및 모델 과부하에 대응 신뢰성
background=True 사용 작업 연속성
WebSocket 모드 사용 지연 시간
턴 진행 중 지시 추가 품질

Responses API 사용

항상 처음부터 Responses API를 사용하세요. OpenAI의 대표 API로, 최신 모델 동작과 내장 도구, 상태를 유지하는 워크플로우, 에이전트 기능을 활용하기에 가장 적합합니다.

워크로드에 맞는 모델 선택

GPT-6 모델 제품군이 워크로드에 얼마나 적합한지 평가하세요. gpt-6-astra는 가장 뛰어난 성능이 필요할 때, gpt-6.1-sol은 Astra보다 낮은 비용으로 복잡한 코딩과 전문 업무를 처리할 때, gpt-6-luna는 반복 가능한 작업을 효율적으로 처리할 때 사용하세요. 모든 요청을 가장 강력한 모델로 보내기보다는 대표 작업에서 성능이 좋은 모델을 선택하세요.

GPT-6로 마이그레이션할 때는 지원되는 범위에서 기존 모델이 워크로드에서 맡았던 역할과 실제 적용된 추론 수준을 유지하세요. 도구를 활용한 추론에는 Responses API를 사용하세요. GPT-6 Astra와 GPT-6.1 Sol에서 도구를 호출하려면 Responses를 사용해야 합니다. GPT-6 Sol과 GPT-6 Luna는 reasoning_effort: "none"으로 설정한 경우에만 Chat Completions에서 함수 호출을 지원합니다. 추론 수준이 none이 아니면 temperature, top_p, top_logprobs를 제거하세요. 또한 logprobs는 Chat Completions 요청에서 제거하고, message.output_text.logprobs는 Responses의 include 배열에서 제거하세요. 모델이나 처리 등급을 선택하기 전에 데이터 레지던시 지원 여부를 확인하세요. 그 밖의 호환성 확인 사항은 모델 마이그레이션 가이드를 참고하세요. 프롬프트를 변경하거나 새 기능을 추가하기 전에 대표 작업으로 평가를 실행하세요. 작업 성공 여부와 지연 시간, 입력·출력·추론·캐시 쓰기 토큰 수, 성공한 작업당 비용을 비교하세요.

reasoning.effort 설정

reasoning.effort로 모델이 답변하기 전에 얼마나 깊이 추론할지 설정하세요.

GPT-6 Astra, GPT-6.1 Sol, GPT-6 Sol, GPT-6 Luna는 low, medium, high, xhigh, max를 지원합니다. GPT-6 Sol과 GPT-6 Luna는 none도 지원하지만 GPT-6 Astra와 GPT-6.1 Sol은 지원하지 않습니다. 추론 수준을 낮추면 응답이 빨라지고 추론 토큰 사용량이 줄어듭니다. 수준을 높이면 모델이 계획 수립, 디버깅, 정보 종합, 여러 단계에 걸친 장단점 검토에 더 많은 시간을 쓸 수 있습니다.

정보 추출, 라우팅, 분류, 정형화된 문장 수정이 주된 작업이라면 low를 사용하세요. 문제를 진단하거나 선택지를 비교하고, 계획을 세우거나 코드의 동작을 추론해야 한다면 medium 또는 high를 사용하세요. xhigh 또는 max는 대표 작업 평가에서 지연 시간과 비용 증가를 감수할 만큼 품질이 향상된 경우에만 사용하세요. minimal에서 마이그레이션하거나 none을 사용하다가 GPT-6 Astra 또는 GPT-6.1 Sol로 전환하는 경우 low부터 시작해 결과를 비교하세요. 그 밖의 경우에는 현재 적용된 추론 수준을 유지하고, 설정을 바꿨을 때 품질, 지연 시간, 비용 목표를 충족하는지 테스트하세요.

품질이 최우선인 고난도 워크로드라면 같은 추론 수준에서 reasoning.mode: "pro"와 표준 모드도 비교하세요. 추론 모드와 추론 수준은 서로 독립적입니다. Pro 모드에서는 모델이 하나의 최종 답변을 반환하기 전에 더 많은 연산을 수행하므로 신뢰성이 높아질 수 있지만 지연 시간과 토큰 사용량도 늘어납니다.

작업에 맞게 추론 수준 조정
from openai import OpenAI

client = OpenAI()

prompt = """
Our CI job started failing after a dependency bump.

Error:
TypeError: Timeout.__init__() got an unexpected keyword argument 'connect'

Identify the likeliest root cause and the smallest safe fix.
"""

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

print(response.output_text)

대화 중 추론 수준 변경

GPT-6 모델을 표준 단일 에이전트 모드로 사용할 때는 다음 사용자 메시지 앞에 configuration_update 입력 항목을 추가해 응답 사이에 추론 수준을 변경할 수 있습니다. 기존 프롬프트 접두부를 계속 캐싱할 수 있도록 요청 수준의 reasoning.effort는 그대로 두세요. 변경 사항은 다음 응답부터 적용되며 이후 다른 업데이트로 덮어쓸 때까지 유지됩니다. 구성 업데이트는 자동 컨텍스트 압축이나 잘라내기와 함께 사용할 수 없으며, /responses/compact는 구성 업데이트가 포함된 대화 기록을 거부합니다. 대화 기록을 압축하려면 compaction_trigger 항목을 포함하고 그 뒤에 새 업데이트를 추가하세요.

text.verbosity 설정

text.verbosity는 답변의 간결함과 충실도 사이에서 균형을 맞추는 기본 설정입니다. 제품에 짧고 빠른 답변이 필요하면 상세도를 낮추세요. 설명을 더 자세히 하거나 구조를 명확히 하고 맥락을 빠짐없이 전달해야 한다면 상세도를 높이세요. 상세도를 낮추면 생성할 출력 토큰이 줄어 결과를 더 빨리 반환합니다.

코딩 작업에서는 medium과 high가 대체로 더 길고 체계적이며 구조가 명확한 출력을 생성합니다. low는 답변을 짧게 유지하고 꼭 필요한 내용만 담습니다.

마이그레이션할 때는 “간결하게 답하세요” 같은 포괄적인 지시가 여전히 도움이 되는지 확인하세요. 기본 상세도는 가급적 text.verbosity로 조정하고, 필수 내용과 구조, 길이는 프롬프트로 지정하세요.

프롬프트도 품질과 토큰 사용량, 비용, 지연 시간에 영향을 줍니다. 상세도를 설정할 때는 최신 모델의 프롬프트 작성 권장 사항을 함께 살펴보세요. 코딩 에이전트의 테스트 및 검증 지침도 포함되어 있습니다.

간결한 출력을 위해 상세도 낮추기
from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-6-astra",
    text={"verbosity": "low"},
    input="""
    Summarize this incident for the next on-call engineer.
    - checkout latency spiked from 220 ms to 4.8 s
    - only us-east-1 was affected
    - rollback is complete
    - likely trigger: cache stampede after deploy
    """,
)

print(response.output_text)

어시스턴트 메시지의 phase 매개변수 설정

phase는 대화 기록에서 어시스턴트 메시지에 붙이는 레이블입니다. 이전 어시스턴트 메시지가 작업 중 진행 상황을 알린 것인지 최종 답변인지 모델에 알려 줍니다. 진행 상황 안내, 도구 호출 전 안내 등 중간 메시지에는 phase: "commentary"를 사용하세요. 완성된 응답에는 phase: "final_answer"를 사용하세요.

예를 들어 어시스턴트가 다음과 같은 메시지를 보낼 수 있습니다.

어시스턴트의 진행 상황 메시지
{
  "role": "assistant",
  "phase": "commentary",
  "content": "I'm checking the logs and comparing them to the last successful deploy."
}

이 메시지는 진행 상황을 알리기 위한 것입니다. 실제 답변은 이후에 다음과 같이 전달할 수 있습니다.

어시스턴트의 최종 답변 메시지
{
  "role": "assistant",
  "phase": "final_answer",
  "content": "The deploy failed because the migration referenced a column that does not exist in production."
}

이 구분은 어시스턴트가 작업을 마치기 전에 사용자에게 진행 상황을 알릴 수 있는 장시간 워크플로우나 도구를 자주 호출하는 워크플로우에서 유용합니다. gpt-5.3-codex 및 이후 모델의 후속 요청에 대화 기록을 포함할 때는 어시스턴트 메시지의 phase를 유지해 다시 전송하세요. 그래야 모델이 진행 상황과 최종 결과를 구분할 수 있습니다. 에이전트가 도중에 멈출 가능성이 줄어 최종 답변을 낼 때까지 작업을 이어가기 쉽습니다.

tool_search 사용

요청마다 전체 도구 목록을 로드하는 대신 도구 검색을 사용하세요. {"type": "tool_search"}를 추가하고 로드 비용이 큰 도구 정의에 defer_loading: true를 지정하면 모델이 실행 시점에 필요한 도구만 로드할 수 있습니다. 요청을 시작할 때 모델에는 검색 도구의 이름과 설명만 보입니다. 모델이 로드를 미룬 도구가 필요하다고 판단해 도구 검색을 실행하면 비로소 해당 도구 정의가 컨텍스트에 로드됩니다. 그때부터 모델이 해당 도구를 호출할 수 있습니다. 이렇게 하면 토큰을 절약하고 캐시 성능을 유지할 수 있습니다.

도구 검색에는 두 가지 모드가 있습니다.

  • 호스팅형 도구 검색이 더 간단합니다. 요청에 어떤 도구를 제공할 수 있는지 미리 아는 경우에 사용하세요.
  • 클라이언트 실행형 도구 검색은 사용자 테넌트, 프로젝트, 권한, 내부 레지스트리 등에 따라 앱이 사용 가능한 도구를 결정해야 할 때 사용하세요.

앱에서 도구 탐색을 직접 제어해야 하는 경우가 아니라면 호스팅형 도구 검색부터 시작하세요.

사용자 의도에 따라 도구를 그룹화하세요. 가능하면 네임스페이스나 MCP 서버를 사용하세요. 모델은 함수가 나열된 긴 목록보다 용도가 명확한 몇 개의 그룹에서 더 쉽게 선택할 수 있습니다. 토큰 효율과 모델 성능을 최적화하려면 네임스페이스마다 함수 수를 대략 10개 미만으로 유지하는 것이 좋습니다.

네임스페이스 설명은 짧게 쓰되 서로의 용도를 구분할 수 있게 하세요. 자세한 지침은 나중에 로드할 도구 정의에 넣으세요. 모든 도구를 하나의 거대한 네임스페이스에 모으지 마세요.

지연 로딩 도구에 호스팅형 도구 검색 사용
from openai import OpenAI

client = OpenAI()

billing_namespace = {
    "type": "namespace",
    "name": "billing",
    "description": "Billing tools for invoices, payments, taxes, and credits.",
    "tools": [
        {
            "type": "function",
            "name": "lookup_invoice",
            "description": "Look up invoice state, taxes, credits, and payment attempts.",
            "parameters": {
                "type": "object",
                "properties": {
                    "invoice_id": {"type": "string"},
                },
                "required": ["invoice_id"],
                "additionalProperties": False,
            },
            "strict": True,
            "defer_loading": True,
        }
    ],
}

crm_namespace = {
    "type": "namespace",
    "name": "crm",
    "description": "CRM tools for account ownership, plans, health, and payment history.",
    "tools": [
        {
            "type": "function",
            "name": "get_account",
            "description": "Fetch account owner, plan, health, and payment history.",
            "parameters": {
                "type": "object",
                "properties": {
                    "account_id": {"type": "string"},
                },
                "required": ["account_id"],
                "additionalProperties": False,
            },
            "strict": True,
            "defer_loading": True,
        }
    ],
}

response = client.responses.create(
    model="gpt-6-astra",
    input=(
        "Find the right billing tool and explain why invoice INV-1043 still "
        "shows overdue after a payment yesterday."
    ),
    tools=[billing_namespace, crm_namespace, {"type": "tool_search"}],
)

print(response.output)

프로그래밍 방식으로 도구 호출

프로그래밍 방식의 도구 호출을 지원하는 모델은 JavaScript를 작성해 호스팅 런타임에서 지원 대상 도구를 호출하고 중간 결과의 크기를 줄일 수 있습니다. 처리 범위가 명확하고 도구가 반환한 대량의 결과를 코드로 가공할 수 있는 단계에 사용하세요. 결과를 필터링하거나 조인하고, 순위를 매기거나 중복을 제거하고, 결과를 결합하거나 검사한 뒤 더 작은 구조화된 결과를 모델에 반환할 수 있습니다.

programmatic_tool_calling 도구를 추가하고 이 방식으로 호출할 각 도구에서 기능을 활성화하세요. 프로그램에서만 호출할 도구에는 allowed_callers: ["programmatic"]을 사용하세요. 모델이 직접 호출해도 되는 도구에는 allowed_callers: ["direct", "programmatic"]을 사용하세요. 각 결과에 따라 모델의 다음 결정이 달라질 수 있거나, 작업에 승인이 필요하거나, 최종 답변에 인용이나 도구 고유의 산출물을 그대로 담아야 한다면 직접 호출 방식을 유지하세요. 모델이 결과를 먼저 살펴보지 않고도 올바른 프로그램을 작성할 수 있도록 도구의 반환 필드와 오류 발생 시 동작을 문서화하세요.

도구 호출 루프는 program과 program_output 항목뿐 아니라 프로그램이 생성한 function_call 항목과 그에 대응하는 function_call_output 항목도 처리해야 합니다. 서비스가 올바른 프로그램을 재개할 수 있도록 각 call_id를 유지하고 함수 호출의 caller를 해당 호출의 출력에 복사하세요.

program_output과 어시스턴트의 최종 메시지를 모두 테스트하세요. 프로그램 결과가 정확해도 최종 답변에는 내용이 빠질 수 있습니다. 같은 워크플로우에서 도구를 직접 호출했을 때와 비교해 작업 성공 여부, 필수 근거 포함 여부, 총 토큰 수, 지연 시간, 비용을 평가하세요.

멀티 에이전트로 작업 병렬 처리

멀티 에이전트를 지원하는 GPT-6 등의 모델은 서로 독립적인 작업을 하위 에이전트에 위임하고 결과를 종합할 수 있습니다. 조사, 분석, 구현을 각각 별도의 컨텍스트에서 병렬로 실행할 수 있는 구체적이고 범위가 명확한 작업으로 나눌 수 있을 때 사용하세요.

요청에서 multi_agent.enabled를 true로 설정하세요. HTTP에서는 베타 Responses SDK의 client.beta.responses를 사용하고 responses_multi_agent=v1을 betas에 전달하세요. HTTP를 직접 사용하거나 WebSocket으로 연결하는 경우 OpenAI-Beta: responses_multi_agent=v1을 전송하세요. 멀티 에이전트가 베타 단계인 동안에는 항목 스키마가 변경될 수 있습니다.

짧은 작업, 각 단계가 직전 단계에 의존하는 순차 작업, 변경 가능한 동일한 리소스에 쓰는 작업에는 에이전트 하나를 사용하는 것이 좋습니다. 하위 에이전트는 토큰 사용량을 늘릴 수 있으므로 max_concurrent_subagents의 기본값인 3으로 시작해 전체 작업의 품질, 지연 시간, 비용을 측정하세요. 도구를 자주 호출하거나 오래 실행되는 멀티 에이전트 워크플로우에서는 WebSocket 모드로 작업을 이어가는 데 드는 오버헤드를 줄일 수 있습니다.

멀티 에이전트를 활성화하기 전에 현재 제약 사항을 확인하세요. /responses/compact, reasoning.summary, max_tool_calls는 지원되지 않습니다. 서버가 루트 컨텍스트와 각 하위 에이전트의 컨텍스트를 자동으로 압축합니다.

비동기 도구 호출 사용

GPT-6 모델에서는 애플리케이션이 도구를 실행하는 동안 모델이 다른 작업을 계속할 수 있다면 함수 도구나 사용자 정의 도구에 async: true를 설정하세요. 오래 걸리는 도구 호출을 일찍 시작하고 모델이 그동안 독립적인 작업을 처리하게 하세요. 호출 실행과 추적은 여전히 애플리케이션이 담당하며, 이후 Responses 요청에서 원래 call_id와 함께 결과를 반환합니다. 비동기 실행은 내장 도구나 프로그래밍 방식의 도구 호출에는 적용되지 않습니다. 멀티 에이전트 모드에서는 비동기 도구와 병렬 도구 호출을 함께 사용하지 마세요. 전체 플로우는 비동기 도구 호출을 참고하세요.

내장 도구 활용

내장 도구는 API가 기본으로 제공하는 기능입니다. 모든 도구를 직접 구현하는 대신 Responses API에서 이미 동작하는 도구를 모델에 제공할 수 있습니다. 모델은 해당 도구를 언제 사용할지 결정합니다.

OpenAI는 내장 도구를 계속 추가하고 있습니다. 워크플로우에 적합한 내장 도구가 있으면 먼저 사용하고, 내장 도구로 처리할 수 없는 작업에는 사용자 정의 도구를 구현하세요. 현재 제공되는 내장 도구 및 관련 옵션은 다음과 같습니다.

  • 웹 검색: 웹에서 최신 정보 검색
  • 파일 검색: 업로드한 파일 또는 벡터 저장소 검색
  • 코드 인터프리터: Python을 실행해 분석, 수학 연산, 차트 작성, 파일 처리 수행
  • 셸: 호스팅 컨테이너나 자체 런타임에서 셸 명령어 실행
  • 컴퓨터 사용: 스크린샷, 클릭, 텍스트 입력, 스크롤로 UI 조작
  • 이미지 생성: 이미지 생성 또는 편집
  • MCP/커넥터: 모델을 외부 서비스 및 도구에 연결
  • 스킬: 재사용 가능한 지침 묶음과 워크플로우 파일 첨부
  • 패치 적용: 구조화된 방식으로 코드 수정

모델 품질도 내장 도구를 우선 사용할 이유입니다. 내장 도구는 OpenAI의 사후 학습 데이터 분포에 속합니다. 즉, 모델은 이러한 도구의 형식과 동작, 출력을 바탕으로 학습과 평가를 거칩니다. 따라서 OpenAI 모델은 새로운 도구를 사용할 때보다 내장 도구를 사용할 때 도구를 더 정확히 선택하고 원활하게 실행하며 실패도 적습니다.

컨텍스트 압축 활용

컨텍스트 압축은 여러 턴에 걸쳐 모델이 어떤 정보를 계속 유지할지 결정하는 컨텍스트 엔지니어링 도구입니다. 오래 실행되는 에이전트에서는 “컨텍스트 한도에 도달할까?”라는 질문만으로는 충분하지 않습니다. 이전 메시지, 도구 로그, 재시도 기록, 오래된 세부 정보가 쌓이면서 모델에 필요한 상태 정보가 밀려납니다.

컨텍스트 압축을 사용하면 후속 턴에 필요한 상태를 보존하면서 컨텍스트 크기를 줄일 수 있습니다. 디버깅 단계를 마치거나 근본 원인의 범위를 좁히는 등 의미 있는 진전이 있으면 이전 컨텍스트 윈도우를 압축하고 그 출력에서 작업을 이어갈 수 있습니다. 다음 턴에서는 모든 중간 추론과 실패한 명령어, 더 이상 유효하지 않은 추론 경로를 다시 다룰 필요가 없어 모델이 중요한 상태 정보에 집중할 수 있습니다.

컨텍스트 압축을 사용하는 방법은 두 가지입니다.

  • 서버에 맡기기: previous_response_id를 사용한다면 context_management를 활성화하고 compact_threshold를 지정하세요. 대화가 너무 커지면 서버가 자동으로 압축합니다. 클라이언트는 계속 최신 사용자 메시지만 전송하면 됩니다.
  • 직접 처리하기: 전체 입력 배열을 직접 관리한다면 client.responses.compact()를 호출하세요. 더 작은 컨텍스트 윈도우가 반환됩니다. 반환된 출력을 다음 responses.create() 호출에 그대로 사용하세요.

압축된 출력을 수정하지 마세요. 이 출력은 사람이 읽는 요약문이 아니라 모델이 작업을 이어가는 데 필요한 내부 상태입니다. 그대로 전달한 뒤 다음 사용자 메시지를 추가하세요.

압축된 응답 상태에서 작업 이어가기
from openai import OpenAI

client = OpenAI()

# Full window collected from a long debugging session:
# user messages, assistant outputs, tool calls, and tool outputs.
long_window = session_items

compacted = client.responses.compact(
    model="gpt-6-astra",
    input=long_window,
)

next_response = client.responses.create(
    model="gpt-6-astra",
    store=False,
    input=[
        *compacted.output,  # Use compact output as-is.
        {
            "type": "message",
            "role": "user",
            "content": (
                "We found the bad cache invalidation path. Write the fix plan "
                "and the verification checklist."
            ),
        },
    ],
)

print(next_response.output_text)

프롬프트 캐싱 최적화

프롬프트 캐싱은 여러 요청이 동일한 긴 접두부를 재사용할 때 지연 시간과 비용을 자동으로 줄입니다. 바뀌지 않는 지침, 예시, 참고 자료를 먼저 배치하고 사용자마다 달라지는 내용을 그 뒤에 넣으세요. 도구 정의와 순서를 일정하게 유지하고, 이전 컨텍스트를 다시 작성하지 말고 새 대화 턴을 뒤에 추가하세요.

GPT-5.6부터 명시적 프롬프트 캐싱을 사용할 수 있습니다. 기본값은 여전히 암시적 캐싱이지만, GPT-5.6 및 이후 모델 제품군은 명시적 캐시 분기점과 요청 전체에 적용되는 캐시 정책도 지원합니다. 고정된 접두부 뒤에 바뀌는 내용이 있다면 재사용할 부분이 끝나는 지점에 prompt_cache_breakpoint를 명시적으로 추가하세요. 암시적 분기점 없이 직접 지정한 분기점만 요청에 적용하려는 경우에만 prompt_cache_options.mode를 explicit으로 설정하세요. 이전 모델은 계속 자동 프롬프트 캐싱만 사용합니다.

GPT-5.5 또는 이전 모델에서 마이그레이션할 때는 prompt_cache_retention을 prompt_cache_options.ttl: "30m"으로 교체하세요. 캐시 설정을 변경하기 전에 모델별 프롬프트 캐싱 차이를 확인하세요.

GPT-5.6 및 이후 모델 제품군에서 캐시 쓰기 단가는 캐싱되지 않은 입력 토큰 단가의 1.25배입니다. cached_tokens와 cache_write_tokens를 기록하고, 쓰기량과 이후 캐시 읽기량을 비교해 순비용을 측정하고 분기점 위치를 조정하세요.

재사용 가능한 접두부를 공유하는 요청에는 일관된 prompt_cache_key를 사용하세요. 관련 요청을 같은 캐시로 라우팅하는 데 도움이 되며 GPT-5.6 이전 모델의 캐시 적중률을 최적화할 수 있습니다. 트래픽이 많은 그룹은 더 많은 키로 트래픽을 분산하는 방법을 참고하세요.

GPT-5.6 이상에서는 prompt_cache_key가 선택 사항이며 키 없이도 최적의 캐시 적중률을 달성할 수 있습니다. 키를 사용하면 고객, 사용자 또는 워크스페이스별로 캐시 사용량을 따로 집계할 수 있어 각 그룹의 캐시 토큰 사용량과 청구 내역을 설명하기 쉽습니다. 고객마다 고유한 키를 할당하고 해당 고객의 관련 요청에서는 같은 키를 유지하세요. 키를 분리하면 한 고객이 다른 고객의 캐시 적중 여부를 탐지하는 것도 방지하는 데 도움이 됩니다. 키를 사용한 캐시 사용량 분리 집계를 참고하세요.

고객별 캐시 사용량 분리 집계
from openai import OpenAI

client = OpenAI()

instructions = """
You are the support agent for Acme.
Follow the Acme support policy and escalation rubric.
Use the same tone, safety rules, and tool plan for each ticket.
"""

response = client.responses.create(
    model="gpt-6-astra",
    prompt_cache_key="tenant-acme-support-agent",
    instructions=instructions,
    input="Summarize the current escalation for the on-call lead.",
)

print(response.output_text)

reasoning.encrypted_content 사용

GPT-6를 비롯한 지원 모델은 호출 간에 추론을 유지할 수 있습니다. 작업의 목표, 가정, 우선순위가 일정하게 유지되면 reasoning.context: "all_turns"를 사용하세요. 이전 추론이 더 이상 관련이 없고 모델이 낡은 접근 방식에 얽매일 수 있다면 current_turn을 사용하세요. reasoning.context를 생략하거나 auto로 설정했다면 응답의 reasoning.context 필드에서 실제 적용된 모드를 확인하세요.

추론 유지는 이전 추론 항목을 사용할 수 있을 때만 작동합니다. 저장된 응답에는 previous_response_id를 사용하세요. 데이터 비보관(ZDR) 요건에 따라 응답 데이터를 저장할 수 없다면 암호화된 추론 내용을 사용해 서버에 상태를 저장하지 않고 다음 호출로 작업을 넘길 수 있습니다.

응답으로 출력되는 추론 항목에는 기본적으로 암호화된 추론 내용이 포함됩니다. 각 추론 항목의 encrypted_content 속성에서 이 내용에 접근할 수 있습니다. 앱이 해당 값을 해석할 필요는 없습니다. 각 추론 항목을 반환된 그대로 유지했다가 다음 턴에 다시 전송하면 모델이 이를 사용해 워크플로우를 이어갈 수 있습니다.

상태를 저장하지 않고 턴 간에 암호화된 추론 전달
from openai import OpenAI

client = OpenAI()

history = [
    {
        "role": "user",
        "content": "Investigate why invoice INV-1043 has mismatched tax totals.",
    }
]

first = client.responses.create(
    model="gpt-6-astra",
    store=False,
    reasoning={"effort": "medium", "context": "current_turn"},
    input=history,
)

history.extend(item.to_dict() for item in first.output)
history.append(
    {
        "role": "user",
        "content": "Now write the customer-facing explanation in plain English.",
    }
)

second = client.responses.create(
    model="gpt-6-astra",
    store=False,
    reasoning={"effort": "medium", "context": "all_turns"},
    input=history,
)

print(second.output_text)

작업에 맞게 이미지 세부 수준 설정

이미지의 detail 기본값은 auto이며 크기를 조정하는 방식은 모델에 따라 다릅니다. 큰 이미지는 입력 토큰을 더 많이 사용하고 지연 시간을 늘릴 수 있습니다. 모델별 이미지 크기 조정 표를 확인하고, 배포 전에 선택한 모델로 이미지 토큰 사용량을 측정하고 한도를 확인하세요.

작업에 적합한 detail을 선택하세요. 이미지 크기를 조정하거나, 미세한 시각적 차이가 중요하지 않다면 low를 사용하세요. 일반적인 고정밀 이미지 분석에는 high를 사용하세요. 크거나 정보가 밀집한 이미지 분석, 좌표에 민감한 작업, OCR, 위치 식별, 시각 검사처럼 세부 정보를 더 많이 확보하면 품질이 높아지는 작업에는 모델이 지원하는 경우 original을 사용하세요. 배포 전에 최악의 조건에서 이미지 토큰 사용량과 지연 시간을 측정하세요.

안전 식별자 전송

개별 최종 사용자에게 서비스를 제공하는 애플리케이션이라면 개인정보를 보호하면서 일관되게 사용할 수 있는 safety_identifier를 요청마다 전송하세요. 이 식별자는 OpenAI가 오용을 감지하고 팀이 정책 위반을 일관되게 추적하는 데 도움이 됩니다. 또한 한 사용자의 오용으로 조직 전체의 접근이 제한될 가능성을 줄여 줍니다.

개인을 식별할 수 있는 정보를 직접 전송하는 대신 사용자 이름이나 이메일 주소를 해시하세요. 로그인하지 않은 사용자에게는 일관된 세션 ID를 사용하세요.

정렬 이탈 모니터링에 대응

GPT-6 Astra 에이전트 워크플로우를 설계할 때는 정렬 이탈 모니터링에 어떻게 대응할지 계획하세요. 요청이 403과 함께 misalignment_policy_violation을 반환하면 해당 대화에서 추가 작업을 실행하도록 보내지 말고 차단된 워크플로우를 자동으로 재시도하지 마세요. 스트리밍 중 발생하는 오류도 처리하고 이미 실행되었을 수 있는 작업을 검토하세요. 팀에 프로젝트 알림이 필요하면 safety.alert.created를 구독하세요. 웹훅을 사용해도 요청 오류는 별도로 처리해야 합니다. 자동으로 중단될 수 있는 Responses 요청은 가이드에서 확인하세요.

트래픽 급증 및 모델 과부하에 대응

복구 방법을 결정하기 전에 HTTP 상태와 error.code를 확인하세요. 429와 함께 slow_down이 반환되면 요청 빈도가 너무 빠르게 증가했다는 뜻입니다. Retry-After가 있으면 해당 지시를 따르고 트래픽을 줄인 뒤 점진적으로 늘리세요. 503과 함께 server_is_overloaded가 반환되면 요청한 모델이 일시적으로 과부하 상태라는 뜻입니다. Retry-After가 있으면 지정된 시간만큼 기다린 뒤 재시도하세요. 헤더가 없으면 지터를 적용해 재시도 간격을 지수적으로 늘리고 재시도 횟수에 상한을 두세요. 청구, 지출, 할당량 관련 오류는 재시도 전에 조치가 필요합니다. 모든 429를 일시적인 요청 한도 초과로 처리하지 마세요. 요청 한도와 오류 코드를 참고하세요.

background=True 사용

시간이 오래 걸릴 수 있는 요청에는 background=True를 사용하세요. 클라이언트 연결을 계속 열어 두는 대신 API가 작업을 시작하고 ID를 반환합니다. 앱은 작업이 완료되거나 실패하거나 취소될 때까지 주기적으로 상태를 조회할 수 있습니다. 대규모 분석, 오래 걸리는 도구 실행, 상태 확인과 재시도가 필요한 작업에 사용하세요.

백그라운드 응답 실행 및 상태 조회
# Replace the illustrative IDs and URLs below with your own resource values.
from openai import OpenAI
import time

client = OpenAI()
log_bundle_file_id = "file_123"

job = client.responses.create(
    model="gpt-6-astra",
    background=True,
    store=False,
    input="Analyze this large log bundle and cluster the primary failure modes.",
    tools=[
        {
            "type": "code_interpreter",
            "container": {
                "type": "auto",
                "file_ids": [log_bundle_file_id],
            },
        }
    ],
)

while job.status in {"queued", "in_progress"}:
    time.sleep(2)
    job = client.responses.retrieve(job.id)

print(job.output_text)

stream=True와 함께 사용하면 진행 상황 이벤트를 받을 수 있지만 첫 이벤트를 받기까지 일반 요청보다 오래 걸릴 수 있습니다.

UI에서는 백그라운드 모드의 동작을 다음과 같이 안내할 수 있습니다. “작업이 진행 중입니다. 여기에서 현재 상태를 확인할 수 있으며, 완료되면 결과가 표시됩니다.”

WebSocket 모드 사용

WebSocket 모드는 장시간 실행되며 도구 호출이 많은 워크플로우를 위해 설계되었습니다. 연결을 계속 열어 두고 새 입력 항목과 previous_response_id만 전송해 작업을 이어갑니다. 도구를 20회 이상 호출하는 워크플로우에서는 전체 실행 속도가 최대 약 40% 빨라진 사례가 있습니다.

동작 방식은 다음과 같습니다. 첫 메시지는 일반 Responses 요청처럼 모델, 지침, 도구, 사용자 입력을 포함합니다. 서버는 이벤트를 스트리밍합니다. 모델이 도구를 요청하면 앱이 해당 도구를 실행합니다. 그다음 새 HTTP 요청을 보내는 대신 같은 소켓에서 response.create 이벤트를 보내면서 previous_response_id에 이전 응답의 ID를 지정하고 새 항목을 함께 전달합니다. 이 과정에서 지연 시간이 줄어듭니다. 일반 HTTP에서는 후속 호출마다 새 요청을 보내지만, WebSocket 모드에서는 연결이 유지되고 해당 연결의 메모리에 가장 최근 응답 상태가 남아 있습니다. 다음 턴이 그 응답에서 이어지면 서비스가 수행할 준비 작업이 줄어듭니다.

요청 한 번에 답변 하나로 끝나는 워크플로우라면 HTTP를 계속 사용하세요. 장시간 실행되는 에이전트처럼 동작하는 워크플로우라면 WebSocket 모드를 사용해 보세요.

한 연결에서 여러 대화를 병렬로 진행할 때는 서로 다른 stream_id 값을 사용하고, 뒤섞여 도착하는 이벤트는 stream_id에 따라 라우팅하세요. 연결 하나는 활성 응답을 최대 16개까지 지원하며, 같은 스트림의 요청은 순서대로 실행됩니다. 연결은 최대 60분간 유지됩니다. 작업을 이어갈 때 previous_response_id는 HTTP 모드와 같은 방식으로 동작하며, 각 스트림의 최신 응답에는 해당 연결 전용 캐시를 사용합니다.

참고로 WebSocket 모드는 데이터를 디스크에 기록하지 않고 메모리에만 저장하므로 ZDR과 함께 사용할 수 있습니다.

Python 예제에서는 pip install "openai[realtime]>=3.8.0"을 사용합니다. JavaScript 예제에서는 npm install openai@^7.10.0 ws를 사용합니다. Ruby 예제에서는 gem install openai async-websocket을 사용합니다.

Go에서는 go get github.com/openai/openai-go/v3@v3.98.0을 실행하세요. Java에서는 Maven 종속성 com.openai:openai-java:4.101.0을 추가하세요. 이 버전의 Go 및 Java SDK는 Responses WebSocket을 기본 지원합니다.

Responses API WebSocket 세션 시작
from openai import OpenAI
from openai.types.responses import FunctionToolParam

test_log_tool: FunctionToolParam = {
    "type": "function",
    "name": "search_test_logs",
    "description": "Search test logs.",
    "parameters": {
        "type": "object",
        "properties": {"query": {"type": "string"}},
        "required": ["query"],
        "additionalProperties": False,
    },
    "strict": True,
}
code_search_tool: FunctionToolParam = {
    "type": "function",
    "name": "search_code",
    "description": "Search source code.",
    "parameters": {
        "type": "object",
        "properties": {"query": {"type": "string"}},
        "required": ["query"],
        "additionalProperties": False,
    },
    "strict": True,
}

client = OpenAI()

with client.responses.connect() as connection:
    # Use the same typed parameters as client.responses.create(...).
    connection.response.create(
        model="gpt-6-astra",
        store=False,
        input=[
            {
                "type": "message",
                "role": "user",
                "content": [
                    {
                        "type": "input_text",
                        "text": (
                            "Find the flaky test in this run, call the tools "
                            "you need, and keep going until you can explain "
                            "the root cause."
                        ),
                    }
                ],
            }
        ],
        tools=[test_log_tool, code_search_tool],
    )
    for event in connection:
        if event.type == "response.completed":
            print(event.response.output)
            break
        if event.type in {"response.failed", "response.incomplete", "error"}:
            raise RuntimeError(event.to_json())
    else:
        raise RuntimeError("Connection closed before the response finished.")

턴 진행 중 지시 추가

GPT-6 모델이 작업하는 동안 사용자가 요구 사항을 추가할 수 있다면 Responses API에 WebSocket으로 연결하세요. response.steer 이벤트를 보낼 때 활성 응답의 ID를 previous_response_id에 넣고 새 사용자 입력을 함께 전달하세요. 이어지는 이벤트를 계속 수신하세요. response.steer.accepted는 업데이트가 대기열에 들어갔다는 뜻입니다. 턴 도중 지시를 추가해도 이미 애플리케이션에 전송한 출력은 바뀌지 않으며 이미 시작된 도구 실행도 되돌릴 수 없습니다. 이벤트 플로우와 도구 결과 처리 방법은 턴 진행 중 지시 추가를 참고하세요.

마무리

Responses API는 더 지능적이고 다양한 작업을 수행하는 OpenAI 애플리케이션의 기반입니다. 개발자는 일회성 프롬프트에서 더 나아가, 도구를 사용하고 컨텍스트를 유지하면서 작업의 복잡도에 맞춰 동작하는 지속적인 워크플로우를 구축할 수 있습니다. 이 가이드의 설계 방법을 적용해 실제 배포 환경에서 성능을 높이세요.