추론
추론 (Reasoning)
모델이 무엇을 생각하는지 스트리밍하고, 드러내서는 안 되는 것을 라운드트립하는 법 — 1.0 버전을 설명드릴게요.
출처: 문서
본문
추론은 모델이 답하기 전에 생각하는 것입니다. 프로듀서는 UI가 진행 중 작업을 보여줄 수 있도록 그것을 스트리밍하고 — 공급자가 실제 chain of thought를 비공개로 유지하는 곳에서는 — 소비자가 읽을 수 없이 저장하고 반환하는 암호화된 산출물을 운반해요.
사용자 상호작용 모델 (User Interaction Model)
추론은 일반적으로 대화와 분리되어 렌더링돼요 — 기본적으로 접혀 있고, 사고로 스타일링됩니다. 프로토콜은 어떤 프레젠테이션도 강제하지 않아요; 소비자는 추론을 완전히 숨길 수 있어요(MAY).
이벤트 (Events)
스팬: REASONING_START와 REASONING_END
추론 스팬은 한 구간의 사고를 괄호로 묶으며, REASONING_START가 열고 REASONING_END가 닫고, messageId로 매칭됩니다. 한 스팬은 여러 추론 메시지를 담을 수 있어요.
- 프로듀서는 이미 열린
messageId의 스팬을 열어선 안 되고(MUST NOT), 연 모든 스팬을 실행이 끝나기 전에 닫아야 하며(MUST), 열지 않은 스팬을 닫아선 안 돼요(MUST NOT). - 스팬의 식별자는 아무것도 네임스페이스하지 않아요: 스팬 안의 추론 메시지는 자신의
messageId를 가져요.
추론 메시지 (Reasoning messages)
추론 메시지는 스트리밍 패턴을 따릅니다: REASONING_MESSAGE_START가 하나를 열고(그 role은 고정, reasoning), REASONING_MESSAGE_CONTENT가 확장하며, REASONING_MESSAGE_END가 닫고, 모두 messageId로 매칭됩니다 — 그리고 REASONING_MESSAGE_CHUNK는 간결한 철자이며, 그 첫 청크는 messageId를 반드시 담아야 해요. 패턴의 규칙은 텍스트 메시지에서와 정확히 적용됩니다.
소비자는 그 규율의 위반을 감지하고 스팬과 추론 메시지 양쪽에서 실행을 실패시켜야 해요(MUST):
- 아무것도 열지 않은 메시지를 명명하는
REASONING_MESSAGE_CONTENT또는REASONING_MESSAGE_END는 지시 대상이 없으며, 소비자는 고아 조각이 명명하는 메시지를 지어내선 안 돼요(MUST NOT). 같은 형태는 텍스트 메시지에 대해 거부되며; 추론도 예외가 아니에요. - 아무것도 열지 않은 스팬을 명명하는
REASONING_END는 같은 방식으로 거부되며, 이미 열린 스팬을 다시 여는REASONING_START도 마찬가지예요. - 이미 열린 추론 메시지를 명명하는
REASONING_MESSAGE_START도 거부돼요 — 그messageId가 다시 쓰이기 전에 메시지는REASONING_MESSAGE_END로 닫혀야 해요. 스팬과 그 안의 메시지는 식별자를 공유할 수 있으므로, 각각 자신의 열린 집합에 대해 검사됩니다. - 실행이 끝날 때 아직 열린 스팬 또는 추론 메시지는 실행을 실패시켜요.
스팬과 추론 메시지는 별개의 네임스페이스입니다: REASONING_START는 스팬을 열고 어떤 메시지도 열지 않으므로, 스팬의 messageId를 명명하는 조각은 다른 어떤 것처럼 고아가 돼요.
REASONING_ENCRYPTED_VALUE
공급자의 불투명하고 암호화된 추론 산출물을 운반해요. subtype은 entityId가 명명하는 종류 — 메시지 또는 도구 호출 — 를 말하며, 값이 저장되는 위치를 결정해요.
- 소비자는
encryptedValue를 불투명하게 취급해야 해요(MUST): 결코 파싱되지 않고, 해석되지 않으며, 어떤 특정 형식이라고 가정되지 않아요. - 소비자는 그 값을 그것이 명명하는 메시지나 도구 호출과 함께 저장하고, 이후 run input에서 수정 없이 반환해야 해요(MUST), 그래야 프로듀서가 그것이 대표하는 추론 컨텍스트를 복원할 수 있어요. 이 규칙은 값을 담을 수 있는 대상을 전제합니다: 액티비티 메시지는 스키마상 암호화된 값을 담지 않으므로, 그것을 명명하는 이벤트는 소비자가 아는 것을 명명하지 않는 것으로 취급됩니다 — 아래의 unknown-
entityId사례요. - 그것을 보존할 수 없는 소비자 — 다운그레이드 경로, 운반할 수 없는 저장소 — 는 콘텐츠를 잃는 것이며 경고해야 해요(MUST) (Versioning).
- 산출물은 그 메시지를 탑니다. 메시지를 재진술하는
MESSAGES_SNAPSHOT은encryptedValue를 포함해 그것을 전체적으로 교체해요 — 그래서 여전히 산출물이 필요한 프로듀서는 스냅샷의 사본에 그것을 재진술해야 하고, 생략하는 프로듀서는 자신의 산출물을 철회한 것입니다. 소비자의 의무는 모든 이벤트가 적용된 후 자신이 보유한 것을 반환하는 것이지, 스냅샷이 제거한 것을 부활시키는 게 아니에요.
그 이벤트는 독립형입니다: 아무것도 열지 않고 닫지 않으며, 열린 실행 안 어디에든 나타날 수 있어요(MAY), 다만 관례적으로 그것이 포착하는 생각의 스팬 안에 도착해요.
메시지 흐름 (Message Flow)
sequenceDiagram
participant Agent
participant Client
Agent->>Client: REASONING_START (span-1)
Agent->>Client: REASONING_MESSAGE_START (msg-9, reasoning)
Agent->>Client: REASONING_MESSAGE_CONTENT (delta) ×N
Agent->>Client: REASONING_MESSAGE_END (msg-9)
Agent->>Client: REASONING_ENCRYPTED_VALUE (message, msg-9)
Agent->>Client: REASONING_END (span-1)
Note over Client: stores msg-9 with its encrypted value,<br/>returns both in the next run's input
데이터 타입 (Data Types)
이벤트 형태는 스키마 참조가 정의합니다: ReasoningStartEvent, ReasoningEndEvent, ReasoningMessageStartEvent, ReasoningMessageContentEvent, ReasoningMessageEndEvent, ReasoningMessageChunkEvent, ReasoningEncryptedValueEvent. 대화 역사에서 추론 메시지는 ReasoningMessage입니다.
오류 처리 (Error Handling)
소비자가 아는 것을 명명하지 않는 entityId를 가진 REASONING_ENCRYPTED_VALUE는 그것이 속한 곳에 저장될 수 없어요; 소비자는 경고하고 버릴 수 있으며(MAY), 그것 때문에 실행을 실패시켜선 안 돼요(MUST NOT).
잘못된 추론 이벤트 — 필수 필드 누락, 문자열이 아닌 subtype — 는 다른 어떤 것과 마찬가지로 잘못된 알려진 값이며 치명적이에요. 스키마가 명명하지 않는 문자열인 subtype은 다릅니다: 그것은 인식하지 못한 자료 — 이 소비자가 출시된 후 추가된 멤버 — 이며 처리 모델이 경고와 함께 벗겨내는데, 필수 위치에서는 그것을 운반한 이벤트를 제거해요.
보안 고려사항 (Security Considerations)
추론 콘텐츠는 일상적으로 프로듀서가 답에 말하지 않기로 선택한 자료를 담아요. 소비자는 그것을 대화와 같은 기밀성으로 취급해야 하고(SHOULD), encryptedValue를 그것을 발행한 프로듀서 외의 어떤 것에도 공급해선 안 돼요(MUST NOT) — 그것은 컨텍스트 복원을 위한 기능이지, 애플리케이션을 위한 데이터가 아니에요.
더 알아보기 (Learn more)
- 이벤트 모델 — 이벤트 봉투·식별자
- Streaming Messages — 추론 메시지 스트리밍 규칙
- Text Messages — 텍스트 메시지 이벤트