Wat de frase betekent
Gebruikers gebruiken "lokale LLM OpenAI API" voor twee gerelateerde dingen. De eerste is een taalmodel dat jij zelf draait, op een laptop of een thuisserver, dat luistert op een lokale poort en het OpenAI-chatformaat spreekt. De tweede is de gewoonte om je app op dat formaat te bouwen, zodat het model erachter verwisseld kan worden.
Het formaat is een eenvoudig contract. Je app stuurt een JSON-body met een model-naam en een lijst van messages, elk met een role van system, user of assistant. De server antwoordt met een JSON-object met de gegenereerde boodschap, of met een stream van kleine chunks als je om streaming vraagt. Officiële SDK's voor Python en JavaScript verpakken dit, en ze laten je de base URL overschrijven, wat de hele truc is.
Veel lokale tools bieden dit contract. Ollama, LM Studio, de llama.cpp-server en vLLM bieden elk een OpenAI-stijl route. Gehoste diensten doen dat ook, vandaar dat dezelfde twintig regels clientcode met beide endpoints kunnen communiceren. Het endpoint op deze site is een van de gehoste diensten. Het accepteert POST /v1/chat/completions en GET /v1/models, en het is bereikbaar via https://api.onekeyllmapi.com/v1.
Lokaal versus gehost in één oogopslag
Geen van beide is over het algemeen beter. Ze ruilen controle in voor inspanning. De tabel houdt zich aan verschillen die voor de categorie gelden, niet voor een specifiek product.
| Vraag | Lokale runner | Gehost OpenAI-achtige API |
|---|---|---|
| Waar prompts heen gaan | Blijft op je machine | Reis naar de provider via HTTPS |
| Hardware | Je levert GPU of CPU en geheugen | Niets aan jouw kant |
| Modelgrootte | Beperkt door je geheugen | Wat de provider serveert |
| Kostemodel | Hardware en stroom | Per token, van prepaid tegoed hier |
| Beschikbaarheid | Zolang je machine aan staat | Altijd-aan server, gedeelde limieten |
| Instellen | Installeren, gewichtswaarden downloaden, afstellen | Een sleutel aanmaken, de base URL instellen |
Als je data nooit een machine mag verlaten die jij beheert, wint lokaal en is gehost het verkeerde hulpmiddel. Als je een groter model nodig hebt dan je hardware aankan, of een bot die vanuit veel plekken bereikbaar moet blijven, wint gehost. Een veelvoorkomende configuratie houdt beide aan en kiest per taak.
Een client van lokaal naar gehost verplaatsen
Als je code al met een lokale runner praat, is de verplaatsing drie waarden. Alles anders, inclusief hoe je berichten bouwt en gestreamde chunks leest, blijft hetzelfde.
- Base URL. Gebruik
https://api.onekeyllmapi.com/v1in plaats van je lokale adres. - API-sleutel. Lokale servers negeren vaak de sleutel. Een gehoste vereist hem als
Authorization: Bearer <key>, en de SDK stuurt hem voor je. - Model ID. Lokale namen zijn wat jij hebt opgehaald. Hier is de ID
uncensored.
Een nette manier om dit flexibel te houden is om alle drie uit omgevingsvariabelen te lezen, zodat één bestand op beide plekken werkt.
import os
from openai import OpenAI
client = OpenAI(
base_url=os.environ.get("LLM_BASE_URL", "https://api.onekeyllmapi.com/v1"),
api_key=os.environ.get("LLM_API_KEY", "YOUR_KEY"),
)
MODEL = os.environ.get("LLM_MODEL", "uncensored")
models = client.models.list()
print([m.id for m in models.data])
resp = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": "Answer in two sentences."},
{"role": "user", "content": "Why do OpenAI-style endpoints make switching models easy?"},
],
temperature=0.5,
)
print(resp.choices[0].message.content)
Dezelfde call vanaf de command line, nuttig voor een snelle rooktest:
curl https://api.onekeyllmapi.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "uncensored", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 20}'
Met Node is het patroon identiek:
import OpenAI from "openai";
const client = new OpenAI({
baseURL: process.env.LLM_BASE_URL ?? "https://api.onekeyllmapi.com/v1",
apiKey: process.env.LLM_API_KEY,
});
const res = await client.chat.completions.create({
model: process.env.LLM_MODEL ?? "uncensored",
messages: [{ role: "user", content: "Name three uses for JSON mode." }],
});
console.log(res.choices[0].message.content);
Wat OpenAI-compatible wel en niet dekt
Compatibel betekent dat het wire format overeenkomt. Het belooft niet dat elk feature dat de originele dienst aanbiedt aanwezig is. Voordat je een echte app migreert, controleer elk van deze tegen de functie.
Wat deze API ondersteunt
- Chatvoltooiingen bij
POST /v1/chat/completionsen een modellijst bijGET /v1/models. - Streaming over server-sent events met
stream: true, met usage gerapporteerd aan het einde van de stream. - Tool calling via
toolsentool_choice, gestreamdtool_calls, en resultaten terug gestuurd alsrole: "tool"berichten. - JSON-modus via
response_format: {"type": "json_object"}. - Samplingcontroles: temperature, top_p, stop, seed en de penaltyparameters worden doorgegeven.
Wat het niet doet
- Geen afbeeldingen, audio of video generatie. Het is alleen tekst.
- Geen embeddings endpoint en geen fine-tuning. Als je app een vectorindex bouwt, heb je een aparte embeddingbron nodig.
- Slechts één model. Het model is een open-weight model dat wordt beheerd door een onafhankelijke provider. Het is niet de officiële API van een grote leverancier, en het is geen router tussen leveranciers, dus je kunt niet tussen modelfamilies kiezen door de ID te wijzigen.
Lokale runners verschillen soms de andere kant op: een lokale server kan een embeddings route aanbieden of je meerdere modellen laden, en de context size is wat je configureert. Lees de docs van de target voor elk, en houd een korte lijst bij van de features die je app echt gebruikt. De quickstart docs tonen de request velden in full.
Context, limieten en kostverschillen
Drie nummers veranderen als je een lokale server verlaat. Het eerste is het window. De context length van een lokale runner is een setting gekoppeld aan je geheugen. Hier is het vast op 100.000 tokens, gedeeld door de prompt en de completion, en max_tokens is optioneel. Het tweede is concurrency. Je eigen machine kan zo diep in de wachtrij staan als je wilt, maar een full key hier staat 8 gelijktijdige verzoeken en 300 per minuut toe, en een trial key 2 en 60. Het derde is de rekening.
Gehost gebruik kost $0,15 per 1M input tokens en $0,50 per 1M output tokens, betaal per gebruik van prepaid credit. Werk door een dagelijkse taak als voorbeeld: een summarizer verwerkt 400 documenten per dag, elk 3.000 tokens in en 300 tokens out. Input is 400 x 3.000 = 1.200.000 tokens, wat 1,2 x $0,15 = $0,18 kost. Output is 400 x 300 = 120.000 tokens, wat 0,12 x $0,50 = $0,06 kost. De dag totaal is $0,24, en een 30 dagen maand is $7,20. Vergelijk dat met de kosten van het draaiende houden van een GPU en van de kaart zelf voordat je besluit.
Wanneer je een limit overschrijdt, antwoordt de API HTTP 429 met de code rate_limited of concurrency. Voor korte overload voegt het Retry-After: 5 toe. Houd retry logica aan die wacht en probeert opnieuw. Verzoeken die falen of geweigerd worden worden niet gefactureerd. Credit verloopt nooit, dus een idle maand kost niets.
Een gestreamd verzoek houdt zijn concurrency slot vast tot de stream eindigt, dus sluit streams zodra je stopt met lezen. Top-ups beginnen bij $20; de tiers en bonuses staan op de pricing page.
Foutopsporing bij problemen met de overschakeling
De meeste mislukte migraties komen door een handvol oorzaken. Werk ze in deze volgorde af.
- 404- of verbindingsfouten. De basis-URL mist waarschijnlijk de
/v1suffix, of heeft een extra pad. Gebruik het precies alshttps://api.onekeyllmapi.com/v1. - Authenticatiefouten. De key ontbreekt of is gestuurd in de verkeerde header. Het formaat is
Authorization: Bearer <key>. SDK-gebruikers moeten bevestigen dat de omgevingsvariabele daadwerkelijk geladen is. - Model niet gevonden. De oude lokale modelnaam staat nog in je configuratie. Roep
GET /v1/modelsaan en gebruik de ID die het opsomt, watuncensoredis. - 429 onder belasting. Je bent voorbij 8 gelijktijdige verzoeken of 300 per minuut op een volledige sleutel. Voeg een wachtrij of semaphore toe.
- Een parameter lijkt genegeerd. Controleer dat het een van de doorgegeven velden is die hierboven zijn vermeld, en vergelijk gedrag met een vaste
seeden lage temperatuur.
Elk antwoord bevat een X-Request-Id header. Log het naast je eigen verzoek-ID zodat een slecht antwoord later getraceerd kan worden. Als je productieverkeer draait en kwaliteit over tijd wilt meten, is het site-artikel LLM Observability: Myths vs Facts een goede volgende lezing. De responseheaders X-Balance-USD, X-RateLimit-Limit-Requests en X-RateLimit-Limit-Concurrency zijn ook het vastleggen waard.
Het proberen zonder verplichting
De goedkoopste manier om te testen of je code schoon port is om het één keer uit te voeren. Maak een account aan met Google of e-mail en wachtwoord, claim dan de $0,50 trial credit van de key pagina. Het kost één klik, heeft geen kaart nodig, is beperkt tot één per persoon en blijft 7 dagen geldig. Haal je sleutel op de API key pagina, stel de drie omgevingsvariabelen van hierboven in en voer je bestaande test suite uit.
Als de tests slagen en het gebruik past in je budget, waardeer je op vanaf $20, met kaart (Visa, Mastercard, Apple Pay, Google Pay) of crypto (USDT op TRC20, USDC op Base). Prompts worden niet gebruikt voor training. Het model is afgestemd om te antwoorden zonder inhoudsbeperkingen voor wettig gebruik door volwassenen, met één vaste regel: geen seksuele inhoud met minderjarigen.
