Skip to main content
Gemini의 네이티브 형식 (/v1beta generateContent)을 호출하면 응답은 OpenAI 호환 모드와 다른 Google의 candidates / parts 구조를 사용합니다. 이 페이지에서는 비스트리밍(generateContent)과 스트리밍(streamGenerateContent) 응답을 모두 파싱하는 방법을 설명합니다.
요청 측(base_url은 https://api.apiyi.com에서 /v1, x-goog-api-key 인증, thinking_level 제어를 제외한 값입니다)은 Gemini 네이티브 형식 가이드에서 다룹니다. 이 페이지는 순전히 응답 측에 대한 내용입니다. 예제에서는 경량 모델 gemini-3.1-flash-lite을 사용합니다.

비스트리밍 응답

엔드포인트 …:generateContent. 답변은 candidates[0].content.parts[]에 있습니다:
답변을 얻으려면 parts를 반복하고 각 text를 이어 붙여야 합니다:
finishReason대문자 STOP입니다( OpenAI의 소문자 stop가 아닙니다); 다른 값으로는 MAX_TOKENSSAFETY가 있습니다. part에는 thoughtSignature만 포함될 수 있고 text는 포함되지 않을 수 있으므로, 반복할 때 if "text" in p로 필터링하십시오. 그렇지 않으면 KeyError가 발생합니다.

추론 서명

Gemini 3-series 모델은 일부에 thoughtSignature(암호화된 추론 상태)를 첨부합니다 — 테스트에서는 경량 gemini-3.1-flash-lite도 이를 반환합니다.
  • 단일 턴: 필요하지 않습니다. 무시하십시오.
  • 멀티 턴 / 함수 호출: 이전 응답의 thoughtSignature를 다음 턴의 contents에 그대로 다시 전달해야 모델이 추론 체인을 계속 이어갈 수 있습니다. 공식 google-genai SDK가 이를 자동으로 처리합니다. REST를 직접 작성할 때는 필드를 누락하지 마십시오. Gemini Function Calling을 참조하십시오.
이것이 OpenAI 호환 모드와의 핵심 차이입니다: 호환 모드에서는 reasoning 모델이 상태를 유지하지 않으며 서명도 노출하지 않습니다. 기본 형식에만 thoughtSignature가 있으며, 이는 턴 간에 다시 전달해야 합니다.

스트리밍 응답(SSE)

엔드포인트 …:streamGenerateContent입니다. 각 줄은 data: {...}이며, 각 청크의 증분은 candidates[0].content.parts[0].text에 있습니다:
APIYI 게이트웨이를 통해 스트리밍하면 항상 SSE data: 줄이 반환됩니다 (?alt=sse이 있든 없든), 그리고 [DONE] 종료 표시는 없습니다 — finishReason == "STOP"인 청크에서 끝납니다. 마지막 청크에는 보통 thoughtSignature만 포함되고 text는 없습니다.
usageMetadata모든 청크에 존재하며 누적됩니다(candidatesTokenCount가 출력과 함께 증가합니다) — 마지막 청크의 값을 그대로 사용하면 되며, 수동으로 합산할 필요가 없습니다.

OpenAI 호환 모드와의 주요 차이점

사용 및 과금

  • thoughtsTokenCount(thinking tokens)는 출력 요율로 과금됩니다. 비용을 절감하려면 thinking_level를 사용해 상한을 설정하십시오.
  • 캐시 적중 필드(cachedContentTokenCount) 할인은 Gemini Cache Billing을 참조하십시오.
  • 전체 필드 참조는 Gemini Native Format Guide의 “사용 필드” 섹션에 있습니다.

관련 링크