C.W.K.
Stream
Lesson 02 of 04 · published

Modes & Call/Response Format

~14 min · tools, modes, function-call, function-response

Level 0Spark
0 XP0/35 lessons0/10 achievements
0/140 XP to next level140 XP to go0% complete

Four function-calling modes

  • AUTO (default) — the model picks: call a tool, or reply with text.
  • ANY — the model must call at least one function. Useful for workflows where text-only is invalid.
  • NONE — the model is forbidden from calling tools, even if they're declared. Useful when you've registered tools but want a single text-only turn.
  • VALIDATED — like ANY, but with strict schema adherence enforced.

You can also restrict which tools the model is allowed to call this turn via allowed_function_names.

Call format — what the model emits

When the model decides to call a tool, the response's candidates[0].content.parts contains one or more function_call parts. Each has:

  • name — which tool to call.
  • args — the JSON object matching your declared parameters.
  • id — opaque identifier (always present on Gemini 3+; sometimes absent on 2.5).

Response format — what you send back

You execute the tool and send the result back in the next user turn as a function_response part:

  • name — must match the original call.
  • response — your result, wrapped in {"result": ...}.
  • id — match the call's id when present.

Gemini vs OpenAI roles

This is where memorizing OpenAI hurts you: Gemini's tool-result role is "user", not "tool". You're conceptually saying "the user provided the tool's output." Multiple tool results go in the same user turn as multiple parts, not as separate messages.

Code

Configure mode + restrict tools·python
from google.genai import types

config = types.GenerateContentConfig(
    tools=[tools],  # the Tool(function_declarations=[...]) from previous lesson
    tool_config=types.ToolConfig(
        function_calling_config=types.FunctionCallingConfig(
            mode='ANY',
            allowed_function_names=['set_light_values'],  # restrict
        ),
    ),
)
Read a function call from the response·python
response = client.models.generate_content(
    model='gemini-2.5-flash',
    contents='Make the lights warm and 30%',
    config=config,
)

# Iterate parts — there might be multiple calls
for part in response.candidates[0].content.parts:
    if part.function_call:
        fc = part.function_call
        print(f'Tool: {fc.name}')
        print(f'Args: {dict(fc.args)}')
        print(f'ID: {fc.id}')  # may be None on 2.5

# Or use the convenience
for fc in (response.function_calls or []):
    ...
Send the result back·python
# Execute YOUR function
result = my_set_light_values(brightness=30, color_temp='warm')
# result might be: {'status': 'ok', 'brightness': 30, 'colorTemperature': 'warm'}

# Build the function-response part
response_part = types.Part.from_function_response(
    name=fc.name,
    response={'result': result},
    id=fc.id,  # match the call's id when present
)

# Append to conversation as a user turn
contents.append(response.candidates[0].content)         # model's call turn
contents.append(types.Content(role='user', parts=[response_part]))  # your result
Gemini vs OpenAI shape — side by side·python
# OpenAI: separate "tool" message per result
# [
#   {role: 'assistant', tool_calls: [{id: 'c1', function: {...}}]},
#   {role: 'tool', tool_call_id: 'c1', content: '{"result": ...}'}
# ]

# Gemini: results go in a USER turn, multiple parts allowed
# [
#   {role: 'model', parts: [{function_call: {name, args, id}}]},
#   {role: 'user',  parts: [{function_response: {name, id, response: {result}}}]},
# ]

External links

Exercise

Take the set_light_values tool from the previous lesson. Call Flash with mode=AUTO and the prompt "What's the weather like?" — observe that it answers in text. Then call again with mode=ANY and the same prompt — observe what happens (it'll force a tool call, possibly with weird args). This is the gap between AUTO's flexibility and ANY's strictness in one experiment.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.