~/tools / 모델 파일과 채팅 템플릿 / Hugging Face Chat Template Tester
Hugging Face Chat Template Tester — Hugging Face 채팅 템플릿을 렌더링해 프롬프트를 확인
Hugging Face 채팅 템플릿(Jinja)이나 모델의 tokenizer_config.json 전체를 붙여 넣고 messages와 tools를 더하면, transformers의 apply_chat_template(..., tokenize=False)가 만드는 프롬프트 텍스트를 그대로 볼 수 있습니다. 이 도구는 transformers와 같은 샌드박스 설정으로 Jinja2를 실행하므로 텍스트, 오류, 줄 번호가 Python과 같습니다. 데이터는 브라우저 밖으로 나가지 않습니다.
Jinja 템플릿(chat_template.jinja)이나, Hugging Face의 모델 파일에 있는 tokenizer_config.json 또는 chat_template.json 전체를 붙여 넣으세요.
메시지의 JSON 목록. apply_chat_template에 넘기는 목록과 같습니다.
도구 정의의 JSON 목록(JSON Schema). 도구를 쓰지 않으면 비워 두세요.
끝에 어시스턴트 차례의 시작을 붙여 모델이 답을 쓰게 합니다(템플릿이 지원하는 경우).
마지막 메시지를 닫지 않고 두어 모델이 이어서 쓰게 합니다(프리필). add_generation_prompt와 함께 쓸 수 없습니다.
apply_chat_template에 키워드 인수로 넘기는 그 밖의 값으로, {"enable_thinking": false}처럼 JSON 객체로 입력합니다. 템플릿이 읽는 변수는 출력 아래에 나열됩니다.
추가 옵션
transformers는 토크나이저의 특수 토큰을 템플릿에 넘깁니다. tokenizer_config.json을 붙여 넣으면 자동으로 채워집니다.
documents를 지원하는 템플릿(RAG)용: {"title": "…", "text": "…"} 같은 객체의 JSON 목록.
strftime_now()가 돌려주는 시각. 비워 두면 현재 시각을 씁니다.
프롬프트 텍스트
<|im_start|>system
You are a helpful assistant.
# Tools
You can call these functions:
<tools>
{"type": "function", "function": {"name": "get_weather", "description": "Get the current weather in a city.", "parameters": {"type": "object", "properties": {"city": {"type": "string", "description": "City name"}}, "required": ["city"]}}}
</tools>
To call one, reply with JSON inside <tool_call></tool_call>.<|im_end|>
<|im_start|>user
What's the weather in Paris?<|im_end|>
<|im_start|>assistant
<tool_call>
{"name": "get_weather", "arguments": {"city": "Paris"}}
</tool_call><|im_end|>
<|im_start|>user
<tool_response>
{"temperature": 22}
</tool_response><|im_end|>
<|im_start|>assistant
이 템플릿에 대해
- 읽는 변수
- apply_chat_template가 설정하는 것: add_generation_prompt, messages, tools특수 토큰: 없음기타: 없음
- {% generation %} 사용
- 아니요
Python에서 확인
transformers와 비교하려면 이것을 실행하세요. MODEL_ID를 모델로 바꾸거나, 자신의 템플릿을 chat_template=로 넘기세요.
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("MODEL_ID")
messages = [
{'role': 'system', 'content': 'You are a helpful assistant.'},
{'role': 'user', 'content': "What's the weather in Paris?"},
{'role': 'assistant', 'content': '', 'tool_calls': [{'type': 'function', 'function': {'name': 'get_weather', 'arguments': {'city': 'Paris'}}}]},
{'role': 'tool', 'name': 'get_weather', 'content': '{"temperature": 22}'},
]
tools = [
{'type': 'function', 'function': {'name': 'get_weather', 'description': 'Get the current weather in a city.', 'parameters': {'type': 'object', 'properties': {'city': {'type': 'string', 'description': 'City name'}}, 'required': ['city']}}},
]
text = tokenizer.apply_chat_template(
messages,
tools=tools,
add_generation_prompt=True,
tokenize=False,
)
print(text)출력은 토큰화 이전의 텍스트입니다. transformers는 이후 add_special_tokens=False로 토큰화하므로, 특수 토큰은 템플릿이 쓴 자리에만 나타납니다.
tools가 주어지고 모델에 tool_use라는 이름의 템플릿이 있으면 transformers는 그것을 씁니다. 이름으로 템플릿을 고를 수도 있습니다.
messages, tools, documents는 Python의 json 모듈처럼 읽습니다. 정수는 int, 소수점이 있는 수는 float가 되며, 템플릿이 출력하는 방식이 달라질 수 있습니다.
2026-11-09에 transformers 5.22.2, Jinja2 3.1.6(Python 3.14)로 확인했습니다. transformers: 채팅 템플릿 · transformers 소스 코드
모든 것이 브라우저 안에서 실행됩니다. 붙여 넣은 내용은 전송되거나 저장되지 않습니다.
Hugging Face의 오픈 모델 대부분에는 채팅 템플릿이 들어 있습니다. 메시지 목록을 모델이 실제로 읽는 텍스트로 바꾸는 작은 Jinja 프로그램입니다. 공백 하나가 빠지거나, BOS 토큰이 두 번 들어가거나, 생성 프롬프트가 틀리면 모델에 보이는 내용이 달라지는데, 템플릿은 실행해 보지 않고는 읽기 어렵습니다. 이 도구는 transformers와 같은 방식으로 템플릿을 실행합니다. 우리는 Jinja2 3.1.6을 JavaScript로 옮겼습니다. 렉서, 파서, 변수가 어디에서 보이는지에 대한 규칙, 상수 접기, transformers가 쓰는 샌드박스, 모든 내장 필터와 테스트, 그리고 문자열·숫자·정렬·오류 메시지에 대한 Python 자체의 동작입니다. 그 위에서 transformers 5.22.2의 apply_chat_template를 따라 bos_token 같은 특수 토큰, tools가 주어졌을 때의 tool_use 템플릿, add_generation_prompt, continue_final_message, documents, reasoning_content, {% generation %} 구간을 처리합니다. 오픈 모델 39개(Qwen, Llama, Mistral, Gemma, Phi, DeepSeek, gpt-oss 등)의 채팅 템플릿을 15종류의 대화로 렌더링했고, 585개 결과가 모두 transformers와 일치했습니다. 그 밖의 20,000개가 넘는 테스트 템플릿도 오류와 줄 번호까지 일치했습니다. 예외는 random 필터를 쓰는 몇 개뿐이며, 이 필터의 결과는 Python에서도 무작위입니다.
이럴 때 사용
- 파인튜닝하거나 서비스하기 전에 모델이 받는 프롬프트를 그대로 확인하기: BOS와 EOS 토큰, 공백, 줄바꿈, 생성 프롬프트
- enable_thinking처럼 템플릿이 읽는 스위치를 찾고 무엇이 바뀌는지 확인하기
- 직접 쓰고 있는 채팅 템플릿 디버깅하기: 오류와 줄 번호, tools, documents, continue_final_message
사용법
- 채팅 템플릿이나 모델의 tokenizer_config.json 또는 chat_template.json 전체를 붙여 넣거나 예시를 고릅니다.
- messages와 tools(Python에서 넘기는 것과 같은 JSON 목록)를 편집하고, add_generation_prompt 등의 옵션을 설정합니다.
- 프롬프트 텍스트와 템플릿이 쓰는 변수를 읽고, 같은 입력을 transformers에서 확인하는 Python 코드를 복사합니다.
FAQ
결과는 apply_chat_template와 같은가요?
apply_chat_template(..., tokenize=False)와 같은, 토큰화 이전의 텍스트입니다. 특수 토큰, add_generation_prompt, continue_final_message, tools, documents는 transformers 5.22.2와 같게 처리합니다. 텍스트를 토큰 IDs로 바꾸지는 않습니다.
bos_token과 eos_token은 어디에서 오나요?
Python에서는 토크나이저에서 옵니다. tokenizer_config.json을 붙여 넣으면 도구가 거기에서 읽습니다. 그렇지 않으면 "추가 옵션"에 입력하세요.
{% generation %}은 무엇을 하나요?
일부 템플릿은 어시스턴트의 답을 {% generation %} … {% endgeneration %}로 감쌉니다. transformers는 이 구간을 return_assistant_tokens_mask에 사용하며, 예를 들어 어시스턴트의 토큰만으로 학습시킬 수 있습니다. 도구는 출력에서 이 구간을 강조 표시합니다.
vLLM, llama.cpp 등 다른 서버에서도 같은 텍스트가 나오나요?
다른 소프트웨어는 같은 템플릿을 다른 엔진이나 다른 설정으로 렌더링할 수 있어서 출력이 다를 수 있습니다. 이 도구는 transformers를 따릅니다.
enable_thinking 같은 변수가 "기타"에 나오는 이유는 무엇인가요?
템플릿은 그 변수를 읽지만 apply_chat_template는 값을 설정하지 않습니다. Python에서 enable_thinking=False를 넘기듯, 추가 변수(예: {"enable_thinking": false})로 넘기면 출력이 바뀝니다.
내 템플릿이 어딘가로 전송되나요?
아니요. 모든 것이 브라우저 안에서 실행됩니다.