Gemini 3.5 Flash의 새로운 기능

Gemini 3.5 Flash의 새로운 기능 (What's new in Gemini 3.5)

Gemini 3.5 Flash는 일반 공개(GA) 상태로 안정적이며, 규모 있는 프로덕션 사용에 준비된 모델이에요. 가장 지능적인 Flash 모델로서 에이전틱 실행, 코딩, 장기간(long-horizon) 작업에서 지속적인 최첨단 성능을 제공합니다.

출처: 문서

본문

이 가이드는 Gemini 3.5 Flash의 개선 사항, API 변경, 마이그레이션 안내를 다룹니다. 최신 모델 선택은 3.6 Flash & 3.5 Flash-Lite를 참고하세요.

새 모델

모델 모델 ID 설명
Gemini 3.5 Flash gemini-3.5-flash 에이전틱·코딩 작업에서 지속적 최첨단 성능을 내는 가장 지능적인 모델.

Gemini 3.5 Flash는 1M 토큰 컨텍스트 윈도우, 65k 최대 출력 토큰, thinking, 그리고 Computer Use (Preview)를 포함해 Gemini 3 Flash와 동일한 도구·플랫폼 기능 세트를 지원해요.

전체 사양은 models overview, 가격은 pricing page를 참고하세요.

빠른 시작 (Quickstart)

이 가이드의 모든 예시는 Interactions API를 사용해요. GenerateContent API도 지원되며 같은 구성 옵션과 권장 사항이 적용됩니다.

from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.5-flash",
    input="Explain how parallel agentic execution works in three sentences."
)
print(interaction.output_text)
import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({});

async function main() {
  const interaction = await client.interactions.create({
    model: "gemini-3.5-flash",
    input: "Explain how parallel agentic execution works in three sentences.",
  });
  console.log(interaction.output_text);
}

main();
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;

Client client = new Client();

CreateModelInteraction params =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.5-flash"))
        .input(
            InteractionsInput.of(
                "Explain how parallel agentic execution works in three sentences."))
        .build();

Interaction interaction =
    client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();

System.out.println(interaction.outputText().orElse(""));
package main

import (
    "context"
    "fmt"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.5-flash"),
            Input: interactions.NewInteractionsInput("Explain how parallel agentic execution works in three sentences."),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }
    if res.Interaction.OutputText != nil {
        fmt.Println(*res.Interaction.OutputText)
    }
}
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.5-flash",
    "input": "Explain how parallel agentic execution works in three sentences."
  }'

새로운 점

  • 지속적인 최첨단 성능 (Sustained frontier performance): 대규모 에이전틱·코딩 작업에 최적화된 가장 지능적인 Flash 모델.
  • 에이전틱 실행 (Agentic execution): 서브 에이전트 배포, 문제 해결, 대규모에서의 빠른 에이전틱 루프.
  • 코딩 (Coding): 반복적인 코딩 사이클, 빠른 탐색, 대안 경로를 시험하고 솔루션을 동적으로 탐색하는 프로토타이핑.
  • 장기간 작업 (Long horizon): 대규모 다단계 워크플로와 도구 사용.
  • 생각 보존 (Thought preservation): 모델이 다중 턴 대화에서 중간 추론을 자동으로 유지해요. API 변경이 필요 없어요.
  • 새 기본 노력 수준 (New default effort level): 기본 thinking 노력이 high에서 medium으로 바뀌었어요. 새 기본 노력 수준 참고.
  • 개선된 low thinking: low는 이제 더 적은 단계가 필요한 코드·에이전틱 작업에서 크게 개선되어, 더 낮은 지연 시간과 비용으로도 강한 품질을 제공해요.
  • GA 출시 (GA release): 대규모 프로덕션 사용을 위한 안정적인 모델.

올바른 Flash 모델 고르기

