Zum Hauptinhalt springen

Einen Textprüf-Workflow auf DeepSeek V4.1 Flash umstellen

DeepSeek-Chat auf V4.1 Flash umstellen: Modell-ID, zu löschende Felder, Reasoning-Budget, geprüfter Testfall, Tool-Verlauf und Tokenkosten.

Autor
Lydia
Erschienen
Lesedauer
13 Min. Lesezeit
Aktualisiert
Eine Frau und ein Mann unterhalten sich über ein türkisfarbenes Fahrrad hinweg in einer sonnigen Reparaturwerkstatt.

Angenommen, ein Dienst schickt Reparaturnotizen an ein DeepSeek-Modell und erwartet ein JSON-Objekt zurück: was geprüft wurde, was empfohlen wurde, ob der Kunde zugestimmt hat und ob die Arbeit erledigt ist. Heute ruft er deepseek-chat, deepseek-flash oder eine OpenRouter-Route auf, und Sie möchten ihn über SpicyAPI (spicyapi.ai) auf DeepSeek V4.1 Flash laufen lassen.

Vier Änderungen genügen: die Modell-ID deepseek/v4.1-flash/chat verwenden, jedes Feld löschen, das dieses Modell nicht akzeptiert, ein reasoning_effort wählen und max_tokens wirklich Spielraum geben, denn das Reasoning wird aus demselben Budget bezahlt. Führen Sie danach einen kleinen Testfall aus, bevor echter Traffic fließt. Auf der Modellseite von V4.1 Flash können Sie die Anfrage ausprobieren.

Was an der Anfrage zu ändern ist

Basis-URL, Schlüssel und Modell-ID sind der einfache Teil (Migrationsdokument). Am Anfrage-Body scheitert es:

In Ihrem aktuellen ClientBei SpicyAPI
Basis-URL https://api.deepseek.com und ein DeepSeek-Schlüsselhttps://api.spicyapi.ai/v1 und ein Schlüssel, der mit sk-spicy- beginnt
Modell deepseek-flash oder die älteren deepseek-chat, deepseek-reasoner, deepseek-v4-flash, deepseek-v4-prodeepseek/v4.1-flash/chat
thinking: {"type": "disabled"}, das Verhalten, das deepseek-chat früher liefertereasoning_effort: "none" überspringt den Reasoning-Durchlauf
Thinking an (Standard)reasoning_effort weglassen für high, oder low für Massenarbeit setzen
reasoning_effort mit max, medium, minimal, xhighNur none, low und high werden akzeptiert; alles andere ergibt 400 invalid_request
temperature, top_p, presence_penalty, frequency_penaltyLöschen; 400 unsupported_parameter
parallel_tool_callsLöschen; bei diesem Modell nicht verfügbar
stopBehalten: bis zu 4 Sequenzen, der getroffene Text wird nicht in die Antwort übernommen
image_url- oder Datei-Partsimage_url-Parts für Bilder behalten; PDF-/Datei-Parts entfernen und deren Text vorher extrahieren
OpenRouter models, route, provider, usage, transforms, plugins und ein reasoning-ObjektDie ersten sechs löschen; reasoning durch das Top-Level-Feld reasoning_effort ersetzen

Dieses gehostete Modell bietet keine Sampling-Steuerung, auch nicht mit reasoning_effort: "none". Prüfen Sie daher die Ergebnisse Ihrer Aufgaben, statt sich für Wiederholbarkeit auf temperature: 0 zu verlassen.

Was gleich bleibt: messages (Text- oder Bildinhalt, bis zu 256), tools (bis zu 128 Definitionen) mit tool_choice (auto, none, required oder eine benannte Funktion), response_format mit {"type": "json_object"}, stop, max_tokens (Standard 32.768, Maximum 384.000) und ein Eingabefenster von 1.048.576 Tokens, das jede gesendete Nachricht zählt, auch den System-Prompt und frühere Tool-Ergebnisse.

SpicyAPI verwirft nie stillschweigend ein Feld: Der 400-Fehler nennt das Feld, und es wird nichts berechnet. Die eigene API von DeepSeek akzeptiert temperature und die Penalty-Felder im Thinking-Modus und ignoriert sie, sodass ein alter Client sie unbemerkt mitschleppen kann.

