Pusula

Open source · Apache 2.0 · v2.0

The first full-featured
Turkish decision model

Decision models answer typed questions about a text (for example, which team should handle a ticket, how urgent it is or whether a human should take over) and return a probability for every option instead of generated text. Existing decision models were developed for English, and their accuracy on Turkish is limited. Pusula is Decision 3.0 adapted to Turkish.

Real customer messages

90.6

Decision 3.0: 84.0 · +6.6

Long customer complaints

88.3

Decision 3.0: 81.5 · +6.8

Turkish Decision Benchmark

92.0

Decision 3.0: 88.5 · +3.5

Accuracy (%) of Pusula. The evaluation method is described under Results.

How it works

A request consists of a text (state) and named questions. The options of each question are defined in the request itself, so new labels can be introduced without retraining.

Request

{
  "state": "Kartımdan bilgim dışında 4.500 TL çekilmiş, hemen bloke edin!",
  "questions": {
    "ekip": {
      "type": "choice",
      "instructions": "Bu talebi hangi ekip ele almalı?",
      "criteria": {
        "dolandiricilik": "Şüpheli işlem ve dolandırıcılık",
        "kart_islemleri": "Kart başvurusu, limit ve şifre",
        "genel_destek": "Diğer sorular"
      }
    },
    "acil": { "type": "noul", "instructions": "Hemen müdahale gerekiyor mu?" },
    "risk": {
      "type": "score",
      "instructions": "Finansal risk ne düzeyde?",
      "criteria": ["Düşük", "Orta", "Yüksek"]
    }
  }
}

Answer (illustrative values)

{
  "answers": {
    "ekip": {
      "type": "choice",
      "choice": "dolandiricilik",
      "probabilities": {"dolandiricilik": 0.94, "kart_islemleri": 0.05, "genel_destek": 0.01},
      "confidence": 0.94
    },
    "acil": {"type": "noul", "noul": 0.97},
    "risk": {
      "type": "score",
      "score": 1.86,
      "probabilities": {"0": 0.02, "1": 0.10, "2": 0.88},
      "confidence": 0.88,
      "legend": {"0": "Düşük", "1": "Orta", "2": "Yüksek"}
    }
  },
  "model": "pusula"
}

Features

Pusula preserves the interface of Decision 3.0 and extends it for Turkish text.

Turkish first

Decision 3.0 has been fine-tuned on Turkish decision data from 20 domains, including banking, law, health, e-commerce, logistics and public services. Informal writing, typos, missing Turkish characters and mixed Turkish–English text are covered.

Options defined at request time

Questions and their options are specified in each request. The model is not limited to a fixed label set.

Three question types

choice (one option), noul (yes/no) and score (ordered levels). Every answer carries a probability for each option.

Drop-in d3 replacement

The request and answer format of the /v1/systemone endpoint of Decision 3.0 is preserved, so Pusula can replace d3 in existing integrations.

Built-in Turkish taxonomy and templates

20 domains, 103 subdomains and 333 intents are provided, together with 20 ready-made templates (topic and intent, 14 checks for messages and 4 for AI agents). Routing through an institution's own topic list is also supported.

Independent evaluation

Pusula has been evaluated against the base Decision 3.0 model on independently labeled Turkish test sets. The Turkish Decision Benchmark is published with the model.

Models

Two models are provided. Both accept identical requests.

Highest accuracy

Pusula (Turkish Decision 3.0)

Recommended for built-in and custom questions, including tasks with many options.

Size
26B: a 0.9 GB LoRA adapter on top of vllm-sr/d3
Runs on
GPU: ≥ 64 GB in BF16, ≥ 24 GB in 4-bit
Benchmark / gold
92.0 / 92.1
Weights
erenextlabs/pusula
Fast, runs on CPU

Pusula Nano

Recommended for high volume and low latency on the built-in questions.

Size
149M (TabiBERT cross-encoder)
Runs on
CPU or any GPU
Benchmark / gold
83.2 / 91.3
Weights
erenextlabs/pusula-nano

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 the published labeling policy. Evaluation labels are used exclusively for evaluation and are never used as training labels.

Decision 3.0 and Pusula, accuracy (%)

Each row shows the change from the base model to Pusula. All values are listed in the table below.

  • Decision 3.0
  • Pusula