Gemini 3.5 Flash는 가장 지능적이고 유능한 Flash 모델이에요. 다만 사용 사례마다 비용과 지연 시간 요구가 다를 수 있어요.

  • Gemini 3.1 Flash-Lite: 3.5 Flash의 고급 추론 깊이가 필요 없는 저비용·대량 작업에는 Gemini 3.1 Flash-Lite를 권장해요. 효율성에 최적화된 안정적인 장기 모델이에요. 자세한 내용은 Flash-Lite 개발자 가이드를 참고하세요.
  • Gemini 3 Flash Preview: GA 안정성과 개선된 추론을 위해 3.5 Flash로의 마이그레이션을 권장하지만, 프리뷰 모델을 계속 테스트하고 싶은 개발자를 위해 Gemini 3 Flash (Preview)는 계속 사용 가능해요.

동작 변경 사항

새 기본 노력 수준: medium

기본 thinking 노력은 이제 medium 이에요. Gemini 3 Flash Preview에서 high에서 바뀌었죠. medium은 더 빠르고 비용 효율적이면서 다양한 작업에서 아주 좋은 결과를 냅니다. 복잡한 문제에서는 high가 모델이 더 깊이 생각하도록 유도해요.

노력 수준 언제 사용할까
minimal 응답 속도에 최적화. 채팅형 사용 사례, 빠른 사실 답변, 간단한 도구 호출.
low 더 낮은 지연 시간과 적은 단계가 필요한 코드·에이전틱 작업. 어느 정도 사고가 필요한 분석·작문 작업에도 잘 맞아요.
medium (기본값) 대부분의 작업에 최고 품질. 복잡한 코드·에이전틱 사용 사례에 권장.
high 모델의 사고·도구 사용 능력을 극대화. 복잡한 추론, 어려운 수학, 가장 어려운 코드·에이전트 작업에 최적. 확장된 생각과 함수 호출을 허용.

기본값을 재정의하려면 구성에서 thinking_level을 설정하세요.

from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.5-flash",
    input="Prove that the square root of 2 is irrational.",
    generation_config={"thinking_level": "high"},
)
print(interaction.output_text)
import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({});

async function main() {
  const interaction = await client.interactions.create({
    model: "gemini-3.5-flash",
    input: "Prove that the square root of 2 is irrational.",
    generationConfig: { thinkingLevel: "high" },
  });
  console.log(interaction.output_text);
}

main();
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.GenerationConfig;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ThinkingLevel;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;

Client client = new Client();

CreateModelInteraction params =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.5-flash"))
        .input(InteractionsInput.of("Prove that the square root of 2 is irrational."))
        .generationConfig(GenerationConfig.builder().thinkingLevel(ThinkingLevel.HIGH).build())
        .build();

Interaction interaction =
    client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();

System.out.println(interaction.outputText().orElse(""));
package main

import (
    "context"
    "fmt"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.5-flash"),
            Input: interactions.NewInteractionsInput("Prove that the square root of 2 is irrational."),
            GenerationConfig: &interactions.GenerationConfig{
                ThinkingLevel: interactions.ThinkingLevelHigh.ToPointer(),
            },
        }),
    })
    if err != nil {
        log.Fatal(err)
    }
    if res.Interaction.OutputText != nil {
        fmt.Println(*res.Interaction.OutputText)
    }
}
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.5-flash",
    "input": "Prove that the square root of 2 is irrational.",
    "generation_config": {"thinking_level": "high"}
  }'

팁: medium부터 시작하세요. 대다수 작업에서 최고 품질을 제공해요. low는 빠르고 저렴하면서 강한 품질의 경험을, high는 복잡한 추론·어려운 수학·어려운 코딩에, minimal은 단순 쿼리에서 속도 최적화에 시도해 보세요.

모델별 지원 thinking 수준 표:

Thinking 수준 Gemini 3.5 Flash Gemini 3.1 Pro Gemini 3.1 Flash-Lite Gemini 3 Flash 설명
minimal 지원 미지원 지원 (기본값) 지원 대부분의 쿼리에 대해 "no thinking" 설정과 일치. minimal이 thinking이 꺼짐을 보장하진 않으며, 복잡한 작업에서 모델이 아주 최소한으로 추론할 수 있음.
low 지원 지원 지원 지원 지연 시간과 비용 최소화.
medium 지원 (기본값) 지원 지원 지원 대부분의 작업에 균형 잡힌 thinking.
high 지원 (Dynamic) 지원 (기본값, Dynamic) 지원 (Dynamic) 지원 (기본값, Dynamic) 추론 깊이 최대화.

중요: 같은 요청에서 thinking_level과 레거시 thinking_budget 파라미터를 함께 사용할 수 없어요. 함께 쓰면 400 오류가 나요.

생각 보존 (Thought preservation)

모델은 다중 턴 대화에서 중간 추론을 자동으로 유지해요. 대화 기록에 존재할 때 추론 컨텍스트가 이월되어 반복 디버깅이나 코드 리팩터링 같은 복잡한 다단계 작업에서 성능을 높여요. API 변경이 필요 없어요.

  • Interactions API: 생각이 이미 자동으로 보존돼요. 동작 변경 없음.
  • GenerateContent API: Gemini 3.5 Flash부터 모델은 대화 기록에 thought signature가 존재할 때 이전 모든 턴의 추론 컨텍스트를 사용해요. 이를 활성화하려면 thought signature를 포함한 전체 수정되지 않은 대화 기록을 contents에 전달하세요. SDK가 자동으로 처리해요.

Gemini 3.x의 파라미터 업데이트와 모범 사례

다음은 Gemini 3.5 Flash를 포함한 모든 Gemini 3.x 모델에 적용돼요.

  • temperature, top_p, top_k: 기본값을 바꾸지 않는 것을 강력히 권장해요. Gemini 3의 추론 능력은 기본 설정에 최적화되어 있어요.
  • thinking_budget 대신 thinking_level을 사용하세요.
  • 함수 호출 응답 매칭: id, name, 응답 수가 앞선 호출과 일치해야 해요.
  • 멀티모달 함수 응답: 멀티모달 콘텐츠를 함수 응답 안에 포함하세요(밖에 두지 말고).
  • 함수 응답의 인라인 지시: 함수 응답 텍스트에 추가하지 말고 별도 part로 두지 마세요.
  • 불필요한 도구 호출 줄이기: 더 낮은 thinking 수준을 쓰거나 시스템 지시를 실험해 에이전틱 워크플로의 도구 호출을 줄이세요.

아래 섹션들에서 코드를 업데이트하는 방법을 살펴볼게요.

샘플링 파라미터 (더 이상 권장하지 않음)

temperature, top_p, top_k는 모든 Gemini 3.x 모델에서 더 이상 권장되지 않아요. Gemini 3의 추론 능력은 기본 설정에 최적화되어 있어요. 모든 요청에서 이 파라미터들을 제거하세요.

# ⚠️ Remove these parameters (not recommended)
generation_config = {
    "temperature": 0.7,
    "top_p": 0.9,
    "top_k": 40,
}

결정성을 보장하려면 사용 사례에 맞는 명시적 규칙이 담긴 시스템 지시를 정의하는 것을 권장해요.

thinking_budget (더 이상 권장하지 않음)

원시 숫자 thinking_budget 파라미터는 모든 Gemini 3.x 모델에서 더 이상 권장되지 않아요. 대신 thinking_level 문자열 열거형을 사용하세요.

# ⚠️ Before (not recommended)
generation_config = {
    "thinking": {"thinking_budget": 7500},
}

# ✅ After
generation_config = {
    "thinking": {"thinking_level": "medium"},
}

사용 가능한 값: minimal, low, medium(기본값), high.

함수 호출: 엄격한 응답 매칭

Interactions API는 이미 불일치 함수 응답에 오류를 내요. GenerateContent API는 아직 오류를 내지 않지만, 불일치 응답은 대부분 finish_reason: STOP과 함께 빈 응답을 반환하게 해요. 항상 다음 규칙을 따르세요.

