IBM이 오픈소스 AI 생태계인 Hugging Face에 '그라나이트 4.1(Granite 4.1) 8B' 모델의 설정 정보를 공개했습니다. 공개된 데이터에는 외부 도구(Tools) 호출 및 문서(Document) 기반 검색(RAG)을 지원하는 정교한 시스템 프롬프트와 Jinja 템플릿이 포함되어 있습니다. 이는 오픈소스 모델이 단순 텍스트 생성을 넘어 기업의 실무 시스템과 안전하게 연동하는 에이전트(Agent) 역할을 수행할 수 있음을 보여주는 중요한 의미를 갖습니다.
번역된 본문
이 데이터는 AI 모델의 텍스트 생성 및 처리 방식을 결정하는 토크나이저(Tokenizer)와 채팅 템플릿(Chat Template)의 설정 코드 일부입니다.
1. 특수 토큰(Special Tokens) 설정
시스템은 모델이 문장의 끝을 인식하는 'eos_token(<|end_of_text|>)'과 문맥을 채우는 'pad_token(<|pad|>)', 알 수 없는 단어를 의미하는 'unk_token(<|unk|>)' 등을 사용하여 텍스트를 처리합니다.
2. 도구(Tool) 연동 지침
모델이 사용자의 요청을 해결하기 위해 외부 API나 기능을 호출(Tool calling)할 수 있도록 안내합니다. AI는 XML 형태의 <tools> 태그 안에 제공된 도구 목록을 확인하고, BeenCalled 형식의 JSON 객체로 함수 이름과 인자를 반환합니다. 만약 요청에 맞는 도구가 없다면 사용자에게 그 사실을 알리도록 프로그래밍되어 있습니다.
3. 문서(Document) 기반 검색(RAG) 지침
모델이 특정 문서를 바탕으로 답변해야 하는 상황을 위한 지침입니다. <documents> 태그 내에 제공된 데이터를 엄격하게 준수하여 답변을 작성하며, 문서에 질문에 대한 정보가 없을 경우 추측하지 않고 데이터 부족으로 답변할 수 없음을 명확히 고지합니다.
4. 동적 프롬프트 생성 로직 (Jinja 템플릿)
시스템은 대화 메시지를 분석해 시스템 지시사항을 동적으로 구성합니다. 사용자가 제공한 시스템 프롬프트가 있다면 이를 기반으로 삼고, 사용 가능한 '도구(Tools)'나 '문서(Documents)' 데이터가 감지되면 해당 지침들을 시스템 프롬프트에 자동으로 이어 붙입니다. 마지막으로 각 메시지의 역할(system, user, assistant 등)을 식별하기 위해 <|start_of_role|> 및 <|end_of_role|> 같은 태그를 사용하여 모델이 안전하고 정확하게 대화 맥락을 이해할 수 있도록 구성되어 있습니다.
","eos_token":"<|end_of_text|>","pad_token":"<|pad|>","unk_token":"<|unk|>"},"chat_template_jinja":"{%- set tools_system_message_prefix = 'You are a helpful assistant with access to the following tools. You may call one or more tools to assist with the user query.\\n\\nYou are provided with function signatures within <tools></tools> XML tags:\\n<tools>' %}\n{%- set tools_system_message_suffix = '\\n</tools>\\n\\nFor each tool call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\\n<tool_call>\\n{\\\"name\\\": <function-name>, \\\"arguments\\\": <args-json-object>}\\n</tool_call>. If a tool does not exist in the provided list of tools, notify the user that you do not have the ability to fulfill the request.' %}\n{%- set documents_system_message_prefix = 'You are a helpful assistant with access to the following documents. You may use one or more documents to assist with the user query.\\n\\nYou are given a list of documents within <documents></documents> XML tags:\\n<documents>' %}\n{%- set documents_system_message_suffix = '\\n</documents>\\n\\nWrite the response to the user\\'s input by strictly aligning with the facts in the provided documents. If the information needed to answer the question is not available in the documents, inform the user that the question cannot be answered based on the available data.' %}\n{%- if available_tools is defined and available_tools %}\n {%- set tools = available_tools %}\n{%- endif %}\n{%- set ns = namespace(tools_system_message=tools_system_message_prefix,\n documents_system_message=documents_system_message_prefix,\n system_message=''\n ) %}\n{%- if tools %}\n {%- for tool in tools %}\n {%- set ns.tools_system_message = ns.tools_system_message + '\\n' + (tool | tojson) %}\n {%- endfor %}\n {%- set ns.tools_system_message = ns.tools_system_message + tools_system_message_suffix %}\n{%- else %}\n {%- set ns.tools_system_message = '' %}\n{%- endif %}\n{%- if documents %}\n {%- for document in documents %}\n {%- set ns.documents_system_message = ns.documents_system_message + '\\n' + (document | tojson) %}\n {%- endfor %}\n {%- set ns.documents_system_message = ns.documents_system_message + documents_system_message_suffix %}\n{%- else %}\n {%- set ns.documents_system_message = '' %}\n{%- endif %}\n{%- if messages[0].role == 'system' %}\n {%- if messages[0].content is string %}\n {%- set ns.system_message = messages[0].content %}\n {%- elif messages[0].content is iterable %}\n {%- for entry in messages[0].content %}\n {%- if entry.type== 'text' %}\n {%- if ns.system_message != '' %}\n {%- set ns.system_message = ns.system_message + '\\n' %}\n {%- endif %}\n {%- set ns.system_message = ns.system_message + entry.text %}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {%- if tools and documents %}\n {%- set ns.system_message = ns.system_message + '\\n\\n' + ns.tools_system_message + '\\n\\n' + ns.documents_system_message %}\n {%- elif tools %}\n {%- set ns.system_message = ns.system_message + '\\n\\n' + ns.tools_system_message %}\n {%- elif documents %}\n {%- set ns.system_message = ns.system_message + '\\n\\n' + ns.documents_system_message %}\n {%- endif %}\n{%- else %}\n {%- if tools and documents %}\n {%- set ns.system_message = ns.tools_system_message + '\\n\\n' + ns.documents_system_message %}\n {%- elif tools %}\n {%- set ns.system_message = ns.tools_system_message %}\n {%- elif documents %}\n {%- set ns.system_message = ns.documents_system_message %}\n {%- endif %}\n{%- endif %}\n{%- if ns.system_message %}\n {{- '<|start_of_role|>system<|end_of_role|>' + ns.system_message + '<|end_of_text|>\\n' }}\n{%- endif %}\n{%- for message in messages %}\n {%- set content = namespace(val='') %}\n {%- if message.content is string %}\n {%- set content.val = message.content %}\n {%- else %}\n {%- if message.content is iterable %}\n {%- for entry in message.content %}\n {%- if entry.type== 'text' %}\n {%- if content.val != '' %}\n {%- set content.val = content.val + '\\n' %}\n {%- endif %}\n {%- set content.val = content.val + entry.text %}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n {%- endif %}\n {%- if (message.role == 'user') or (message.role == 'system' and not loop.first) %}\n {{- '<|start_of_role|>' + message.role + '<|end_of_role|>' + content.val + '<|end_of_text|>\\n' }}\n {%- elif message.role == 'assistant' %}\n {{- '<|start_of_role|>' + message.role + '<|end_of_role|>' + content.val }}\n {%- if message.tool_calls %}\n {%- for tool_call in message.tool_calls %}\n {%- if (loop.first and content.val) or (not loop.first) %}\n {{- '\\n' }}\n {%- endif %}\n {%- if tool_call.function %}\n {%- set tool_call = tool_call.function %}\n {%- endif %}\n {{- '<tool_call>\\n{\"name\": \"' }}\n {{- tool_call.name }}\n {{- '\", \"arguments\": ' }}\n {%- if tool_call.arguments is string %}\n {{- tool_call.arguments }}\n {%- else %}\n {{- tool_call.arguments | tojson }}\n {%- endif %}\n {{- '}\\n</tool_call>' }}\n {%- endfor %}\n {%- endif %}\n {{- '<|end_of_text|>\\n' }}\n {%- elif message.role == 'tool' %}\n {%- if loop.first or (messages[loop.index0 - 1].role != 'tool') %}\n {{- '<|start_of_role|>user<|end_of_role|>' }}\n {%- endif %}\n {{- '\\n<tool_response>\\n' }}\n {{- content.val }}\n {{- '\\n</tool_response>' }}\n {%- if loop.last or (messages[loop.index0 + 1].role != 'tool') %}\n {{- '<|end_of_text|>\\n' }}\n {%- endif %}\n {%- endif %}\n{%- endfor %}\n{%- if add_generation_prompt %}\n {{- '<|start_of_role|>assistant<|end_of_role|>' }}\n{%- endif %}"},"createdAt":"2026-04-06T13:18:47.000Z","discussionsDisabled":false,"discussionsSorting":"recently-created","downloads":1220,"downloadsAllTime":1220,"id":"ibm-granite/granite-4.1-8b","isLikedByUser":false,"availableInferenceProviders":[],"showHuggingChatEntry":false,"inference":"","lastModified":"2026-04-21T22:54:58.000Z","likes":31,"pipeline_tag":"text-generation","library_name":"transformers","librariesOther":[],"trackDownloads":true,"model-index":null,"private":false,"repoType":"model","gated":false,"tags":["transformers","safetensors","granite","text-generation","language","granite-4.1","conversational","arxiv:0000.00000","license:apache-2.0","endpoints_compatible","deploy:azure","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":"granite","label":"granite","type":"other","clickable":true},{"id":"language","label":"language","type":"other","clickable":true},{"id":"granite-4.1","label":"granite-4.1","type":"other","clickable":true},{"id":"conversational","label":"conversational","type":"other","clickable":true},{"id":"endpoints_compatible","label":"Inference Endpoints","type":"other","clickable":true},{"id":"arxiv:0000.00000","label":"arxiv:0000.00000","type":"arxiv","extra":{}},{"id":"license:apache-2.0","label":"apache-2.0","type":"license"},{"id":"deploy:azure","label":"azure","type":"deploy"},{"type":"region","label":"🇺🇸 Region: US","id":"region:us"}],"transformersInfo":{"auto_model":"AutoModelForCausalLM","pipeline_tag":"text-generation","processor":"AutoTokenizer"},"widgetData":[{"text":"Hi, what can you help me with?"},{"text":"What is 84 * 3 / 2?"},{"text":"Tell me an interesting fact about the universe!"},{"text":"Explain quantum computing in simple terms."}],"safetensors":{"parameters":{"BF16":8791592960},"total":8791592960,"sharded":true,"totalFileSize":17583258045},"hasBlockedOids":false,"region":"us","isQuantized":false},"discussionsStats":{"closed":0,"open":1,"total":1},"query":{},"inferenceContextData":{"billableEntities":[],"entityName2Providers":{}},"hasQuantizations":true}"> Granite-4.1-8B Model Summary: Granite-4.1-8B is a 8B parameter long-context instruct model finetuned from Granite-4.1-8B-Base using a combination of open source instruction datasets with permissive license and internally collected synthetic datasets. G