Der stille Fehler ist der Modellname. In der eigenen API von DeepSeek ist V4 Flash eingestellt, und deepseek-v4-flash leitet vorübergehend auf V4.1 Flash um; der aktuelle Name ist deepseek-flash. Bei V4 Pro ist es anders: DeepSeek kündigte zunächst für den 14. September einen Wechsel auf Flash an, bestätigte dann aber in seinem Änderungsprotokoll, dass der V4-Pro-Dienst mit unveränderter Abrechnung weiterläuft. Gehen Sie nicht davon aus, dass jeder alte Pro-Aufruf bereits auf Flash läuft.

Bei SpicyAPI haben die drei DeepSeek-Chat-Routen jeweils eigene veröffentlichte Verträge: deepseek/v4-flash/chat in der Konfiguration zu belassen, ist eine gültige Anfrage mit einer Ausgabegrenze von 65.536 Tokens und höheren Preisen. Ein Alias des nativen Dienstes ändert diesen gehosteten Vertrag nicht. Verwenden Sie für diese Migration ausdrücklich deepseek/v4.1-flash/chat.

Diese Route akzeptiert Bilder über image_url-Parts, aber keine PDF-/Datei-Parts. Extrahieren Sie den Text eines PDFs, bevor Sie ihn senden; die reinen Text-Beispiele mit Reparaturnotizen unten brauchen keine Bildeingabe.

Der Antwort Platz geben

Das Modell denkt, bevor es antwortet, und das Reasoning geht von max_tokens ab. Der Standard-Effort ist high, und eine Obergrenze von 120 Tokens lieferte überhaupt keinen Inhalt. Das Standard-max_tokens beträgt 32.768, und ein längeres Ergebnis wird abgeschnitten. Bemessen Sie die Obergrenze nach der sichtbaren Antwort plus einigen tausend Tokens Denkspielraum, nicht nach dem Maximum von 384.000.

Beginnen Sie die Extraktion mit niedrigem Effort (Low). Wenn dabei eine nötige Unterscheidung verloren geht, probieren Sie High für diesen Datensatz, statt jede Zeile teurer zu machen. Nutzen Sie bei großen Eingaben die Streaming-Schnittstelle.

Zuerst im Playground ausprobieren

  1. Öffnen Sie DeepSeek V4.1 Flash, wählen Sie Playground und stellen Sie die Effort-Steuerung auf Low.
  2. Tragen Sie die JSON-Vorgabe aus dem Skript unten in System prompt und die Reparaturnotiz R17 in Message to the model ein und klicken Sie auf Run model.
  3. Prüfen Sie, dass eine ausstehende Zustimmung nicht zu einer abgeschlossenen Reparatur wird, bevor Sie Ihre App migrieren.

Einen Testfall laufen lassen, der den teuren Fehler findet

Eine Reparaturnotiz eignet sich gut als Testfall, weil eine flüssige Zusammenfassung auf eine Weise falsch sein kann, die Geld kostet. „Austausch empfohlen“ ist keine Kundenzustimmung, und Zustimmung ist keine erledigte Arbeit.

Legen Sie einen Schlüssel aus API Keys in SPICY_API_KEY, speichern Sie dieses Skript als check_repair.py und führen Sie python3 check_repair.py aus. Der System-Prompt zeigt die JSON-Struktur und enthält das Wort „json“, das der JSON-Modus-Leitfaden von DeepSeek verlangt.

python
import json
import os
import uuid
import urllib.request
import re

SOURCE = (
    'Repair note R17: "Inspected the rear brake pads. Recommend replacement before '
    'the next long ride. Customer approval is pending." No later work record is supplied.'
)
KEYS = {"inspected", "recommended_action", "authorized", "completed", "evidence"}
REQUIRED_QUOTES = (
    "Inspected the rear brake pads.",
    "Recommend replacement before the next long ride.",
    "Customer approval is pending.",
)