요구 사항 세부 사항
id 포함 모든 FunctionResponse는 해당 FunctionCall의 id를 포함해야 함
name 일치 응답의 name은 호출의 name과 일치해야 함
수 일치 받은 각 FunctionCall에 대해 정확히 하나의 FunctionResponse를 반환
# ✅ Include matching call_id and name in the function_result
final_interaction = client.interactions.create(
    model="gemini-3.5-flash",
    previous_interaction_id=interaction.id,
    tools=[my_tool],
    input=[{
        "type": "function_result",
        "name": fc_step.name,
        "call_id": fc_step.id,
        "result": [{"type": "text", "text": json.dumps(result)}],
    }],
)
// ✅ Include matching call_id and name in the function_result
const finalInteraction = await client.interactions.create({
  model: "gemini-3.5-flash",
  previousInteractionId: interaction.id,
  tools: [myTool],
  input: [{
    type: "function_result",
    name: fcStep.name,
    call_id: fcStep.id,
    result: [{ type: "text", text: JSON.stringify(result) }],
  }],
});
import java.util.Arrays;
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Function;
import com.google.genai.gaos.models.interactions.FunctionResultStep;
import com.google.genai.gaos.models.interactions.FunctionResultStepResultUnion;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.List;

Client client = new Client();

// Assumes interactionId, callId, functionName, myTool, and resultJson from previous step
String interactionId = "interaction-id-123";
String callId = "call-id-123";
String functionName = "get_weather";
Function myTool = Function.builder().name(functionName).build();
String resultJson = "{\"temperature\": \"72F\"}";

// ✅ Include matching callId and name in the FunctionResultStep
FunctionResultStep functionResult =
    FunctionResultStep.builder()
        .name(functionName)
        .callId(callId)
        .result(
            FunctionResultStepResultUnion.of(
                Arrays.asList(TextContent.builder().text(resultJson).build())))
        .build();

CreateModelInteraction params =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.5-flash"))
        .previousInteractionId(interactionId)
        .tools(Arrays.asList(myTool))
        .input(InteractionsInput.ofStep(Arrays.asList(functionResult)))
        .build();

Interaction finalInteraction =
    client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
package main

import (
    "context"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    // Assumes interactionID, callID, functionName, myTool, and resultJSON from previous step
    interactionID := "interaction-id-123"
    callID := "call-id-123"
    functionName := "get_weather"
    myTool := interactions.NewTool(interactions.Function{Name: genai.Ptr(functionName)})
    resultJSON := `{"temperature": "72F"}`

    // ✅ Include matching CallID and Name in the FunctionResultStep
    functionResult := interactions.NewStep(interactions.FunctionResultStep{
        Name:   genai.Ptr(functionName),
        CallID: callID,
        Result: interactions.NewFunctionResultStepResultUnion([]interactions.FunctionResultSubcontent{
            interactions.NewFunctionResultSubcontent(interactions.TextContent{Text: resultJSON}),
        }),
    })

    finalRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model:                 interactions.Model("gemini-3.5-flash"),
            PreviousInteractionID: genai.Ptr(interactionID),
            Tools:                 []interactions.Tool{myTool},
            Input:                 interactions.NewInteractionsInput([]interactions.Step{functionResult}),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }
    _ = finalRes
}
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.5-flash",
    "previous_interaction_id": "<INTERACTION_ID>",
    "tools": [...],
    "input": [{
      "type": "function_result",
      "name": "my_function",
      "call_id": "<CALL_ID>",
      "result": [{"type": "text", "text": "..."}]
    }]
  }'

멀티모달 함수 응답

클라이언트가 함수 응답 밖에 이미지를 제공하는 것을 자주 봐요. 이는 예상 밖의 모델 동작(예: 생각 유출, thought leakage)과 낮은 품질 출력으로 이어질 수 있어요. Multimodal Function Responses API 문서의 권장사항을 따라 멀티모달 콘텐츠를 모델에 보내는 함수 응답 part에 포함하세요. 모델은 다음 턴에서 이 멀티모달 콘텐츠를 처리해 더 정보가 풍부한 응답을 낼 수 있어요.

