ANTIGRAVITY LABJP
Articles/AI Tools
AI Tools/2026-04-19Intermediate

Building Japanese NLP Apps with Gemma 4 in Antigravity — Summarization and Sentiment Analysis

Learn how to use Gemma 4's strong Japanese language capabilities in Antigravity to build Python apps for text summarization and sentiment analysis, with step-by-step code examples.

gemma412python26nlpjapanese3antigravity430

When you're processing Japanese text with AI and want to avoid sending sensitive data to the cloud, Gemma 4 is one of the best tools you have right now. As an open-source model from Google with strong multilingual capabilities, it handles Japanese surprisingly well — especially for tasks like summarization, sentiment analysis, and translation.

We will set up a Python environment inside Antigravity and implement two practical NLP features: Japanese text summarization and sentiment analysis. If you have been curious about Gemma 4 but weren't sure what to build first, these two make for a solid starting point.

Why Gemma 4 Works Well for Japanese

Gemma 4 was trained on a diverse multilingual corpus that includes Japanese, Chinese, Korean, and other major languages alongside English. Compared to Gemma 3, the Japanese language understanding has improved noticeably — particularly around implicit subjects (a common feature in Japanese grammar) and the varied use of sentence-ending particles.

The model also comes in multiple sizes, which matters when you're deciding between API access and local deployment. For getting started, the API approach is the fastest path since you don't need to manage model weights or hardware requirements.

Setting Up the Python Environment in Antigravity

Open a new project in Antigravity and install the required packages from the terminal:

# Install Google GenAI SDK
pip install google-genai python-dotenv
 
# Create the environment file — never hardcode API keys
touch .env

Add your API key to the .env file:

GEMINI_API_KEY=YOUR_GEMINI_API_KEY

Antigravity automatically picks up .env files from the project root, so you don't need any additional configuration. Here's the base setup for your Python file:

import os
from dotenv import load_dotenv
from google import genai
 
load_dotenv()
 
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])

Implementing Japanese Text Summarization

Let's build a summarization function first. The goal is to take a long piece of Japanese text — a news article, a report, an email thread — and condense it to a specified number of sentences.

def summarize_japanese(text: str, max_sentences: int = 3) -> str:
    """
    Summarize Japanese text within the specified sentence count.
    
    Args:
        text: Japanese text to summarize
        max_sentences: Maximum number of sentences in the summary (default: 3)
    
    Returns:
        Summarized text
    """
    if not text.strip():
        raise ValueError("Input text is empty")
    
    prompt = f"""Summarize the following Japanese text in {max_sentences} sentences or fewer.
Prioritize the most important information. Do not add information not present in the original.
Output only the summary — no preamble or explanation.
 
Text:
{text}"""
    
    response = client.models.generate_content(
        model="gemma-4-27b-it",  # Gemma 4 27B instruction-tuned variant
        contents=prompt,
        config={"temperature": 0.3}  # Lower temperature for stable, consistent output
    )
    
    return response.text.strip()
 
 
# Test it
sample_text = """
東京都は19日、2026年度の予算案を発表した。総額は15兆3千億円で、
前年度比で約3%増となる。重点項目として、子育て支援の充実と
デジタルインフラの整備が挙げられた。子育て支援では、
保育所の定員を2万人分増やす計画が盛り込まれた。
デジタルインフラでは、5G基地局の拡充と行政手続きの
オンライン化を推進する方針が示された。
"""
 
result = summarize_japanese(sample_text, max_sentences=2)
print(result)
# Expected output (in Japanese):
# Tokyo announced its FY2026 budget of 15.3 trillion yen, a 3% increase.
# Key priorities include childcare expansion (20,000 new nursery spots) and digital infrastructure.

One detail worth noting: the prompt explicitly says "no preamble or explanation." Without this instruction, the model will often start with something like "Certainly, here is the summary:" — which is annoying to strip out programmatically, so it's better to prevent it upfront.

Adding Sentiment Analysis

Now let's add a sentiment analysis function. This is useful for review monitoring, customer feedback processing, and social media analysis — all common use cases in Japanese B2C products.

from dataclasses import dataclass
import json
 
@dataclass
class SentimentResult:
    label: str          # "positive" / "negative" / "neutral"
    score: float        # Confidence score from 0.0 to 1.0
    reason: str         # Explanation in Japanese
 
 
