Chat Template Rendering Examples for Agents
These examples illustrate a general template mechanism.
chat_template.jinjais an example template name, not a runtime file shipped by this repository.
This document uses a continuing agent conversation to explain chat_template.jinja. It renders structured messages, tools, tool results, and related input into the complete prompt received by the model. The surrounding agent runtime parses the model output, executes tool calls, and returns the final visible text to the user.
A conversation has three layers:
- Original
messages: data passed to the template by the API or agent runtime. - Model input: the complete prompt rendered by
chat_template.jinja. - User output: text displayed after the runtime filters internal content such as
<think>and<tool_call>from model output.
The examples assume:
enable_thinking = true
add_generation_prompt = true
reasoning_effort is not providedThe template therefore renders this default:
<|system|>Reasoning Effort: MaxExample 1: An ordinary first turn
Input messages:
[
{
"role": "user",
"content": "Write a Linux command to find the five largest files in the current directory"
}
]The model receives:
[gMASK]<sop><|system|>Reasoning Effort: Max<|user|>Write a Linux command to find the five largest files in the current directory<|assistant|><think>The model might output:
I will use du, sort the results, and limit them to five entries.</think>
Use:
```bash
du -ah . | sort -rh | head -n 5
```
To include files only and exclude directories, use:
```bash
find . -type f -exec du -h {} + | sort -rh | head -n 5
```The user receives:
Use:
```bash
du -ah . | sort -rh | head -n 5
```
To include files only and exclude directories, use:
```bash
find . -type f -exec du -h {} + | sort -rh | head -n 5
```<think>...</think> contains internal reasoning and should not be displayed to users in a normal product.
Example 2: A second turn without tools
The user follows up in the second turn:
Can you filter by modification time to include only the last seven days?Input messages might be:
[
{
"role": "user",
"content": "Write a Linux command to find the five largest files in the current directory"
},
{
"role": "assistant",
"content": "Use:\n\n```bash\ndu -ah . | sort -rh | head -n 5\n```"
},
{
"role": "user",
"content": "Can you filter by modification time to include only the last seven days?"
}
]The model receives:
[gMASK]<sop><|system|>Reasoning Effort: Max
<|user|>Write a Linux command to find the five largest files in the current directory
<|assistant|><think></think>
Use:
```bash
du -ah . | sort -rh | head -n 5
```
<|user|>Can you filter by modification time to include only the last seven days?
<|assistant|><think>The historical assistant message now includes:
<think></think>The template clears historical reasoning so that old reasoning is not repeatedly fed back to the model.
The user receives:
Yes:
```bash
find . -type f -mtime -7 -exec du -h {} + | sort -rh | head -n 5
```
`-mtime -7` selects files modified within the last seven days.Example 3: An agent using a tool
Suppose this tool is available:
{
"name": "run_shell",
"description": "Run a shell command",
"parameters": {
"type": "object",
"properties": {
"cmd": { "type": "string" }
},
"required": ["cmd"]
}
}The user asks:
Show me the five largest files in the current directoryThe model receives:
[gMASK]<sop><|system|>Reasoning Effort: Max<|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>
{"name": "run_shell", "description": "Run a shell command", "parameters": {"type": "object", "properties": {"cmd": {"type": "string"}}, "required": ["cmd"]}}
</tools>
For each function call, output the function name and arguments within the following XML format:
<tool_call>{function-name}<arg_key>{arg-key-1}</arg_key><arg_value>{arg-value-1}</arg_value>...</tool_call>
<|user|>Show me the five largest files in the current directory
<|assistant|><think>The model might first output a tool call:
I need to run du to inspect the results.</think>
<tool_call>run_shell<arg_key>cmd</arg_key><arg_value>du -ah . | sort -rh | head -n 5</arg_value></tool_call>The user usually does not receive a final answer yet. The agent runtime intercepts <tool_call> and executes the tool.
After the tool returns, a tool message is appended to messages:
{
"role": "tool",
"content": "120M\t./node_modules\n45M\t./dist\n12M\t./logs/app.log\n8M\t./assets\n4M\t./README.md"
}On the next request, the model receives:
...
<|assistant|><think></think>
<tool_call>run_shell<arg_key>cmd</arg_key><arg_value>du -ah . | sort -rh | head -n 5</arg_value></tool_call>
<|observation|><tool_response>120M ./node_modules
45M ./dist
12M ./logs/app.log
8M ./assets
4M ./README.md</tool_response>
<|assistant|><think>The model finally outputs:
The five largest entries in the results are:
1. `./node_modules`: 120M
2. `./dist`: 45M
3. `./logs/app.log`: 12M
4. `./assets`: 8M
5. `./README.md`: 4M</think>
The five largest entries in the current directory are:
```text
120M ./node_modules
45M ./dist
12M ./logs/app.log
8M ./assets
4M ./README.md
```The user finally receives:
The five largest entries in the current directory are:
```text
120M ./node_modules
45M ./dist
12M ./logs/app.log
8M ./assets
4M ./README.md
```Example 4: Continuing a conversation after tool use
The user continues:
Then delete dist for meThe conversation history received by the model includes:
- The initial user request
- The assistant tool call
- The tool result
- The final assistant answer
- The new user request
For example:
[gMASK]<sop><|system|>Reasoning Effort: Max
<|system|>
# Tools
...
<|user|>Show me the five largest files in the current directory
<|assistant|><think></think>
<tool_call>run_shell<arg_key>cmd</arg_key><arg_value>du -ah . | sort -rh | head -n 5</arg_value></tool_call>
<|observation|><tool_response>120M ./node_modules
45M ./dist
...</tool_response>
<|assistant|><think></think>
The five largest entries in the current directory are:
```text
120M ./node_modules
45M ./dist
...
```
<|user|>Then delete dist for me
<|assistant|><think>If the agent has permission to execute directly, it might call:
<tool_call>run_shell<arg_key>cmd</arg_key><arg_value>rm -rf dist</arg_value></tool_call>An agent runtime with a permission check may request confirmation here. The user receives a UI confirmation request instead of model text, for example:
Request to execute command: rm -rf dist
Allow this command?This is controlled by the agent runtime permission system rather than the template.
Key points
The template determines what the model sees and how it should format tool calls. What the user ultimately sees depends on how the surrounding runtime filters and interprets model output.
Normally, the runtime should filter out:
<think>...</think>
<tool_call>...</tool_call>
<tool_response>...</tool_response>Only the final natural-language content should be shown to the user.