EvaluationQuestionsDecision 3.0PusulaPusula Nano
Real customer messages (500 held-out, licensed)7,50084.090.689.9
Long customer complaints (500 held-out, licensed)4,50081.588.384.6
Turkish Decision Benchmark (2,194 messages)19,86188.592.083.2
Gold test set (757 held-out messages)11,35586.392.191.3
Custom questions in unseen sectors40092.893.555.5
MASSIVE tr-TR, 60-way intent, zero-shot (human-written)2,97485.385.232.7
OffensEval 2020 Turkish, offensive language (real tweets)3,52888.488.381.8

Gold test set, per question

QuestionDecision 3.0Pusula
Domain82.083.0
Message type69.093.3
Urgency (4 levels)53.184.0
Emotion89.293.9
Missing information71.570.9
Action required88.692.1
Human handoff81.487.6
Personal data96.496.4
Security risk95.699.1
Insults and hate speech99.2100.0
Fraud92.198.8
Life and safety98.099.1
Legal risk95.595.9
Churn risk85.789.3
Sales opportunity97.297.5
  • Real customer messages: Evaluation was performed on two held-out sets of 500 anonymized messages licensed from a commercial partner: customer messages (reviews, complaints and questions) and long, detailed customer complaints. These sets are not published.
  • Version 2.0: the evaluation sets were extended to the 20 templates and labeled under the v2.0 labeling policy, so the scores are not comparable with those published for v1.0. A comparison with v1.0, including the evaluations on which v2.0 is lower, is given in the README.
  • Custom questions (questions that are not among the built-in templates) and the missing-information template are answered by the base Decision 3.0 model with the adapter disabled; the other built-in templates are answered with the adapter.
  • Pusula Nano was trained mainly on the built-in questions. For tasks that differ from the built-in questions, or that have many options, Pusula is recommended.
  • MASSIVE and OffensEval are not included in the training data.

Quick start

A CUDA build of PyTorch should be installed beforehand. Pusula Nano requires only the serve extra and runs on CPU.

Installation

pip install "pusula[serve,d3] @ git+https://github.com/erenextlabs/pusula"
hf download vllm-sr/d3 --local-dir ~/d3 --exclude "assets/*"     # base Decision 3.0 weights (~52 GB)
hf download erenextlabs/pusula --local-dir ~/pusula                # Pusula adapter (~0.9 GB)
# or the small model, which needs no base weights:
hf download erenextlabs/pusula-nano --local-dir ~/pusula-nano      # Pusula Nano (~0.6 GB)

Python

from pusula.inference import D3Engine, DecisionEngine

engine = D3Engine.load("~/d3", adapter="~/pusula")      # Pusula (Turkish Decision 3.0)
# engine = DecisionEngine.load("~/pusula-nano")          # Pusula Nano (GPU or CPU)

answers = engine.decide(
    "Siparişim 5 gündür kargoda, hâlâ gelmedi. Artık iptal etmek istiyorum.",
    {
        "niyet": {
            "type": "choice",
            "instructions": "Müşteri ne istiyor?",
            "criteria": {
                "kargo_takip": "Gönderinin nerede olduğunu öğrenmek",
                "iptal": "Siparişi iptal etmek",
                "iade": "Teslim alınan ürünü iade etmek",
            },
        },
        "temsilci": {"type": "noul", "instructions": "Bir insan temsilciye aktarılmalı mı?"},
    },
)
print(answers["niyet"]["choice"], answers["niyet"]["confidence"])

The HTTP API, the built-in taxonomy, guidance on writing questions and the use of confidence values are documented in the README.

Training your own model

All components used to build Pusula are included in the repository, so Decision 3.0 can be fine-tuned on data from other domains or languages. Labeled decision data is generated with a local open-weight model, cleaned and used to fine-tune d3 with QLoRA. Each stage can be resumed.

Training guide in the README

License and acknowledgements

Pusula is released under the Apache 2.0 license and builds on vllm-sr/d3 (vLLM Semantic Router), Qwen3.8 (Qwen Team, Alibaba Cloud) and TabiBERT (Boğaziçi University TABILAB), all licensed under Apache 2.0.

Data provenance

Pusula models were trained primarily on synthetic Turkish data generated for this project. A limited set of real customer messages, licensed from a commercial partner, was also included in the training data. These messages were anonymized prior to use and are not redistributed in any form.