def analyze_sentiment(text: str) -> SentimentResult:
    """
    Analyze the sentiment of Japanese text.
    
    Returns:
        SentimentResult with label, confidence score, and reasoning
    
    Raises:
        ValueError: If the model output cannot be parsed as JSON
    """
    prompt = f"""Analyze the sentiment of the following Japanese text and return a JSON object.
 
Required JSON format:
{{
  "label": "positive" or "negative" or "neutral",
  "score": confidence from 0.0 to 1.0 (two decimal places),
  "reason": "one-sentence explanation in Japanese"
}}
 
Return only the JSON object — no other text.
 
Text:
{text}"""
    
    response = client.models.generate_content(
        model="gemma-4-27b-it",
        contents=prompt,
        config={"temperature": 0.1}  # Very low temperature for deterministic classification
    )
    
    # Parse JSON, handling potential code block wrapping
    raw = response.text.strip()
    if raw.startswith("```"):
        raw = raw.split("```")[1]
        if raw.startswith("json"):
            raw = raw[4:]
    
    try:
        data = json.loads(raw)
        return SentimentResult(
            label=data["label"],
            score=float(data["score"]),
            reason=data["reason"]
        )
    except (json.JSONDecodeError, KeyError) as e:
        raise ValueError(f"Failed to parse model output: {raw}") from e
 
 
# Test with Japanese reviews
reviews = [
    "このカフェ、雰囲気も良くてコーヒーも美味しかったです。また来たいです!",
    "注文してから40分待たされた上に、料理が冷めていた。二度と行かない。",
    "普通の定食屋さんです。価格相応かと思います。",
]
 
for review in reviews:
    result = analyze_sentiment(review)
    print(f"[{result.label.upper()}] score={result.score:.2f} | {result.reason}")

What I've found in practice is that Gemma 4 handles the subtleties of Japanese sentiment reasonably well — phrases like まあまあ (so-so), 悪くはない (not bad), or 普通 (ordinary) tend to land in the neutral range with appropriate confidence scores, rather than being misclassified as positive.

Things That Will Trip You Up

The -it suffix matters: You need to specify the instruction-tuned variant (gemma-4-27b-it) rather than the base model. The base model won't follow instructions reliably, and the quality difference is significant.

JSON output can be inconsistent: Even with a clear prompt, the model occasionally wraps JSON in a markdown code block or adds a brief preamble. The cleaning logic in the code above handles the most common cases. If you want a more robust solution, the Google GenAI SDK supports response_schema to enforce structured output at the API level.

Context window limits on long documents: Gemma 4 has a large context window, but very long documents (100,000+ characters) will need to be chunked before processing. For handling large-scale API interactions in Antigravity, the Antigravity Python SDK Function Calling Guide covers batching and retry patterns worth applying here too.

What to Build Next

With these two functions working, a natural next step is wrapping them in a FastAPI endpoint — you can then call the NLP features from a frontend or integrate with other internal tools. Antigravity's built-in web server preview makes this kind of prototyping fast.

If your use case involves data you can't send to a cloud API, running Gemma 4 locally is worth exploring. The process is more involved, but once set up, you get fully offline inference with the same model.

Start with whichever piece of Japanese text you have nearby — an email, a note, a product review — and run it through summarize_japanese(). The feedback loop of testing in Antigravity's inline chat while iterating on the prompt is genuinely enjoyable.

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

AI Tools2026-04-14
Gemma 4 Implicit Caching in Antigravity: Cut Your Credit Costs by 40% Without Changing a Line of Code
A practical guide to leveraging Gemma 4's Implicit Caching in Antigravity. Learn how to structure your projects to dramatically reduce credit consumption when working with large codebases.
AI Tools2026-04-10
Fine-Tuning Gemma 4 with Antigravity: A Practical Guide to Building Custom AI Models
Learn how to fine-tune Gemma 4 using LoRA/QLoRA and integrate your custom model into Antigravity. From dataset preparation to local deployment, this step-by-step guide covers everything with code examples.
Tips2026-05-12
4 Runtime Error Patterns from Gemma 4-Generated Code in Antigravity — and How to Fix Them
Gemma 4 writes clean-looking code — until it runs. This guide covers the four most common runtime error patterns in Antigravity-generated Python code: TypeError, AttributeError, asyncio issues, and import conflicts.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →