Pusula
An open-source AI decision engine for Turkish. Pusula is Decision 3.0 (vllm-sr/d3) fine-tuned on Turkish decision data. For each message, typed questions (for example, how a request should be routed, how urgent it is, whether a human should take over, or whether it contains a prompt injection) are answered with a probability for every option in a single forward pass, without text generation.
Doğru karar, doğru yön.
| Version | v1.0 (18 October 2026); the preview weights of 17 October 2026 remain available as revision v1.0-onizleme |
| Base model | vllm-sr/d3 (26B, Apache-2.0) |
| This repository | LoRA adapter (rank 32) + code readout, ~0.9 GB |
| Language | Turkish |
| Training data | Specially curated Turkish data: synthetic messages generated for this project and human-written customer messages licensed from a commercial partner |
| Interface | Same request and answer format as d3's /v1/systemone |
Results
Accuracy (%). Evaluation labels were assigned blind and independently by two annotators (Claude Opus 5.5 and Claude Sonnet 5.5); disagreements were adjudicated, and all labels follow Pusula's written labeling policy. The real customer messages were labeled blind by Claude under the same policy. Evaluation labels are used exclusively for evaluation and are never used as training labels.
| Evaluation | Questions | Decision 3.0 | Pusula |
|---|---|---|---|
| Real customer messages (500 held-out, licensed) | 4,500 | 77.4 | 85.6 |
| Long customer complaints (500 held-out, licensed) | 4,500 | 81.4 | 88.0 |
| Turkish Decision Benchmark (2,194 messages) | 19,861 | 88.5 | 92.6 |
| Gold test set (759 held-out messages) | 7,015 | 85.5 | 90.4 |
| Your own questions (497 messages × 3 ad-hoc questions) | 1,491 | 94.8 | 94.2 |
| MASSIVE tr-TR, 60-way intent, zero-shot (human-written Turkish) | 2,974 | 85.3 | 85.2 |
| OffensEval 2020 Turkish, offensive language (real tweets) | 3,528 | 88.4 | 88.3 |
Per question:
| Question | Gold set: Decision 3.0 | Gold set: Pusula | Benchmark: Decision 3.0 | Benchmark: Pusula |
|---|---|---|---|---|
| Urgency (4 levels) | 53.2 | 78.9 | 76.5 | 86.6 |
| Human handoff | 81.5 | 89.2 | 77.1 | 88.6 |
| Domain | 82.1 | 86.8 | 89.9 | 94.0 |
| Emotion | 85.0 | 88.3 | 71.3 | 81.0 |
| Security risk | 94.2 | 98.0 | 97.5 | 99.2 |
| Action required | 88.9 | 90.5 | 89.2 | 90.0 |
| Personal data | 96.4 | 96.3 | 93.6 | 94.8 |
| Intent | 96.8 | 97.0 | 97.9 | 98.0 |
The two real evaluation sets (customer messages, and long, detailed customer complaints) were licensed from a commercial partner, are held out from training and are not published. Urgency is partly subjective: the two annotators agree on 84.4% of gold-set messages, which bounds the attainable score. MASSIVE and OffensEval are not included in the training data.
Usage
Pusula is loaded with the pusula package. Generic PEFT loading of the adapter is not sufficient, since the code
readout and the non-causal attention hook of the d3 prompt contract are applied by this package.
pip install "pusula[d3] @ git+https://github.com/hsnsahinhsn/pusula"
hf download vllm-sr/d3 --local-dir d3 --exclude "assets/*"
hf download hsnsahinhsn/pusula --local-dir pusula
from pusula.inference import D3Engine
engine = D3Engine.load("d3", adapter="pusula")
answers = engine.decide(
"Kartımdan bilgim dışında üç çekim yapıldı, hemen engelleyin!",
{
"temsilci": {"type": "noul", "instructions": "Bir insan temsilciye aktarılmalı mı?"},
"aciliyet": {"type": "score", "instructions": "Ne kadar acil?", "criteria": ["Rutin", "Yakın", "Yüksek", "Kritik"]},
},
)
An HTTP server (pusula-serve), a built-in Turkish taxonomy (20 domains, 86 subdomains, 299 intents) and the
benchmark are provided in the Pusula repository. A smaller model with the same
interface is available as Pusula Nano (149M, CPU-capable), which can
be tried on Google Colab without installation:
Hardware requirements: approximately 64 GB of GPU memory in BF16, or approximately 24 GB when loaded in 4-bit.
Training
- Data: about 13,500 synthetic Turkish messages across 20 domains, written by Qwen3.8-27B (Apache-2.0) from fixed targets (intent, urgency, emotion, style, persona, length); every question was answered again blind by a separate judge pass and by the base model, and only labels on which they agree are kept. TabiBERT was used to remove duplicates and likely label errors and to build hard intent distractors. Plus about 7,400 real messages licensed from a commercial partner and anonymized prior to use (about 3,500 customer messages and about 4,000 long customer complaints), labeled by Qwen3.8-27B under the written labeling policy; about 2,800 synthetic messages written by Qwen3.8-27B in the style of real customer messages; and about 8,900 messages with ad-hoc questions of many options, answered by the base model. Messages of the evaluation sets are excluded from training.
- Labeling policy: all training labels follow the written labeling policy, which was applied by Qwen3.8-27B with explicit decision rules (urgency, human handoff and opinion-only reviews).
- Method: a BF16 LoRA (rank 32, all attention and MLP projections) and the code readout were trained, continuing from an earlier Pusula adapter, for 225 optimizer steps over 24,000 questions, with a doubled share for ad-hoc questions. The checkpoint with the highest validation accuracy (step 100) is published.
Limitations
- Urgency is partly subjective. Where urgency drives costly actions, the probabilities should be used rather than only the top level.
- Emotion is the weakest built-in question on the benchmark (81.0). A bias toward "angry" over "disappointed" in critical reviews, observed in the preview release (76.3), was reduced by a revised labeling rule.
- Most of the training data is synthetic. Real traffic may differ in style and topic mix; evaluation on application-specific data is recommended before deployment.
Contributors and citation
Pusula is developed by the following contributors:
| Name | Role | GitHub | Hugging Face |
|---|---|---|---|
| Hasan Şahin | Project lead | hsnsahinhsn | hsnsahinhsn |
| Ahmet Sayman | Contributor | asayman | asaymantr |
Source code: github.com/hsnsahinhsn/pusula.
@software{pusula2026,
title = {Pusula: The First Full-Featured Turkish Decision Model},
author = {Şahin, Hasan and Sayman, Ahmet},
year = {2026},
version = {1.0},
url = {https://github.com/hsnsahinhsn/pusula},
license = {Apache-2.0}
}
License and attribution
Released under Apache-2.0. Pusula is built on vllm-sr/d3 (vLLM Semantic Router Team, Apache-2.0), which is itself built
on Qwen3.8-27B (Apache-2.0). Qwen3.8-27B was used for data generation and labeling, and boun-tabilab/TabiBERT
(Apache-2.0) for data curation. External
evaluations: Amazon MASSIVE (CC BY 4.0) and OffensEval 2020 Turkish (Çöltekin, 2020; CC BY). See NOTICE.