def check(response: dict) -> list[str]:
    choice = response["choices"][0]
    problems = []
    if choice.get("finish_reason") != "stop":
        problems.append(f"finish_reason is {choice.get('finish_reason')!r}: the reply may be cut off")
    content = (choice.get("message") or {}).get("content")
    if not content or not content.strip():
        return problems + ["empty content: reasoning may have used the whole max_tokens budget"]
    try:
        data = json.loads(content)
    except json.JSONDecodeError as error:
        return problems + [f"not valid JSON: {error}"]

    if not isinstance(data, dict):
        return problems + ["JSON must be an object"]
    if missing := KEYS - data.keys():
        problems.append(f"missing keys: {sorted(missing)}")
    for key in ("inspected", "authorized", "completed"):
        if data.get(key) is not None and type(data.get(key)) is not bool:
            problems.append(f"{key} must be true, false or null")
    if data.get("inspected") is not True:
        problems.append("inspected should be true")
    if data.get("authorized") is not False:
        problems.append("authorized must be false: approval is pending")
    if data.get("completed") is not None:
        problems.append("completed must be null: no completion record is supplied")
    action = data.get("recommended_action")
    if not isinstance(action, str) or not action.strip():
        problems.append("recommended_action must be a non-empty string")
    else:
        words = set(re.findall(r"[a-z]+", action.lower()))
        # A lexical screen, not a proof of semantic equivalence.
        required = {"rear", "long", "ride"}
        compatible = (required <= words
                      and bool(words & {"replace", "replacement", "replacing"})
                      and bool(words & {"pad", "pads"})
                      and not words & {"not", "no", "never", "front", "after"})
        if not compatible:
            problems.append("review recommendation wording against R17")
    quotes = data.get("evidence")
    if not isinstance(quotes, list) or not quotes:
        problems.append("evidence must be a non-empty list of quotes")
    else:
        problems += [f"invalid or unmatched quote: {q!r}" for q in quotes
                     if not isinstance(q, str) or not q.strip() or q not in SOURCE]
        for expected in REQUIRED_QUOTES:
            if not any(isinstance(q, str) and expected in q for q in quotes):
                problems.append(f"missing supporting quote: {expected}")
    return problems



body = {'model': 'deepseek/v4.1-flash/chat',
 'messages': [{'role': 'system',
               'content': 'Extract only facts stated in the source. Reply with one '
                          'JSON object shaped like {"inspected": null, '
                          '"recommended_action": null, "authorized": null, '
                          '"completed": null, "evidence": []}. inspected, '
                          'authorized and completed are true, false or null; use '
                          'null for anything the source does not state. evidence '
                          'lists exact quotes from the source that support every '
                          'non-null value.'},
              {'role': 'user',
               'content': 'Repair note R17: "Inspected the rear brake pads. '
                          'Recommend replacement before the next long ride. '
                          'Customer approval is pending." No later work record is '
                          'supplied.'}],
 'max_tokens': 2048,
 'reasoning_effort': 'low',
 'response_format': {'type': 'json_object'}}
request = urllib.request.Request(
    "https://api.spicyapi.ai/v1/chat/completions",
    data=json.dumps(body).encode(),
    headers={"Authorization": "Bearer " + os.environ["SPICY_API_KEY"],
             "Content-Type": "application/json",
             "Idempotency-Key": str(uuid.uuid4())},
)
with urllib.request.urlopen(request, timeout=90) as reply:
    response = json.load(reply)
problems = check(response)
print(json.dumps(response.get("usage", {})))
if problems:
    raise RuntimeError("; ".join(problems))
print(response["choices"][0]["message"]["content"])

Erwartet wird: geprüft, Zustimmung weiter ausstehend, Fertigstellung unbekannt. Die Empfehlung muss die hinteren Bremsbeläge und die Frist „vor der nächsten langen Fahrt“ erhalten.

Zustimmung und Fertigstellung als eigene Testfälle ergänzen

Hören Sie nicht beim Fall „Zustimmung ausstehend“ auf. Nutzen Sie diese als Vorlagen für weitere Testfälle: Passen Sie SOURCE, REQUIRED_QUOTES und die erwarteten Werte für Zustimmung und Fertigstellung an, bevor Sie jeden einzelnen ausführen. Die R17-Prüfung lässt sich nicht unverändert gegen R18 oder R19 ausführen:

Letzter EintragAuthorizedCompleted
R17: “Customer approval is pending.” Kein späterer Eintragfalsenull
R18: “Customer approved the quoted replacement. Parts ordered; work scheduled for Thursday.”truenull
R19: “Replaced pads; road check completed Thursday.” Mit dem genehmigten Auftrag verknüpfttruetrue

Halten Sie Auftrags-ID, Reihenfolge der Einträge und Datum bei der Quelle: R18 löst die ausstehende Zustimmung ab, aber die Terminierung der Arbeit belegt noch keine Fertigstellung. Lässt sich eine undatierte „erledigt“-Notiz nicht demselben Auftrag zuordnen, geben Sie die ungeklärte Verknüpfung zurück, statt sie mit R17 zu verschmelzen.

