Back to Blogs
#ai#api#gemini#python

[AI in Practice] Upgrading from Gemini 3.5/3.6 to Gemini 4 Argon: Migration Notes and Pitfalls for LINE Bot Developers

Background I have a LINE Bot that I use every day, linebot-helper-python. I use it daily...

Updated 12 min read
Cover for [AI in Practice] Upgrading from Gemini 3.5/3.6 to Gemini 4 Argon: Migration Notes and Pitfalls for LINE Bot Developers

Stylized promotional blogger visual with modern editorial branding and the text

Background

I have a LINE Bot that I use every day, linebot-helper-python. I use it daily to summarize URLs, ask follow-up questions about YouTube video content, search for map locations, and manage bookmarks. In terms of model configuration, to balance response speed and budget, many workflows were previously running on Gemini 3.5 (such as gemini-3.5-flash-lite for high-throughput, low-latency classification and data extraction) and Gemini 3.6 (such as gemini-3.6-flash for multi-step tool calling and multimodal reasoning).

In mid-October, Google officially pushed Gemini 4 Argon (gemini-4-argon) to the GA stable version (paired with Python google-genai >= 2.30.1).

After reading the official announcement and migration documents, the most attractive features on the surface are the big numbers: a 1M unified token window shared by input, thinking, and output; Long Decode that automatically relays a single call up to 1 million output tokens; Agentic Video Understanding which is now officially GA and saves 88% of tokens; and the Interactions API (/v1beta/interactions), which has become the default mainstream.

But if your goal is the same as mine—to upgrade (or partially switch) the existing Gemini 3.5 / 3.6 in your LINE Bot to Gemini 4 Argon—don't assume it's as simple as changing model="gemini-3.6-flash" to model="gemini-4-argon".

This generation has several changes in parameter specifications, token budget calculation methods, caching mechanisms, and even assumptions about waiting times that hit the pain points of LINE Bots exactly. This article organizes all the details you need to pay attention to when migrating from 3.5 / 3.6 to Gemini 4.


Specification Comparison: 3.5 Flash-Lite / 3.6 Flash vs. Gemini 4 Argon

Before diving into settings, let's look at the positioning differences of these three models in one table:

Item gemini-3.5-flash-lite gemini-3.6-flash gemini-4-argon
Positioning Ultra-fast, low-cost, high-throughput classification & structured extraction Balance of speed, multi-step Agent, and multimodality Flagship deep reasoning, complex coding, long output, and autonomous agents
Context Window 1,048,576 1,048,576 1,048,576 (Shared Input + Thinking + Output)
Max Single Output 65,536 65,536 generateContent: Non-streaming 32,768 / Streaming 65,536
Interactions API: Synchronous 65,536
(Long Decode can continue up to 1M for both)
Default thinking_level "minimal" "medium" "medium" (Supports only low / medium / high)
Context Caching Supported Supported Implicit Caching only (Calling Explicit will error)
temperature / top_p / top_k Deprecated (Ignored) Deprecated (Ignored) Deprecated (Ignored, official requirement to remove)
Pricing (Input / Output) $0.30 / $2.50 (per 1M) $1.50 / $7.50 (per 1M) Early bird until 2026/11/30: $2.00 / $10.00
(Reverts to $4.00 / $20.00 from 12/1; 95% discount for cache hits)
Free Tier Available Available None (Must be linked to Paid Tier billing)

Just by looking at this table, you can identify several pitfalls you'll encounter if you only change the model name. Let's break them down one by one.


Pitfall 1: LINE Bots usually set max_output_tokens very small, which returns an empty string in Gemini 4

This is the first hidden trap that LINE Bot developers are most likely to fall into.

Because a single LINE text message has a 5,000-character limit, and mobile screens are not suitable for long-winded content, many people (including myself in the past) are used to setting max_output_tokens to 2048 or 4096 in GenerateContentConfig as a safeguard to save money and prevent text overflow.

If you set it this way on Gemini 4 Argon, when encountering a slightly complex problem, you will find the model returns finish_reason: "MAX_TOKENS", but response.text is empty, or it cuts off after barely two sentences.

The reason is that Gemini 4 Argon adopts a Unified 1M Input-Output Window, and has two hard rules:

  1. Thinking tokens are counted directly towards the max_output_tokens budget: Every thinking token the model spends before answering is deducted from your max_output_tokens. When a question requires deep reasoning, the model can easily burn through your 4096 limit just by thinking, hitting a wall and stopping before it even starts outputting the formal answer.
  2. generateContent non-streaming single request limit decreased from 64K to 32K: In Gemini 3.5 / 3.6, the single non-streaming response limit was 65,536; in gemini-4-argon, if you continue using traditional generateContent, the non-streaming single limit has been lowered to 32,768 tokens (streaming or using the new Interactions API synchronous call remains at 65,536).

