Ab Version 0.35 unterstützt Ollama Entscheidungsmodelle, die auf der Jev-API von TypeSafe basieren. Hierbei handelt es sich nicht um Chat-Modelle im üblichen Sinne: Sie schreiben keinen Text, sondern beantworten eine Reihe getippter Fragen zum übertragenen Zustand. Für die Klassifizierung, Weiterleitung, Moderation und Triage erweist sich dies als schneller und zuverlässiger, als einen regulären LLM zu bitten, JSON zurückzugeben und dann seine Antwort zu analysieren.
In diesem Beitrag schaue ich mir an, was Entscheidungsmodelle sind, wie sie auf HTTP-Ebene funktionieren, welche Modelle bereits verfügbar sind und wie man sie in vorhandenen Code einbaut, damit reguläre generative Modelle weiterhin funktionieren.
Wie unterscheiden sich Entscheidungsmodelle von regulären
?
Ein regulärer LLM empfängt eine Eingabeaufforderung und generiert Token für Token Text. Selbst wenn Sie sie bitten, mit einem Wort zu antworten, findet die Generierung immer noch im Inneren statt, und das Format der Antwort muss durch ein Diagramm, Anweisungen und anschließende Überprüfung kontrolliert werden. Das Entscheidungsmodell funktioniert anders: Sie übergeben Status und Fragen mit Typen und das Modell gibt Wahrscheinlichkeiten und ausgewählte Optionen zurück. Kein Freitext, kein JSON-Parsing aus der Antwort.
Der neue Endpunkt heißt /v1/systemone. In einer Anfrage können Sie mehrere Fragen gleichzeitig stellen und das Model wird alle beantworten. Dies ist praktisch für Aufgaben, bei denen Sie mehrere zusammenhängende Entscheidungen treffen müssen: zum Beispiel die Bestimmung des Teams, die Notwendigkeit einer Rückgabe und die Dringlichkeit des Tickets.
Welche Modelle sind verfügbar
Jetzt können Sie drei Entscheidungsmodelle über Ollama ausführen:
- nimble ist ein offenes Modell mit 9 Milliarden Parametern von Bespoke Labs. Es ist das größte und genaueste verfügbare Gerät.
- tev1 ist ein experimentelles Modell mit 4 Milliarden Parametern von Together AI.
- tev1:0.8b ist ein experimentelles Modell mit 0,8 Milliarden Parametern von Together AI. Am schnellsten und einfachsten.
Sie arbeiten alle lokal, erfordern keine Bezahlung und senden keine Daten an einen externen Dienst. Ollama 0.35 und höher werden unterstützt.
Installation
Überprüfen Sie zunächst die Ollama-Version:
ollama --version
Laden Sie dann das gewünschte Modell herunter. Für die einfachste:
ollama pull tev1:0.8b
Für die Vollversion von tev1:
ollama pull tev1
Für flink:
ollama pull nimble
Das flinke Modell benötigt etwa 9,5 GB Speicherplatz, daher empfiehlt es sich, vor dem Herunterladen etwas Speicherplatz freizugeben. tev1:0.8b benötigt weniger als ein Gigabyte.
Erste Anfrage per Curl
Das einfachste Beispiel ist die Feststellung, ob es sich bei einem Text um eine Stellenanzeige handelt:
curl http://localhost:11434/v1/systemone -d '{
"model": "tev1:0.8b",
"state": {
"message": "Senior Swift developer, Berlin, remote friendly"
},
"questions": {
"isJob": {
"type": "noul",
"instructions": "Does the message advertise a job posting that someone can apply to?"
}
}
}'
Die Antwort sieht so aus:
{
"model": "tev1:0.8b",
"answers": {
"isJob": {
"type": "noul",
"noul": 0.921
}
},
"usage": {
"input_tokens": 42,
"output_tokens": 0
}
}
Das Noul-Feld ist eine Wahrscheinlichkeit von 0 bis 1. Die Entscheidung wird durch Vergleich mit einem Schwellenwert getroffen, normalerweise 0,5. Im Gegensatz zum generativen Modell ist es nicht erforderlich, eine Antwort im JSON-Format anzufordern und dann zu überprüfen, ob das Modell sie nicht beschädigt hat.
Arten von Fragen
Entscheidungsmodelle unterstützen drei Arten von Fragen.
noul ist eine binäre Frage. Gibt die Wahrscheinlichkeit zurück, dass eine Aussage wahr ist:
{
"questions": {
"refund": {
"type": "noul",
"instructions": "Does the customer explicitly ask for a refund?"
}
}
}
Auswahl – Auswahl einer Option aus einem bestimmten Satz. Gibt die ausgewählte Option, die Wahrscheinlichkeiten aller Optionen und die Konfidenz zurück:
{
"questions": {
"team": {
"type": "choice",
"instructions": "Which team should handle this ticket?",
"criteria": {
"billing": "Payments and refunds",
"technical": "Bugs and integrations",
"other": "None of the above"
}
}
}
}
Score – Bewertung auf einer Skala. Gibt die Zahl, Legende und Wahrscheinlichkeiten für jeden Skalenpunkt zurück:
{
"questions": {
"urgency": {
"type": "score",
"instructions": "How urgent is this ticket?",
"criteria": ["Routine", "Soon", "Urgent"]
}
}
}
Eine Anfrage kann mehrere Fragen unterschiedlichen Typs gleichzeitig enthalten. Dies macht Entscheidungsmodelle für die Triage geeignet: eine Operation, ein Zustand, mehrere unabhängige Entscheidungen.
Python ohne zusätzliche Bibliotheken
Für Anfragen reicht die Standard-URLib aus; Ein separates SDK ist nicht erforderlich:
import json
from urllib.request import Request, urlopen
OLLAMA_DECISION_URL = "http://localhost:11434/v1/systemone"
def ask_decision(state, questions, model="tev1:0.8b"):
payload = {
"model": model,
"state": state,
"questions": questions,
}
request = Request(
OLLAMA_DECISION_URL,
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
with urlopen(request, timeout=3600) as response:
return json.loads(response.read().decode())["answers"]
Verwendung:
answers = ask_decision(
{"message": "Senior Swift developer, Berlin, remote friendly"},
{
"isJob": {
"type": "noul",
"instructions": "Does the message advertise a job posting that someone can apply to?"
}
},
)
probability = answers["isJob"]["noul"]
is_job = probability >= 0.5
Wenn Sie ein offizielles Python-SDK benötigen, heißt es typesafe-sdk. Für localhost kann es mit den Umgebungsvariablen TYPESAFE_BASE_URL, TYPESAFE_API_KEY und TYPESAFE_DEFAULT_MODEL an Ollama weitergeleitet werden. Für einfache Aufgaben reicht jedoch eine direkte HTTP-Anfrage.
Wie man versteht, dass ein Modell eine Entscheidung unterstützt
Entscheidungsmodelle können nicht über /api/generate oder /api/chat antworten. Wenn Sie eine solche Anfrage senden, gibt Ollama einen 400-Fehler mit einem Text wie dem folgenden zurück:
"tev1:0.8b" does not support generate
Dies ist wichtig, wenn Sie bereits Code haben, der über /api/generate mit regulären Modellen funktioniert: Wenn Sie das Modell in ein Entscheidungsmodell ändern, funktioniert es nicht mehr. Besser ist es, sich vorab über /api/show über die Fähigkeiten des Modells zu informieren und die entsprechende Aufrufmethode auszuwählen:
import json
from urllib.request import Request, urlopen
OLLAMA_SHOW_URL = "http://localhost:11434/api/show"
def supports_decision(model):
request = Request(
OLLAMA_SHOW_URL,
data=json.dumps({"model": model}).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urlopen(request, timeout=30) as response:
capabilities = json.loads(response.read().decode()).get("capabilities", [])
except (OSError, TypeError, ValueError):
return False
return "decision" in capabilities
Entscheidungsmodelle werden nur Entscheidungen in ihren Fähigkeiten haben. Normale Modelle verfügen dort über Vervollständigungen, Werkzeuge oder andere Funktionen. Wenn Ollama nicht verfügbar ist, ist es sinnvoll, das Modell als normal zu betrachten und den generativen Pfad zu verwenden.
So integrieren Sie es in vorhandenen Code
Der einfachste Weg besteht darin, den Klassifikator nicht neu zu schreiben, sondern ihn in zwei Strategien zu unterteilen. Die generative Strategie funktioniert wie zuvor: Sie sammelt die Eingabeaufforderung, sendet sie an /api/generate und analysiert den JSON. Die Entscheidungsstrategie sendet den Status und die eingegebene Frage an /v1/systemone und vergleicht die Wahrscheinlichkeit mit einem Schwellenwert.
Die Wahl der Strategie erfolgt an einer Stelle beim Erstellen eines Klassifikators:
def create_classifier(model):
if supports_decision(model):
return DecisionClassifier(model)
return GenerativeClassifier(model)
Dieser Ansatz hat mehrere Vorteile. Generative Modelle laufen unverändert weiter. Das Entscheidungsmodell kann durch Ändern einer Umgebungsvariablen aktiviert werden. Und der gesamte Unterschied zwischen den beiden Methoden konzentriert sich auf zwei kleine Klassen und ist nicht über die gesamte Anwendung verteilt.
Für eine binäre Klassifizierung sieht die Entscheidungsstrategie etwa so aus:
async def classify(text):
answers = await ask_decision(
{"message": text},
{
"isJob": {
"type": "noul",
"instructions": instructions,
}
},
model,
)
probability = answers["isJob"]["noul"]
return probability >= 0.5, probability
Bitte beachten Sie, dass das Entscheidungsmodell keine Erklärung zurückgibt. Wenn Ihr Ergebnisformat ein Grundfeld enthält, können Sie es aus der Wahrscheinlichkeit konstruieren: Speichern Sie beispielsweise die Wahrscheinlichkeit selbst oder eine Zeichenfolge wie „Das Modell hat die Nachricht mit 0,935 als freie Stelle bewertet.“ Das ist ehrlicher, als einen Grund zu erfinden, den das Modell nicht angegeben hat.
Anweisungen sollten eine Frage sein
Dies ist die wichtigste praktische Schlussfolgerung. Entscheidungsmodelle verstehen keine langen Eingabeaufforderungen im Stil von „Sie klassifizieren Nachrichten, antworten mit wahr, wenn…, andernfalls mit falsch.“ Sie wollen eine kurze, direkte Frage.
Auf die gleiche Nachricht zu einer offenen Stelle habe ich folgende Wahrscheinlichkeiten erhalten:
- Direkte Frage „Ist diese Nachricht eine Stellenausschreibung?“ – 0,921.
- Lange Anweisungen, die erklären, was als freie Stelle gilt – 0,026.
- Lange Anweisungen mit einer Frage am Ende – 0,391.
Der Unterschied beträgt fast das Dreißigfache. Das Modell macht keinen Fehler bei der Klassifizierung, es versteht einfach nicht, was es von ihm will, wenn die Frage in einem Absatz versteckt ist. Daher lohnt es sich, für Entscheidungsmodelle separate kurze Anweisungen zu behalten und für generative Modelle lange Eingabeaufforderungen zu belassen.
Es ist praktisch, eine separate Umgebungsvariable zu erstellen:
OLLAMA_JOB_CLASSIFIER_DECISION_INSTRUCTIONS=Does the message advertise a job posting that someone can apply to?
Und verwenden Sie eine reguläre Eingabeaufforderung nur für den generativen Pfad.
Schwellenwert und Wahrscheinlichkeiten
Der Schwellenwert von 0,5 eignet sich als Standardwert, es ist jedoch sinnvoll, ihn in die Konfiguration einzubeziehen. Bei verschiedenen Aufgaben sind die Kosten einer falsch positiven und einer falsch negativen Antwort unterschiedlich. Zur Moderation ist es sicherer, die Schwelle anzuheben; Bei der Suche nach offenen Stellen ist es sicherer, den Wert zu senken, um keine nützlichen Nachrichten zu verpassen.
Es ist auch nützlich, die Wahrscheinlichkeit selbst zu protokollieren und nicht nur den resultierenden booleschen Wert. Wenn der Klassifikator einen Fehler macht, zeigt das Protokoll, ob es sich um eine sichere Antwort oder eine Entscheidung an der Grenze handelte. Bei Auswahlfragen lohnt es sich, Wahrscheinlichkeiten und Vertrauen zu speichern: Sie zeigen, wie stark das Modell zwischen den Optionen schwankt.
Leistung und Speicher
Die Geschwindigkeit hängt stark von der Größe des Modells und der Hardware ab. Auf der CPU habe ich in meinen Tests folgende Zahlen erhalten:
- tev1:0.8b – Sekundenbruchteile zum Lösen, passt problemlos in den Speicher.
- tev1 – 4B, deutlich langsamer, aber immer noch für interaktive Aufgaben geeignet.
- flink – 9 B in Q8_0, etwa 10 GB im Speicher. Die erste Anfrage inklusive Laden des Modells dauerte etwa 137 Sekunden, nachfolgende Lösungen benötigten zwischen 12 und 32 Sekunden auf der CPU.
Nimble benötigt viel RAM. Auf einer Maschine mit 16 GB und Docker/WSL mit einem Limit von etwa 8 GB passt das Modell nicht: Das System beginnt zu tauschen und die Container reagieren nicht mehr. Das Erhöhen des WSL-Limits auf 12 GB über die .wslconfig-Datei hat geholfen:
[wsl2]
memory=12GB
swap=8GB
Nach der Änderung müssen Sie „wsl –shutdown“ und Docker Desktop neu starten. Aber selbst mit 12 GB bleibt die Reserve gering: Das Modell nimmt etwa 10 GB auf, und für das System bleibt nicht mehr viel übrig.
Standardmäßig entlädt Ollama das Modell nach fünf Minuten Inaktivität und gibt so Speicher frei. Das ist praktisch: Nimble beschäftigt nicht ständig 10 GB, sondern lädt das Modell bei jedem neuen Start nach einer Pause erneut.
Wann sollten Entscheidungsmodelle verwendet werden?
Entscheidungsmodelle eignen sich gut für Aufgaben, bei denen Sie eine schnelle und kostengünstige Antwort auf eine klar formulierte Frage benötigen:
- Klassifizierung von Nachrichten, Tickets und Anfragen.
- Routing nach Befehlen oder Ausführern.
- Inhaltsmoderation und Sicherheitsüberprüfungen.
- Schnelle binäre und multivariate Lösungen für Spiele oder interaktive Anwendungen.
Sie eignen sich schlecht für Aufgaben, bei denen detaillierter Text benötigt wird: Erklärung, Feldextraktion, Zusammenfassung, Antwortgenerierung. Zu diesem Zweck bleiben die üblichen generativen Modelle bestehen. Das beste Ergebnis wird durch die Kombination erzielt: Ein Entscheidungsmodell trifft eine Entscheidung, und ein generatives Modell erklärt sie oder extrahiert Daten.
Gesamt
Entscheidungsmodelle in Ollama sind ein separates, engeres Werkzeug als reguläre LLMs. Sie ersetzen keine generativen Modelle, aber sie nehmen den Routineteil der Arbeit weg: getippte Antworten, Wahrscheinlichkeiten statt Textanalyse und ein vorhersehbares Format. Wenn Sie bereits über eine Klassifizierungspipeline verfügen, besteht der Übergang darin, die Fähigkeiten des Modells zu überprüfen, eine separate Aufrufstrategie festzulegen und kurze Anleitungsfragen zu stellen.
Quellen
https://ollama.com/blog/ollama-now-supports-jev-style-decision-models
https://ollama.com/library/nimble
https://ollama.com/library/tev1
https://typesafe.ai
Leave a Reply