Dieselbe dreiteilige Trennung zeigt sich im Produktions-Workflow eines Creators: „Dieses Charakterdesign freigeben“, „Design freigegeben“ und „Video aus dem freigegebenen Design erzeugt“ sind eine Anfrage, eine Entscheidung und eine Ausführung. Lassen Sie den Extraktions-Prompt diese Stufen getrennt ausgeben, jeweils mit dem Eintrag, der sie belegt, und bewahren Sie Widersprüche zwischen Notizen, statt das Modell den selbstsichersten Satz wählen zu lassen.

Zustimmung und Fertigstellung in Tool-Workflows trennen

Ein Zustimmungseintrag beweist nicht, dass die Reparatur stattgefunden hat: Schlagen Sie den Fertigstellungseintrag nach, bevor Sie den Status ändern, und führen Sie Zustimmung und Fertigstellung in dem, was Ihre Tools zurückgeben, als getrennte Felder.

Chat ohne Tools braucht nichts Zusätzliches. Sind tools in der Anfrage, besteht ein Client, der jede Assistant-Nachricht nur aus Rolle und Inhalt neu aufbaut, den ersten Durchgang und scheitert im zweiten mit einem 400, sodass ein Test mit nur einem Durchgang den Fehler verbirgt. Hängen Sie die Assistant-Nachricht genau so an, wie sie zurückkam, einschließlich reasoning_content, ergänzen Sie dann pro Aufruf eine tool-Nachricht mit der passenden tool_call_id und begrenzen Sie die Zahl der Runden. Testen Sie zwei Durchgänge, nicht einen. Die Chat-Rezepte zeigen die vollständige Schleife.

Einen Agent den Aufruf vorbereiten lassen

Bitten Sie für wiederkehrende Datensatz-Extraktion Ihren Coding-Agent, den SpicyAPI Skill zu nutzen: “Read deepseek/v4.1-flash/chat, then adapt the example to my input; show the request before running it.” Die Abfrage über die CLI lautet spicyapi models get deepseek/v4.1-flash/chat --json; über MCP ist es spicyapi_model_get mit model: "deepseek/v4.1-flash/chat". Chat-Aufrufe laufen über einen kompatiblen Client oder die Chat-API; die Befehle für Medienaufgaben erzeugen keine Chat-Antworten.

Die Rechnung neu berechnen

Die Preise betragen 0,30 $ pro Million ungecachter Eingabe-Tokens, 0,006 $ pro Million gecachter Eingabe-Tokens und 1,20 $ pro Million Ausgabe-Tokens, ein einheitlicher Preis bei jeder Anfragelänge. Ein ungecachter Prompt mit 40.000 Tokens und 2.000 Ausgabe-Tokens kostet 0,0144 $. Werden 30.000 der Eingabe-Tokens als gecacht und 10.000 als ungecacht berechnet, kostet derselbe Aufruf 0,00558 $. Reasoning-Tokens werden als Ausgabe berechnet, daher kann eine kurze sichtbare Antwort mehr Ausgabe verbrauchen als erwartet; nur none hält sie aus der Rechnung heraus.

Beim Verlassen der eigenen DeepSeek-API sind zwei Vergleiche wichtig. Deren Listenpreise betragen zu Spitzenzeiten ebenfalls 0,30, 0,006 und 1,20 $, aber außerhalb der Spitzenzeiten gilt dort der halbe Preis, während es hier einen einheitlichen Preis gibt: Ein Batch, den Sie bei DeepSeek außerhalb der Spitzenzeiten laufen lassen, kostet bei SpicyAPI für dieselben Tokens etwa das Doppelte. Und der Preis für gecachte Eingabe beträgt ein Fünfzigstel des Eingabepreises, aber nur für ein Präfix, das von Aufruf zu Aufruf Byte für Byte identisch ist: Ein System-Prompt mit 1.500 Tokens über 10.000 Aufrufe sind 15 Millionen Eingabe-Tokens, 4,50 $ ungecacht und höchstens 0,09 $, wenn jeder davon ein Cache-Treffer wäre. Vergleichen Sie die zurückgegebene usage und die abgerechneten Kosten mit diesen Schätzungen. Ein Zeitstempel oder umgestellte Anweisungen können ein gemeinsames Präfix brechen; unveränderte Eingabe allein garantiert keinen Cache-Treffer.

Wo jede DeepSeek-Route landet

