Praktyczny przewodnik po odpowiedziach w postaci zwykłego tekstu i JSON
Lekcje wyciągnięte podczas tworzenia 12-osobowej symulacji Jeopardy zasilanej przez AI Ministral-3-14B-Instruct-2512.
Uruchomienie Ministral-3 na vLLM Jest zaskakująco potężny. Model jest szybki, kreatywny i potrafi generować wysokiej jakości odpowiedzi nawet pod dużym obciążeniem.
Ale gdy przejdziesz od prostych podpowiedzi w czacie do strukturyzowane dane wyjściowe, automatyzacja lub użycie programistyczneszybko robi się skomplikowane.
W trakcie tworzenia Gra oparta na sztuczeniu maszynowym Jeopardy z 12 jednoczesnymi graczami i setkami wywołań modelunatrafiliśmy na kilka praktycznych problemów:
Ten przewodnik podsumowuje praktyczne wnioski wyciągnięte podczas rozwiązywania tych problemóworaz konkretnymi wzorcami, które możesz ponownie wykorzystać w swoich projektach.
Nasz projekt porównawczy symuluje pełną grę Jeopardy, w której:
Pojedynczy przebieg gry może łatwo przekroczyć 800 wywołań API.
To środowisko ujawniło przypadki brzegowe, które rzadko pojawiają się w prostych demonstracjach — co czyni je doskonałym środowiskiem testowym do zrozumienia, jak Ministral zachowuje się w rzeczywistych warunkach produkcyjnych.
Modele Ministral nie używaj standardowej konfiguracji tokenizera HuggingFace.
Oznacza to, że polecenie uruchamiające musi wyraźnie włączyć Format tokenizera Mistral.
vllm serve mistralai/Ministral-3-14B-Instruct-2512 \
--tokenizer_mode mistral \
--config_format mistral \
--load_format mistral
Jeśli Twoja aplikacja polega na wywoływanie funkcji, dodaj flagi narzędzi:
--enable-auto-tool-choice
--tool-call-parser mistral
W przeciwieństwie do niektórych innych modeli, Ministral nie obsługuje chat_template_kwargs.
Jeśli wyślesz żądanie w następujący sposób:
{
"chat_template_kwargs": {
"enable_thinking": false
}
}
vLLM zwraca:
HTTP 400: chat_template is not supported for Mistral tokenizers
Oznacza to funkcje takie jak przełączanie "trybu myślenia" (stosowane z modelami takimi jak Qwen lub DeepSeek) są po prostu niedostępne.
Na szczęście, rzadko jest to potrzebne, ponieważ Ministral domyślnie generuje zwięzłe odpowiedzi.
Ten oficjalna dokumentacja vLLM konsekwentnie używa następującej wartości z Ministral-3:
temperature = 0.15
Na pierwszy rzut oka wydaje się to niezwykle niskie. Jednak okazuje się, że tak jest. krytyczne dla zadań strukturalnych.
Korzystając z domyślnych ustawień w stylu OpenAI:
temperature: 0.7
model staje się nadmiernie kreatywny pod względem struktury.
Proste zapytanie takie jak:
{ "expertise": "2-3 topics they know best" }
może zwrócić coś takiego:
{
"expertise": [
{
"category": "Gourmet Pizza Alchemy",
"detail": "Can transform random ingredients into Michelin-star pizza"
},
{
"category": "Sumo Wrestling Physics",
"detail": "Understands body mechanics and center-of-gravity combat"
}
]
}
Technicznie poprawny JSON, ale... nie to, czego wymaga schemat.
W efekcie:
max_tokens przekroczono limity0.15 działa lepiejW niskiej temperaturze model staje się strukturalnie zdyscyplinowany.
temperature: 0.15
Korzyści:
Nawet generowanie kreatywnych tekstów pozostaje silne — model po prostu przestaje improwizować ze strukturą.
Rekomendacja:
Użyj temperature: 0.15 jako domyślne ustawienie dla Ministral-3.
Generowanie JSON czytelny maszynowo Generowanie czytelnego JSON z LLM jest trudniejsze niż się wydaje.
Ministral ma tendencję do interpretacji pól schematu semantycznie zamiast strukturalnie, co prowadzi do głęboko zagnieżdżonej struktury wyjściowej.
Na przykład zapytanie:
Return JSON with these fields.
często generuje rozbudowane struktury.
Przykładowe zapytanie:
{ "expertise": "2-3 topics they know best" }
Typowa odpowiedź:
{
"expertise": [
{
"category": "Ancient Roman Engineering",
"detail": "Knows aqueduct systems in surprising detail"
},
{
"category": "Pizza Dough Chemistry",
"detail": "Obsessed with yeast fermentation dynamics"
}
]
}
To zużywa trzy razy więcej niż oczekiwane tokeny.
Najbardziej niezawodnym rozwiązaniem jest połączenie dwie instrukcje.
Respond with ONLY valid JSON.
No markdown, no explanation, no text before or after the JSON.
Keep values as short plain strings — never use nested objects or arrays.
Bezpośrednio obok definicji schematu:
Every value MUST be a short plain string — NO arrays, NO nested objects.
Połączony z 0.15co powoduje przewidywalny, płaski JSON.
Nawet przy ograniczeniach, Ministral ma tendencję do generowania dłuższe wartości niż w przypadku innych modeli.
Przykładowa obserwacja z naszego benchmarku:
| Model | Liczba tokenów wymagana |
|---|---|
| GPT-4o | ~512 |
| Qwen | ~512 |
| Ministral-3 | ~1024 |
Bezpieczna zasada:
Ustal budżet na 1,5–2× więcej tokenów dla danych wyjściowych JSON.
Nawet przy idealnych promptach, modele czasem generują nieprawidłowy JSON.
Dobrą strategią jest dodanie warstwy defensywnej analizy składniowej.
function extractJSON(raw, shape) {
var text = raw.replace(/^```(?:json)?\s*/i, '').replace(/\s*```$/i, '').trim();
if (shape === 'array') {
var m = text.match(/\[[\s\S]*\]/);
if (m) text = m[0];
} else {
var m = text.match(/\{[\s\S]*\}/);
if (m) text = m[0];
}
return text;
}
Śledź otwarte nawiasy i automatycznie je zamykaj:
var stack = [];
var inStr = false, esc = false;
for (var i = 0; i < text.length; i++) {
var ch = text[i];
if (esc) { esc = false; continue; }
if (ch === '\\') { esc = true; continue; }
if (ch === '"') { inStr = !inStr; continue; }
if (inStr) continue;
if (ch === '{') stack.push('}');
else if (ch === '[') stack.push(']');
else if (ch === '}' || ch === ']') stack.pop();
}
text = text.replace(/,\s*$/, '');
while (stack.length > 0)
text += stack.pop();
Jeśli model nadal zwraca zagnieżdżone struktury:
if (Array.isArray(value)) {
flat = value.map(function(item) {
if (typeof item === 'string') return item;
if (typeof item === 'object') return Object.values(item).join(' — ');
return String(item);
}).join(', ');
}
Prosta pętla ponownych prób dramatycznie zwiększa niezawodność.
Ponieważ Ministral zachowuje się konsekwentnie w niskiej temperaturzepowtórne próby zwykle się powadzą.
Zalecane:
2–3 retry attempts
Ministral uwielbia formatowanie.
Nawet jeśli poprosisz o zwykły tekst, to ma tendencję do generowania:
Dzieje się tak, ponieważ model jest dostarczany z wbudowanym zachęta do formatowania bogatych markdown w poleceniu systemowym.
Wiele potoków opiera się na prostych sprawdzeniach ciągów znaków.
Przykład:
verdict.toUpperCase().startsWith('CORRECT')
Jeśli model zwróci:
**CORRECT**
Sprawdzenie się nie powiodło.
Najbezpieczniejszym podejściem jest znormalizuj wszystkie wyjścia przed przetwarzaniem.
function stripMarkdown(text) {
if (!text) return text;
var s = text.replace(/\*\*([^*]+)\*\*/g, '$1');
s = s.replace(/__([^_]+)__/g, '$1');
s = s.replace(/\*([^*]+)\*/g, '$1');
s = s.replace(/^#{1,6}\s+/gm, '');
s = s.replace(/`([^`]+)`/g, '$1');
s = s.replace(/^```[a-z]*\s*$/gm, '');
return s.trim();
}
Zastosuj to do każdej odpowiedzi modelu, nie tylko Ministral.
Pozwala to uniknąć rozgałęzień specyficznych dla modelu i utrzymuje spójność potoków.
Jeśli Twój system obsługuje wiele rodzin modeli (Mistral, Qwen, DeepSeek, Llama itp.), najbardziej przejrzysty projekt to skoncentruj zachowanie modelu w jednym miejscu.
Przykład:
function buildModelProfile(modelName) {
var lower = modelName.toLowerCase();
var isMistral = lower.includes('mistral') || lower.includes('ministral');
return {
family: isMistral ? 'Mistral' : 'Generic',
jsonSystemInstruction: isMistral
? 'Respond with ONLY valid JSON. No markdown. Keep values as short plain strings.'
: 'You output only valid JSON. No markdown fences, no explanation.',
jsonSchemaHint: isMistral
? ' Every value MUST be a short plain string — NO arrays, NO nested objects.'
: '',
jsonTemperature: isMistral ? 0.15 : 0.7,
defaultTemperature: isMistral ? 0.15 : 0.7,
plainTextInstruction: ' Do not use markdown formatting.'
};
}
Pozwala to na zachowanie reszty Twojego systemu. niezależny od modelu.
Dodawanie nowego modelu później staje się trywialne.
| Ustawienie | Zalecana wartość | Powód |
|---|---|---|
| tokenizer_mode | mistral | Wymagane dla poprawnego tokenizera |
| config_format | mistral | Wymagane |
| load_format | mistral | Wymagane |
| chat_template_kwargs | Nie wysyłaj | Nieobsługiwane |
| temperatura | 0.15 | Zapobiega halucynacjom strukturalnym |
| Instrukcja JSON | Jawne wartości płaskie | Unikaj zagnieżdżonych obiektów |
| max_tokens | 1,5–2× typowy | Model jest rozwlekły |
| Usuwanie formatowania Markdown | Zawsze | Zapobiegaj błędom formatowania |
| Ponowne próby JSON | 2–3 próby | Niezawodna regeneracja |
Ministral-3 działa wyjątkowo dobrze po odpowiednim dostrojeniu.
Kiedy już:
model staje się zdumiająco przewidywalny i gotowy do produkcji.
W naszym teście porównawczym Jeopardy, ta konfiguracja obsługiwała:
Wszystko działa lokalnie na Infrastruktura GPU Trooper.AI.
Wypróbuj pełny szablon wdrożenia vLLM tutaj: Serwer kompatybilny z vLLM OpenAI
Wypożycz swój własny serwer GPU już dziś i zacznij tworzyć niesamowite aplikacje AI! Serwery GPU Trooper.AI są zbudowane z wyselekcjonowanego, wysokiej klasy sprzętu z ostatnich lat, zaprojektowane, aby zapewnić Ci najlepszą wydajność, bezpieczeństwo i niezawodność dla wszystkich Twoich potrzeb związanych ze sztuczną inteligencją.
Lokalizacja w UE · Wysoka prywatność · Świetna wydajność · Najlepsze wsparcie