Flex 추론
Flex 추론 (Flex inference)
Gemini Flex API는 표준 요율에 비해 50% 비용 절감을 제공하는 추론 티어예요. 그 대신 지연 시간이 변동되고 최선 노력(best-effort) 가용성을 가져요. 동기 처리가 필요하지만 표준 API의 실시간 성능을 요구하지 않는, 지연 시간에 관대한(latency-tolerant) 워크로드에 맞춰 설계됐죠.
출처: 원문
본문
Flex 사용 방법 (How to use Flex)
Flex 티어를 사용하려면 요청 본문에서 service_tier를 flex로 지정하세요. 이 필드를 생략하면 기본적으로 요청은 표준 티어를 사용해요.
from google import genai
client = genai.Client()
try:
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Analyze this dataset for trends...",
config={"service_tier": "flex"},
)
print(response.text)
except Exception as e:
print(f"Flex request failed: {e}")
import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI({});
async function main() {
try {
const response = await ai.models.generateContent({
model: "gemini-3.8-flash",
contents: "Analyze this dataset for trends...",
config: { serviceTier: "flex" },
});
console.log(response.text);
} catch (e) {
console.log(`Flex request failed: ${e}`);
}
}
await main();
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
result, err := client.Models.GenerateContent(
ctx,
"gemini-3.8-flash",
genai.Text("Analyze this dataset for trends..."),
&genai.GenerateContentConfig{
ServiceTier: "flex",
},
)
if err != nil {
log.Printf("Flex request failed: %v", err)
return
}
fmt.Println(result.Text())
}
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{
"parts":[{"text": "Summarize the latest research on quantum computing."}]
}],
"service_tier": "flex"
}'
Flex 추론의 동작 방식 (How Flex inference works)
Gemini Flex 추론은 표준 API와 Batch API의 24시간 처리 사이의 간극을 메워요. 비수요(off-peak)의 "버릴 수 있는(sheddable)" 컴퓨팅 용량을 활용해 백그라운드 작업과 순차 워크플로를 위한 비용 효율적인 솔루션을 제공하죠.
| 기능 | Flex | Priority | 표준(Standard) | Batch |
|---|---|---|---|---|
| 가격(Pricing) | 50% 할인 | 표준보다 75-100% 비쌈 | 정가 | 50% 할인 |
| 지연 시간(Latency) | 수 분(1–15분 목표) | 낮음(초 단위) | 초~분 | 최대 24시간 |
| 신뢰성(Reliability) | 최선 노력(버릴 수 있음) | 높음(버릴 수 없음) | 높음 / 중상 | 높음(처리량 기준) |
| 인터페이스(Interface) | 동기(Synchronous) | 동기 | 동기 | 비동기(Asynchronous) |
주요 이점 (Key benefits)
- 비용 효율성(Cost efficiency): 비프로덕션 평가, 백그라운드 에이전트, 데이터 강화에 상당한 비용 절감.
- 낮은 마찰(Low friction): 배치 객체, 작업 ID, 폴링을 관리할 필요 없이 기존 요청에 매개변수 하나만 추가하면 돼요.
- 동기 워크플로(Synchronous workflows): 다음 요청이 이전 요청의 출력에 의존하는 순차 API 체인에 이상적이라, 에이전트 워크플로에서 Batch보다 더 유연해요.
사용 사례 (Use cases)
- 오프라인 평가(Offline evaluations): "LLM-as-a-judge" 회귀 테스트나 리더보드 실행.
- 백그라운드 에이전트(Background agents): 수 분의 지연이 허용되는 CRM 업데이트, 프로필 구축, 콘텐츠 중재 같은 순차 작업.
- 예산 제약 연구(Budget-constrained research): 제한된 예산으로 높은 토큰 볼륨이 필요한 학술 실험.
레이트 리밋 (Rate limits)
Flex 추론 트래픽은 일반 레이트 리밋에 포함돼요. Batch API처럼 확장된 레이트 리밋을 제공하지는 않아요.
버릴 수 있는 용량 (Sheddable capacity)
Flex 트래픽은 더 낮은 우선순위로 처리돼요. 표준 트래픽에 급증이 있으면 고우선순위 사용자를 위한 용량을 확보하기 위해 Flex 요청이 선점되거나 방출될 수 있어요. 고우선순위 추론을 찾고 있다면 Priority 추론을 확인하세요.
오류 코드 (Error codes)
Flex 용량을 사용할 수 없거나 시스템이 혼잡하면 API가 표준 오류 코드를 반환해요:
- 503 Service Unavailable: 시스템이 현재 용량 한계 상태예요.
- 429 Too Many Requests: 레이트 리밋 또는 리소스 고갈.
클라이언트 책임 (Client responsibility)
- 서버 측 폴백 없음: Flex 용량이 가득 차도 시스템이 Flex 요청을 자동으로 표준 티어로 업그레이드하지 않아 예상치 못한 요금을 방지해요.
- 재시도(Retries): 지수 백오프로 자체 클라이언트 측 재시도 로직을 구현해야 해요.
- 타임아웃(Timeouts): Flex 요청은 큐에 머물 수 있으므로, 조기 연결 종료를 피하기 위해 클라이언트 측 타임아웃을 10분 이상으로 늘리는 걸 권장해요.
타임아웃 윈도우 조정하기 (Adjust timeout windows)
REST API와 클라이언트 라이브러리에 대해 요청별 타임아웃을 구성할 수 있고, 클라이언트 라이브러리를 사용할 때만 전역 타임아웃을 구성할 수 있어요.
항상 클라이언트 측 타임아웃이 의도한 서버 대기(window) 시간(예: Flex 대기 큐의 경우 600초 이상)을 커버하도록 하세요. SDK는 타임아웃 값을 밀리초 단위로 기대해요.
요청별 타임아웃 (Per-request timeouts)
from google import genai
client = genai.Client()
try:
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="why is the sky blue?",
config={
"service_tier": "flex",
"http_options": {"timeout": 900000}
},
)
except Exception as e:
print(f"Flex request failed: {e}")
# Example with streaming
try:
response = client.models.generate_content_stream(
model="gemini-3.8-flash",
contents=["List 5 ideas for a sci-fi movie."],
config={
"service_tier": "flex",
"http_options": {"timeout": 60000}
}
# Per-request timeout for the streaming operation
)
for chunk in response:
print(chunk.text, end="")
except Exception as e:
print(f"An error occurred during streaming: {e}")
import {GoogleGenAI} from '@google/genai';
const client = new GoogleGenAI({});
async function main() {
try {
const response = await client.models.generateContent({
model: "gemini-3.8-flash",
contents: "why is the sky blue?",
config: {
serviceTier: "flex",
httpOptions: {timeout: 900000}
},
});
} catch (e) {
console.log(`Flex request failed: ${e}`);
}
// Example with streaming
try {
const response = await client.models.generateContentStream({
model: "gemini-3.8-flash",
contents: ["List 5 ideas for a sci-fi movie."],
config: {
serviceTier: "flex",
httpOptions: {timeout: 60000}
},
});
for await (const chunk of response.stream) {
process.stdout.write(chunk.text());
}
} catch (e) {
console.log(`An error occurred during streaming: ${e}`);
}
}
await main();
package main
import (
"context"
"fmt"
"log"
"time"
"google.golang.org/api/iterator"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
defer client.Close()
timeoutCtx, cancel := context.WithTimeout(ctx, 900*time.Second)
defer cancel()
_, err = client.Models.GenerateContent(
timeoutCtx,
"gemini-3.8-flash",
genai.Text("why is the sky blue?"),
&genai.GenerateContentConfig{
ServiceTier: "flex",
},
)
if err != nil {
fmt.Printf("Flex request failed: %v\n", err)
}
// Example with streaming
streamTimeoutCtx, streamCancel := context.WithTimeout(ctx, 60*time.Second)
defer streamCancel()
iter := client.Models.GenerateContentStream(
streamTimeoutCtx,
"gemini-3.8-flash",
genai.Text("List 5 ideas for a sci-fi movie."),
&genai.GenerateContentConfig{
ServiceTier: "flex",
},
)
for {
response, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
fmt.Printf("An error occurred during streaming: %v\n", err)
break
}
fmt.Print(response.Candidates[0].Content.Parts[0])
}
}
REST 호출에서는 HTTP 헤더와 curl 옵션을 조합해 타임아웃을 제어할 수 있어요:
X-Server-Timeout 헤더(서버 측 타임아웃): 이 헤더는 Gemini API 서버에 선호하는 타임아웃(기본 600초)을 제안해요. 서버가 이를 존중하려 시도하지만 보장되지는 않아요. 값은 초 단위여야 해요.
curl의 --max-time(클라이언트 측 타임아웃): curl --max-time <seconds> 옵션은 전체 작업이 완료될 때까지 curl이 기다릴 총 시간(초)에 하드 한도를 설정해요. 클라이언트 측 안전장치죠.
# Set a server timeout hint of 120 seconds and a client-side curl timeout of 125 seconds.
curl --max-time 125 \
-X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Server-Timeout: 120" \
-d '{
"contents": [{
"parts":[{"text": "Summarize the latest research on quantum computing."}]
}],
"service_tier": "flex"
}'
전역 타임아웃 (Global timeouts)
특정 genai.Client 인스턴스(클라이언트 라이브러리 전용)를 통해 이루어지는 모든 API 호출이 기본 타임아웃을 갖기를 원한다면, http_options와 genai.types.HttpOptions로 클라이언트 초기화 시 설정할 수 있어요.
from google import genai
from google.genai import types
global_timeout_ms = 120000
client_with_global_timeout = genai.Client(
http_options=types.HttpOptions(timeout=global_timeout_ms)
)
try:
# Calling generate_content using global timeout...
response = client_with_global_timeout.models.generate_content(
model="gemini-3.8-flash",
contents="Summarize the history of AI development since 2000.",
config={"service_tier": "flex"},
)
print(response.text)
# A per-request timeout will *override* the global timeout for that specific call.
shorter_timeout = 30000
response = client_with_global_timeout.models.generate_content(
model="gemini-3.8-flash",
contents="Provide a very brief definition of machine learning.",
config={
"service_tier": "flex",
"http_options":{"timeout": shorter_timeout}
} # Overrides the global timeout
)
print(response.text)
except TimeoutError:
print(
f"A GenerateContent call timed out. Check if the global or per-request timeout was exceeded."
)
except Exception as e:
print(f"An error occurred: {e}")
import {GoogleGenAI} from '@google/genai';
const globalTimeoutMs = 120000;
const clientWithGlobalTimeout = new GoogleGenAI({httpOptions: {timeout: globalTimeoutMs}});
async function main() {
try {
// Calling generate_content using global timeout...
const response1 = await clientWithGlobalTimeout.models.generateContent({
model: "gemini-3.8-flash",
contents: "Summarize the history of AI development since 2000.",
config: { serviceTier: "flex" },
});
console.log(response1.text());
// A per-request timeout will *override* the global timeout for that specific call.
const shorterTimeout = 30000;
const response2 = await clientWithGlobalTimeout.models.generateContent({
model: "gemini-3.8-flash",
contents: "Provide a very brief definition of machine learning.",
config: {
serviceTier: "flex",
httpOptions: {timeout: shorterTimeout}
} // Overrides the global timeout
});
console.log(response2.text());
} catch (e) {
if (e.name === 'TimeoutError' || e.message?.includes('timeout')) {
console.log(
"A GenerateContent call timed out. Check if the global or per-request timeout was exceeded."
);
} else {
console.log(`An error occurred: ${e}`);
}
}
}
await main();
package main
import (
"context"
"fmt"
"log"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
defer client.Close()
model := client.GenerativeModel("gemini-3.8-flash")
// Go uses context for timeouts, not client options.
// Set a default timeout for requests.
globalTimeout := 120 * time.Second
fmt.Printf("Using default timeout of %v seconds.\n", globalTimeout.Seconds())
fmt.Println("Calling generate_content (using default timeout)...")
ctx1, cancel1 := context.WithTimeout(ctx, globalTimeout)
defer cancel1()
resp1, err := model.GenerateContent(ctx1, genai.Text("Summarize the history of AI development since 2000."), &genai.GenerateContentConfig{ServiceTier: "flex"})
if err != nil {
log.Printf("Request 1 failed: %v", err)
} else {
fmt.Println("GenerateContent 1 successful.")
fmt.Println(resp1.Text())
}
// A different timeout can be used for other requests.
shorterTimeout := 30 * time.Second
fmt.Printf("\nCalling generate_content with a shorter timeout of %v seconds...\n", shorterTimeout.Seconds())
ctx2, cancel2 := context.WithTimeout(ctx, shorterTimeout)
defer cancel2()
resp2, err := model.GenerateContent(ctx2, genai.Text("Provide a very brief definition of machine learning."), &genai.GenerateContentConfig{
ServiceTier: "flex",
})
if err != nil {
log.Printf("Request 2 failed: %v", err)
} else {
fmt.Println("GenerateContent 2 successful.")
fmt.Println(resp2.Text())
}
}
재시도 구현하기 (Implement retries)
Flex는 버릴 수 있고 503 오류로 실패하므로, 실패한 요청을 계속 처리하기 위해 재시도 로직을 선택적으로 구현하는 예시를 드릴게요:
import time
from google import genai
client = genai.Client()
def call_with_retry(max_retries=3, base_delay=5):
for attempt in range(max_retries):
try:
return client.models.generate_content(
model="gemini-3.8-flash",
contents="Analyze this batch statement.",
config={"service_tier": "flex"},
)
except Exception as e:
# Check for 503 Service Unavailable or 429 Rate Limits
print(e.code)
if attempt < max_retries - 1:
delay = base_delay * (2 ** attempt) # Exponential Backoff
print(f"Flex busy, retrying in {delay}s...")
time.sleep(delay)
else:
# Fallback to standard on last strike (Optional)
print("Flex exhausted, falling back to Standard...")
return client.models.generate_content(
model="gemini-3.8-flash",
contents="Analyze this batch statement."
)
# Usage
response = call_with_retry()
print(response.text)
import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI({});
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function callWithRetry(maxRetries = 3, baseDelay = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
console.log(`Attempt ${attempt + 1}: Calling Flex tier...`);
const response = await ai.models.generateContent({
model: "gemini-3.8-flash",
contents: "Analyze this batch statement.",
config: { serviceTier: 'flex' },
});
return response;
} catch (e) {
if (attempt < maxRetries - 1) {
const delay = baseDelay * (2 ** attempt);
console.log(`Flex busy, retrying in ${delay}s...`);
await sleep(delay * 1000);
} else {
console.log("Flex exhausted, falling back to Standard...");
return await ai.models.generateContent({
model: "gemini-3.8-flash",
contents: "Analyze this batch statement.",
});
}
}
}
}
async function main() {
const response = await callWithRetry();
console.log(response.text);
}
await main();
package main
import (
"context"
"fmt"
"log"
"math"
"time"
"google.golang.org/genai"
)
func callWithRetry(ctx context.Context, client *genai.Client, maxRetries int, baseDelay time.Duration) (*genai.GenerateContentResponse, error) {
modelName := "gemini-3.8-flash"
content := genai.Text("Analyze this batch statement.")
flexConfig := &genai.GenerateContentConfig{
ServiceTier: "flex",
}
for attempt := 0; attempt < maxRetries; attempt++ {
log.Printf("Attempt %d: Calling Flex tier...", attempt+1)
resp, err := client.Models.GenerateContent(ctx, modelName, content, flexConfig)
if err == nil {
return resp, nil
}
log.Printf("Attempt %d failed: %v", attempt+1, err)
if attempt < maxRetries-1 {
delay := time.Duration(float64(baseDelay) * math.Pow(2, float64(attempt)))
log.Printf("Flex busy, retrying in %v...", delay)
time.Sleep(delay)
} else {
log.Println("Flex exhausted, falling back to Standard...")
return client.Models.GenerateContent(ctx, modelName, content)
}
}
return nil, fmt.Errorf("retries exhausted") // Should not be reached
}
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
defer client.Close()
resp, err := callWithRetry(ctx, client, 3, 5*time.Second)
if err != nil {
log.Fatalf("Failed after retries: %v", err)
}
fmt.Println(resp.Text())
}
가격 (Pricing)
Flex 추론은 표준 API의 50% 가격으로 책정되며 토큰당 과금돼요.
지원 모델 (Supported models)
다음 모델들이 Flex 추론을 지원해요:
| 모델 | Flex 추론 |
|---|---|
| Gemini 3.8 Flash | ✔️ |
| Gemini 3.7 Flash | ✔️ |
| Gemini 3.6 Flash | ✔️ |
| Gemini 3.5 Flash-Lite | ✔️ |
| Gemini 3.5 Flash | ✔️ |
| Gemini 3.1 Flash-Lite | ✔️ |
| Gemini 3.1 Pro Preview | ✔️ |
| Gemini 3 Flash Preview | ✔️ |
| Gemini 3 Pro Image Preview | ✔️ |
| Gemini 2.5 Pro | ✔️ |
| Gemini 2.5 Flash | ✔️ |
| Gemini 2.5 Flash Image | ✔️ |
| Gemini 2.5 Flash-Lite | ✔️ |
다음 단계 (What's next)
Gemini의 다른 추론 및 최적화 옵션을 읽어보세요:
- 초저지연을 위한 Priority 추론.
- 24시간 내 비동기 처리를 위한 Batch API.
- 입력 토큰 비용 절감을 위한 컨텍스트 캐싱.
더 알아보기 (Learn more)
- Gemini API 가격 — 표준 가격과 Flex 할인.
- Priority 추론 — 초저지연 워크로드.
- Batch API — 비동기 배치 처리.