Chat, Streaming, Tool Calling
Chat geht über zwei Endpunkte: /v1/chat/completions im OpenAI-Format und /v1/messages im Anthropic-Format. Beide nehmen dieselben Modelle aus der Modellliste (Kategorie Chat).
Streaming
Beide Endpunkte streamen per Server-Sent Events, wenn du "stream": true setzt.
- curl
- Python
- TypeScript
- Anthropic (Python)
curl -N https://api.openhippo.io/v1/chat/completions \
-H "Authorization: Bearer $OPENHIPPO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openhippo/gpt-oss-120b",
"stream": true,
"messages": [{"role": "user", "content": "Explain SSE in two sentences."}]
}'
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.openhippo.io/v1", api_key=os.environ["OPENHIPPO_API_KEY"])
stream = client.chat.completions.create(
model="openhippo/gpt-oss-120b",
messages=[{"role": "user", "content": "Explain SSE in two sentences."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.openhippo.io/v1",
apiKey: process.env.OPENHIPPO_API_KEY,
});
const stream = await client.chat.completions.create({
model: "openhippo/gpt-oss-120b",
messages: [{ role: "user", content: "Explain SSE in two sentences." }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
process.stdout.write("\n");
import os
from anthropic import Anthropic
client = Anthropic(base_url="https://api.openhippo.io", auth_token=os.environ["OPENHIPPO_API_KEY"])
with client.messages.stream(
model="openhippo/gpt-oss-120b",
max_tokens=512,
messages=[{"role": "user", "content": "Explain SSE in two sentences."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print()
Tool Calling
Tool Calling (Function Calling) im OpenAI-Format ist in unseren Tests abgedeckt für:
- selbst gehostet:
openhippo/Qwen3-VL-30B-A3B-Instruct(hippo-vision),openhippo/Qwen3.8-27B(hippo-coding),openhippo/gpt-oss-120b(hippo-chat-large), - Partner:
aki-io/glm5.3-754b,aki-io/qwen3.6-35b,aki-io/deepseek-v4.1-flash-552b,mistral/mistral-large-4,mistral/glm-5.3,telekom/glm-5.2,telekom/qwen3.6-35b,tensorx/glm-5.3-flash,tensorx/kimi-k3,tensorx/deepseek-v4-pro.
Getestet sind einfache Aufrufe, mehrere Tools zur Auswahl und Streaming mit Tools, jeweils mit tool_choice: "auto".
import json, os
from openai import OpenAI
client = OpenAI(base_url="https://api.openhippo.io/v1", api_key=os.environ["OPENHIPPO_API_KEY"])
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
messages = [{"role": "user", "content": "What is the weather in Augsburg?"}]
response = client.chat.completions.create(model="openhippo/gpt-oss-120b", messages=messages, tools=tools)
message = response.choices[0].message
if not message.tool_calls:
print(message.content) # answered without a tool
else:
messages.append(message)
for call in message.tool_calls:
args = json.loads(call.function.arguments)
print(call.function.name, args)
result = {"city": args.get("city"), "temp_c": 14} # your tool's result
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
final = client.chat.completions.create(model="openhippo/gpt-oss-120b", messages=messages, tools=tools)
print(final.choices[0].message.content)
Ob das Modell ein Tool aufruft, entscheidet es selbst; das Beispiel prüft deshalb tool_calls, bevor es darauf zugreift.
Noch nicht dokumentiert: andere tool_choice-Werte als "auto" (z. B. ein erzwungenes Tool oder "none") und parallele Tool-Aufrufe (parallel_tool_calls). Fragen: support@openhippo.io.
Bilder
Bilder verstehen nur Modelle der Kategorie Vision (siehe Modelle). Das Bild geht als image_url mit, entweder als URL oder als Data-URI (data:image/png;base64,...):
import base64, os
from openai import OpenAI
client = OpenAI(base_url="https://api.openhippo.io/v1", api_key=os.environ["OPENHIPPO_API_KEY"])
with open("photo.jpg", "rb") as f:
image = base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model="hippo-vision",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What is in this picture?"},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image}"}},
],
}],
)
print(response.choices[0].message.content)
Einige Modelle ohne eigenes Bildverständnis haben einen Alias mit der Endung -vision. Dort beschreibt ein Vision-Modell desselben Anbieters das Bild zuerst; dieser Beschreibungsschritt wird zusätzlich abgerechnet. Welches Modell beschreibt: Vision-Aliase.
OCR
Texterkennung läuft über Chat Completions mit dem Modell openhippo/GLM-OCR und einem Bild pro Request. Das Bild geht als URL oder als Data-URI mit:
import base64, os
from openai import OpenAI
client = OpenAI(base_url="https://api.openhippo.io/v1", api_key=os.environ["OPENHIPPO_API_KEY"])
with open("invoice.png", "rb") as f:
image = base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model="openhippo/GLM-OCR",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Output the text of this document."},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image}"}},
],
}],
)
print(response.choices[0].message.content)
Reasoning
reasoning_effort (OpenAI-Format) und thinking (Anthropic-Format) werden auf die Stufen des jeweiligen Modells abgebildet.
Für hippo-coding gilt:
- Stufen
low,medium,xhigh; Standard istxhigh. - Andere Werte werden auf die nächsthöhere Stufe gerundet (z. B.
high→xhigh). "none"schaltet das Reasoning aus.
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.openhippo.io/v1", api_key=os.environ["OPENHIPPO_API_KEY"])
response = client.chat.completions.create(
model="hippo-coding",
reasoning_effort="low",
messages=[{"role": "user", "content": "Write a Python function that checks for primes."}],
)
print(response.choices[0].message.content)
Bekannte Grenzen
- Unbekannte Parameter werden stillschweigend verworfen, statt einen Fehler zu erzeugen.
- Tool Calling ist nur für die oben genannten Modelle getestet.
- OCR mit
openhippo/GLM-OCR: ein Bild pro Request, siehe OCR. /v1/responsesunterstützt nur das Anlegen einer Antwort, kein Abrufen oder Löschen.