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

# Gemini 工具调用示例

> 使用Gemini API进行Function Calling工具调用的完整示例代码

# Gemini 工具调用示例

以下示例展示如何使用Gemini的Function Calling功能，让AI能够调用外部工具来获取信息或执行操作。

## 快速开始

只需要替换 `<API-KEY>` 为你的实际API密钥即可运行。

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://model-api.skyengine.com.cn/v1beta/models/gemini-2.5-flash:generateContent" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <API-KEY>" \
    -d '{
      "contents": [
        {
          "role": "user",
          "parts": [
            {
              "text": "计算一下 (25 + 15) * 3 - 20 等于多少？"
            }
          ]
        }
      ],
      "tools": [{
        "functionDeclarations": [
          {
            "name": "calculate_math",
            "description": "执行数学计算，支持基本的四则运算和括号",
            "parameters": {
              "type": "object",
              "properties": {
                "expression": {
                  "type": "string",
                  "description": "要计算的数学表达式，如 '2+3*4' 或 '(10+5)/3'"
                }
              },
              "required": [
                "expression"
              ]
            }
          }
        ]
      }]
    }'
  ```

  ```python Python theme={null}
  import requests

  # 配置API密钥和基础URL
  API_KEY = "<API-KEY>"
  BASE_URL = "https://model-api.skyengine.com.cn/v1beta"

  # 定义计算器工具函数
  def calculate_math(expression):
      """执行安全的数学计算"""
      try:
          # 安全检查，只允许基本的数学操作
          allowed_chars = set('0123456789+-*/.() ')
          if not all(c in allowed_chars for c in expression):
              return {"error": "表达式包含不允许的字符", "status": "error"}

          # 禁止一些危险的函数调用
          dangerous_words = ['import', 'exec', 'eval', '__']
          if any(word in expression.lower() for word in dangerous_words):
              return {"error": "表达式包含不安全的内容", "status": "error"}

          result = eval(expression)
          return {
              "expression": expression,
              "result": result,
              "formatted": f"{expression} = {result}",
              "status": "success"
          }
      except Exception as e:
          return {"error": f"计算出错: {str(e)}", "status": "error"}

  # 工具函数映射
  AVAILABLE_FUNCTIONS = {
      "calculate_math": calculate_math
  }

  def gemini_function_calling(user_message):
      """使用Gemini进行函数调用对话"""
      url = f"{BASE_URL}/models/gemini-2.5-flash:generateContent"
      headers = {
          "Content-Type": "application/json",
          "Authorization": f"Bearer {API_KEY}"
      }

      # 定义可用的工具
      tools = [
          {
              "functionDeclarations": [
                  {
                      "name": "calculate_math",
                      "description": "执行数学计算，支持基本的四则运算和括号",
                      "parameters": {
                          "type": "object",
                          "properties": {
                              "expression": {
                                  "type": "string",
                                  "description": "要计算的数学表达式，如 '2+3*4' 或 '(10+5)/3'"
                              }
                          },
                          "required": ["expression"]
                      }
                  }
              ]
          }
      ]

      messages = [
          {
              "role": "user",
              "parts": [
                  {
                      "text": user_message
                  }
              ]
          }
      ]

      data = {
          "contents": messages,
          "tools": tools
      }

      try:
          response = requests.post(url, headers=headers, json=data)

          if response.status_code != 200:
              return f"API错误: {response.status_code} - {response.text}"

          result = response.json()

          # 处理Gemini的响应
          if 'candidates' in result and len(result['candidates']) > 0:
              candidate = result['candidates'][0]
              content = candidate.get('content', {})
              parts = content.get('parts', [])

              # 检查是否有函数调用（注意：API返回的是 functionCall 而不是 function_call）
              function_calls = [part for part in parts if 'functionCall' in part]

              if function_calls:
                  print("检测到函数调用请求:")

                  # 处理函数调用并收集结果
                  function_responses = []

                  for part in parts:
                      if 'functionCall' in part:
                          function_call = part['functionCall']
                          function_name = function_call['name']
                          function_args = function_call.get('args', {})

                          print(f"- 调用函数: {function_name}")
                          print(f"- 参数: {function_args}")

                          # 执行函数调用
                          if function_name in AVAILABLE_FUNCTIONS:
                              try:
                                  function_result = AVAILABLE_FUNCTIONS[function_name](**function_args)
                                  print(f"- 结果: {function_result}")

                                  function_responses.append({
                                      "functionResponse": {
                                          "name": function_name,
                                          "response": function_result
                                      }
                                  })

                              except Exception as e:
                                  error_result = {"error": f"函数执行失败: {str(e)}", "status": "error"}
                                  function_responses.append({
                                      "functionResponse": {
                                          "name": function_name,
                                          "response": error_result
                                      }
                                  })
                          else:
                              error_result = {"error": f"未知的函数: {function_name}", "status": "error"}
                              function_responses.append({
                                  "functionResponse": {
                                      "name": function_name,
                                      "response": error_result
                                  }
                              })

                  # 将函数结果发送回Gemini生成最终回复
                  # 模型的函数调用响应需要指定 role: "model"
                  messages.append({
                      "role": "model",
                      "parts": parts
                  })

                  # 函数执行结果需要指定 role: "user"
                  messages.append({
                      "role": "user",
                      "parts": function_responses
                  })

                  data["contents"] = messages
                  final_response = requests.post(url, headers=headers, json=data)

                  if final_response.status_code == 200:
                      final_result = final_response.json()
                      if 'candidates' in final_result and len(final_result['candidates']) > 0:
                          final_content = final_result['candidates'][0]['content']
                          final_parts = final_content.get('parts', [])
                          # 提取文本内容
                          text_parts = [part.get('text', '') for part in final_parts if 'text' in part]
                          return '\n'.join(text_parts)
                      else:
                          return "无法获取最终回复"
                  else:
                      return f"获取最终回复失败: {final_response.status_code} - {final_response.text}"
              else:
                  # 没有函数调用，直接返回文本回复
                  text_parts = [part.get('text', '') for part in parts if 'text' in part]
                  return '\n'.join(text_parts)
          else:
              return "没有获得有效回复"

      except Exception as e:
          return f"请求处理出错: {str(e)}"

  # 使用示例
  if __name__ == "__main__":
      print("=== Gemini计算器工具调用示例 ===\n")

      query = "计算一下 (25 + 15) * 3 - 20 等于多少？"
      print(f"用户问题: {query}")
      print("AI回复:")
      response = gemini_function_calling(query)
      print(response)
  ```
</CodeGroup>

## Gemini工具调用的特点

### 1. 工具定义格式

Gemini使用 `functionDeclarations` 数组来定义工具：

```json theme={null}
{
  "tools": [{
    "functionDeclarations": [
      {
        "name": "function_name",
        "description": "函数描述",
        "parameters": {
          "type": "object",
          "properties": {
            "param": {
              "type": "string",
              "description": "参数描述"
            }
          },
          "required": ["param"]
        }
      }
    ]
  }]
}
```

### 2. 响应结构

Gemini的工具调用响应格式：

```json theme={null}
{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "function_name",
              "args": {
                "param": "value"
              }
            }
          }
        ]
      }
    }
  ]
}
```

### 3. 工作流程

1. 用户发送带有工具定义的消息
2. Gemini分析是否需要使用工具
3. Gemini返回包含 `functionCall` 的响应
4. 客户端执行对应的函数
5. 客户端将结果作为 `functionResponse` 发送回Gemini
6. Gemini基于工具结果生成最终回复

## 结果示例

```json 200 theme={null}
{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "calculate_math",
              "args": {
                "expression": "(25 + 15) * 3 - 20"
              }
            }
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 150,
    "candidatesTokenCount": 50,
    "totalTokenCount": 200
  }
}
```

## Google Search 工具

Gemini 支持内置的 Google Search 工具，可以让模型搜索实时信息来回答问题。与自定义函数调用不同，Google Search 是由 Gemini 自动执行的，无需客户端处理搜索逻辑。

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://model-api.skyengine.com.cn/v1beta/models/gemini-2.5-flash:generateContent" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <API-KEY>" \
    -d '{
      "contents": [
        {
          "parts": [
            {"text": "2024年欧洲杯冠军是谁？"}
          ]
        }
      ],
      "tools": [
        {
          "googleSearch": {}
        }
      ]
    }'
  ```

  ```python Python theme={null}
  import requests

  API_KEY = "<API-KEY>"
  BASE_URL = "https://model-api.skyengine.com.cn/v1beta"

  def gemini_google_search(query):
      """使用 Gemini 的 Google Search 工具进行搜索"""
      url = f"{BASE_URL}/models/gemini-2.5-flash:generateContent"
      headers = {
          "Content-Type": "application/json",
          "Authorization": f"Bearer {API_KEY}"
      }

      data = {
          "contents": [
              {
                  "parts": [
                      {"text": query}
                  ]
              }
          ],
          "tools": [
              {
                  "googleSearch": {}
              }
          ]
      }

      response = requests.post(url, headers=headers, json=data)

      if response.status_code == 200:
          result = response.json()
          if 'candidates' in result and len(result['candidates']) > 0:
              parts = result['candidates'][0]['content'].get('parts', [])
              text_parts = [part.get('text', '') for part in parts if 'text' in part]
              return '\n'.join(text_parts)
      return f"错误: {response.status_code} - {response.text}"

  # 使用示例
  if __name__ == "__main__":
      query = "2024年欧洲杯冠军是谁？"
      print(f"问题: {query}")
      print("回答:")
      print(gemini_google_search(query))
  ```
</CodeGroup>

### Google Search 工具特点

* **自动执行**: 模型会自动调用 Google Search 获取信息，无需客户端处理
* **实时信息**: 可以获取最新的新闻、事件、数据等实时信息
* **简单配置**: 只需在 `tools` 中添加 `{"googleSearch": {}}` 即可启用

## 注意事项

1. **消息角色**: 多轮对话时，所有消息都需要指定 `role` 字段（`user` 或 `model`）
2. **字段命名**: API 使用 camelCase 命名（`functionCall`、`functionResponse`），而不是 snake\_case
3. **函数响应**: 函数执行结果需要以 `role: "user"` 的消息发送回模型
4. **错误处理**: 建议在函数执行中添加完善的错误处理机制
