Since Gemma 4 launched in April 2026, the number of developers building agents on Antigravity has grown fast. A common frustration pattern: "I got Gemma 4 running, but it doesn't do what I expect." In most cases, the problem isn't the model — it's tool definition and memory management.
Why Gemma 4 + Antigravity Works Well Together
Gemma 4's most relevant improvement for agent development is function calling accuracy. Smaller open models have historically struggled with one specific judgment: knowing when to call a tool versus when to answer directly. Gemma 4 handles this significantly better than its predecessors.
Antigravity, as Google's agent development platform, is designed with Gemma 4 integration as a first-class concern. Tool registration, execution, and result passing are handled natively — less boilerplate than most frameworks.
The combination excels at tasks that require mixing multiple external tools: search, calculation, database lookup, file operations. What would require substantial orchestration code in other setups comes together more cleanly here.
Environment Setup: Connecting Gemma 4 to Antigravity
The standard setup routes through Vertex AI:
pip install google-cloud-aiplatform antigravity-sdkimport vertexai
from antigravity import AgentBuilder, Tool
from vertexai.preview.generative_models import GenerativeModel
# Initialize Vertex AI
vertexai.init(project="your-project-id", location="us-central1")
# Connect Gemma 4
model = GenerativeModel("gemma-4-it") # Instruction Tuned variant
# Initialize agent builder
agent_builder = AgentBuilder(model=model)On model variant selection: gemma-4-pro is more capable but slower and more expensive. gemma-4-it (Instruction Tuned) has a better speed-accuracy balance for most agent tasks and is the right default unless you have a specific reason to need the Pro tier.
Tool Design: What to Give the Agent and What to Withhold
Over-equipping agents is the most common design mistake. Even with Gemma 4's improved tool selection, giving an agent too many tools increases confusion and incorrect tool calls. The working principle is: three to five tools maximum per agent.
Here's a tool definition that produces consistent results:
from antigravity import Tool, ToolParameter
search_tool = Tool(
name="web_search",
description=(
"Search the web for current information or fact verification. "
"DO NOT use for general knowledge you already know. "
"Use specific search terms, not full sentences."
),
parameters=[
ToolParameter(
name="query",
type="string",
description="Search query using specific terms, not natural language sentences.",
required=True
),
ToolParameter(
name="max_results",
type="integer",
description="Number of results to retrieve (1-5)",
required=False,
default=3
)
],
function=execute_web_search
)
calculator_tool = Tool(
name="calculate",
description=(
"Evaluate mathematical expressions. Use for any arithmetic, including simple multiplication. "
"ALWAYS use this tool for calculations — do not calculate in your head."
),
parameters=[
ToolParameter(
name="expression",
type="string",
description="Math expression to evaluate. Examples: '1234 * 5678', '(100 * 0.08) + 1000'",
required=True
)
],
function=safe_calculate
)
agent = agent_builder.build(
tools=[search_tool, calculator_tool],
system_instruction="""
You are a business research assistant.
Use web_search only when current information is required — not for things you already know.
Always use the calculator tool for any arithmetic — never compute mentally.
"""
)The description field is where tool behavior gets shaped. Writing both "when to use" and "when NOT to use" is important — Gemma 4 uses this to make the call/don't-call decision, and explicit negative cases reduce unwanted tool invocations significantly.
Memory Patterns: Choosing the Right Approach
Antigravity provides three memory mechanisms, each suited to different use cases.
In-session memory is the default: full conversation history is maintained in context. This works fine for short interactions but degrades for longer conversations as the context grows.
Summary memory periodically compresses older conversation history into a summary, keeping a rolling window of recent messages intact. This is the right choice for extended task sessions.
External memory offloads memory to a vector store (Vertex AI Vector Search or compatible alternatives). This is the pattern for agents that need to reference large bodies of information — past projects, documentation libraries, knowledge bases.
from antigravity.memory import SummaryMemory, ExternalMemory
# Summary memory for extended sessions
memory = SummaryMemory(
max_recent_messages=10, # Keep last 10 messages verbatim
summary_interval=20, # Summarize every 20 messages
summary_model=model # Use the same model for summarization
)
# External memory for knowledge-intensive agents
external_memory = ExternalMemory(
vector_store="vertex-ai-vector-search",
index_id="your-index-id",
top_k=5 # Retrieve top 5 relevant past items per query
)
agent = agent_builder.build(
tools=[search_tool, calculator_tool],
memory=memory,
system_instruction="..."
)Decision rule: use in-session memory for single-session tasks. Use summary memory for multi-session or long-running workflows. Use external memory when the agent needs to reference large amounts of prior information that won't fit in context.
Running the Agent
import asyncio
async def run_task(user_request: str) -> str:
response = await agent.run_async(
user_message=user_request,
session_id="session-001" # Provide for session continuity
)
# Inspect tool calls during development
for step in response.steps:
if step.type == "tool_call":
print(f"Tool: {step.tool_name}({step.arguments})")
print(f"Result: {step.result[:100]}...")
return response.final_answer
async def main():
result = await run_task(
"Look up the latest stable Python version released in 2026 "
"and give me the command to create a virtual environment with it."
)
print(result)
asyncio.run(main())The steps inspection is worth building into your development workflow. Seeing which tools the agent called and what results they returned makes diagnosing unexpected behavior much faster than reading the final answer alone.
Pre-Production Checklist
Before connecting an agent to real workflows:
Rate-limit all external tool calls. Agents can enter loops that result in high-frequency API calls. Add rate limiting at the tool function level:
import time
from functools import wraps
def rate_limited(calls_per_second: float):
min_interval = 1.0 / calls_per_second
last_called = [0.0]
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
elapsed = time.time() - last_called[0]
if elapsed < min_interval:
time.sleep(min_interval - elapsed)
result = func(*args, **kwargs)
last_called[0] = time.time()
return result
return wrapper
return decorator
@rate_limited(calls_per_second=1.0)
def execute_web_search(query: str, max_results: int = 3) -> str:
# actual search implementation
...Set a maximum step count. Antigravity's max_steps parameter prevents runaway agents. Set this conservatively and increase only when your specific task profile requires it.
Identify human review points. Any action with meaningful external impact — sending communications, deleting data, making purchases — should require human confirmation before execution. Full automation should be limited to tasks where errors are low-cost and easily caught.
Test the failure modes. Deliberately test what happens when a tool returns an error, when a search returns no results, when the response is ambiguous. How an agent behaves at its edges matters as much as how it behaves in the happy path.
The Gemma 4 and Antigravity combination is genuinely capable for agent development. Starting with narrow, low-risk tasks — information gathering, draft generation, data formatting — gives you a solid baseline before expanding scope.