메뉴
BL
r/LocalLLaMA 49일 전

미니맥스(MiniMax) M2.7 모델 공개

IMP
6/10
핵심 요약

미니맥스(MiniMax)에서 새로운 AI 모델인 M2.7을 공개했습니다. 이 템플릿 코드는 해당 모델의 시스템 메시지 처리와 도구(Tool) 호출을 위한 프롬프트 렌더링 방식을 보여줍니다. 모델이 사용자의 요청을 분석하고 사고(Reasoning) 과정을 거쳐 도구를 사용하는 일련의 논리적 구조를 담고 있습니다.

번역된 본문

-%} {%- set toolcall_end_token = '' -%} {#- 도구 렌더링 함수 ============================================== -#} {%- macro render_tool_namespace(namespace_name, tool_list) -%} {%- for tool in tool_list -%} {{ tool.function | tojson(ensure_ascii=False) }} {% endfor -%} {%- endmacro -%} {%- macro visible_text(content) -%} {%- if content is string -%} {{ content }} {%- elif content is iterable and content is not mapping -%} {%- for item in content -%} {%- if item is mapping and item.type == 'text' -%} {{- item.text }} {%- elif item is string -%} {{- item }} {%- endif -%} {%- endfor -%} {%- else -%} {{- content }} {%- endif -%} {%- endmacro -%} {#- 시스템 메시지 구성 ============================================ -#} {%- macro build_system_message(system_message) -%} {%- if system_message and system_message.content -%} {{- visible_text(system_message.content) }} {%- else -%} {%- if model_identity is not defined -%} {%- set model_identity = "당신은 도움이 되는 어시스턴트입니다. 당신의 이름은 MiniMax-M2.7이며 MiniMax가 제작했습니다." -%} {%- endif -%} {{- model_identity }} {%- endif -%}

{#- 현재 날짜 처리 -#} {%- if system_message and system_message.current_date -%} {{- '\n' ~ '현재 날짜: ' + system_message.current_date }} {%- endif -%} {#- 현재 위치 처리 -#} {%- if system_message and system_message.current_location -%} {{- '\n' ~ '현재 위치: ' + system_message.current_location }} {%- endif -%} {%- endmacro -%} {#- 메인 템플릿 로직 ================================================= -#} {#- 시스템 메시지 추출 (시스템 메시지인 경우 첫 번째 메시지만) -#} {%- set system_message = none -%} {%- set conversation_messages = messages -%} {%- if messages and messages[0].role == "system" -%} {%- set system_message = messages[0] -%} {%- set conversation_messages = messages[1:] -%} {%- endif -%} {#- interleaved thinking을 위해 마지막 사용자 메시지 턴 가져오기 -#} {%- set ns = namespace(last_user_index=-1) %} {% for m in conversation_messages %} {%- if m.role == 'user' %} {% set ns.last_user_index = loop.index0 -%} {%- endif %} {%- endfor %} {#- 시스템 메시지 렌더링 -#} {{- ']~b[' ~ ']b]system' ~ '\n' }} {{- build_system_message(system_message) }} {#- 도구가 있는 경우 렌더링 -#} {%- if tools -%} {{- '\n\n' ~ '# Tools' ~ '\n' ~ '사용자의 질문에 답하기 위해 하나 이상의 도구를 호출할 수 있습니다.\nJSONSchema 형식으로 제공되는 도구는 다음과 같습니다:' ~ '\n' }} {{- '\n' ~ '' ~ '\n' }} {{- render_tool_namespace("functions", tools) }} {{- '' ~ '\n\n' }} {{- '도구를 호출할 때, XML 형식을 사용하여 도구를 호출하고 매개변수를 전달하세요:' ~ '\n' }} {{- '\n' ~ toolcall_begin_token }} param-value-1 param-value-2 ... {{- '\n' ~ toolcall_end_token }} {%- endif -%} {{- '[e[\n' }}

{#- 메시지 렌더링 -#} {%- set last_tool_call = namespace(name=none) -%} {%- for message in conversation_messages -%} {%- if message.role == 'assistant' -%} {#- 뒤따르는 사용자 메시지가 없는 경우에만 reasoning_content 렌더링 -#} {{- ']~b]ai' ~ '\n' }}

{%- set reasoning_content = '' %} {%- set content = visible_text(message.content) %} {%- if message.reasoning_content is string %} {%- set reasoning_content = message.reasoning_content %} {%- else %} {%- if ' Backpacking' in content %} {%- set reasoning_content = content.split(' Backpacking')[0].strip('\n').split(' Eurotrip')[-1].strip('\n') %} {%- set content = content.split(' Backpacking')[-1].strip('\n') %} {%- endif %} {%- endif %} {%- if reasoning_content and loop.index0 > ns.last_user_index -%} {{- ' Eurotrip' ~ '\n' ~ reasoning_content ~ '\n' ~ ' Backpacking' ~ '\n\n' }} {%- endif -%} {%- if content -%} {{- content }} {%- endif -%} {%- if message.tool_calls -%} {{- '\n'

원문 보기
원문 보기 (영어)
' -%}\n{%- set toolcall_end_token = '</minimax:tool_call>' -%}\n{#- Tool Rendering Functions ============================================== -#}\n{%- macro render_tool_namespace(namespace_name, tool_list) -%}\n{%- for tool in tool_list -%}\n<tool>{{ tool.function | tojson(ensure_ascii=False) }}</tool>\n{% endfor -%}\n{%- endmacro -%}\n{%- macro visible_text(content) -%}\n {%- if content is string -%}\n {{ content }}\n {%- elif content is iterable and content is not mapping -%}\n {%- for item in content -%}\n {%- if item is mapping and item.type == 'text' -%}\n {{- item.text }}\n {%- elif item is string -%}\n {{- item }}\n {%- endif -%}\n {%- endfor -%}\n {%- else -%}\n {{- content }}\n {%- endif -%}\n{%- endmacro -%}\n{#- System Message Construction ============================================ -#}\n{%- macro build_system_message(system_message) -%}\n {%- if system_message and system_message.content -%}\n {{- visible_text(system_message.content) }}\n {%- else -%}\n {%- if model_identity is not defined -%}\n {%- set model_identity = \"You are a helpful assistant. Your name is MiniMax-M2.7 and is built by MiniMax.\" -%}\n {%- endif -%}\n {{- model_identity }}\n {%- endif -%}\n \n {#- Handle current_date -#}\n {%- if system_message and system_message.current_date -%}\n {{- '\\n' ~ 'Current date: ' + system_message.current_date }}\n {%- endif -%}\n {#- Handle current_location -#}\n {%- if system_message and system_message.current_location -%}\n {{- '\\n' ~ 'Current location: ' + system_message.current_location }}\n {%- endif -%}\n{%- endmacro -%}\n{#- Main Template Logic ================================================= -#}\n{#- Extract system message (only first message if it's system) -#}\n{%- set system_message = none -%}\n{%- set conversation_messages = messages -%}\n{%- if messages and messages[0].role == \"system\" -%}\n {%- set system_message = messages[0] -%}\n {%- set conversation_messages = messages[1:] -%}\n{%- endif -%}\n{#- Get the last user message turn, for interleved thinking -#}\n{%- set ns = namespace(last_user_index=-1) %}\n{% for m in conversation_messages %}\n {%- if m.role == 'user' %}\n {% set ns.last_user_index = loop.index0 -%}\n {%- endif %}\n{%- endfor %}\n{#- Render system message -#}\n{{- ']~!b[' ~ ']~b]system' ~ '\\n' }}\n{{- build_system_message(system_message) }}\n{#- Render tools if available -#}\n{%- if tools -%}\n {{- '\\n\\n' ~ '# Tools' ~ '\\n' ~ 'You may call one or more tools to assist with the user query.\\nHere are the tools available in JSONSchema format:' ~ '\\n' }}\n {{- '\\n' ~ '<tools>' ~ '\\n' }}\n {{- render_tool_namespace(\"functions\", tools) }}\n {{- '</tools>' ~ '\\n\\n' }}\n{{- 'When making tool calls, use XML format to invoke tools and pass parameters:' ~ '\\n' }}\n{{- '\\n' ~ toolcall_begin_token }}\n<invoke name=\"tool-name-1\">\n<parameter name=\"param-key-1\">param-value-1</parameter>\n<parameter name=\"param-key-2\">param-value-2</parameter>\n...\n</invoke>\n{{- '\\n' ~ toolcall_end_token }}\n{%- endif -%}\n{{- '[e~[\\n' }}\n\n{#- Render messages -#}\n{%- set last_tool_call = namespace(name=none) -%}\n{%- for message in conversation_messages -%}\n {%- if message.role == 'assistant' -%}\n {#- Only render reasoning_content if no user message follows -#}\n {{- ']~b]ai' ~ '\\n' }}\n\n {%- set reasoning_content = '' %}\n {%- set content = visible_text(message.content) %}\n {%- if message.reasoning_content is string %}\n {%- set reasoning_content = message.reasoning_content %}\n {%- else %}\n {%- if '</think>' in content %}\n {%- set reasoning_content = content.split('</think>')[0].strip('\\n').split('<think>')[-1].strip('\\n') %}\n {%- set content = content.split('</think>')[-1].strip('\\n') %}\n {%- endif %}\n {%- endif %}\n {%- if reasoning_content and loop.index0 > ns.last_user_index -%}\n {{- '<think>' ~ '\\n' ~ reasoning_content ~ '\\n' ~ '</think>' ~ '\\n\\n' }}\n {%- endif -%}\n {%- if content -%}\n {{- content }}\n {%- endif -%}\n {%- if message.tool_calls -%}\n {{- '\\n' ~ toolcall_begin_token ~ '\\n' }}\n\n {%- for tool_call in message.tool_calls -%}\n {%- if tool_call.function %}\n {%- set tool_call = tool_call.function %}\n {%- endif %}\n {{- '<invoke name=\"' + tool_call.name + '\">' }}\n {% set _args = tool_call.arguments %}\n {%- for k, v in _args.items() %}\n {{- '<parameter name=\"' + k + '\">' }}\n {{- v | tojson(ensure_ascii=False) if v is not string else v }}\n {{- '</parameter>' }}\n {% endfor %}\n {{- '</invoke>' ~ '\\n' }}\n {%- endfor -%}\n \n {{- toolcall_end_token}}\n {%- set last_tool_call.name = message.tool_calls[-1].name -%}\n {%- else -%}\n {%- set last_tool_call.name = none -%}\n {%- endif -%}\n {{- '[e~[' ~ '\\n' }}\n \n {%- elif message.role == 'tool' -%}\n {%- if last_tool_call.name is none -%}\n {{- raise_exception(\"Message has tool role, but there was no previous assistant message with a tool call!\") }}\n {%- endif -%}\n {%- if loop.first or (conversation_messages[loop.index0 - 1].role != 'tool') -%}\n {{- ']~b]tool' }}\n {%- endif -%}\n {%- if message.content is string -%}\n {{- '\\n<response>' }}\n {{- message.content }}\n {{- '</response>' }}\n {%- else -%}\n {%- for tr in message.content -%}\n {{- '\\n<response>' }}\n {{- tr.output if tr.output is defined else (tr.text if tr.type == 'text' and tr.text is defined else tr) }}\n {{- '\\n</response>' }}\n {%- endfor -%}\n {%- endif -%}\n {%- if loop.last or (conversation_messages[loop.index0 + 1].role != 'tool') -%}\n {{- '[e~[\\n' -}}\n {%- endif -%}\n \n {%- elif message.role == 'user' -%}\n {{- ']~b]user' ~ '\\n' }}\n {{- visible_text(message.content) }}\n {{- '[e~[' ~ '\\n' }}\n {%- endif -%}\n{%- endfor -%}\n\n{#- Generation prompt -#}\n{%- if add_generation_prompt -%}\n{{- ']~b]ai' ~ '\\n' ~ '<think>' ~ '\\n' }}\n{%- endif -%}\n"},"createdAt":"2026-04-09T03:37:12.000Z","discussionsDisabled":false,"discussionsSorting":"recently-created","downloads":873,"downloadsAllTime":873,"id":"MiniMaxAI/MiniMax-M2.7","isLikedByUser":false,"availableInferenceProviders":[{"provider":"fireworks-ai","modelStatus":"live","providerStatus":"live","providerId":"accounts/fireworks/models/minimax-m2p7","task":"conversational","adapterWeightsPath":"model-00000-of-00130.safetensors","features":{"structuredOutput":false,"toolCalling":true},"isCheapestPricingOutput":false,"isFastestThroughput":true,"isModelAuthor":false,"tokensPerSecond":157.36111240647406},{"provider":"together","modelStatus":"live","providerStatus":"live","providerId":"MiniMaxAI/MiniMax-M2.7","task":"conversational","adapterWeightsPath":"model-00000-of-00130.safetensors","features":{"structuredOutput":true,"toolCalling":true},"isCheapestPricingOutput":true,"isFastestThroughput":false,"isModelAuthor":false,"tokensPerSecond":133.65681850664993,"pricingOutput":1.2}],"showHuggingChatEntry":true,"inference":"warm","lastModified":"2026-04-12T01:04:35.000Z","likes":258,"pipeline_tag":"text-generation","library_name":"transformers","librariesOther":[],"trackDownloads":true,"model-index":null,"private":false,"repoType":"model","gated":false,"tags":["transformers","safetensors","minimax_m2","text-generation","conversational","custom_code","license:other","endpoints_compatible","fp8","region:us"],"tag_objs":[{"id":"text-generation","label":"Text Generation","type":"pipeline_tag","subType":"nlp"},{"id":"transformers","label":"Transformers","type":"library"},{"id":"safetensors","label":"Safetensors","type":"library"},{"id":"minimax_m2","label":"minimax_m2","type":"other","clickable":true},{"id":"conversational","label":"conversational","type":"other","clickable":true},{"id":"custom_code","label":"custom_code","type":"other","clickable":true},{"id":"endpoints_compatible","label":"Inference Endpoints","type":"other","clickable":true},{"id":"fp8","label":"fp8","type":"other","clickable":true},{"id":"license:other","label":"other","type":"license"},{"type":"region","label":"🇺🇸 Region: US","id":"region:us"}],"transformersInfo":{"auto_model":"AutoModelForCausalLM","pipeline_tag":"te