V4.1 FlashV4 FlashV4 Pro
Modell-IDdeepseek/v4.1-flash/chatdeepseek/v4-flash/chatdeepseek/v4-pro/chat
Max. Ausgabe384.00065.536384.000
Eingabe / gecacht / Ausgabe pro 1 Mio.0,30 $ / 0,006 $ / 1,20 $0,44 $ / 0,014 $ / 1,32 $1,32 $ / 0,044 $ / 3,96 $
parallel_tool_callsNicht verfügbarNicht verfügbarVerfügbar

Alle drei nehmen 1.048.576 Eingabe-Tokens, den Effort none, low oder high (Standard high) und ein Standard-max_tokens von 32.768. Beim Wechsel von deepseek/v4-flash/chat ist der Anfrage-Body identisch, nur die ID ändert sich: Die Ausgabegrenze wächst fast um das Sechsfache, und alle Preise sinken. Beim Wechsel von V4 Pro verlieren Sie parallel_tool_calls und zahlen 77 % weniger für Eingabe und etwa 70 % weniger für Ausgabe. Ob V4 Flash oder V4 Pro für eine bestimmte Aufgabe besser passt, ist eine eigene Entscheidung, die DeepSeek V4 Flash vs. Pro behandelt.

Wenn Ihre App Erwachsenenfiktion schreibt

V4.1 Flash ist bei SpicyAPI als unzensiert gelistet, aber das ist kein Versprechen, dass es jede Anfrage für Erwachsenenfiktion vollständig erfüllt. In unseren Tests im September 2026 kamen direkte Anfragen nach intensiven Szenen für Erwachsene jedes Mal abgeschwächt zurück, während die Einrahmung als Fiktion oder ein im System-Prompt gesetzter Rahmen mehr davon vollständig ausgab, wenn auch nicht alle (Details im Testbericht zu V4.1 Flash). Wurden Ihre Prompts für ein Modell geschrieben, das Anfragen ohne Rahmung akzeptierte, verlegen Sie den Rahmen bei der Migration in die System-Nachricht und halten Sie jede Figur erwachsen.

Migrationsfehler direkt beheben

SymptomWahrscheinliche UrsacheKorrektur
400 unsupported_parameter mit temperature, top_p, einem Penalty-Feld, parallel_tool_calls oder thinkingFeld aus dem alten Client übernommenLöschen
content ist leer oder finish_reason ist lengthmax_tokens für Reasoning verbraucht, oder die Antwort überschritt esmax_tokens erhöhen, Effort senken, erneut versuchen
JSON lässt sich parsen, meldet aber erledigte ArbeitEmpfehlung als Fertigstellung gelesenGetrennte Felder führen, Zitate verlangen, Prüfskript ausführen
Fehler im zweiten Durchgang einer Tool-KonversationAssistant-Nachricht ohne reasoning_content neu aufgebautDie zurückgegebene Nachricht unverändert anhängen
402 trotz ausreichendem GuthabenDie Reservierung (Hold) 40201 übersteigt das Guthaben, oder das Ausgabenlimit 40202 ist erreichtDen Fehler prüfen: ein übermäßiges Ausgabebudget für den Hold verringern oder die Limits des Schlüssels bzw. Workspaces prüfen
Wiederverwendeter Idempotency-Key abgelehnt (400 oder 409)Der Schlüssel gehört zu einer abgeschlossenen Anfrage oder zu einem anderen BodyEin 400 bei einer abgeschlossenen Anfrage kann die Antwort nicht erneut ausliefern; 409 kann einen geänderten Body bedeuten. Den Schlüssel nur für einen identischen Netzwerk-Wiederholungsversuch innerhalb seines Zeitfensters wiederverwenden; vor einem neuen kostenpflichtigen Aufruf die Abrechnung der Aufgabe prüfen
Ein langer Aufruf ohne Streaming bricht nach etwa 100 Sekunden abAbbruch am NetzwerkrandDie Antwort streamen

Umschalten, ohne die alte Vergleichsbasis zu verlieren

Behalten Sie die alte Modell-ID in der Konfiguration und führen Sie den Testfall mit beiden aus. Verlagern Sie den Traffic, sobald er mit der neuen ID besteht, Ihre eigenen Quellen validiert sind und die geloggte usage zur obigen Rechnung passt.

Auch in English · 日本語 · 한국어 · Français · Español · Português (Brasil) · Русский · Italiano · Polski

Selbst ausprobieren

Sie zahlen nur für das, was Sie ausführen – ohne Tarif, ohne Abo.

Erstellt mit MiniMax H3 · ByteDance Seedance 2.0 Fast