Cause and Solution: The official migration guide states clearly—if your old project set max_output_tokens below 32K, please increase it to at least 32768 (or just keep the default 65536) when upgrading to gemini-4-argon.

In Gemini 4, max_output_tokens is used as a "total emergency brake to prevent burning through money in extreme situations," not to control the length of the answer.

  • To spend fewer tokens and speed up response: Lower the thinking_level="low".
  • To make the output fit LINE message length: Write it in the system_instruction (e.g., "Please keep it within 400 words and use bullet points").
# ❌ Old safeguard setting often used in LINE Bots; thinking process will consume all 2048 tokens on gemini-4-argon
config = types.GenerateContentConfig(
    max_output_tokens=2048,
)

# ✅ Correct way for Gemini 4 Argon: Relax max_output_tokens, use thinking_level to control cost and latency
config = types.GenerateContentConfig(
    max_output_tokens=32768,
    thinking_config=types.ThinkingConfig(thinking_level="low"),
    system_instruction="You are a LINE assistant. Keep answers concise and within 500 words.",
)
Enter fullscreen mode Exit fullscreen mode

Pitfall 2: Differences in thinking_level settings—3.5-flash-lite's "minimal" cannot be moved directly

If you have already changed the old-school thinking_budget (passing an integer token count) to thinking_level in Gemini 3.5 / 3.6, there is another small trap here:

  • On gemini-3.5-flash-lite, the default thinking level is called "minimal".
  • But on gemini-4-argon, only three levels are supported: "low", "medium" (default), and "high".

If your config shares the same generator and you bring "minimal" into gemini-4-argon as is, or if you still have the old thinking_budget (although the current API will map it to the closest level, it will return a deprecation warning), it will make your settings messy.

For LINE Bots, the practical division of these three levels in gemini-4-argon is very clear:

  • "low": The first choice for general LINE conversations, URL summaries, and real-time Q&A. Lowest token consumption and lowest Time to First Token (TTFT).
  • "medium" (default): Suitable for scenarios requiring multiple tool calls (Function Calling), reading long videos, or writing code.
  • "high": Deep math, complex itinerary optimization, long-form analysis. Note: Setting this to "high" makes it almost impossible to finish within the valid time of a LINE replyToken. You must use an asynchronous push architecture.

Pitfall 3: LINE Webhook's few-second lifespan vs. official recommendation of "20-minute Timeout"

When reading the Gemini 4 Argon migration document, one item made me laugh out loud:

Increase client timeouts: Set HTTP client timeouts to at least 15–20 minutes per call.

The official documentation even added a note in the Long Decode section: when facing difficult tasks, gemini-4-argon might spend an entire 32K or 64K hop entirely on thinking, only outputting the real answer in the next hop (under generateContent, the new SDK google-genai >= 2.30.1 has automatic_continuation=True enabled by default, which uses continuation_token to automatically loop for you on the client side; under the Interactions API, to exceed the single sync limit of 65536, you must enable background=True to let the server side run multiple hops).

This is perfectly fine when running a CLI script on your own computer; but in a LINE Bot + Cloud Run architecture, waiting synchronously on the client side is a disaster:

  1. LINE's replyToken has an extremely short lifespan and won't wait two minutes for you to think.
  2. LINE users staring at a screen with no response for more than 10 seconds will start pressing the button a second or third time.
  3. If you wait synchronously for automatic_continuation to finish several hops within the same Webhook request, Cloud Run connections and workers will quickly become deadlocked.

Cause and Solution: To put Gemini 4 into a LINE Bot, you must do two things architecturally:

1. Don't phase out 3.5 / 3.6; instead, create a "Fast/Slow Model Router"

The official documentation emphasizes that gemini-3.6-flash and gemini-3.5-flash-lite are still the main models for stable online supply. The healthiest LINE Bot architecture is not "switching everything to gemini-4-argon," but rather:

  • First-line instant replies / Intent classification / Simple structured extraction: Continue to hand these to gemini-3.5-flash-lite ($0.30/1M, extremely fast) or gemini-3.6-flash ($1.50/1M, concise, saves steps in tool calling).
  • Heavy reasoning / Long video follow-up / Complex tasks: Only then route to gemini-4-argon.

2. Use the new Interactions API with background=True + webhook_config for heavy tasks

In this generation, Google has labeled our familiar generateContent as (Legacy) and is pushing the Gemini Interactions API (/v1beta/interactions) across its documentation.

