JavaScript-Beispiele
Chat Completions
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://llm.aihosting.mittwald.de/v1" });
const resp = await client.chat.completions.create({
model: "Devstral-Small-2-24B-Instruct-2512",
messages: [{ role: "user", content: "Hallo aus JS!" }],
});
console.log(resp.choices[0].message.content);
Vision (Bild + Text)
Die Vision-Modelle auf mittwald AI Hosting akzeptieren Bilder ausschließlich als Base64-kodierte Data-URLs. Das Senden von Bild-URLs wird nicht unterstützt und führt zu einem Serverfehler.
Bilder kodieren und verkleinern
Installiere sharp für die Bildverarbeitung:
npm install sharp
Immer vor dem Senden verkleinern. Große Bilder erhöhen die Wartezeit bis zum ersten Token (TTFT) erheblich. Eine maximale Kantenlänge von 1024 px ist ein sicherer Standardwert:
import sharp from "sharp";
async function encodeImage(path: string, maxPx = 1024): Promise<string> {
const img = sharp(path);
const { width = 0, height = 0 } = await img.metadata();
const longest = Math.max(width, height);
const resized =
longest > maxPx
? img.resize(width >= height ? maxPx : undefined, height > width ? maxPx : undefined)
: img;
const buf = await resized.jpeg({ quality: 85 }).toBuffer();
return `data:image/jpeg;base64,${buf.toString("base64")}`;
}
Eine Vision-Anfrage stellen
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://llm.aihosting.mittwald.de/v1" });
const resp = await client.chat.completions.create({
model: "Ministral-3-14B-Instruct-2512",
messages: [
{
role: "user",
content: [
{ type: "text", text: "Beschreibe dieses Bild detailliert." },
{ type: "image_url", image_url: { url: await encodeImage("foto.jpg") } },
],
},
],
temperature: 0.1,
max_tokens: 512,
});
console.log(resp.choices[0].message.content);
Modell auswählen
| Modell | Max. Bilder | Stärken |
|---|---|---|
Qwen3.5-122B-A10B-FP8 | 20+ | Beste Genauigkeit, OCR, komplexe Szenen |
Ministral-3-14B-Instruct-2512 | 4 | Ausgewogenes Verhältnis von Geschwindigkeit und Qualität |
Qwen3.6-35B-A3B-FP8 | 5+ | Schnell bei wiederholten Anfragen |
Devstral-Small-2-24B-Instruct-2512 | 4 | Code-Workflows mit Bildern |
Bei Qwen-Modellen sollte der Thinking-Modus deaktiviert werden, um unnötigen Overhead zu vermeiden:
const resp = await client.chat.completions.create({
model: "Qwen3.5-122B-A10B-FP8",
messages: [
{
role: "user",
content: [
{ type: "text", text: "Extrahiere den gesamten Text aus diesem Dokument." },
{ type: "image_url", image_url: { url: await encodeImage("dokument.jpg") } },
],
},
],
temperature: 0.7,
max_tokens: 1024,
// @ts-expect-error vLLM-spezifischer Parameter, nicht in OpenAI-Typen enthalten
extra_body: { chat_template_kwargs: { enable_thinking: false } },
});
console.log(resp.choices[0].message.content);
Tool-calling (Funktionsaufrufe)
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://llm.aihosting.mittwald.de/v1" });
const tools = [
{
type: "function",
function: {
name: "get_weather",
description: "Aktuelle Wetterdaten für eine Stadt abrufen",
parameters: {
type: "object",
properties: {
city: { type: "string", description: "Stadtname" },
},
required: ["city"],
},
},
},
];
const resp = await client.chat.completions.create({
model: "Devstral-Small-2-24B-Instruct-2512",
messages: [{ role: "user", content: "Wie ist das Wetter in München?" }],
tools,
tool_choice: "auto",
});
const toolCall = resp.choices[0].message.tool_calls?.[0];
if (toolCall) {
console.log(`Funktion: ${toolCall.function.name}`);
console.log(`Argumente: ${toolCall.function.arguments}`);
}
Streaming-Antworten
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://llm.aihosting.mittwald.de/v1" });
const stream = await client.chat.completions.create({
model: "Devstral-Small-2-24B-Instruct-2512",
messages: [
{
role: "user",
content: "Schreibe ein kurzes Gedicht über das Programmieren",
},
],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || "";
process.stdout.write(content);
}