# ✅ Include multimodal content in the function response
final_interaction = client.interactions.create(
    model="gemini-3.5-flash",
    previous_interaction_id=interaction.id,
    input=[
        {
            "type": "function_result",
            "name": tool_call.name,
            "call_id": tool_call.id,
            "result": [
                {"type": "text", "text": "instrument.jpg"},
                {
                    "type": "image",
                    "mime_type": "image/jpeg",
                    "data": base64_image_data,
                },
            ],
        }
    ],
)
// ✅ Include multimodal content in the function response
const finalInteraction = await client.interactions.create({
  model: "gemini-3.5-flash",
  previousInteractionId: interaction.id,
  input: [{
    type: "function_result",
    name: toolCall.name,
    call_id: toolCall.id,
    result: [
      { type: "text", text: "instrument.jpg" },
      {
        type: "image",
        mime_type: "image/jpeg",
        data: base64ImageData,
      },
    ],
  }],
});
import java.util.Arrays;
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.FunctionResultStep;
import com.google.genai.gaos.models.interactions.FunctionResultStepResultUnion;
import com.google.genai.gaos.models.interactions.ImageContent;
import com.google.genai.gaos.models.interactions.ImageContentMimeType;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.List;

Client client = new Client();

// Assumes interactionId, callId, functionName, and base64ImageData from previous step
String interactionId = "interaction-id-123";
String callId = "call-id-123";
String functionName = "get_instrument_image";
String base64ImageData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=";

// ✅ Include multimodal content in the function response
FunctionResultStep functionResult =
    FunctionResultStep.builder()
        .name(functionName)
        .callId(callId)
        .result(
            FunctionResultStepResultUnion.of(
                Arrays.asList(
                    TextContent.builder().text("instrument.jpg").build(),
                    ImageContent.builder()
                        .mimeType(ImageContentMimeType.IMAGE_JPEG)
                        .data(base64ImageData)
                        .build())))
        .build();

CreateModelInteraction params =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.5-flash"))
        .previousInteractionId(interactionId)
        .input(InteractionsInput.ofStep(Arrays.asList(functionResult)))
        .build();

Interaction finalInteraction =
    client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
package main

import (
    "context"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    // Assumes interactionID, callID, functionName, and base64ImageData from previous step
    interactionID := "interaction-id-123"
    callID := "call-id-123"
    functionName := "get_instrument_image"
    base64ImageData := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="

    // ✅ Include multimodal content in the function response
    functionResult := interactions.NewStep(interactions.FunctionResultStep{
        Name:   genai.Ptr(functionName),
        CallID: callID,
        Result: interactions.NewFunctionResultStepResultUnion([]interactions.FunctionResultSubcontent{
            interactions.NewFunctionResultSubcontent(interactions.TextContent{
                Text: "instrument.jpg",
            }),
            interactions.NewFunctionResultSubcontent(interactions.ImageContent{
                MimeType: interactions.ImageContentMimeType("image/jpeg").ToPointer(),
                Data:     genai.Ptr(base64ImageData),
            }),
        }),
    })

    finalRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model:                 interactions.Model("gemini-3.5-flash"),
            PreviousInteractionID: genai.Ptr(interactionID),
            Input:                 interactions.NewInteractionsInput([]interactions.Step{functionResult}),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }
    _ = finalRes
}

함수 응답의 인라인 지시

클라이언트가 함수 응답과 함께 추가 지시를 후속 Parts로 제공하는 것을 자주 봐요. 이는 예상 밖의 모델 동작(예: 생각 유출)과 낮은 품질 출력으로 이어질 수 있어요. 대신 추가 지시를 두 개의 개행으로 구분해 함수 응답 텍스트 끝에 붙이세요.

