vibestudio-HQ commited on
Commit
c09a9cc
·
verified ·
1 Parent(s): 869a02e

Delete update doc

Browse files
Files changed (1) hide show
  1. update doc +0 -485
update doc DELETED
@@ -1,485 +0,0 @@
1
- # MiniMax-M2 Tool Calling Guide
2
-
3
- ## Introduction
4
-
5
- The MiniMax-M2 model supports tool calling capabilities, enabling the model to identify when external tools need to be called and output tool call parameters in a structured format. This document provides detailed instructions on how to use the tool calling features of MiniMax-M2.
6
-
7
- ## Basic Example
8
-
9
- The following Python script implements a weather query tool call example based on the OpenAI SDK:
10
-
11
- ```py
12
- from openai import OpenAI
13
- import json
14
-
15
- client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")
16
-
17
- def get_weather(location: str, unit: str):
18
- return f"Getting the weather for {location} in {unit}..."
19
-
20
- tool_functions = {"get_weather": get_weather}
21
-
22
- tools = [{
23
- "type": "function",
24
- "function": {
25
- "name": "get_weather",
26
- "description": "Get the current weather in a given location",
27
- "parameters": {
28
- "type": "object",
29
- "properties": {
30
- "location": {"type": "string", "description": "City and state, e.g., 'San Francisco, CA'"},
31
- "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
32
- },
33
- "required": ["location", "unit"]
34
- }
35
- }
36
- }]
37
-
38
- response = client.chat.completions.create(
39
- model=client.models.list().data[0].id,
40
- messages=[{"role": "user", "content": "What's the weather like in San Francisco? use celsius."}],
41
- tools=tools,
42
- tool_choice="auto"
43
- )
44
-
45
- print(response)
46
-
47
- tool_call = response.choices[0].message.tool_calls[0].function
48
- print(f"Function called: {tool_call.name}")
49
- print(f"Arguments: {tool_call.arguments}")
50
- print(f"Result: {get_weather(**json.loads(tool_call.arguments))}")
51
- ```
52
-
53
- **Output Example:**
54
-
55
- ```
56
- Function called: get_weather
57
- Arguments: {"location": "San Francisco, CA", "unit": "celsius"}
58
- Result: Getting the weather for San Francisco, CA in celsius...
59
- ```
60
-
61
- ## Manually Parsing Model Output
62
-
63
- **We strongly recommend using vLLM or SGLang for parsing tool calls.** If you cannot use the built-in parser of inference engines (e.g., vLLM and SGLang) that support MiniMax-M2, or need to use other inference frameworks (such as transformers, TGI, etc.), you can manually parse the model's raw output using the following method. This approach requires you to parse the XML tag format of the model output yourself.
64
-
65
- ### Example Using Transformers
66
-
67
- Here is a complete example using the transformers library:
68
-
69
- ```py
70
- from transformers import AutoTokenizer
71
-
72
- def get_default_tools():
73
- return [
74
- {
75
- "name": "get_current_weather",
76
- "description": "Get the latest weather for a location",
77
- "parameters": {
78
- "type": "object",
79
- "properties": {
80
- "location": {
81
- "type": "string",
82
- "description": "A certain city, such as Beijing, Shanghai"
83
- }
84
- },
85
- }
86
- "required": ["location"],
87
- "type": "object"
88
- }
89
- ]
90
-
91
- # Load model and tokenizer
92
- tokenizer = AutoTokenizer.from_pretrained(model_id)
93
- prompt = "What's the weather like in Shanghai today?"
94
- messages = [
95
- {"role": "system", "content": "You are a helpful assistant."},
96
- {"role": "user", "content": prompt},
97
- ]
98
-
99
- # Enable function calling tools
100
- tools = get_default_tools()
101
-
102
- # Apply chat template and include tool definitions
103
- text = tokenizer.apply_chat_template(
104
- messages,
105
- tokenize=False,
106
- add_generation_prompt=True,
107
- tools=tools
108
- )
109
-
110
- # Send request (using any inference service)
111
- import requests
112
- payload = {
113
- "model": "MiniMaxAI/MiniMax-M2",
114
- "prompt": text,
115
- "max_tokens": 4096
116
- }
117
- response = requests.post(
118
- "http://localhost:8000/v1/completions",
119
- headers={"Content-Type": "application/json"},
120
- json=payload,
121
- stream=False,
122
- )
123
-
124
- # Model output needs manual parsing
125
- raw_output = response.json()["choices"][0]["text"]
126
- print("Raw output:", raw_output)
127
-
128
- # Use the parsing function below to process the output
129
- tool_calls = parse_tool_calls(raw_output, tools)
130
- ```
131
-
132
- ## 🛠️ Tool Call Definition
133
-
134
- ### Tool Structure
135
-
136
- Tool calls need to define the `tools` field in the request body. Each tool consists of the following parts:
137
-
138
- ```json
139
- {
140
- "tools": [
141
- {
142
- "name": "search_web",
143
- "description": "Search function.",
144
- "parameters": {
145
- "properties": {
146
- "query_list": {
147
- "description": "Keywords for search, list should contain 1 element.",
148
- "items": { "type": "string" },
149
- "type": "array"
150
- },
151
- "query_tag": {
152
- "description": "Category of query",
153
- "items": { "type": "string" },
154
- "type": "array"
155
- }
156
- },
157
- "required": [ "query_list", "query_tag" ],
158
- "type": "object"
159
- }
160
- }
161
- ]
162
- }
163
- ```
164
-
165
- **Field Descriptions:**
166
-
167
- - `name`: Function name
168
- - `description`: Function description
169
- - `parameters`: Function parameter definition
170
- - `properties`: Parameter property definition, where key is the parameter name and value contains detailed parameter description
171
- - `required`: List of required parameters
172
- - `type`: Parameter type (usually "object")
173
-
174
- ### Internal Processing Format
175
-
176
- When processing within the MiniMax-M2 model, tool definitions are converted to a special format and concatenated to the input text. Here is a complete example:
177
-
178
- ```
179
- ]~!b[]~b]system
180
- You are a helpful assistant.
181
-
182
- # Tools
183
- You may call one or more tools to assist with the user query.
184
- Here are the tools available in JSONSchema format:
185
-
186
- <tools>
187
- <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>
188
- </tools>
189
-
190
- When making tool calls, use XML format to invoke tools and pass parameters:
191
-
192
- <minimax:tool_call>
193
- <invoke name="tool-name-1">
194
- <parameter name="param-key-1">param-value-1</parameter>
195
- <parameter name="param-key-2">param-value-2</parameter>
196
- ...
197
- </invoke>
198
- [e~[
199
- ]~b]user
200
- When were the latest announcements from OpenAI and Gemini?[e~[
201
- ]~b]ai
202
- <think>
203
- ```
204
-
205
- **Format Description:**
206
-
207
- - `]~!b[]~b]system`: System message start marker
208
- - `[e~[`: Message end marker
209
- - `]~b]user`: User message start marker
210
- - `]~b]ai`: Assistant message start marker
211
- - `]~b]tool`: Tool result message start marker
212
- - `<tools>...</tools>`: Tool definition area, each tool is wrapped with `<tool>` tag, content is JSON Schema
213
- - `<minimax:tool_call>...</minimax:tool_call>`: Tool call area
214
- - `<think>...</think>`: Thinking process marker during generation
215
-
216
- ### Model Output Format
217
-
218
- MiniMax-M2 uses structured XML tag format:
219
-
220
- ```xml
221
- <minimax:tool_call>
222
- <invoke name="search_web">
223
- <parameter name="query_tag">["technology", "events"]</parameter>
224
- <parameter name="query_list">["\"OpenAI\" \"latest\" \"release\""]</parameter>
225
- </invoke>
226
- <invoke name="search_web">
227
- <parameter name="query_tag">["technology", "events"]</parameter>
228
- <parameter name="query_list">["\"Gemini\" \"latest\" \"release\""]</parameter>
229
- </invoke>
230
- </minimax:tool_call>
231
- ```
232
-
233
- Each tool call uses the `<invoke name="function_name">` tag, and parameters use the `<parameter name="parameter_name">` tag wrapper.
234
-
235
- ## Manually Parsing Tool Call Results
236
-
237
- ### Parsing Tool Calls
238
-
239
- MiniMax-M2 uses structured XML tags, which require a different parsing approach. The core function is as follows:
240
-
241
- ```py
242
- import re
243
- import json
244
- from typing import Any, Optional, List, Dict
245
-
246
-
247
- def extract_name(name_str: str) -> str:
248
- """Extract name from quoted string"""
249
- name_str = name_str.strip()
250
- if name_str.startswith('"') and name_str.endswith('"'):
251
- return name_str[1:-1]
252
- elif name_str.startswith("'") and name_str.endswith("'"):
253
- return name_str[1:-1]
254
- return name_str
255
-
256
-
257
- def convert_param_value(value: str, param_type: str) -> Any:
258
- """Convert parameter value based on parameter type"""
259
- if value.lower() == "null":
260
- return None
261
-
262
- param_type = param_type.lower()
263
-
264
- if param_type in ["string", "str", "text"]:
265
- return value
266
- elif param_type in ["integer", "int"]:
267
- try:
268
- return int(value)
269
- except (ValueError, TypeError):
270
- return value
271
- elif param_type in ["number", "float"]:
272
- try:
273
- val = float(value)
274
- return val if val != int(val) else int(val)
275
- except (ValueError, TypeError):
276
- return value
277
- elif param_type in ["boolean", "bool"]:
278
- return value.lower() in ["true", "1"]
279
- elif param_type in ["object", "array"]:
280
- try:
281
- return json.loads(value)
282
- except json.JSONDecodeError:
283
- return value
284
- else:
285
- # Try JSON parsing, return string if failed
286
- try:
287
- return json.loads(value)
288
- except json.JSONDecodeError:
289
- return value
290
-
291
-
292
- def parse_tool_calls(model_output: str, tools: Optional[List[Dict]] = None) -> List[Dict]:
293
- """
294
- Extract all tool calls from model output
295
-
296
- Args:
297
- model_output: Complete output text from the model
298
- tools: Tool definition list for getting parameter type information, format can be:
299
- - [{"name": "...", "parameters": {...}}]
300
- - [{"type": "function", "function": {"name": "...", "parameters": {...}}}]
301
-
302
- Returns:
303
- Parsed tool call list, each element contains name and arguments fields
304
-
305
- Example:
306
- >>> tools = [{
307
- ... "name": "get_weather",
308
- ... "parameters": {
309
- ... "type": "object",
310
- ... "properties": {
311
- ... "location": {"type": "string"},
312
- ... "unit": {"type": "string"}
313
- ... }
314
- ... }
315
- ... }]
316
- >>> output = '''<minimax:tool_call>
317
- ... <invoke name="get_weather">
318
- ... <parameter name="location">San Francisco</parameter>
319
- ... <parameter name="unit">celsius</parameter>
320
- ... </invoke>
321
- ... </minimax:tool_call>'''
322
- >>> result = parse_tool_calls(output, tools)
323
- >>> print(result)
324
- [{'name': 'get_weather', 'arguments': {'location': 'San Francisco', 'unit': 'celsius'}}]
325
- """
326
- # Quick check if tool call marker is present
327
- if "<minimax:tool_call>" not in model_output:
328
- return []
329
-
330
- tool_calls = []
331
-
332
- try:
333
- # Match all <minimax:tool_call> blocks
334
- tool_call_regex = re.compile(r"<minimax:tool_call>(.*?)</minimax:tool_call>", re.DOTALL)
335
- invoke_regex = re.compile(r"<invoke name=(.*?)</invoke>", re.DOTALL)
336
- parameter_regex = re.compile(r"<parameter name=(.*?)</parameter>", re.DOTALL)
337
-
338
- # Iterate through all tool_call blocks
339
- for tool_call_match in tool_call_regex.findall(model_output):
340
- # Iterate through all invokes in this block
341
- for invoke_match in invoke_regex.findall(tool_call_match):
342
- # Extract function name
343
- name_match = re.search(r'^([^>]+)', invoke_match)
344
- if not name_match:
345
- continue
346
-
347
- function_name = extract_name(name_match.group(1))
348
-
349
- # Get parameter configuration
350
- param_config = {}
351
- if tools:
352
- for tool in tools:
353
- tool_name = tool.get("name") or tool.get("function", {}).get("name")
354
- if tool_name == function_name:
355
- params = tool.get("parameters") or tool.get("function", {}).get("parameters")
356
- if isinstance(params, dict) and "properties" in params:
357
- param_config = params["properties"]
358
- break
359
-
360
- # Extract parameters
361
- param_dict = {}
362
- for match in parameter_regex.findall(invoke_match):
363
- param_match = re.search(r'^([^>]+)>(.*)', match, re.DOTALL)
364
- if param_match:
365
- param_name = extract_name(param_match.group(1))
366
- param_value = param_match.group(2).strip()
367
-
368
- # Remove leading and trailing newlines
369
- if param_value.startswith('\n'):
370
- param_value = param_value[1:]
371
- if param_value.endswith('\n'):
372
- param_value = param_value[:-1]
373
-
374
- # Get parameter type and convert
375
- param_type = "string"
376
- if param_name in param_config:
377
- if isinstance(param_config[param_name], dict) and "type" in param_config[param_name]:
378
- param_type = param_config[param_name]["type"]
379
-
380
- param_dict[param_name] = convert_param_value(param_value, param_type)
381
-
382
- tool_calls.append({
383
- "name": function_name,
384
- "arguments": param_dict
385
- })
386
-
387
- except Exception as e:
388
- print(f"Failed to parse tool calls: {e}")
389
- return []
390
-
391
- return tool_calls
392
- ```
393
-
394
- **Usage Example:**
395
-
396
- ```py
397
- # Define tools
398
- tools = [
399
- {
400
- "name": "get_weather",
401
- "parameters": {
402
- "type": "object",
403
- "properties": {
404
- "location": {"type": "string"},
405
- "unit": {"type": "string"}
406
- },
407
- "required": ["location", "unit"]
408
- }
409
- }
410
- ]
411
-
412
- # Model output
413
- model_output = """Let me help you query the weather.
414
- <minimax:tool_call>
415
- <invoke name="get_weather">
416
- <parameter name="location">San Francisco</parameter>
417
- <parameter name="unit">celsius</parameter>
418
- </invoke>
419
- </minimax:tool_call>"""
420
-
421
- # Parse tool calls
422
- tool_calls = parse_tool_calls(model_output, tools)
423
-
424
- # Output results
425
- for call in tool_calls:
426
- print(f"Function called: {call['name']}")
427
- print(f"Arguments: {call['arguments']}")
428
- # Output: Function called: get_weather
429
- # Arguments: {'location': 'San Francisco', 'unit': 'celsius'}
430
- ```
431
-
432
- ### Executing Tool Calls
433
-
434
- After parsing is complete, you can execute the corresponding tool and construct the return result:
435
-
436
- ```py
437
- def execute_function_call(function_name: str, arguments: dict):
438
- """Execute function call and return result"""
439
- if function_name == "get_weather":
440
- location = arguments.get("location", "Unknown location")
441
- unit = arguments.get("unit", "celsius")
442
- # Build function execution result
443
- return {
444
- "role": "tool",
445
- "content": [
446
- {
447
- "name": function_name,
448
- "type": "text",
449
- "text": json.dumps({
450
- "location": location,
451
- "temperature": "25",
452
- "unit": unit,
453
- "weather": "Sunny"
454
- }, ensure_ascii=False)
455
- }
456
- ]
457
- }
458
- elif function_name == "search_web":
459
- query_list = arguments.get("query_list", [])
460
- query_tag = arguments.get("query_tag", [])
461
- # Simulate search results
462
- return {
463
- "role": "tool",
464
- "content": [
465
- {
466
- "name": function_name,
467
- "type": "text",
468
- "text": f"Search keywords: {query_list}, Category: {query_tag}\nSearch results: Relevant information found"
469
- }
470
- ]
471
- }
472
-
473
- return None
474
- ```
475
-
476
- ### Returning Tool Execution Results to the Model
477
-
478
- After successfully parsing tool calls, you should add the tool execution results to the conversation history so that the model can access and utilize this information in subsequent interactions. Refer to [chat\_template.jinja](https://huggingface.co/MiniMaxAI/MiniMax-M2/blob/main/chat_template.jinja) for concatenation format.
479
-
480
- ## References
481
-
482
- - [MiniMax-M2 Model Repository](https://github.com/MiniMax-AI/MiniMax-M2)
483
- - [vLLM Project Homepage](https://github.com/vllm-project/vllm)
484
- - [SGLang Project Homepage](https://github.com/sgl-project/sglang)
485
- - [OpenAI Python SDK](https://github.com/openai/openai-python)