推理提供商文件

函式呼叫與推理提供商

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

函式呼叫與推理提供商

函式呼叫使語言模型能夠透過根據使用者輸入生成結構化函式呼叫來與外部工具和 API 進行互動。此功能允許您構建可以執行檢索即時資料、進行計算或與外部服務互動等操作的 AI 代理。

當您向經過工具使用微調的語言模型提供函式描述時,它可以根據使用者請求決定何時呼叫這些函式,執行它們,並將結果整合到自然語言響應中。例如,您可以構建一個助手來獲取即時天氣資料以提供準確的響應。

本指南假定您擁有 Hugging Face 帳戶和訪問令牌。您可以在 huggingface.co 建立免費帳戶,並從您的設定頁面獲取令牌。

定義函式

第一步是實現您希望模型呼叫的函式。我們將使用一個簡單的天氣函式示例,它返回給定位置的當前天氣。

一如既往,我們將首先初始化我們的推理客戶端。

openai
huggingface_hub

在 OpenAI 客戶端中,我們將使用 base_url 引數來指定我們希望用於請求的提供商。

import json
import os

from openai import OpenAI

# Initialize client
client = OpenAI(
    base_url="https://router.huggingface.co/v1",
    api_key=os.environ["HF_TOKEN"],
)

我們可以將函式定義為執行簡單任務的 Python 函式。在本例中,該函式將以位置、溫度和條件字典的形式返回當前天氣。

# Define the function
def get_current_weather(location: str) -> dict:
    """Get weather information for a location."""
    # In production, this would call a real weather API
    weather_data = {
        "San Francisco": {"temperature": "22°C", "condition": "Sunny"},
        "New York": {"temperature": "18°C", "condition": "Cloudy"},
        "London": {"temperature": "15°C", "condition": "Rainy"},
    }
    
    return weather_data.get(location, {
        "location": location,
        "error": "Weather data not available"
    })

現在我們需要定義函式模式,它向語言模型描述我們的天氣函式。此模式告訴模型函式期望哪些引數以及它執行什麼操作。


# Define the function schema
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get current weather for a location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string", 
                        "description": "City name"
                    },
                },
                "required": ["location"],
            },
        },
    },
]

該模式是一種 JSON Schema 格式,描述了函式的功能、其引數以及哪些引數是必需的。描述有助於模型理解何時以及如何呼叫函式。

在聊天中處理函式

函式在典型的聊天完成對話中起作用。模型將根據使用者輸入決定何時呼叫它們。

user_message = "What's the weather like in San Francisco?"

messages = [
    {
        "role": "system",
        "content": "You are a helpful assistant with access to weather data."
    },
    {"role": "user", "content": user_message}
]

# Initial API call with tools
response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1-0528",
    messages=messages,
    tools=tools,
    tool_choice="auto" # Let the model decide when to call functions
)

response_message = response.choices[0].message

tool_choice 引數用於控制模型何時呼叫函式。在本例中,我們使用 auto,這意味著模型將決定何時呼叫函式(0 次或多次)。下面我們將擴充套件 tool_choice 和其他引數。

接下來,我們需要檢查模型響應中模型決定呼叫了哪些函式。如果呼叫了,我們需要執行該函式並將結果新增到對話中,然後將最終響應傳送給使用者。


# Check if model wants to call functions
if response_message.tool_calls:
    # Add assistant's response to messages
    messages.append(response_message)

    # Process each tool call
    for tool_call in response_message.tool_calls:
        function_name = tool_call.function.name
        function_args = json.loads(tool_call.function.arguments)

        # Execute the function
        if function_name == "get_current_weather":
            result = get_current_weather(function_args["location"])
            
            # Add function result to messages
            messages.append({
                "tool_call_id": tool_call.id,
                "role": "tool",
                "name": function_name,
                "content": json.dumps(result),
            })

    # Get final response with function results
    final_response = client.chat.completions.create(
        model="deepseek-ai/DeepSeek-R1-0528",
        messages=messages,
    )

    return final_response.choices[0].message.content
else:
    return response_message.content

工作流程很簡單:使用您的工具進行初始 API 呼叫,檢查模型是否要呼叫函式,如果需要則執行它們,將結果新增到對話中,並獲取使用者的最終響應。

我們已經處理了模型想要呼叫函式並且該函式實際存在的情況。然而,模型可能會嘗試呼叫不存在的函式,因此我們也需要考慮這一點。我們還可以使用 strict 模式來處理這個問題,我們將在後面介紹。

多個函式

您可以為更復雜的助手定義多個函式。

# Define multiple functions
def get_current_weather(location: str) -> dict:
    """Get current weather for a location."""
    return {"location": location, "temperature": "22°C", "condition": "Sunny"}

def get_weather_forecast(location: str, date: str) -> dict:
    """Get weather forecast for a location."""
    return {
        "location": location,
        "date": date,
        "forecast": "Sunny with chance of rain",
        "temperature": "20°C"
    }

# Function registry
AVAILABLE_FUNCTIONS = {
    "get_current_weather": get_current_weather,
    "get_weather_forecast": get_weather_forecast,
}

# Multiple tool schemas
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get current weather for a location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string", "description": "City name"}
                },
                "required": ["location"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "get_weather_forecast",
            "description": "Get weather forecast for a location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string", "description": "City name"},
                    "date": {"type": "string", "description": "Date in YYYY-MM-DD format"},
                },
                "required": ["location", "date"],
            },
        },
    },
]

response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1-0528",
    messages=messages,
    tools=tools,
    tool_choice="auto"
)

我們定義了多個函式並將它們新增到了工具列表中。模型將根據使用者輸入決定何時呼叫它們。我們還可以使用 tool_choice 引數強制模型呼叫特定函式。