# ✅ Append inline instructions to the end of the function response separated by two newlines
result_text = f"{json.dumps(result)}\n\n<your inline instructions>"

final_interaction = client.interactions.create(
    model="gemini-3.5-flash",
    previous_interaction_id=interaction.id,
    tools=[my_tool],
    input=[{
        "type": "function_result",
        "name": fc_step.name,
        "call_id": fc_step.id,
        "result": [{"type": "text", "text": result_text}],
    }],
)
// ✅ Append inline instructions to the end of the function response separated by two newlines
const resultText = `${JSON.stringify(result)}\n\n<your inline instructions>`;

const finalInteraction = await client.interactions.create({
  model: "gemini-3.5-flash",
  previousInteractionId: interaction.id,
  tools: [myTool],
  input: [{
    type: "function_result",
    name: fcStep.name,
    call_id: fcStep.id,
    result: [{ type: "text", text: resultText }],
  }],
});
import java.util.Arrays;
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Function;
import com.google.genai.gaos.models.interactions.FunctionResultStep;
import com.google.genai.gaos.models.interactions.FunctionResultStepResultUnion;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.List;

Client client = new Client();

// Assumes interactionId, callId, functionName, myTool, and resultJson from previous step
String interactionId = "interaction-id-123";
String callId = "call-id-123";
String functionName = "get_weather";
Function myTool = Function.builder().name(functionName).build();
String resultJson = "{\"temperature\": \"72F\"}";

// ✅ Append inline instructions to the end of the function response separated by two newlines
String resultText = resultJson + "\n\n<your inline instructions>";

FunctionResultStep functionResult =
    FunctionResultStep.builder()
        .name(functionName)
        .callId(callId)
        .result(
            FunctionResultStepResultUnion.of(
                Arrays.asList(TextContent.builder().text(resultText).build())))
        .build();

CreateModelInteraction params =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.5-flash"))
        .previousInteractionId(interactionId)
        .tools(Arrays.asList(myTool))
        .input(InteractionsInput.ofStep(Arrays.asList(functionResult)))
        .build();

Interaction finalInteraction =
    client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
package main

import (
    "context"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    // Assumes interactionID, callID, functionName, myTool, and resultJSON from previous step
    interactionID := "interaction-id-123"
    callID := "call-id-123"
    functionName := "get_weather"
    myTool := interactions.NewTool(interactions.Function{Name: genai.Ptr(functionName)})
    resultJSON := `{"temperature": "72F"}`

    // ✅ Append inline instructions to the end of the function response separated by two newlines
    resultText := resultJSON + "\n\n<your inline instructions>"

    functionResult := interactions.NewStep(interactions.FunctionResultStep{
        Name:   genai.Ptr(functionName),
        CallID: callID,
        Result: interactions.NewFunctionResultStepResultUnion([]interactions.FunctionResultSubcontent{
            interactions.NewFunctionResultSubcontent(interactions.TextContent{Text: resultText}),
        }),
    })

    finalRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model:                 interactions.Model("gemini-3.5-flash"),
            PreviousInteractionID: genai.Ptr(interactionID),
            Tools:                 []interactions.Tool{myTool},
            Input:                 interactions.NewInteractionsInput([]interactions.Step{functionResult}),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }
    _ = finalRes
}

불필요한 도구 호출 줄이기

도구 호출이 과하게 발생한다면 두 가지 기법이 도움이 돼요.

  1. thinking 수준을 먼저 낮추기 (medium, low, minimal): 더 높은 thinking 수준은 모델이 탐색·검증에 더 많은 도구를 쓰게 하므로, 수준을 낮추면 도구 호출을 줄일 수 있어요.
  2. 시스템 지시 추가하기: thinking 수준을 조정한 뒤에도 과사용이 계속되면 도구 사용을 제한하는 프롬프트를 고려하세요. 예를 들어:
You have a limited action budget of <n> tool calls. Use them efficiently.

마이그레이션 체크리스트

