A 4B parameter text-only model fine-tuned for reliable tool selection, structured JSON output, and knowing when NOT to use tools. Built on Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled, trained with LoRA on 6,855 quality-filtered synthetic examples.
Architecture: Qwen3_5ForCausalLM (text-only, no vision encoder). Vision weights from the base model have been stripped — this model is purpose-built for text-based tool calling.
1from transformers import AutoModelForCausalLM, AutoTokenizer
2import torch
34model = AutoModelForCausalLM.from_pretrained(5"enfuse/smol-tools-4b",# or local path6 torch_dtype=torch.bfloat16,7 device_map="auto",8 trust_remote_code=True,9)10tokenizer = AutoTokenizer.from_pretrained("enfuse/smol-tools-4b", trust_remote_code=True)1112tools =[13{"type":"function","function":{14"name":"web_search",15"description":"Search the web for information",16"parameters":{"type":"object","properties":{17"query":{"type":"string"}18},"required":["query"]}19}}20]2122messages =[23{"role":"system","content":"You are a helpful assistant with access to tools."},24{"role":"user","content":"What's the latest news about SpaceX?"},25]2627prompt = tokenizer.apply_chat_template(messages, tools=tools, tokenize=False, add_generation_prompt=True)28inputs = tokenizer(prompt, return_tensors="pt").to(model.device)29output = model.generate(**inputs, max_new_tokens=512, temperature=0.1, do_sample=True)30print(tokenizer.decode(output[0][inputs["input_ids"].shape[1]:], skip_special_tokens=False))
The model responds with optional thinking followed by tool calls or a direct answer:
With tool call:
<think>
The user wants to search for SpaceX news. I should use the web_search tool.
</think>
I'll search for the latest SpaceX news for you.
<tool_call>
{"name": "web_search", "arguments": {"query": "latest SpaceX news"}}
</tool_call>
Without tool call (direct answer):
<think>
This is a general knowledge question I can answer directly without any tools.
</think>
The capital of France is Paris. It has been the capital since...
Quality filtering: Removed examples with malformed JSON, missing tool calls, or incorrect tool usage (5,000 → 4,578)
Targeted generation: Generated 2,277 additional examples focusing on reasoning_heavy and complex_multi_step scenarios with explicit <think> tag prompting
Combined dataset: 6,855 examples across 7 scenario types
What Worked (Experiment Log)
Experiment
F1
Key Finding
Base model (no training)
0.888
Strong baseline from Claude distillation
R1: 5K unfiltered data
0.913
Fine-tuning helps
R2: 15K unfiltered data
0.905
More dirty data hurts
R3: 4.6K filtered data
0.950
Data quality > quantity
R3: 6.9K filtered + targeted
0.955
Targeted reasoning data helps
R4: 13.6K all-clean data
0.935
Too much data overfits
R4: 5 epochs
0.920
More epochs overfits
R5: Higher LoRA rank (64)
0.930
Rank 32 is sufficient
R5: Lower LR (5e-5)
0.910
1e-4 is optimal
smol-tools Family
All models share the same base architecture, tool schema, and output format. Choose based on your context length needs:
If you need GPT-4-level complex multi-step planning (our weakest category at F1=0.818), use a bigger model
If latency and cost don't matter, just call a frontier API — they'll outperform any 4B model on hard reasoning
If your use case requires tools not seen during training, test carefully — the model generalizes to new tool schemas but hasn't been validated on every possible tool type
Limitations
complex_multi_step scenarios (F1=0.818) remain the weakest — the model sometimes struggles with multi-step planning involving 3+ chained tools
No thinking rate in evaluation (0%) — the model reasons but doesn't always use explicit <think> tags at low temperature
Trained on synthetic data only — real-world tool-use patterns may differ
Inherits Qwen3.5-4B base model limitations (context window, knowledge cutoff)
Hardware
Training: 1× NVIDIA H200 NVL (141 GB HBM3e)
Inference (BF16): Any GPU with ≥10 GB VRAM
Inference (Q8_0 GGUF): Any device with ≥6 GB RAM — Jetson Orin NX, consumer GPUs
Inference (Q4_K_M GGUF): Any device with ≥4 GB RAM — Jetson Orin Nano, phones, Raspberry Pi 5