我們可以以與單個函式示例類似的方式處理工具執行。這次使用 elif 語句來處理不同的函式。

# execute the response
response_message = response.choices[0].message

# check if the model wants to call functions
if response_message.tool_calls:
    # process the tool calls
    for tool_call in response_message.tool_calls:
        function_name = tool_call.function.name
        function_args = json.loads(tool_call.function.arguments)

        # execute the function
        if function_name == "get_current_weather":
            result = get_current_weather(function_args["location"])
        elif function_name == "get_weather_forecast":
            result = get_weather_forecast(function_args["location"], function_args["date"])

        # add the result to the conversation
        messages.append({
            "tool_call_id": tool_call.id,
            "role": "tool",
            "name": function_name,
            "content": json.dumps(result),
        })

    # get the final response with function results
    final_response = client.chat.completions.create(
        model="deepseek-ai/DeepSeek-R1-0528",
        messages=messages,
    )

    return final_response.choices[0].message.content
else:
    return response_message.content

🎉 您已經構建了一個功能性助手,可以呼叫多個函式來獲取天氣資料!

額外配置

讓我們看看函式呼叫與推理提供商的一些額外配置選項,以充分利用其功能。

提供商選擇

您可以指定要使用的推理提供商,以更好地控制性能和成本。這將透過減少模型響應中的差異來幫助函式呼叫。

openai
huggingface_hub

在 OpenAI 客戶端中,您可以透過將提供商 ID 附加到模型引數來指定要用於請求的提供商,如下所示

# The OpenAI client automatically routes through Inference Providers
# You can specify provider preferences in your HF settings
client = OpenAI(
    base_url="https://router.huggingface.co/v1",
    api_key=os.environ["HF_TOKEN"],
)

client.chat.completions.create(
-     model="deepseek-ai/DeepSeek-R1-0528", # automatically select provider based on hf.co/settings/inference-providers
+     model="deepseek-ai/DeepSeek-R1-0528:nebius", # manually select Nebius AI
+     model="deepseek-ai/DeepSeek-R1-0528:hyperbolic", # manually select Hyperbolic
      ...
)

透過切換提供商,您可以看到模型的響應發生變化,因為每個提供商都使用不同的模型配置。

每個推理提供商都有不同的功能和效能特徵。您可以在推理提供商部分找到有關每個提供商的更多資訊。

工具選擇選項

您可以使用 tool_choice 引數控制何時以及呼叫哪些函式。

tool_choice 引數用於控制模型何時呼叫函式。在大多數情況下,我們使用 auto,這意味著模型將決定何時呼叫函式(0 次或多次)。

# Let the model decide (default)
response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1-0528",
    messages=messages,
    tools=tools,
    tool_choice="auto"  # Model decides when to call functions
)

然而,在某些用例中,您可能希望強制模型呼叫函式,以便它從不根據自己的知識回覆,而只根據函式呼叫結果回覆。

# Force the model to call at least one function
response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1-0528",
    messages=messages,
    tools=tools,
    tool_choice="required"  # Must call at least one function
)

如果您有簡單的函式,這會很好用,但如果您有更復雜的函式,您可能希望使用 tool_choice 引數強制模型至少呼叫一次特定函式。

openai
huggingface_hub

例如,假設您的助手的唯一工作是提供給定位置的天氣。您可能希望強制模型呼叫 get_current_weather 函式,而不呼叫任何其他函式。

# Force a specific function call
response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1-0528",
    messages=messages,
    tools=tools,
    tool_choice={
        "type": "function",
        "function": {"name": "get_current_weather"}
    }
)

在這裡,我們強制模型呼叫 get_current_weather 函式,而不呼叫任何其他函式。

嚴格模式

使用嚴格模式可確保函式呼叫完全遵循您的模式。這有助於防止模型使用意外引數呼叫函式,或呼叫不存在的函式。

# Define tools with strict mode
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get current weather for a location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string", "description": "City name"},
                },
                "required": ["location"],
+                "additionalProperties": False,  # Strict mode requirement
            },
+            "strict": True,  # Enable strict mode
        },
    },
]

嚴格模式確保函式引數與您的模式完全匹配:不允許使用額外屬性,必須提供所有必需引數,並且嚴格執行資料型別。

並非所有提供商都支援嚴格模式。您可以檢視提供商的文件以瞭解它是否支援嚴格模式。

流式響應

啟用流式傳輸以實現帶有函式呼叫的即時響應。這對於向用戶顯示模型的進度或更有效地處理長時間執行的函式呼叫很有用。

# Enable streaming with function calls
stream = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1-0528",
    messages=messages,
    tools=tools,
    tool_choice="auto",
    stream=True  # Enable streaming
)

# Process the stream
for chunk in stream:
    if chunk.choices[0].delta.tool_calls:
        # Handle tool call chunks
        tool_calls = chunk.choices[0].delta.tool_calls
    
    if chunk.choices[0].delta.content:
        # Handle content chunks
        content = chunk.choices[0].delta.content

流式傳輸允許您在響應到達時處理它們,向用戶顯示即時進度,並更有效地處理長時間執行的函式呼叫。

並非所有提供商都支援流式傳輸。您可以檢視提供商的文件以瞭解它是否支援流式傳輸,或者您可以參考此動態模型相容性表

後續步驟

現在您已經瞭解瞭如何使用函式呼叫與推理提供商,您可以開始構建自己的代理和助手了!為什麼不嘗試以下一些想法呢

  • 嘗試更小的模型以獲得更快的響應和更低的成本
  • 構建一個可以獲取即時資料的代理
  • 使用推理模型構建一個可以與外部工具進行推理的代理
< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.