참고: 코딩 에이전트로 이 마이그레이션을 자동화하세요. 스킬을 지원하는 코딩 에이전트(Antigravity 같은)를 쓴다면 Gemini API 스킬을 설치하고 다음을 실행하세요: /gemini-api-dev migrate my app to Gemini 3.5 Flash

google-genai SDK v2.0.0 이상으로 업데이트하는 것을 강력히 권장해요. 이 버전은 Interactions API에 파괴적 변경을 도입해요. 자세한 내용은 breaking changes migration guide를 참고하세요.

Gemini 3 Flash Preview에서 마이그레이션

  • 모델 이름 업데이트: gemini-3-flash-preview → gemini-3.5-flash
  • 가격 검토. Gemini 3.5 Flash는 Gemini 3 Flash Preview보다 비싸요. 비용에 매우 민감한 사용 사례라면 Gemini 3.1 Flash-Lite로 마이그레이션하는 것을 고려하세요. 자세한 내용은 pricing page를 참고하세요.
  • 구성에서 temperature, top_p, top_k 제거(더 이상 권장하지 않음).
  • thinking_budget을 thinking_level로 교체.
  • 모든 FunctionResponse part에 id와 일치하는 name 추가.
  • 프롬프트 테스트. 기본 노력이 high → medium으로 바뀜. 품질·속도·비용 확인.
  • Thought preservation이 이제 기본적으로 켜짐. 추론 컨텍스트가 턴을 넘어 이월되어 성능은 좋아지지만 토큰 사용량이 늘 수 있음.
  • 불필요한 도구 호출 줄이기: thinking 수준부터 낮추고(medium, low, minimal), 그래도 과사용이면 도구 사용을 제한하는 시스템 지시 추가.
  • Computer Use 지원됨.

Gemini 2.5에서 마이그레이션

위의 모든 것에 더해:

  • 프롬프트 단순화. 사고 사슬(chain-of-thought) 프롬프트 엔지니어링으로 추론을 강제했다면, 더 단순한 프롬프트와 함께 thinking_level: "medium" 또는 "high"를 시도해 보세요.
  • PDF·미디어 워크로드 테스트. 조밀한 문서 파싱의 특정 동작에 의존했다면 media_resolution_high 설정을 테스트해 정확도가 유지되는지 확인하세요. Gemini 3 기본값으로의 마이그레이션은 PDF의 토큰 사용량을 늘리고 동영상은 줄일 수 있어요. 요청이 컨텍스트 윈도우를 초과하면 media_resolution을 명시적으로 낮추세요. 자세한 내용은 media resolution 문서 참고.
  • 결합 도구 사용(combined tool use) 활용. Google Search, URL 컨텍스트, 코드 실행, 커스텀 함수를 같은 요청에서 사용할 수 있어요.
  • 멀티모달 함수 응답을 사용한다면 멀티모달 콘텐츠를 함수 응답 part 안으로(옆이 아니라) 옮기세요.
  • 함수 응답과 함께 인라인 지시를 사용한다면 두 개의 개행으로 구분해 함수 응답 텍스트에 붙이세요(별도 part가 아니라).
  • 이미지 분할(segmentation)은 Gemini 3.x에서 지원되지 않아요. 분할 워크로드는 thinking을 끈 Gemini 2.5 Flash를 계속 사용하세요.
  • 구성에서 candidate_count 제거(Gemini 3.x에서 지원 안 함).

Gemini 3 패밀리 기능

