> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crazyrouter.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Gemini Tool Calling

> 2026-03-23 Crazyrouter 생산 환경 검증을 기반으로 한 Gemini 네이티브 도구 기능

> 업데이트: 2026-06-06

# Gemini Tool Calling

```
POST /v1beta/models/{model}:generateContent
```

2026년 3월 23일 기준, Crazyrouter 생산 환경에서는 `gemini-3.1-pro`가 다음 Gemini 네이티브 도구 기능을 안정적으로 트리거할 수 있음을 검증했습니다.

* `codeExecution`
* `googleSearch`
* `urlContext`
* `functionDeclarations`

<Note>
  본 페이지에는 생산 환경에서 실제로 성공적으로 트리거된 요청 패턴과 응답 마커만 수록되어 있습니다.
</Note>

***

## 코드 실행

아래 요청은 생산 환경에서 `executableCode`와 `codeExecutionResult` 두 개의 핵심 응답 블록을 반환했습니다.

```bash theme={null}
curl "https://api.crazyrouter.com/v1beta/models/gemini-3.1-pro:generateContent?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {
        "role": "user",
        "parts": [
          {"text": "Use code execution. Compute the sum of the first 20 prime numbers and state the result."}
        ]
      }
    ],
    "tools": [
      {
        "codeExecution": {}
      }
    ]
  }'
```

생산 환경에서 실측된 핵심 응답 형태:

```json theme={null}
{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "executableCode": {
              "language": "PYTHON",
              "code": "..."
            }
          },
          {
            "codeExecutionResult": {
              "outcome": "OUTCOME_OK",
              "output": "639\n"
            }
          },
          {
            "text": "The sum is 639."
          }
        ]
      }
    }
  ]
}
```

***

## Google 검색

아래 요청은 생산 환경에서 `groundingMetadata`를 반환했으며, 이는 모델이 실제로 Google Search를 트리거했음을 나타냅니다.

```bash theme={null}
curl "https://api.crazyrouter.com/v1beta/models/gemini-3.1-pro:generateContent?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {
        "role": "user",
        "parts": [
          {"text": "Use Google Search. What are two AI news items from March 2026?"}
        ]
      }
    ],
    "tools": [
      {
        "googleSearch": {}
      }
    ]
  }'
```

현재 다음을 근거로 확인할 수 있습니다.

* `candidates[0].groundingMetadata`
* 정상적인 텍스트 답변은 여전히 `candidates[0].content.parts[*].text`에 있음

***

## URL 컨텍스트

아래 요청은 생산 환경에서 `urlContextMetadata`를 반환했으며, 동시에 `groundingMetadata`도 함께 반환했습니다.

```bash theme={null}
curl "https://api.crazyrouter.com/v1beta/models/gemini-3.1-pro:generateContent?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {
        "role": "user",
        "parts": [
          {"text": "Use URL context to summarize https://example.com/ in one sentence."}
        ]
      }
    ],
    "tools": [
      {
        "urlContext": {}
      }
    ]
  }'
```

현재 다음을 근거로 확인할 수 있습니다.

* `candidates[0].urlContextMetadata`
* `candidates[0].groundingMetadata`

***

## 커스텀 함수 호출

아래 요청은 생산 환경에서 `functionCall`을 반환했습니다.

```bash theme={null}
curl "https://api.crazyrouter.com/v1beta/models/gemini-3.1-pro:generateContent?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {
        "role": "user",
        "parts": [
          {"text": "What is the weather in Beijing? Use the provided function."}
        ]
      }
    ],
    "tools": [
      {
        "functionDeclarations": [
          {
            "name": "get_weather",
            "description": "Get weather info for a city",
            "parameters": {
              "type": "object",
              "properties": {
                "city": {
                  "type": "string"
                }
              },
              "required": ["city"]
            }
          }
        ]
      }
    ]
  }'
```

핵심 응답 형태:

```json theme={null}
{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "get_weather",
              "args": {
                "city": "Beijing"
              }
            }
          }
        ]
      }
    }
  ]
}
```

함수 결과를 다시 전달할 때는, 그대로 Gemini 네이티브의 `functionResponse` 구조를 사용하면 됩니다.
