0% read

如何用 Gemma 4 函式呼叫建構 AI 代理

Apr 7, 2026

Gemma 4 內建原生函式呼叫支援,這意味著你可以建構不只是生成文字——還能採取行動的 AI 代理。呼叫 API、查詢資料庫、搜尋網路、執行計算。本指南展示如何用 Gemma 4 和 Python 從頭建構一個可運作的代理。

什麼是函式呼叫?

函式呼叫讓模型決定何時使用外部工具而不是猜測答案。與其問 Gemma 4「東京的天氣如何?」得到幻覺式的回應,模型會輸出一個結構化請求呼叫你的天氣 API,你執行它,將結果餵回,然後模型根據真實資料生成自然語言答案。

流程看起來像這樣:

使用者:「東京的天氣如何?」
  → 模型:{"function": "get_weather", "args": {"city": "Tokyo"}}
  → 你的程式碼呼叫天氣 API → 回傳 {"temp": 22, "condition": "sunny"}
  → 模型:「東京現在是攝氏 22 度,天氣晴朗。」

用 JSON Schema 定義工具

首先,你需要告訴 Gemma 4 有哪些工具可用。每個工具都用 JSON schema 定義,描述其名稱、用途和參數:

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get current weather for a city. Use this when the user asks about weather conditions.",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "City name, e.g. 'Tokyo', 'New York'"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "Temperature unit"
                    }
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "calculate",
            "description": "Perform mathematical calculations. Use for any math the user asks about.",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {
                        "type": "string",
                        "description": "Math expression to evaluate, e.g. '2 + 2', 'sqrt(144)'"
                    }
                },
                "required": ["expression"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "web_search",
            "description": "Search the web for current information. Use when the user asks about recent events or facts you're unsure about.",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "Search query"
                    },
                    "num_results": {
                        "type": "integer",
                        "description": "Number of results to return (default: 3)"
                    }
                },
                "required": ["query"]
            }
        }
    }
]

良好的工具描述至關重要。模型依靠它們來決定呼叫哪個工具以及何時呼叫。明確地描述每個工具該在何時使用。

建構代理迴圈

以下是一個透過 Ollama API 使用 Gemma 4 的完整 Python 代理:

import json
import requests
import math

OLLAMA_URL = "http://localhost:11434/api/chat"
MODEL = "gemma4:12b"

# 定義你的工具實作
def get_weather(city: str, unit: str = "celsius") -> dict:
    """Simulated weather API — replace with a real API call"""
    # 在正式環境中,呼叫 OpenWeatherMap、WeatherAPI 等
    return {
        "city": city,
        "temperature": 22,
        "unit": unit,
        "condition": "sunny",
        "humidity": 45
    }

def calculate(expression: str) -> dict:
    """Safe math evaluation"""
    allowed_names = {
        "sqrt": math.sqrt,
        "sin": math.sin,
        "cos": math.cos,
        "pi": math.pi,
        "e": math.e,
        "abs": abs,
        "round": round
    }
    try:
        result = eval(expression, {"__builtins__": {}}, allowed_names)
        return {"expression": expression, "result": result}
    except Exception as e:
        return {"expression": expression, "error": str(e)}

def web_search(query: str, num_results: int = 3) -> dict:
    """Simulated web search — replace with real search API"""
    return {
        "query": query,
        "results": [
            {"title": f"Result about {query}", "snippet": "Relevant information..."}
        ]
    }

# 將函式名稱對應到實作
TOOL_MAP = {
    "get_weather": get_weather,
    "calculate": calculate,
    "web_search": web_search,
}

def call_gemma(messages: list, tools: list) -> dict:
    """Send a chat request to Gemma 4 via Ollama"""
    response = requests.post(OLLAMA_URL, json={
        "model": MODEL,
        "messages": messages,
        "tools": tools,
        "stream": False
    })
    return response.json()