Gemini 3.5 Flash는 Computer Use를 포함해 모든 Gemini 3 패밀리 기능을 물려받아요. Gemini 3에서 도입되어 이어지는 기능들:

  • Thinking: API 호출 전반에 걸쳐 보존되는 암호화된 추론 컨텍스트. Interactions API에서 자동, GenerateContent에서 암묵적.
  • 도구와 구조화 출력: JSON 모드를 내장 도구(Search, URL 컨텍스트, 코드 실행, 함수 호출)와 결합.
  • 멀티모달 함수 응답: 함수 호출 결과에서 이미지·오디오·기타 미디어 반환.
  • 이미지 포함 코드 실행: 이미지를 처리·생성하는 코드 실행.
  • 결합 도구 사용: 같은 요청에서 내장 도구와 커스텀 함수 호출 사용.
  • 미디어 해상도: 이미지·동영상·PDF 입력의 토큰 할당을 세밀하게 제어. Gemini 3 모델은 혼합 충실도 프롬프트를 위한 콘텐츠 항목별 해상도 설정(low, medium, high, ultra_high)을 지원.
  • Thought signatures: 모델 내부 추론의 암호화된 표현. 상태 없는(stateless) 모드의 다중 턴 함수 호출에 필요. Interactions API와 공식 SDK가 자동 관리.

프롬프팅 모범 사례

Gemini 3.x 모델은 추론 모델이라 프롬프트 방식이 달라져요.

  • 정확한 지시 (Precise instructions): 간결하게. Gemini 3.x는 직접적이고 명확한 지시에 가장 잘 반응해요. 이전 모델용으로 설계된 장황하거나 복잡한 프롬프트 엔지니어링 기법은 과잉 분석을 유발할 수 있어요.
  • 출력 장황함 (Output verbosity): 기본적으로 Gemini 3과 3.1은 덜 장황하고 직접적·효율적인 답변을 선호해요. 대화형 톤이 필요하면 프롬프트에서 명시적으로 유도하세요(예: "친절하고 말 많은 어시스턴트처럼 설명해줘").
  • 컨텍스트 관리 (Context management): 대용량 데이터셋(전체 책, 코드베이스, 긴 동영상)을 다룰 때는 데이터 컨텍스트 다음인 프롬프트 끝에 특정 지시·질문을 두세요. "앞선 정보에 기반하여..." 같은 문구로 질문을 시작해 모델의 추론을 고정하세요.

프롬프트 설계 전략에 대해 더 알고 싶다면 prompt engineering guide를 참고하세요.

제한 사항

  • 이미지 분할(segmentation)은 Gemini 3.x에서 지원되지 않아요. 분할 워크로드는 thinking을 끈 Gemini 2.5 Flash를 계속 사용하세요.

FAQ

  1. Gemini 3.5 Flash의 지식 컷오프는 언제인가요? Gemini 3.5 Flash의 지식 컷오프는 2025년 1월이에요. 더 최신 정보는 Search Grounding 도구를 사용하세요.
  2. 컨텍스트 윈도우 한도는 어떻게 되나요? Gemini 3.5 Flash는 100만 토큰 입력 컨텍스트 윈도우와 최대 65k 출력 토큰을 지원해요.
  3. 기존 thinking_budget 코드는 계속 동작하나요? 네. thinking_budget은 하위 호환성을 위해 여전히 지원되지만, 더 예측 가능한 성능을 위해 thinking_level로의 마이그레이션을 권장해요. 같은 요청에서 둘 다 쓰지 마세요.
  4. Gemini 3.5 Flash는 Batch API를 지원하나요? 네. 자세한 내용은 Batch API 가이드를 참고하세요.
  5. Context Caching이 지원되나요? 네, Context Caching이 지원돼요.
  6. 어떤 도구가 지원되나요? Gemini 3.5 Flash는 Google Search, Google Maps 접지, File Search, Code Execution, URL Context, 표준 Function Calling을 지원하며, 결합 도구 사용과 Computer Use도 포함해요.

다음 단계

더 알아보기 (Learn more)

Gemini 3.5 Flash는 GA로 안정적인 프로덕션 준비 모델이에요. thinking_level 중심의 새로운 파라미터 체계와 에이전틱 실행·생각 보존이 핵심 변경점이에요. 커스텀 에이전트를 만들거나 Computer Use를 활용하고 싶다면 custom-agents와 computer-use 문서를 이어서 보면 좋아요.