The greatest value of the Interactions API for LINE Bots is its native support for background=True and Webhooks (supporting project-level Static Webhooks or Dynamic webhook_config included in a single request):

  1. A user asks a question on LINE that requires gemini-4-argon with "high" thinking or long output.
  2. The LINE Bot first calls the LINE Loading Animation API and uses replyToken to reply instantly: "This is a deep question. I am performing deep reasoning in the background and will push the result to you once finished!"
  3. Simultaneously call client.interactions.create(..., background=True, webhook_config=...), handing the task to Google's server to run multiple hops slowly. You can even put the line_user_id directly into user_metadata so Google returns it as-is during the callback.
  4. When Google finishes and sends an interaction.completed event to your /webhooks/gemini endpoint, use client.interactions.get(interaction_id) to retrieve the result (if multiple Long Decode hops over 64K were run, all segments will be fully recorded in the model_output of interaction.steps). Then, calmly call LINE's push_message to push the result into the chat room.
from google import genai

client = genai.Client()

def dispatch_heavy_line_task(line_user_id: str, prompt: str):
    # Hand over to Google server for background execution (even multi-round 64K hops for Long Decode will be automatically completed on the server side)
    interaction = client.interactions.create(
        model="gemini-4-argon",
        input=prompt,
        background=True,
        generation_config={
            "max_output_tokens": 131072,
            "thinking_level": "high",
        },
        webhook_config={
            "uris": ["https://your-cloud-run.a.run.app/webhooks/gemini"],
            "user_metadata": {"line_user_id": line_user_id},
        },
    )
    return interaction.id
Enter fullscreen mode Exit fullscreen mode

Pitfall 4: Explicit Caching Errors—Prompt order determines if you save 95%

If your LINE Bot contains a full product FAQ, long System Instructions, or large documents uploaded by users, you might have previously used client.caches.create() to create an Explicit Cache and then put cached_content into GenerateContentConfig to save money.

After upgrading to gemini-4-argon, this code must be completely removed.

gemini-4-argon does not support Explicit Caching. If you call caches.create or include cached_content in the config, the API will return an Error.

Instead, it uses Implicit Caching, which is enabled by default:

  • As long as a single Prompt length reaches 4,096 tokens or more, and the preceding content (Prefix) matches a previous request, the system will automatically hit the cache.
  • Cache-hit Input Tokens receive a 95% discount (priced at 0.05x)—at early bird prices, this drops from $2.00 / 1M to $0.10 / 1M, which is cheaper than gemini-3.5-flash-lite! (Even when Long Decode automatically continues to the next hop, the repeated Context from before will automatically apply the 95% cache discount.)

Key impact on LINE Bots: Since this has become automatic Prefix Matching, the order in which you assemble your Prompt determines the thickness of your bill:

  • Always put at the beginning (Immutable): Long system_instruction, shared background knowledge base, Few-shot examples, fixed background documents for that group.
  • Always put at the end (Changes every time): current_time timestamp, LINE user name/status, the current message.

If you accidentally write "Current time: 2026-10-15 21:40:02" on the first line of your System Prompt, the first token of every request will be different, and the 95% cache discount will immediately drop to zero.


Pitfall 5: Strict rules tightening since 3.5 / 3.6—Sampling parameters, Prefill, and Thought Signatures

These three rules have actually been in effect since gemini-3.5-flash-lite and gemini-3.6-flash, but if you are organizing your codebase across versions, be sure to clean them up together:

1. Remove temperature, top_p, top_k, candidate_count

These four sampling parameters are all deprecated and ignored on Gemini 3.5 / 3.6 and Gemini 4 Argon (official notice says future generations will return HTTP 400 if these parameters are included). If you used to set temperature=0.0 to ensure stable output format, delete them all now and switch to Structured Outputs (response_schema) and clear system_instruction.

2. Prohibit Prefilled Model Turns (The last turn cannot be role: "model")

