ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [OpenAI][Responses API] store: false일 때 reasoning.encrypted_content를 안 넘기면 연속 함수 호출이 비싸지는 이유
    기타개발지식/풀스택개발 2026. 6. 27. 20:16

    IT 리서치 노트

    [OpenAI][Responses API] store: false일 때 reasoning.encrypted_content를 안 넘기면 연속 함수 호출이 비싸지는 이유

    Responses API를 stateless로 돌리면서도 함수 호출 품질을 유지하려면 `store: false`만 넣고 끝내면 안 된다. 2026년 6월 27일 기준 OpenAI 공식 문서를 다시 보면, stateless 또는 ZDR 흐름에서는 `reasoning.encrypted_content`와 function call output의 `call_id`를 함께 챙겨야 이전 추론이 이어진다. 이 글은 그 값을 빼먹었을 때 왜 비용과 함수 호출 품질이 같이 흔들리는지 정리한 것이다.

    1. 개요

    결론부터 말하면 stateless Responses 흐름에서 reasoning.encrypted_content를 다시 전달하지 않으면 모델이 함수 호출 사이에서 필요한 추론을 다시 시작할 수 있다. 이때 응답이 바로 깨지지 않아도 reasoning token이 늘고, 연속 함수 호출의 정확도가 떨어질 수 있다. 그래서 store: false를 쓰는 설계는 반드시 encrypted reasoning item replay와 call_id 검증을 한 세트로 가져가야 한다.

    이미 reasoning summary와 usage 글이 로그 관점을 다뤘다면 이번 글은 상태 전달 관점이다. 또 prompt caching 글을 봤다면, reasoning item 누락이 왜 토큰 사용량에도 영향을 주는지 이해하기 쉽다.

    2. 어디서 실제로 막히는가

    실무에서 가장 흔한 실수는 세 가지다. 첫째, store: false만 넣고 응답 output_text만 다음 턴에 붙인다. 둘째, encrypted reasoning을 받아 놓고도 function result replay에서는 빼먹는다. 셋째, function result를 다시 넣으면서 call_id를 틀리게 넘겨 tool 호출과 결과 연결이 끊긴다.

    OpenAI 전환 가이드는 stateless 또는 ZDR 흐름이면 encrypted reasoning item을 같이 쓰라고 적고 있고, create reference는 reasoning.encrypted_content가 stateless multi-turn에서 reasoning item을 다시 쓸 수 있게 한다고 설명한다. reasoning best practices는 함수 호출이 많은 복잡한 흐름에서 reasoning item이 문맥에 포함되지 않으면 성능 저하와 reasoning token 증가가 생길 수 있다고 적는다.

    즉 이 문제는 단순히 '이전 대화를 얼마나 많이 다시 넣느냐'가 아니다. 어떤 item을 다시 넣느냐가 중요하다. assistant message만 다시 넣고 reasoning item이나 function_call_output을 빼면, 모델은 함수 호출 직전의 판단 근거를 잃는다. 결과적으로 같은 정책 조회나 같은 비교 과정을 다시 밟으며 토큰이 더 들 수 있다.

    • 증상: 함수 호출은 되지만 두 번째 턴부터 답이 흔들리거나 길어진다.
    • 실패: store: false 이후 assistant message만 replay한다.
    • 막힘: function_call_output의 call_id가 맞는지 검증하지 않는다.
    • 누락: encrypted reasoning item을 include로 받지 않거나 다음 턴에 안 넣는다.
    증상 먼저 볼 곳 판단 기준
    함수 호출 뒤 답이 산만해진다 replay input item 목록 reasoning item이 빠졌는지 본다
    토큰이 갑자기 늘어난다 usage와 reasoning token 함수 호출 이후 reasoning이 재시작됐는지 본다
    function result가 반영되지 않는다 call_id output call과 input result가 정확히 연결됐는지 본다

    3. 실무에서 적용하는 순서

    stateless Responses 운용은 다섯 단계로 고정해 두는 편이 안전하다. 먼저 요청에 store: false를 넣는다. 다음으로 include: ["reasoning.encrypted_content"]를 넣어 encrypted reasoning item을 받는다. 세 번째로 첫 응답의 output item 전체를 다음 입력 후보로 보관한다. 네 번째로 function result를 넣을 때 function_call_output과 정확한 call_id를 같이 붙인다. 마지막으로 usage와 reasoning summary를 같은 trace에 저장해 replay 누락이 비용 증가와 맞물리는지 확인한다.

    1. store: false와 include: ["reasoning.encrypted_content"]를 같이 설정한다.
    2. 첫 응답의 reasoning item과 assistant output item을 함께 보관한다.
    3. function result는 function_call_output으로 넣고 call_id를 맞춘다.
    4. 다음 요청 입력에는 필요한 output item을 빠뜨리지 않는다.
    5. usage와 reasoning summary를 저장해 replay 누락 때 토큰이 늘어나는지 본다.
    점검 메모 예시
    store=false
    include=reasoning.encrypted_content
    replayed_items=assistant_output,reasoning_item,function_call_output
    call_id_verified=true
    reasoning_tokens_delta=compare_previous_turn
    summary_saved=true

    공식 문서가 모든 구현체의 프레임워크별 예시를 다 보여 주지는 않는다. 다만 문서가 분명히 말하는 기준은 같다. stateless 흐름에서는 reasoning item을 다시 전달해야 하고, function result는 call_id로 연결해야 한다. 이 두 조건이 빠지면 나머지 품질 문제는 대부분 뒤늦게 드러난다.

    4. 공식 문서와 예시 화면으로 확인하기

    첫 화면은 Responses 전환 가이드의 encrypted reasoning 설명 구간이다. 여기서는 상태 저장을 끄더라도 reasoning 맥락을 이어 갈 수 있다는 전제를 먼저 확인해야 한다.

    Responses 전환 가이드는 stateless 흐름에서도 encrypted reasoning으로 reasoning 맥락을 이어 갈 수 있다고 설명한다.
    Responses 전환 가이드는 stateless 흐름에서도 encrypted reasoning으로 reasoning 맥락을 이어 갈 수 있다고 설명한다.

    즉 `store: false` 자체가 문제의 핵심은 아니다. 문제는 상태를 끈 뒤 reasoning item을 다시 전달하지 않아 다음 함수 호출 턴에서 모델이 다시 생각을 시작하게 만드는 구현이다.

    두 번째 자료는 conversation state 가이드의 수동 상태 관리 예시다. 여기서는 실제 코드에서 store=False와 include=["reasoning.encrypted_content"]를 함께 넣는 모습을 확인할 수 있다.

    conversation state 가이드는 stateless 대화 예시에서 <code>store=False</code>와 encrypted reasoning item 포함을 함께 보여 준다.
    conversation state 가이드는 stateless 대화 예시에서 <code>store=False</code>와 encrypted reasoning item 포함을 함께 보여 준다.

    문장 설명만 읽을 때보다 구현 예시를 보면 더 분명하다. 수동 상태 관리에서는 output item 전체를 history에 더하고, 다음 요청에도 encrypted reasoning item이 계속 따라가야 같은 흐름이 유지된다.

    세 번째 화면은 Responses create reference의 `include` 항목이다. 여기서는 `reasoning.encrypted_content`가 왜 필요한지 가장 직접적으로 설명한다.

    API reference는 `reasoning.encrypted_content`가 stateless multi-turn에서 reasoning items를 다시 쓸 수 있게 만든다고 적고 있다.
    API reference는 `reasoning.encrypted_content`가 stateless multi-turn에서 reasoning items를 다시 쓸 수 있게 만든다고 적고 있다.

    즉 이 값은 디버깅 장식이 아니라 stateless 운용의 핵심 입력이다. 응답에서 받은 encrypted reasoning을 다음 요청에 다시 넘겨야 모델이 이전 추론을 이어서 사용할 수 있다.

    네 번째 자료는 reasoning best practices 문서의 함수 호출 관련 설명이다. 여기서는 reasoning item이 문맥에 안 들어가면 성능 저하와 reasoning token 증가가 생길 수 있다고 적고 있다.

    OpenAI는 복잡한 함수 호출 흐름에서 reasoning item을 놓치면 성능 저하와 reasoning token 증가가 생길 수 있다고 설명한다.
    OpenAI는 복잡한 함수 호출 흐름에서 reasoning item을 놓치면 성능 저하와 reasoning token 증가가 생길 수 있다고 설명한다.

    이 문단은 이번 글의 운영 기준을 거의 그대로 만든다. stateless 설계 자체보다, 함수 호출 직후 필요한 reasoning item을 얼마나 정확히 다시 전달하느냐가 응답 품질과 비용을 같이 흔든다는 뜻이다.

    실무에서는 요청 예시를 한 번 고정해 두는 편이 안전하다. `store: false`, `include`, `function_call_output`, `call_id` 네 항목을 한 요청 흐름으로 묶어 두면 누락을 줄이기 쉽다.

    stateless Responses 흐름에서 encrypted reasoning과 `call_id`를 함께 넘기는 예시다.
    stateless Responses 흐름에서 encrypted reasoning과 `call_id`를 함께 넘기는 예시다.

    특히 function result를 다시 넣을 때 `call_id`가 틀리면 reasoning item을 잘 챙겨도 연속 턴이 어긋난다. 이 점은 이미 reasoning summary와 usage 글에서 본 로그 저장 기준과도 같이 움직인다.

    이 주제는 상태 관리 방식 비교표가 있어야 빨리 정리된다. stateful, stateless replay, stateless replay 누락을 같은 표에 놓으면 어디서 비용이 새는지 설명이 쉬워진다.

    Responses 상태 관리 방식을 비교한 표다.
    Responses 상태 관리 방식을 비교한 표다.

    이미 background mode 글을 봤다면, 이번 표는 비동기 여부가 아니라 상태 전달 책임을 어디에 두는지의 차이로 읽으면 된다.

    5. 주의사항과 리스크

    첫 번째 리스크는 encrypted reasoning을 chain-of-thought 원문으로 오해하는 것이다. 공식 문서는 encrypted reasoning을 재사용용 상태 조각으로 설명하지, 사람이 읽는 디버그 출력으로 설명하지 않는다. 두 번째 리스크는 stateless replay를 직접 구현하면서 민감한 item 저장 기간과 삭제 기준을 정하지 않는 것이다. 세 번째 리스크는 function result를 별도 큐에서 비동기로 넣으며 call_id 연결을 검증하지 않는 것이다.

    운영 전에 확인할 때는 최소한 하나의 다중 함수 호출 시나리오를 만들고, encrypted reasoning을 켠 경우와 끈 경우의 usage 차이를 짧게 비교해 보는 편이 좋다. 여기서 차이가 크면 이후 실제 서비스에서도 token과 응답 안정성이 같이 흔들릴 가능성이 높다.

    • encrypted reasoning은 state replay용이지 사람이 읽는 원문 추론 로그가 아니다.
    • stateless replay 저장 기간과 삭제 기준을 별도로 정한다.
    • call_id 검증이 빠지면 함수 호출 체인이 조용히 깨질 수 있다.

    6. 결론

    Responses API를 stateless로 쓰면서 함수 호출 품질을 지키려면 store: false만으로는 부족하다. encrypted reasoning item, function_call_output, call_id, usage 저장이 함께 있어야 모델이 이전 판단을 이어서 쓰고 token 재소비도 줄일 수 있다.

    • store: false와 encrypted reasoning replay를 한 세트로 본다.
    • function result는 반드시 맞는 call_id와 연결한다.
    • reasoning token 증가는 replay 누락 신호로 먼저 의심한다.

    7. 참고 링크

    1. https://developers.openai.com/api/docs/guides/migrate-to-responses
    2. https://developers.openai.com/api/reference/resources/responses/methods/create/
    3. https://developers.openai.com/api/docs/guides/reasoning-best-practices
    4. https://developers.openai.com/api/docs/guides/conversation-state
    5. https://developers.openai.com/api/docs/guides/reasoning
Designed by Tistory.