Gemini 3.8 Flash는 2026년 9월 2일에 출시되었으며, Google은 "도구를 반복적으로 호출"하도록 구축했습니다. 즉, 어려운 작업에서 한 번에 모든 것을 추측하는 대신 호출을 하고, 결과를 확인하고, 다시 호출합니다. 이는 에이전트에게는 희소식이지만 3.7 Flash에 맞게 도구 루프가 조정된 사용자에게는 새로운 골칫거리입니다. 두 가지 API 세부 정보가 다른 어떤 것보다 중요합니다. 모든 함수 결과는 `call_id`와 `name`을 모두 포함해야 하며, `generateContent`가 아닌 Interactions API가 이제 루프를 실행하는 기본 방법입니다.
이 가이드는 Interactions API에서 전체 두 단계 흐름을 안내하고, 아마도 아직 실행 중일 레거시 `generateContent` 형태를 보여주며, 새 모델이 도구에 더 많은 턴과 토큰을 소비하는 이유를 설명하고, 매일 실행할 수 있는 테스트 설정으로 마무리합니다. 이 테스트 설정은 도구의 백엔드를 모의하고, 두 턴을 연결하며, `call_id` 왕복을 검증합니다. 모델 개요가 먼저 필요하다면, Gemini 3.8 Flash란 무엇인가부터 시작하십시오. 아래 필드 이름은 Google의 함수 호출 문서에서 가져온 것입니다.
여기의 모든 요청은 JSON을 포함하는 일반 HTTP이므로, 애플리케이션 코드에 넣기 전에 Apidog에서 구축하고 디버깅할 수 있습니다.
Gemini 3.8 Flash의 함수 호출 한눈에 보기
| 항목 | Gemini 3.8 Flash |
|---|---|
| 모델 ID | gemini-3.8-flash (안정적이며, 프리뷰 접미사 없음) |
| 기본 API | Interactions API (POST /v1beta/interactions); generateContent는 레거시이지만 완벽하게 지원됨 |
| 도구 선언 | tools: [{"type": "function", "name", "description", "parameters"}] |
| 모델의 호출 | id, name, arguments를 포함하는 function_call 단계 |
| 사용자의 응답 | call_id + name (둘 다 필수) 및 previous_interaction_id를 포함하는 function_result |
| 사고 수준 | thinking_level low / medium (기본값) / high; minimal은 유효성 검사 오류 반환 |
| 도구 사용 점수 | Tau3-Banking 45%, 3.7 Flash 대비 +12포인트 (Artificial Analysis, 독립) |
| 토큰 비용 | AA 인덱스에서 작업당 약 48k 출력 토큰, 3.7 Flash 대비 +30% |
| 가격 | 2026년 12월 31일까지 100만 토큰당 입력 $0.75 / 출력 $3.75; 사고는 출력으로 청구됨 |
1단계: 도구 선언하기
Interactions API에서 도구는 평면 객체입니다: `function` 유형의 `type`, `name`, 모델이 언제 호출할지 결정하는 데 읽는 `description`, 그리고 `parameters` 아래의 JSON Schema. 설명을 구체적으로 유지하세요. "주문 ID로 현재 배송 상태 조회"는 적절한 순간에 호출되지만, "주문 도우미"는 무작위로 호출될 수 있습니다.
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"input": "Where is order A1029 right now?",
"generation_config": {"thinking_level": "low"},
"tools": [{
"type": "function",
"name": "get_order_status",
"description": "Look up the current shipping status of an order by its ID.",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"]
}
}]
}'
이 요청의 두 가지 선택은 의도적입니다. 단일 조회는 기본 `medium`이 필요하지 않으므로 `thinking_level`은 `low`입니다. 사고 수준 가이드에서 이를 높여야 할 때를 다룹니다. 그리고 `temperature`는 없습니다. Google의 Gemini 3 지침은 기본값 1.0을 유지하는 것인데, 낮추면 루프가 발생할 수 있기 때문입니다. 이는 도구 루프 내에서 가장 원치 않는 일입니다.
2단계: function_call 단계 읽기
Interactions API는 단일 메시지로 응답하지 않습니다. 상호작용 자체의 `id`와 실행 단계 목록(모델의 생각, 도구 호출, 모델이 답변을 가지면 최종적으로 `model_output` 단계)을 반환합니다. 모델이 도구가 필요하다고 판단하면, 목록은 `model_output` 대신 `function_call` 단계를 포함합니다:
{
"type": "function_call",
"id": "call_8f2d...",
"name": "get_order_status",
"arguments": {"order_id": "A1029"}
}
세 가지 필드가 있으며, 이 세 가지 필드가 모두 필요합니다. `id`는 `call_id`로 다시 보낼 핸들입니다. `name`은 실행할 함수를 알려주며, 역시 다시 반환되어야 합니다. `arguments`는 이미 파싱된 JSON이므로, 실행하기 전에 자체 규칙에 따라 유효성을 검사하십시오. 모델은 선언한 형태를 채우지만, 주문 ID가 5자리 길이인지 알지 못합니다.
응답 상단의 상호작용 `id`를 동시에 저장하십시오. 이것은 다음 턴에서 `previous_interaction_id`가 됩니다.
3단계: call_id와 name으로 결과 반환하기
함수를 실행한 다음, `input`이 `function_result`인 두 번째 요청을 보냅니다. Gemini 3.8 Flash에서는 `call_id`와 `name`이 모두 필수입니다. 둘 중 하나라도 누락되면 호출이 실패하며, 이는 이전 모델용으로 작성된 루프를 옮길 때 가장 흔하게 발생하는 문제입니다.
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"previous_interaction_id": "<interaction id from step 2>",
"input": [{
"type": "function_result",
"name": "get_order_status",
"call_id": "call_8f2d...",
"result": [{"type": "text", "text": "{\"status\":\"in_transit\",\"eta\":\"2026-09-05\"}"}]
}]
}'
`result`는 콘텐츠 파트 목록이며, 텍스트 파트는 JSON을 문자열로 전달합니다. `previous_interaction_id`가 이전 턴을 가리키므로, 서버는 이미 원래 프롬프트, 도구 선언 및 모델의 추론을 가지고 있습니다. 이 중 어느 것도 다시 보낼 필요가 없습니다. 응답은 또 다른 단계 목록입니다. `model_output`으로 끝나면 작업이 완료된 것이고, SDK는 텍스트를 `interaction.output_text`로 노출합니다. 다른 `function_call`이 포함되어 있다면, 2단계로 돌아갑니다. 이 루프가 전체 패턴입니다.
Python에서는 `client.interactions.create(model="gemini-3.8-flash", input=..., ...)` 흐름을 사용하며, 동일한 JSON 필드를 키워드 인수로 사용한 다음, `previous_interaction_id`와 `function_result` 목록을 `input`으로 사용하여 두 번째 `create`를 호출합니다. Gemini 3.8 Flash API 사용법은 엔드포인트가 익숙하지 않은 경우 키, 스트리밍 및 토큰 사용량 읽기를 다룹니다.
레거시 generateContent 대안
대부분의 기존 Gemini 코드는 여전히 `models/gemini-3.8-flash:generateContent`를 호출하며, Google은 이 기능이 "완벽하게 지원"되며 지원 종료 날짜가 없다고 말합니다. 용어는 다르지만 규칙은 동일합니다. 도구는 `functionDeclarations` 아래에 선언되고, 모델은 `functionCall` 파트로 응답하며, 사용자는 `functionResponse` 파트로 응답합니다. 레거시 형태에서 모델의 `functionCall` 파트는 `id`를 포함하고, 사용자 `functionResponse` 파트는 `name` 및 `response`와 함께 자체 `id` 필드에 동일한 값을 에코해야 합니다. 이는 Interactions API의 `call_id`와 다른 필드 이름으로 동일한 계약이며, Google의 Gemini 3 지침은 `id`와 `name` 모두 필수라고 명시합니다.
두 가지 실제적인 차이점이 있습니다. 첫째, `generateContent`는 상태 비저장 방식이므로 대화를 직접 관리해야 합니다. 모델의 `functionCall` 파트와 반환된 모든 생각 서명을 포함하여 전체 `contents` 기록이 매 턴마다 다시 전달됩니다. 둘째, 사고 수준은 `generation_config.thinking_level` 대신 `generationConfig.thinkingConfig.thinkingLevel` 아래에 구성됩니다.
{"generationConfig": {"thinkingConfig": {"thinkingLevel": "low"}}}
사고 토큰은 응답에서 `usageMetadata.thoughtsTokenCount`로 나타나며 출력으로 청구됩니다. 새 프로젝트에 두 API 중 하나를 선택해야 한다면 Interactions API를 선택하세요. 서버 측 상태는 재전송된 기록에 서명이나 `call_id`가 누락되는 종류의 버그를 제거합니다.
3.8 Flash가 도구를 반복적으로 호출하는 이유와 루프를 제한하는 방법
Google의 출시 게시물에 따르면, 이 모델은 "더 열심히 작동"하며 복잡한 작업에서 "추가 추론 단계를 실행하고 도구를 반복적으로 호출"하여 "더 작은 추론 단계"를 거치고 작업을 확인합니다. Google은 또한 이 모델이 "더 오래 실행되고 복잡한 작업에 더 많은 토큰을 사용할 수 있도록 설계되었다"고 말합니다. Artificial Analysis는 그 효과를 측정했습니다. 그들의 인덱스에서 작업당 약 48k 출력 토큰으로, 3.7 Flash보다 30% 증가했으며, 동일한 토큰당 가격에서 `high`의 작업당 비용은 $0.58, 3.7 Flash의 $0.40과 비교됩니다. `medium`은 $0.41, `low`는 $0.24였습니다.
도구 루프의 경우, 이는 작업당 더 많은 `function_call` 단계를 의미합니다. 장점은 분명합니다. AA의 도구 사용 평가인 Tau3-Banking은 12포인트 상승하여 45%가 되었습니다. 단점은 상한이 없는 루프가 이제 8월보다 더 오래 실행된다는 것입니다. 적용 순서대로 네 가지 제어 방법은 다음과 같습니다.
- 하니스에서 최대 턴 수. 작업당 `function_call` 단계를 세고 사용자가 선택한 제한에서 멈춥니다. 조회에는 6~10이 합리적인 시작 범위이며, 에이전트 코딩에는 더 높습니다. 제한에 도달하면 도구 없이 최종 턴을 보내거나 사용자에게 오류를 반환하십시오. 모델은 스스로 제한하지 않습니다.
- 경로별 `thinking_level`. 조회 및 단일 홉 도구에는 `low`, 다단계 작업에는 `medium` (기본값), 추가 검증이 필요한 경우에만 `high`. `minimal`을 보내지 마십시오. 3.8 Flash는 유효성 검사 오류를 반환합니다.
- 양쪽의 타임아웃. Gemini 호출에 대한 요청당 타임아웃과 루프에 대한 작업당 전체 시간입니다. AA의 고수준 추론 실행은 작업당 평균 2.5분, `low`에서는 0.8분이었습니다.
- 멱등 도구. 반복적인 모델은 재시도합니다. `get_order_status`는 두 번 호출해도 안전하게 만들고, 부작용이 있는 모든 것(환불, 발송)은 확인 단계를 요구하도록 만드십시오.
예산이 추가 턴을 감당할 수 없다면, 3.7에서 3.8 Flash 마이그레이션 가이드는 구성 플래그 뒤에 3.7 Flash(여전히 완벽하게 지원됨)를 유지하는 방법을 다룹니다.
사고 서명, 병렬 호출 및 구조화된 출력
사고 서명(Thought signatures). Gemini 3 모델은 추론에 서명을 첨부합니다. 기본 저장된 Interactions 흐름에서는 `previous_interaction_id`가 이를 처리합니다. 상태 비저장 설정을 위해 `store: false`로 설정하거나 `generateContent`를 사용하는 경우, 모든 파트 유형에 대해 수신된 그대로 사고 블록과 서명을 다시 보내야 합니다. 잘라내거나, 순서를 바꾸거나, 다시 직렬화하지 마십시오. 서명은 불투명하며 어떤 편집도 이를 무효화합니다. Google의 Interactions API 문서는 저장 방식과 상태 비저장 방식의 장단점을 다룹니다.
병렬 호출(Parallel calls). 응답은 목록이므로 모델이 여러 독립적인 조회를 동시에 원할 때 둘 이상의 `function_call` 단계를 포함할 수 있습니다. Google의 함수 호출 문서는 Gemini 3 모델이 모든 호출에 고유한 ID를 반환하여 결과가 어떤 순서로든 반환될 수 있음을 확인합니다. 동일한 `input` 배열에서 각 호출에 대해 고유한 `call_id`와 일치시켜 하나의 `function_result`를 반환하여 처리하십시오. `name`만으로 일치시키는 것은 충분하지 않습니다. 동일한 함수에 대한 두 번의 호출에는 두 개의 다른 `call_id` 값이 필요합니다.
구조화된 출력(Structured outputs). 3.8 Flash는 동일한 모델에서 구조화된 출력과 함수 호출을 지원합니다. 깔끔한 패턴은 루프를 위한 도구와 최종 답변을 위한 JSON 스키마를 사용하는 것입니다. 이렇게 하면 루프를 닫는 `model_output`이 산문이 아닌 기계가 읽을 수 있는 형태가 됩니다. Google의 함수 호출 및 구조화된 출력 페이지에 구성이 문서화되어 있습니다. 더미 도구를 선언하고 해당 `arguments`를 읽어 가짜로 만들지 마십시오. 모델이 호출할 것이 없다고 판단하는 순간 작동이 중단됩니다.
위의 모든 내용은 모델이 선언된 함수를 통해 시스템에 도달한다고 가정합니다. Google은 또한 3.8 Flash용 Computer use (Preview)를 나열합니다. 구조화된 API가 에이전트의 화면 제어보다 나은 경우, 컴퓨터 사용 대 구조화된 API를 참조하십시오.
Apidog에서 도구 루프 테스트하기
도구 루프에는 세 가지 실패 지점이 있습니다: 선언, ID 왕복, 최종 답변. 실제 백엔드를 건드리지 않고 Apidog에서 이 세 가지 모두를 다룰 수 있습니다.
1. 도구의 백엔드를 모의하세요. `GET /orders/{order_id}`를 엔드포인트로 정의하고 모의 서버를 켜세요. `{"status": "in_transit", "eta": "2026-09-05"}`와 같은 고정된 응답 본문을 제공하여 모든 실행이 동일한 입력을 받도록 하고, 모델의 최종 답변 변경 사항이 데이터베이스가 아닌 모델 자체의 소행임을 확인하세요. 테스트 환경에서는 하니스가 모의 URL을 가리키고, 프로덕션에서는 실제 서비스를 가리킵니다.
2. 테스트 시나리오에서 두 턴을 연결하세요. `GEMINI_API_KEY`를 환경 변수로 저장하고 `x-goog-api-key` 헤더에서 `{{GEMINI_API_KEY}}`로 참조하세요. 그런 다음 세 단계로 시나리오를 구축하세요:
- 단계 A: 프롬프트와 `get_order_status` 선언으로 `/v1beta/interactions`에 POST 요청을 보냅니다. 상호작용 `id`와 `function_call` 단계의 `id`, `name`, `arguments.order_id`를 변수로 추출합니다.
- 단계 B: `{{order_id}}`로 모의 엔드포인트에 GET 요청을 보냅니다. 이것은 "함수 실행" 단계입니다.
- 단계 C: `call_id`를 `{{call_id}}`로, `name`을 `{{tool_name}}`으로, `previous_interaction_id`를 `{{interaction_id}}`로 설정하고, 단계 B의 본문을 텍스트 부분으로 하여 `function_result`를 POST합니다.
3. 중요한 것을 검증하세요.
- 단계 A는 200을 반환하고 `type`이 `function_call`이며 `name`이 `get_order_status`와 동일한 단계를 포함합니다.
- 추출된 `arguments.order_id`는 `A1029`와 같으며, 이는 모델이 프롬프트를 파싱하고 스키마를 준수했음을 증명합니다.
- 단계 C는 200을 반환하고 두 번째 `function_call` 없이 `type`이 `model_output`인 단계로 끝나며, 이는 사용자가 보낸 `call_id`와 `name`이 수락되었고 루프가 한 번의 왕복으로 닫혔음을 증명합니다.
- 최종 텍스트에 `in_transit`이 포함되어 있으며, 이는 모델이 자체 추측 대신 도구 결과를 사용했음을 증명합니다.
- `generateContent`에 대해 동일한 시나리오를 실행하는 경우, `thinking_level`당 `usageMetadata.thoughtsTokenCount`에 상한선을 추가하십시오. 이는 "더 열심히 작동"으로 인한 비용 증가가 청구서에 도달하기 전에 잡아냅니다.
시나리오를 매일 실행하도록 예약하세요. 모델 동작은 조용한 업데이트에 따라 달라지며, 지난주에 한 번의 왕복으로 닫혔던 루프가 두 번이 필요하게 될 수 있습니다. AI 에이전트 API 테스트 가이드는 다단계 검증에 대해 더 자세히 설명하며, 비용을 지불하기 전에 Apidog를 다운로드하여 무료 계층에서 시나리오를 구축할 수 있습니다.
자주 묻는 질문
Gemini 3.8 Flash에서 `call_id`는 필수입니까? 예. Interactions API에서는 모든 `function_result`에 `call_id`와 `name`이 필요하며, `generateContent`에서는 모든 `functionResponse`에 호출의 `id`와 `name`이 필요합니다. 이름만 보냈던 이전 코드는 Gemini 3 모델에서 실패합니다.
제 도구 루프가 3.7보다 3.8 Flash에서 더 많은 턴을 실행하는 이유는 무엇입니까? 의도된 설계입니다. Google은 모델이 "도구를 반복적으로 호출"하며 "더 오래 실행되고 복잡한 작업에 더 많은 토큰을 사용할 수 있다"고 말합니다. 하니스에서 턴 수를 제한하고 `thinking_level`을 낮추십시오. 사고 수준 가이드에 수준별 측정 비용이 나와 있습니다.
함수 호출에 여전히 `generateContent`를 사용할 수 있습니까? 예. Google은 이를 레거시라고 부르지만, 지원 종료 날짜 없이 "완벽하게 지원된다"고 말합니다. 사고 서명을 포함하여 기록을 직접 관리해야 하며, 호출 ID(이 API에서는 `id`로 표기)와 `name`이 여전히 적용됩니다.
`thinking_level` "minimal"이 도구와 함께 작동합니까? 아니요. 3.8 Flash에서는 유효성 검사 오류를 반환합니다. `low`를 사용하십시오.
도구 사용량이 많은 작업의 비용은 얼마나 됩니까? 토큰당 가격은 2026년 12월 31일까지 100만 토큰당 입력 $0.75, 출력 $3.75이며, 사고는 출력으로 청구됩니다. Artificial Analysis는 그들의 인덱스에서 `high`일 때 작업당 $0.58, `medium`일 때 $0.41, `low`일 때 $0.24로 측정했습니다. 사용자의 작업은 다를 것이므로 토큰 수를 확인하고 측정하십시오.
상한선을 정하여 루프를 배포하세요
도구를 선언하고, `function_call` 단계를 읽은 다음, `previous_interaction_id` 아래에 `call_id`와 `name`을 모두 포함하는 `function_result`를 반환하십시오. 이것이 전체 계약입니다. Gemini 3.8 Flash에서 변경된 점은 모델의 반복 의지이므로, 하니스는 프로덕션에 배포되기 전에 턴 제한, 경로별 `thinking_level`, 그리고 타임아웃이 필요합니다. 백엔드를 모의하고, 두 턴을 연결하며, ID 왕복을 검증하고, 실행을 예약하십시오. Google의 Gemini 3.8 Flash의 새로운 기능 페이지에 마이그레이션 노트가 있으며, 필라 가이드에는 모델에 대한 모든 다른 정보가 있습니다.