A common Prompt technique used to be: to prevent the model from saying "Sure! Here is the summary..." or to force it to start outputting JSON from {, you would put {"role": "model", "parts": [{"text": "{"}]} as the last entry in the contents array.

Now, if the last turn of non-empty content in the payload is the model role, the API will return an HTTP 400 Error. To suppress the opening remarks, please write it properly into the system_instruction.

3. Multi-turn conversations and Function Calling must preserve thought_signature (or just use previous_interaction_id)

When a LINE Bot runs multi-step tool calls (e.g., first check bookmark DB $\rightarrow$ then fetch web content $\rightarrow$ finally summarize), the Part returned by the model will contain a thought_signature. If you manually maintain the conversation history array but only extract and reassemble the text and function_call, missing the thought_signature, the quality of multi-turn tool calls will degrade significantly or even error out.

For those who don't want to manage thought_signature serialization themselves, the easiest way to upgrade to Gemini 4 is to use the Interactions API's previous_interaction_id:

# Only remember the last interaction.id for that LINE user in Redis; let Google's server handle history state and thought_signature
interaction = client.interactions.create(
    model="gemini-4-argon",
    input=user_message,
    previous_interaction_id=last_interaction_id,
)
Enter fullscreen mode Exit fullscreen mode

The real weapon worth upgrading your LINE Bot for: Agentic Video Understanding GA

After discussing all the pitfalls, let's talk about a positive upgrade for gemini-4-argon (and 3.8-flash) that is most noticeable for LINE Bots: Agentic Video Understanding is officially GA.

One core feature of my LINE Bot is "drop a YouTube link and ask follow-up questions about the video content." Previously, traditional video understanding (static mode) involved taking a screenshot of the entire video every second (1 FPS) and stuffing it into the Context Window. For a 30-60 minute long lecture or Podcast video, even if the Context could fit it, the token consumption was staggering.

After switching to Agentic mode (Note: it still defaults to static on all models including gemini-4-argon, so it must be explicitly enabled), the model's behavior changes to:

  1. First read the audio transcript and timeline structure.
  2. Based on the user's question, decide which timestamps to "scrub" to.
  3. Dynamically load high-resolution and high-frame-rate frames only for key scenes to look closely.

Whether you use the new Interactions API or the original generate_content, remember to add the corresponding parameters (parameter names and casing differ slightly between the two):

# Method A: Using the new Interactions API (parameter is processing="agentic")
interaction = client.interactions.create(
    model="gemini-4-argon",
    input=[
        {
            "type": "video",
            "uri": youtube_url,
            "mime_type": "video/mp4",
            "processing": "agentic", # Remember to enable explicitly; default is still static
        },
        {
            "type": "text",
            "text": "On the page where the speaker shows the architecture diagram, what are the three bottlenecks mentioned? Please include [MM:SS] timestamps.",
        },
    ],
    generation_config={
        "max_output_tokens": 32768,
        "thinking_level": "medium",
    },
)

# Method B: Using traditional generate_content (parameter is media_processing="AGENTIC")
response = client.models.generate_content(
    model="gemini-4-argon",
    contents=[
        types.Part.from_uri(
            file_uri=youtube_url,
            mime_type="video/mp4",
            media_processing="AGENTIC", # Remember to enable explicitly; default is still STATIC
        ),
        "On the page where the speaker shows the architecture diagram, what are the three bottlenecks mentioned? Please include [MM:SS] timestamps.",
    ],
    config=types.GenerateContentConfig(
        max_output_tokens=32768,
        thinking_config=types.ThinkingConfig(thinking_level="medium"),
    ),
)
Enter fullscreen mode Exit fullscreen mode

Official tests show that for long videos over 5-10 minutes and "needle in a haystack" detail questions, token usage is saved by up to 88%, and accuracy is improved by 7%. This point alone completely makes up for the higher unit price of gemini-4-argon.


Upgrade Checklist

Finally, here is a PR self-check list for LINE Bot projects before upgrading from Gemini 3.5 / 3.6 to gemini-4-argon:

  1. SDK and Billing Confirmation: Upgrade google-genai to >= 2.30.1; confirm the project associated with the API Key is linked to a Paid Tier (Free Tier and Google AI Pro cannot call gemini-4-argon).
  2. Remove Sampling Parameters and Prefill: Search the entire project and remove temperature, top_p, top_k, candidate_count, and any prefilled prompts ending with role="model".
  3. Remove Explicit Caching: Remove caches.create and cached_content; check Prompt assembly logic to ensure fixed, long System Instructions are placed at the beginning to trigger the 95% discount of Implicit Caching.
  4. Increase max_output_tokens: Increase any limit smaller than 32768 to at least 32768 (to avoid empty responses caused by thinking tokens consuming the budget); move word count limits to system_instruction.
  5. Check thinking_level Enum Values: Replace 3.5-flash-lite specific "minimal" or old thinking_budget with "low", "medium", or "high".
  6. Fast/Slow Routing and Async Push: Tasks that need an instant reply within a few seconds for LINE replyToken should be set to thinking_level="low" or continue to be handled by 3.5-flash-lite / 3.6-flash; deep reasoning tasks should use the Interactions API (background=True + webhook_config) paired with LINE push_message.
  7. Enable Agentic Mode for Video Understanding: When processing YouTube or long videos, add media_processing="AGENTIC" to Part.from_uri (or "processing": "agentic" for the Interactions API).

If you use a Coding Agent that supports Skills (like Antigravity or Claude Code), Google also provides a migration Skill (/gemini-api-dev migrate my app to Gemini 4 Argon) that can help automatically scan for these parameter changes. However, architectural levels like "LINE replyToken timeout routing" and "Prompt prefix cache order" still need to be designed manually.