์๋ฆฌ์ฆ: LLM Tool Calling ๋ด๋ถ ์๋ฆฌ๋ถํฐ ์์ด์ ํธ ์ง์ ๊ตฌํ๊น์ง
์ด ์๋ฆฌ์ฆ๋ ์ฌ์ฉ์์ ์์ฐ์ด ํ ์ค์ด tool ์คํ์ผ๋ก ๋ฐ๋๋ ๋ด๋ถ ์ฒ๋ฆฌ ๊ณผ์ ์ ๋จ๊ณ๋ณ๋ก ํด๋ถํ๊ณ , ์ต์ข ์ ์ผ๋ก ์คํ์์ค ๋ชจ๋ธ + ์์ฒด middleware๋ก ๋๋ง์ ์์ด์ ํธ๋ฅผ ์ง์ ๊ตฌํํ๋ ๊ฒ๊น์ง ๋๋ฌํ๋ ๊ณผ์ ์ด๋ค.
| ํธ | ๋ด์ฉ | ํต์ฌ |
|---|---|---|
| 1ํธ | ์ ์ฒด ์กฐ๊ฐ๋ | ์์ฐ์ด โ tool ์คํ๊น์ง 5๊ฐ ๋ ์ด์ด์ ์กด์ฌ๋ฅผ ํ์ธ |
| 2ํธ (๋ณธ๋ฌธ) | Chat Template | JSON์ด ๋ชจ๋ธ์ ์ง์ ๋ค์ด๊ฐ์ง ์๋๋ค |
| 3ํธ | Tokenization | ๋ชจ๋ธ์ ํ ์คํธ๋ฅผ ์ฝ์ง ๋ชปํ๋ค - ํ ํฐ ID์ control token |
| 4ํธ | ๋ชจ๋ธ ์ถ๋ก | โtool์ ์ธ๊น ๋ง๊นโ ํ๋จ๊ณผ constrained decoding |
| 5ํธ | Tool ์คํ | tool_use๋ฅผ ๋ฐ์ ํด๋ผ์ด์ธํธ์ ์คํ ๋ฃจํ |
| 6ํธ | Native vs Non-native | ๊ฐ์ ๊ธฐ๋ฅ, ๋ค๋ฅธ ๊ตฌ์กฐ โ Middleware |
| 7ํธ | Middleware ๋ง๋ค๊ธฐ | ํ๋กฌํํธ ์กฐ๋ฆฝ + ์ถ๋ ฅ ํ์ฑ + ์คํ ๋ฃจํ ์ง์ ๊ตฌํ |
| 8ํธ | ์คํ์์ค ๋ชจ๋ธ ๋ก์ปฌ ๊ตฌ์ถ | Ollama/vLLM์ผ๋ก ๋ก์ปฌ LLM ์๋น |
| 9ํธ | ๋๋ง์ ์์ด์ ํธ | ๋ชจ๋ธ + Middleware = ์์ด์ ํธ ์์ฑ |
- Chat Template์ API๊ฐ ๋ฐ์ tools JSON๊ณผ messages๋ฅผ ๋ชจ๋ธ์ด ์ดํดํ ์ ์๋ ํ๋์ ๊ธด ํ๋กฌํํธ ํ ์คํธ๋ก ์กฐ๋ฆฝํ๋ ๋ณํ ๋ ์ด์ด
- LLM์ JSON์ ์ง์ ํ์ฑํ์ง ์์ผ๋ฉฐ, ๋ชจ๋ ์ ๋ ฅ์ ํ ์คํธ ๋ฌธ์์ด๋ก ๋ณํ๋์ด ๋ชจ๋ธ์ ์ ๋ฌ๋๋ ๊ตฌ์กฐ์ ์ ์ฒ๋ฆฌ ๊ณผ์
- ๋ฒค๋๋ง๋ค ๋ณํ ํํ๊ฐ ๋ค๋ฅด๋ฉฐ(Claude๋ ์์คํ ํ๋กฌํํธ, OpenAI๋ ๋น๊ณต๊ฐ ํ ํ๋ฆฟ, Gemini๋ function_declarations, Mistral์ control token, GLM์ XML ํ๊ทธ), ์ด๊ฒ์ด ๋ชจ๋ธ์ด ์ค์ ๋ก ๋ณด๋ ์ ๋ ฅ์ ์ค์ฒด
ํด๋น ๊ฐ๋ ์ด ํ์ํ ์ด์
- 1ํธ์์ 5๊ฐ ๋ ์ด์ด ์ค ์ฒซ ๋ฒ์งธ๊ฐ Chat Template์ด๋ผ๋ ๊ฒ์ ํ์ธํ๋ค. ํ์ง๋ง โJSON์ด ํ ์คํธ๋ก ๋ณํ๋๋คโ๋ ๊ฒ์ด ๊ตฌ์ฒด์ ์ผ๋ก ์ด๋ค ์๋ฏธ์ธ์ง๋ ์์ง ๋ธ๋๋ฐ์ค๋ค
- tool ์ ์๋ฅผ ์ ์์ฑํ๋ ค๋ฉด, ๊ทธ๊ฒ์ด ๋ชจ๋ธ์๊ฒ ์ด๋ค ํํ๋ก ๋ณด์ด๋์ง ์์์ผ ํ๋ค. description์ด ๊ธธ๋ฉด ํ ํฐ์ ๋ง์ด ์๋นํ๋ ์ด์ ๋ ์ฌ๊ธฐ์ ์๋ค
- ๋ฒค๋๋ง๋ค ๋ณํ ํํ๊ฐ ๋ค๋ฅด๋ค๋ ๊ฒ์, ๊ฐ์ tool ์ ์๋ ๋ชจ๋ธ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ํด์๋ ์ ์๋ค๋ ๋ป์ด๋ค
AS-IS
sequenceDiagram autonumber box ๊ฐ๋ฐ์ ์์ญ participant Dev as ๊ฐ๋ฐ์ end box AI ์๋น์ค ์์ญ participant API as API ์๋ฒ participant LLM as LLM end Dev->>API: tools JSON + messages JSON Note over API,LLM: JSON์ด ๊ทธ๋๋ก ๋ชจ๋ธ์ ๋ค์ด๊ฐ๋ค? LLM-->>API: tool_use ์๋ต
TO-BE
sequenceDiagram autonumber box ๊ฐ๋ฐ์ ์์ญ participant Dev as ๊ฐ๋ฐ์ end box AI ์๋น์ค ์์ญ participant API as API ์๋ฒ participant CT as Chat Template participant LLM as LLM end Dev->>API: tools JSON + messages JSON API->>CT: JSON ๋ถํด CT->>LLM: ํ๋์ ๊ธด ํ๋กฌํํธ ํ ์คํธ Note over CT,LLM: "In this environment you have access to..." LLM-->>API: tool_use ์๋ต
API JSON์ ๋ชจ๋ธ์ ์ง์ ๋ค์ด๊ฐ์ง ์๋๋ค
๊ฐ๋ฐ์๊ฐ API์ ๋ณด๋ด๋ ๊ฒ์ structured JSON์ด๋ค:
const response = await anthropic.messages.create({
model: "claude-opus-4-6",
tools: [{
name: "get_weather",
description: "Get the current weather in a given location",
input_schema: {
type: "object",
properties: {
location: { type: "string", description: "The city and state" }
},
required: ["location"]
}
}],
messages: [{ role: "user", content: "์์ธ ๋ ์จ ์๋ ค์ค" }]
});ํ์ง๋ง LLM์ JSON ํ์๊ฐ ์๋๋ค. ์ด JSON์ API ์๋ฒ์์ Chat Template์ ํตํด ํ๋์ ํ ์คํธ ๋ฌธ์์ด๋ก ๋ณํ๋ ํ ๋ชจ๋ธ์ ์ ๋ฌ๋๋ค.
Claude์ Chat Template - ์์คํ ํ๋กฌํํธ ์ฝ์
Anthropic์ ๊ณต์ ๋ฌธ์์์ ์ด ๋ณํ ๊ฒฐ๊ณผ๋ฅผ ๊ณต๊ฐํ๊ณ ์๋ค. tools ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ๋ฉด API๊ฐ ์๋์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ์์คํ
ํ๋กฌํํธ๋ฅผ ๊ตฌ์ฑํ๋ค:
In this environment you have access to a set of tools you can use to answer the user's question.
{{ FORMATTING INSTRUCTIONS }}
String and scalar parameters should be specified as is, while lists and objects should use JSON format.
Note that spaces for string values are not stripped.
The output is not expected to be valid XML and is parsed with regular expressions.
Here are the functions available in JSONSchema format:
{{ TOOL DEFINITIONS IN JSON SCHEMA }}
{{ USER SYSTEM PROMPT }}
{{ TOOL CONFIGURATION }}์ฆ, ๊ฐ๋ฐ์๊ฐ ๋ณด๋ธ tools JSON ๋ฐฐ์ด์ด {{ TOOL DEFINITIONS IN JSON SCHEMA }} ์๋ฆฌ์ ํ
์คํธ๋ก ์ฝ์
๋๋ค. ๋ชจ๋ธ ์
์ฅ์์๋ ์ด๊ฒ์ด ๊ทธ๋ฅ ์์คํ
ํ๋กฌํํธ์ ์ผ๋ถ ํ
์คํธ์ผ ๋ฟ์ด๋ค.
์ด๊ฒ์ด ์๋ฏธํ๋ ๊ฒ:
- tool์
description์ด ๊ธธ์๋ก ์์คํ ํ๋กฌํํธ๊ฐ ๊ธธ์ด์ง๊ณ , ์ ๋ ฅ ํ ํฐ์ด ์ฆ๊ฐํ๋ค - Anthropic ๊ณต์ ๋ฌธ์์ ๋ฐ๋ฅด๋ฉด tool use ์ ๋ชจ๋ธ๋ณ๋ก 313~530๊ฐ์ ์ถ๊ฐ ์์คํ ํ๋กฌํํธ ํ ํฐ์ด ์๋น๋๋ค (tool ์ ์ ํ ํฐ ์ ์ธ)
- โ๋ชจ๋ธ์ด tool์ ์ดํดํ๋คโ๋ ๊ฒ์ ๋ง๋ฒ์ด ์๋๋ผ, ์์คํ ํ๋กฌํํธ์ ์ ํ ์ง์๋ฅผ ๋ฐ๋ฅด๋ ๊ฒ์ด๋ค
OpenAI(GPT)์ Chat Template - ๋น๊ณต๊ฐ ์์คํ ํ๋กฌํํธ
OpenAI๋ Claude์ ๋์ผํ๊ฒ tool ์ ์๋ฅผ ์์คํ ๋ฉ์์ง์ ์ฝ์ ํ์ง๋ง, ์ ํํ ๋ด๋ถ ํฌ๋งท์ ๊ณต๊ฐํ์ง ์๋๋ค.
๊ณต์์ ์ผ๋ก ํ์ธ๋ ๊ฒ:
- tool ์ ์(description, param types ๋ฑ)๊ฐ ํ๋กฌํํธ์ ์ผ๋ถ๋ก ๋ชจ๋ธ์ ์ ๋ฌ๋๋ค
- ํน์ ํ ํฐ์ผ๋ก tool ์ ์์ ์์๊ณผ ๋์ ๊ตฌ๋ถํ๋ ๊ฒ์ผ๋ก ์ถ์ ๋์ง๋ง, ์ ํํ ํ ํฐ์ ๋น๊ณต๊ฐ
- tool ์ ์๋ ์ ๋ ฅ ํ ํฐ์ผ๋ก ๊ณ์ฐ๋์ด ๊ณผ๊ธ๋๋ค
GPT-4.1 ๊ณต์ ๊ฐ์ด๋์์๋ tool ์คํค๋ง๋ฅผ ์์คํ
ํ๋กฌํํธ์ ์ง์ ์ฝ์
ํ๋ ๋์ API์ tools ํ๋๋ฅผ ์ฌ์ฉํ ๊ฒ์ ๊ถ์ฅํ๋ค. API๋ฅผ ํตํด ์ ๋ฌํ๋ฉด ๋ชจ๋ธ์ด ํ์ต๋ ๋ด๋ถ ํฌ๋งท์ ๋ง๊ฒ ๋ณํ๋๊ธฐ ๋๋ฌธ์, ์๋ ์ฝ์
๋๋น SWE-bench์์ 2% ๋์ ์ฑ๋ฅ์ ๋ณด์๋ค.
Gemini(Google)์ Chat Template - function_declarations
Gemini๋ OpenAPI ์คํค๋ง ํธํ ํ์์ผ๋ก tool์ ์ ์ํ๋ค:
const response = await ai.models.generateContent({
model: "gemini-3-flash",
contents: "์์ธ ๋ ์จ ์๋ ค์ค",
config: {
tools: [{
functionDeclarations: [{
name: "get_weather",
description: "Get current weather by city name",
parameters: {
type: "object",
properties: {
city: { type: "string", description: "City name" }
},
required: ["city"]
}
}]
}]
}
});Gemini๋ ๋ด๋ถ ๋ณํ ํฌ๋งท์ ๊ณต๊ฐํ์ง ์์ง๋ง, Gemini 2.5/3 ์๋ฆฌ์ฆ๋ ๋ด๋ถ โthinkingโ ๊ณผ์ ์ ํตํด ์ด๋ค ํจ์๋ฅผ ํธ์ถํ ์ง, ์ด๋ค ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ ์ง ํ๋จํ๋ค.
Mistral์ Chat Template - Control Token
Mistral(ํ๋์ค AI ๊ธฐ์ , ๋ํ ๋ชจ๋ธ: Mistral Large, Mixtral, Codestral)์ ๋ด๋ถ ํฌ๋งท์ ๊ฐ์ฅ ์์ธํ๊ฒ ๊ณต๊ฐํ ๋ฒค๋๋ค. ํ ์คํธ๊ฐ ์๋ control token์ผ๋ก tool ์ ์ ์์ญ์ ๊ฐ์ผ๋ค:
<s>[AVAILABLE_TOOLS] [{"type": "function", "function": {"name": "calculator",
"description": "Performs mathematical calculations", "parameters": {"type":
"object", "properties": {"operation": {"type": "string"}},
"required": ["operation"]}}}] [/AVAILABLE_TOOLS]
[INST] What's 2+2? [/INST]
[TOOL_CALLS] [{"name": "calculator", "arguments": {"operation": "2+2"}}]</s>
[TOOL_RESULTS] [{"name": "calculator", "content": 4}] [/TOOL_RESULTS]
2+2=4</s>์ฌ๊ธฐ์ [AVAILABLE_TOOLS], [TOOL_CALLS], [TOOL_RESULTS]๋ ์ผ๋ฐ ํ
์คํธ๊ฐ ์๋๋ผ control token์ด๋ค. ์ด ์ฐจ์ด๋ 3ํธ(Tokenization)์์ ์์ธํ ๋ค๋ฃฌ๋ค.
ํต์ฌ์ ๋์ผํ๋ค: JSON์ด ๊ทธ๋๋ก ๋ชจ๋ธ์ ๋ค์ด๊ฐ๋ ๊ฒ์ด ์๋๋ผ, ํน์ ํํ์ ํ ์คํธ ์ํ์ค๋ก ๋ณํ๋๋ค.
GLM์ Chat Template - ํน์ ํ ํฐ + XML ํ๊ทธ
GLM(์ค๊ตญ ์นญํ๋ THUDM ํ, ๋ํ ๋ชจ๋ธ: GLM-4, ChatGLM, GLM-4.6)์ ํน์ ํ ํฐ์ผ๋ก ์ญํ ์ ๊ตฌ๋ถํ๊ณ , XML ํ๊ทธ๋ก tool์ ์ ์ํ๋ค:
[gMASK]<sop><|system|>
# Tools
You may call one or more functions to assist with the user query.
You are provided with function signatures within <tools></tools> XML tags:
<tools>
{"type": "function", "function": {"name": "get_weather",
"description": "Get current weather by city name",
"parameters": {"type": "object", "properties":
{"city": {"type": "string"}}, "required": ["city"]}}}
</tools>
For each function call, output the function name and arguments within
the following XML format:
<tool_call>{function_name}<arg_key>{key}</arg_key>
<arg_value>{value}</arg_value></tool_call>
<|user|>
์์ธ ๋ ์จ ์๋ ค์ค
<|assistant|>
<think>์ฌ๊ธฐ์:
[gMASK]<sop>- ๋ชจ๋ธ์ ์์ ํน์ ํ ํฐ<|system|>,<|user|>,<|assistant|>- ์ญํ ๊ตฌ๋ถ ํน์ ํ ํฐ<tools>...</tools>- tool ์ ์ ์์ญ<tool_call>...<arg_key>...<arg_value>...</tool_call>- tool ํธ์ถ ์ถ๋ ฅ ํ์<think>- ๋ชจ๋ธ์ ์ฌ๊ณ ๊ณผ์ ์์
๋ฒค๋๋ณ ๋น๊ต
์ธ ๋ฒค๋ ๋ชจ๋ โJSON โ ํ ์คํธ ๋ณํโ์ด๋ผ๋ ๋์ผํ ๋ชฉ์ ์ ์ํํ์ง๋ง, ๋ฐฉ์์ด ๋ค๋ฅด๋ค:
| Claude | OpenAI (GPT) | Gemini | Mistral | GLM | |
|---|---|---|---|---|---|
| tool ์ ์ ์์น | ์์คํ ํ๋กฌํํธ ํ ์คํธ | ์์คํ ๋ฉ์์ง ์ฝ์ (๋น๊ณต๊ฐ) | ๋น๊ณต๊ฐ | [AVAILABLE_TOOLS] control token | <tools> XML ํ๊ทธ |
| ์ญํ ๊ตฌ๋ถ | API ๋ ๋ฒจ์์ ์ฒ๋ฆฌ | API ๋ ๋ฒจ์์ ์ฒ๋ฆฌ | API ๋ ๋ฒจ์์ ์ฒ๋ฆฌ | [INST] ํ๊ทธ | <|system|> <|user|> ํน์ ํ ํฐ |
| tool call ์ถ๋ ฅ | JSON (์ ๊ท์ ํ์ฑ) | JSON (๋น๊ณต๊ฐ ํ์ฑ) | JSON (functionCall) | [TOOL_CALLS] + JSON | <tool_call> XML ํ๊ทธ |
| ๊ฒฝ๊ณ ํ์ | ํ ์คํธ ์ง์๋ฌธ | ํน์ ํ ํฐ (์ถ์ ) | ๋น๊ณต๊ฐ | control token (injection ๋ถ๊ฐ) | ํน์ ํ ํฐ + XML |
| ๋ด๋ถ ํฌ๋งท ๊ณต๊ฐ | ํ ํ๋ฆฟ ๊ตฌ์กฐ ๊ณต๊ฐ | ๋น๊ณต๊ฐ | ๋น๊ณต๊ฐ | ํ ํฐ ์์ค ๊ณต๊ฐ | ๋ชจ๋ธ ์ฝ๋์์ ํ์ธ ๊ฐ๋ฅ |
ํต์ฌ: ๊ฒฐ๊ตญ ๋ชจ๋ ๊ฒ์ ํ ์คํธ
์ธ ๋ฒค๋์ ๋ฐฉ์์ด ๋ฌ๋ผ ๋ณด์ด์ง๋ง, ๊ณตํต์ ์ ํ๋๋ค:
API JSON โ ํ๋์ ๊ธด ํ ์คํธ ์ํ์ค โ ๋ชจ๋ธ์ ์ ๋ ฅ
๋ชจ๋ธ์ ์ด ํ ์คํธ๋ฅผ ์ฝ๊ณ :
- โ์ด๋ค tool์ด ์ฌ์ฉ ๊ฐ๋ฅํ์งโ ํ์ ํ๊ณ
- โ์ฌ์ฉ์๊ฐ ๋ฌด์์ ์ํ๋์งโ ์ดํดํ๊ณ
- โ์ด๋ค tool์ ์ด๋ค ์ธ์๋ก ํธ์ถํ ์งโ ๊ฒฐ์ ํ๋ค
์ด ๊ฒฐ์ ์ด ๋ง๋ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง, ์ค์ ๋ก๋ ์์คํ ํ๋กฌํํธ์ ์ ํ ์ง์๋ฅผ ๋ฐ๋ฅด๋ ๊ฒ + fine-tuning์ผ๋ก ํ์ต๋ ํจํด์ ์กฐํฉ์ด๋ค.
๋ค์ ํธ: ์ด ํ ์คํธ๊ฐ ๋ชจ๋ธ์ ๋ฐ๋ก ๋ค์ด๊ฐ๋ ๊ฒ๋ ์๋๋ค
Chat Template์ด JSON์ ํ ์คํธ๋ก ๋ณํํ๋ค๋ ๊ฒ์ ํ์ธํ๋ค. ๊ทธ๋ฐ๋ฐ ๋ชจ๋ธ์ ํ ์คํธ๋ ์ง์ ์ฒ๋ฆฌํ ์ ์๋ค.
๋ชจ๋ธ์ ์ํ ์ฐ์ฐ(ํ๋ ฌ ๊ณฑ์
)์ผ๋ก ๋์ํ๋ฏ๋ก, ํ
์คํธ๋ฅผ **์ซ์(ํ ํฐ ID)**๋ก ๋ณํํ๋ ๊ณผ์ ์ด ๋ฐ๋์ ํ์ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ๊ณผ์ ์์ Mistral์ [AVAILABLE_TOOLS] ๊ฐ์ control token์ด ์ผ๋ฐ ํ
์คํธ์ ์ด๋ป๊ฒ ๋ค๋ฅด๊ฒ ์ฒ๋ฆฌ๋๋์ง๊ฐ ๋๋ฌ๋๋ค.
๋ค์ ํธ์์ ์ด Tokenization ๊ณผ์ ์ ์ดํด๋ณธ๋ค.
์ฐธ๊ณ ๋ฌธ์
- Anthropic - Tool Use System Prompt Structure - Claude๊ฐ ๊ณต๊ฐํ ์ค์ ์์คํ ํ๋กฌํํธ ํ ํ๋ฆฟ (โIn this environment you have access toโฆโ)
- OpenAI - Function Calling Guide - GPT์ tool calling ๊ณต์ ๊ฐ์ด๋
- OpenAI Community - Function Calling Prompt Injection - โtool ์ ์๊ฐ ์์คํ ๋ฉ์์ง์ ์ฝ์ ๋๋คโ๋ ๊ณต์ ํ์ธ
- Gemini - Function Calling - Gemini์ function_declarations ํ์๊ณผ ์ํฌํ๋ก์ฐ
- Mistral - Tokenization & Tool Calling Deep Dive - control token ๊ธฐ๋ฐ tool calling ํํ (๊ฐ์ฅ ์์ธํ ๋ด๋ถ ํฌ๋งท ๊ณต๊ฐ)
- GLM-4 Chat Template - GLM-4์ ํน์ ํ ํฐ๊ณผ chat template ๊ตฌ์กฐ
- GLM-4.6 Tool-Integrated Reasoning Guide -
<tool_call>,<arg_key>,<arg_value>XML ํ์ - HuggingFace - Chat Templates - chat template ์ผ๋ฐ ๊ฐ๋