def run_agent(user_input: str, tools: list, max_steps: int = 5):
    """Run the agent loop with multi-step tool use"""
    messages = [
        {
            "role": "system",
            "content": "You are a helpful assistant. Use the provided tools when needed. Always use tools for weather, calculations, and current information instead of guessing."
        },
        {"role": "user", "content": user_input}
    ]

    for step in range(max_steps):
        response = call_gemma(messages, tools)
        message = response["message"]

        # 檢查模型是否要呼叫工具
        if "tool_calls" in message and message["tool_calls"]:
            # 處理每個工具呼叫
            for tool_call in message["tool_calls"]:
                func_name = tool_call["function"]["name"]
                func_args = tool_call["function"]["arguments"]

                print(f"  → Calling {func_name}({func_args})")

                # 執行工具
                if func_name in TOOL_MAP:
                    result = TOOL_MAP[func_name](**func_args)
                else:
                    result = {"error": f"Unknown tool: {func_name}"}

                # 將工具呼叫和結果加到訊息
                messages.append(message)
                messages.append({
                    "role": "tool",
                    "content": json.dumps(result)
                })
        else:
            # 模型給了最終的文字回應
            print(f"Agent: {message['content']}")
            return message["content"]

    return "Agent reached maximum steps without completing."

# 執行代理
if __name__ == "__main__":
    run_agent("What's the weather in Tokyo and what's 15% of 8500?", tools)

這個代理可以處理多步驟查詢。當你問「東京的天氣如何,以及 8500 的 15% 是多少?」時,Gemma 4 會分別呼叫 get_weathercalculate,然後將兩個結果合成為一個自然的回應。

多步驟代理模式

真實的代理通常需要串聯多個工具呼叫,後面的呼叫依賴前面的結果:

# 範例:「找我附近的餐廳並查看那裡的天氣」
# 步驟 1:模型呼叫 web_search("restaurants near me")
# 步驟 2:模型看到結果,呼叫 get_weather(結果中的城市)
# 步驟 3:模型將兩者合成為推薦

# 代理迴圈自然地處理這個——每個工具結果都被
# 加到對話中,模型根據完整歷史決定下一步要做什麼

用於可靠工具使用的結構化輸出

Gemma 4 支援結構化輸出,這意味著你可以強制模型以特定的 JSON 格式回應。當你需要代理的最終答案是機器可讀的結構時這很有用:

response = requests.post(OLLAMA_URL, json={
    "model": MODEL,
    "messages": messages,
    "format": {
        "type": "object",
        "properties": {
            "answer": {"type": "string"},
            "confidence": {"type": "number"},
            "sources": {
                "type": "array",
                "items": {"type": "string"}
            }
        },
        "required": ["answer", "confidence"]
    },
    "stream": False
})

這保證輸出是符合你 schema 的有效 JSON——不再需要解析自由格式文字並祈禱一切順利。

更好函式呼叫的技巧

技巧原因
撰寫詳細的工具描述模型依賴描述來選擇正確的工具
在 schema 中使用 required 欄位防止模型遺漏關鍵參數
工具數量限制在 5-10 個太多工具會讓模型困惑
在描述中加入範例「例如 'New York'、'London'」幫助模型正確格式化參數
優雅地處理錯誤回傳錯誤資訊以便模型可以重試或通知使用者
設定 max_steps 限制防止模型不斷呼叫工具造成無限迴圈

常見陷阱

模型忽略工具直接回答: 讓你的 system prompt 明確告訴模型使用工具。加上「絕不猜測天氣/數學/事實——一律使用提供的工具。」

參數型別錯誤: 如果模型為整數參數傳送 "3" 而不是 3,在你的工具實作中加入型別轉換。

模型不必要地呼叫工具: 在工具描述中明確說明何時該使用它們。「僅當使用者明確詢問天氣時使用」比「取得天氣資訊」更好。

下一步

函式呼叫將 Gemma 4 從聊天機器人轉變為實際的工具。一旦你接上真實 API——天氣、搜尋、資料庫、電子郵件——你就擁有了一個能在現實世界採取有意義行動的 AI 代理,全部在你自己的硬體上本機執行。

gemma4 — interact

Stop reading. Start building.

~/gemma4 $ Get hands-on with the models discussed in this guide. No deployment, no friction, 100% free playground.

Launch Playground />
Gemma 4 AI

Gemma 4 AI

Related Guides

如何用 Gemma 4 函式呼叫建構 AI 代理 | 部落格