Python-Beispiele
Die Nutzung der Modelle innerhalb von Programmiersprachen kann komfortabel über bestehende Libraries stattfinden, welche die OpenAI-API unterstützen. Somit kann mittwalds AI-Hosting in vielen Fällen als Drop-In-Replacement genutzt werden.
Für die folgenden Beispiele müssen zunächst über einen Python-Paketmanager die Libraries installiert werden und der im mStudio generierte API-Key in einer .env-Datei hinterlegt werden:
pip install python-dotenv openai langchain-openai
echo 'OPENAI_API_KEY="sk-…"' > .env
Anschließend kann über das OpenAI-Paket ein Modell angesprochen werden:
from openai import OpenAI
from dotenv import load_dotenv
# Load .env file
load_dotenv()
# Initialize client with custom host and key from environment
client = OpenAI(
base_url="https://llm.aihosting.mittwald.de/v1"
)
# Make a simple call
response = client.chat.completions.create(
model="Ministral-3-14B-Instruct-2512",
temperature = 0.15,
messages=[
{"role": "user", "content": "Moin und hallo!"}
]
)
print(response.choices[0].message.content)
Alternativ kann auch langchain verwendet werden:
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
# Load .env file
load_dotenv()
# Initialize client with custom host and key from environment
chat = ChatOpenAI(
model="Ministral-3-14B-Instruct-2512",
base_url="https://llm.aihosting.mittwald.de/v1",
temperature = 0.15
)
# Get response
response = chat.invoke([
HumanMessage(content="Moin and hello!")
])
print(response.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 Pillow für die Bildverarbeitung:
pip install Pillow
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, der für die meisten Aufgaben ausreichend Qualität liefert:
import base64
import io
from PIL import Image
def encode_image(path: str, max_px: int = 1024) -> str:
"""Bild auf max_px an der längsten Seite skalieren und als Base64-Data-URL zurückgeben."""
with Image.open(path) as img:
w, h = img.size
scale = min(1.0, max_px / max(w, h))
if scale < 1.0:
img = img.resize((int(w * scale), int(h * scale)), Image.LANCZOS)
buf = io.BytesIO()
img.save(buf, format="JPEG", quality=85)
b64 = base64.b64encode(buf.getvalue()).decode()
return f"data:image/jpeg;base64,{b64}"
Eine Vision-Anfrage stellen
from openai import OpenAI
client = OpenAI(base_url="https://llm.aihosting.mittwald.de/v1")
resp = 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": encode_image("foto.jpg")}},
]
}],
temperature=0.1,
max_tokens=512,
)
print(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:
resp = 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": encode_image("dokument.jpg")}},
]
}],
temperature=0.7,
max_tokens=1024,
extra_body={"chat_template_kwargs": {"enable_thinking": False}},
)
print(resp.choices[0].message.content)
Tool-Calling (Function Calling)
from openai import OpenAI
client = OpenAI(base_url="https://llm.aihosting.mittwald.de/v1")
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Aktuelles Wetter abrufen",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}
]
resp = client.chat.completions.create(
model="Devstral-Small-2-24B-Instruct-2512",
messages=[{"role": "user", "content": "Wie ist das Wetter in Berlin?"}],
tools=tools,
tool_choice="auto"
)
# Prüfen, ob das Modell ein Tool aufgerufen hat
if resp.choices[0].message.tool_calls:
call = resp.choices[0].message.tool_calls[0]
print(f"Funktion: {call.function.name}")
print(f"Argumente: {call.function.arguments}")
Streaming-Antworten
from openai import OpenAI
client = OpenAI(base_url="https://llm.aihosting.mittwald.de/v1")
stream = 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 chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)