English Version | Chinese Version | Japanese Version
MiniMax-M2.1はMiniMax-M2と同じtoolcall構文をサポートしています。
MiniMax-M2.1モデルはツール呼び出し機能をサポートしており、外部ツールを呼び出す必要がある場合にモデルがそれを識別し、ツール呼び出しパラメータを構造化された形式で出力することができます。本ドキュメントでは、MiniMax-M2.1のツール呼び出し機能の使用方法について詳しく説明します。
以下のPythonスクリプトは、OpenAI SDKに基づく天気問い合わせツール呼び出しの例を実装しています。
from openai import OpenAI
import json
client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")
def get_weather(location: str, unit: str):
return f"Getting the weather for {location} in {unit}..."
tool_functions = {"get_weather": get_weather}
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City and state, e.g., 'San Francisco, CA'"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location", "unit"]
}
}
}]
response = client.chat.completions.create(
model=client.models.list().data[0].id,
messages=[{"role": "user", "content": "What's the weather like in San Francisco? use celsius."}],
tools=tools,
tool_choice="auto"
)
print(response)
tool_call = response.choices[0].message.tool_calls[0].function
print(f"Function called: {tool_call.name}")
print(f"Arguments: {tool_call.arguments}")
print(f"Result: {get_weather(**json.loads(tool_call.arguments))}")出力例
Function called: get_weather
Arguments: {"location": "San Francisco, CA", "unit": "celsius"}
Result: Getting the weather for San Francisco, CA in celsius...
ツール呼び出しの解析にはvLLMやSGLangの使用を強く推奨します。 MiniMax-M2.1をサポートする推論エンジン(例:vLLMやSGLang)の組み込みパーサーを使用できない場合や、他の推論フレームワーク(transformers、TGIなど)を使用する必要がある場合は、以下の方法でモデルの生の出力を手動で解析できます。この方法では、モデル出力のXMLタグ形式を自分で解析する必要があります。
以下はtransformersライブラリを使用した完全な例です:
from transformers import AutoTokenizer
def get_default_tools():
return [
{
"name": "get_current_weather",
"description": "Get the latest weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "A certain city, such as Beijing, Shanghai"
}
},
}
"required": ["location"],
"type": "object"
}
]
# Load model and tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_id)
prompt = "What's the weather like in Shanghai today?"
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt},
]
# Enable function calling tools
tools = get_default_tools()
# Apply chat template and include tool definitions
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
tools=tools
)
# Send request (using any inference service)
import requests
payload = {
"model": "MiniMaxAI/MiniMax-M2.1",
"prompt": text,
"max_tokens": 4096
}
response = requests.post(
"http://localhost:8000/v1/completions",
headers={"Content-Type": "application/json"},
json=payload,
stream=False,
)
# Model output needs manual parsing
raw_output = response.json()["choices"][0]["text"]
print("Raw output:", raw_output)
# Use the parsing function below to process the output
tool_calls = parse_tool_calls(raw_output, tools)Tool callsを使用するには、リクエストボディにtoolsフィールドを定義する必要があります。各ツールは以下の部分で構成されます:
{
"tools": [
{
"name": "search_web",
"description": "Search function.",
"parameters": {
"properties": {
"query_list": {
"description": "Keywords for search, list should contain 1 element.",
"items": { "type": "string" },
"type": "array"
},
"query_tag": {
"description": "Category of query",
"items": { "type": "string" },
"type": "array"
}
},
"required": [ "query_list", "query_tag" ],
"type": "object"
}
}
]
}Tool callsはリクエストボディにtoolsフィールドを定義する必要があります。各ツールは以下の部分で構成されます:
{
"tools": [
{
"name": "search_web",
"description": "Search function.",
"parameters": {
"properties": {
"query_list": {
"description": "Keywords for search, list should contain 1 element.",
"items": { "type": "string" },
"type": "array"
},
"query_tag": {
"description": "Category of query",
"items": { "type": "string" },
"type": "array"
}
},
"required": [ "query_list", "query_tag" ],
"type": "object"
}
}
]
}概要フィールドの説明:
name: 関数名description: 関数の説明parameters: 関数のパラメータ定義properties: パラメータのプロパティ定義、キーがパラメータ名で値が詳細なパラメータ説明を含むrequired: 必須パラメータのリストtype: パラメータの型(通常は "object")
MiniMax-M2.1モデル内で処理する際、ツール定義は特殊なフォーマットに変換され、入力テキストに連結されます。以下は完全な例です:
]~!b[]~b]system
あなたは役に立つアシスタントです。
# Tools
あなたはユーザーのクエリを支援するために1つ以上のツールを呼び出すことができます。
以下はJSONSchema形式で利用可能なツールです:
<tools>
<tool>{"name": "search_web", "description": "Search function.", "parameters": {"type": "object", "properties": {"query_list": {"type": "array", "items": {"type": "string"}, "description": "Keywords for search, list should contain 1 element."}, "query_tag": {"type": "array", "items": {"type": "string"}, "description": "Category of query"}}, "required": ["query_list", "query_tag"]}}</tool>
</tools>
tool callsを行う際は、XML形式を使用してツールを呼び出し、パラメータを渡します:
<minimax:tool_call>
<invoke name="tool-name-1">
<parameter name="param-key-1">param-value-1</parameter>
<parameter name="param-key-2">param-value-2</parameter>
...
</invoke>
[e~[
]~b]user
When were the latest announcements from OpenAI and Gemini?[e~[
]~b]ai
<think>
フォーマットの説明:
]~!b[]~b]system: システムメッセージ開始マーカー[e~[: メッセージ終了マーカー]~b]user: ユーザーメッセージ開始マーカー]~b]ai: アシスタントメッセージ開始マーカー]~b]tool: ツール結果メッセージ開始マーカー<tools>...</tools>: ツール定義エリア、各ツールは<tool>タグでラップされ、内容はJSON Schema<minimax:tool_call>...</minimax:tool_call>: Tool call 領域<think>...</think>: 思考プロセスマーカー(生成中)
MiniMax-M2.1 は構造化されたXMLタグ形式を使用します:
<minimax:tool_call>
<invoke name="search_web">
<parameter name="query_tag">["technology", "events"]</parameter>
<parameter name="query_list">["\"OpenAI\" \"latest\" \"release\""]</parameter>
</invoke>
<invoke name="search_web">
<parameter name="query_tag">["technology", "events"]</parameter>
<parameter name="query_list">["\"Gemini\" \"latest\" \"release\""]</parameter>
</invoke>
</minimax:tool_call>各ツールコールは <invoke name="function_name"> タグを使用し、パラメータは <parameter name="parameter_name"> タグでラップされます。
MiniMax-M2.1 は構造化されたXMLタグを使用しており、異なる解析アプローチが必要です。コア関数は以下の通りです:
import re
import json
from typing import Any, Optional, List, Dict
def extract_name(name_str: str) -> str:
"""Extract name from quoted string"""
name_str = name_str.strip()
if name_str.startswith('"') and name_str.endswith('"'):
return name_str[1:-1]
elif name_str.startswith("'") and name_str.endswith("'"):
return name_str[1:-1]
return name_str
def convert_param_value(value: str, param_type: str) -> Any:
"""Convert parameter value based on parameter type"""
if value.lower() == "null":
return None
param_type = param_type.lower()
if param_type in ["string", "str", "text"]:
return value
elif param_type in ["integer", "int"]:
try:
return int(value)
except (ValueError, TypeError):
return value
elif param_type in ["number", "float"]:
try:
val = float(value)
return val if val != int(val) else int(val)
except (ValueError, TypeError):
return value
elif param_type in ["boolean", "bool"]:
return value.lower() in ["true", "1"]
elif param_type in ["object", "array"]:
try:
return json.loads(value)
except json.JSONDecodeError:
return value
else:
# Try JSON parsing, return string if failed
try:
return json.loads(value)
except json.JSONDecodeError:
return value
def parse_tool_calls(model_output: str, tools: Optional[List[Dict]] = None) -> List[Dict]:
"""
Extract all tool calls from model output
Args:
model_output: Complete output text from the model
tools: Tool definition list for getting parameter type information, format can be:
- [{"name": "...", "parameters": {...}}]
- [{"type": "function", "function": {"name": "...", "parameters": {...}}}]
Returns:
Parsed tool call list, each element contains name and arguments fields
Example:
>>> tools = [{
... "name": "get_weather",
... "parameters": {
... "type": "object",
... "properties": {
... "location": {"type": "string"},
... "unit": {"type": "string"}
... }
... }
... }]
>>> output = '''<minimax:tool_call>
... <invoke name="get_weather">
... <parameter name="location">San Francisco</parameter>
... <parameter name="unit">celsius</parameter>
... </invoke>
... </minimax:tool_call>'''
>>> result = parse_tool_calls(output, tools)
>>> print(result)
[{'name': 'get_weather', 'arguments': {'location': 'San Francisco', 'unit': 'celsius'}}]
"""
# Quick check if tool call marker is present
if "<minimax:tool_call>" not in model_output:
return []
tool_calls = []
try:
# Match all <minimax:tool_call> blocks
tool_call_regex = re.compile(r"<minimax:tool_call>(.*?)</minimax:tool_call>", re.DOTALL)
invoke_regex = re.compile(r"<invoke name=(.*?)</invoke>", re.DOTALL)
parameter_regex = re.compile(r"<parameter name=(.*?)</parameter>", re.DOTALL)
# Iterate through all tool_call blocks
for tool_call_match in tool_call_regex.findall(model_output):
# Iterate through all invokes in this block
for invoke_match in invoke_regex.findall(tool_call_match):
# Extract function name
name_match = re.search(r'^([^>]+)', invoke_match)
if not name_match:
continue
function_name = extract_name(name_match.group(1))
# Get parameter configuration
param_config = {}
if tools:
for tool in tools:
tool_name = tool.get("name") or tool.get("function", {}).get("name")
if tool_name == function_name:
params = tool.get("parameters") or tool.get("function", {}).get("parameters")
if isinstance(params, dict) and "properties" in params:
param_config = params["properties"]
break
# Extract parameters
param_dict = {}
for match in parameter_regex.findall(invoke_match):
param_match = re.search(r'^([^>]+)>(.*)', match, re.DOTALL)
if param_match:
param_name = extract_name(param_match.group(1))
param_value = param_match.group(2).strip()
# Remove leading and trailing newlines
if param_value.startswith('\n'):
param_value = param_value[1:]
if param_value.endswith('\n'):
param_value = param_value[:-1]
# Get parameter type and convert
param_type = "string"
if param_name in param_config:
if isinstance(param_config[param_name], dict) and "type" in param_config[param_name]:
param_type = param_config[param_name]["type"]
param_dict[param_name] = convert_param_value(param_value, param_type)
tool_calls.append({
"name": function_name,
"arguments": param_dict
})
except Exception as e:
print(f"Failed to parse tool calls: {e}")
return []
return tool_calls使用例:
# Define tools
tools = [
{
"name": "get_weather",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"},
"unit": {"type": "string"}
},
"required": ["location", "unit"]
}
}
]
# Model output
model_output = """Let me help you query the weather.
<minimax:tool_call>
<invoke name="get_weather">
<parameter name="location">San Francisco</parameter>
<parameter name="unit">celsius</parameter>
</invoke>
</minimax:tool_call>"""
# Parse tool calls
tool_calls = parse_tool_calls(model_output, tools)
# Output results
for call in tool_calls:
print(f"Function called: {call['name']}")
print(f"Arguments: {call['arguments']}")
# Output: Function called: get_weather
# Arguments: {'location': 'San Francisco', 'unit': 'celsius'}解析が完了したら、対応するツールを実行し、返却結果を構築できます:
def execute_function_call(function_name: str, arguments: dict):
"""Execute function call and return result"""
if function_name == "get_weather":
location = arguments.get("location", "Unknown location")
unit = arguments.get("unit", "celsius")
# Build function execution result
return {
"role": "tool",
"content": [
{
"name": function_name,
"type": "text",
"text": json.dumps({
"location": location,
"temperature": "25",
"unit": unit,
"weather": "Sunny"
}, ensure_ascii=False)
}
]
}
elif function_name == "search_web":
query_list = arguments.get("query_list", [])
query_tag = arguments.get("query_tag", [])
# Simulate search results
return {
"role": "tool",
"content": [
{
"name": function_name,
"type": "text",
"text": f"Search keywords: {query_list}, Category: {query_tag}\nSearch results: Relevant information found"
}
]
}
return Noneツールコールの解析に成功したら、ツールの実行結果を会話履歴に追加し、モデルが後続のやり取りでこの情報にアクセスして活用できるようにします。連結フォーマットについては chat_template.jinja を参照してください。