Modell-IDs gehören nicht in TypeScript
· 5 Min. Lesezeit
Eine Modell-ID ist die sich am schnellsten ändernde Tatsache in diesem ganzen System. Anbieter benennen sie um, stellen sie ein, liefern eine datierte Variante, ändern still, worauf der undatierte Alias zeigt, und machen die Hälfte davon davon abhängig, welches Konto fragt. Kompiliert man das in ein Paket, ist garantiert, dass das Paket binnen Wochen falsch ist – nicht auf offensichtliche Weise kaputt, was wenigstens einen Bug-Report ergäbe, sondern auf genau die Weise falsch, bei der eine Auswahlliste jemandem ein Modell anbietet, das sein Schlüssel nicht aufrufen darf.
Der Katalog ist also eine JSON-Datei, und interessant ist nicht, dass es JSON ist. Interessant ist, was die Schichtung darunter über Gewissheit eingesteht.
Fünf Schichten, spätere schlagen frühere
0. pi-ai's built-in models whatever it knows about the catalogued vendors
1. the bundled catalog.json 27 providers, 6 verified models
2. ~/.oharness/catalog.json your edits, and what discovery found
3. a catalog path in config
4. providers / models in config
5. /models refresh asks the vendor directly
Lesen Sie diese Zahlenspalte als Rangfolge der Verlässlichkeit, nicht als Ladereihenfolge. Schicht 0 ist die Momentaufnahme der Welt von jemand anderem. Schicht 1 ist das, was wir bereit waren, ausdrücklich festzuhalten. Schicht 5 ist der Anbieter, der über Ihr Konto Auskunft gibt, jetzt gerade – und sie gewinnt, denn nichts, was wir vor drei Monaten ausgeliefert haben, weiß mehr über Ihre Berechtigungen als der Endpunkt, den Sie gleich aufrufen.
Die mitgelieferte Schicht enthält siebenundzwanzig Anbieter und sechs verifizierte Modelle, und dieses Verhältnis ist das ganze Design. Anbieterfakten – der Endpunkt, die Umgebungsvariable, das Wire-Protokoll – sind stabil genug zum Ausliefern. Modell-IDs sind es nicht, deshalb werden nur die ausdrücklich festgehalten, die sich tatsächlich verifizieren ließen, und alles andere kommt über die Erkennung, die bei jedem Anbieter dessen eigenes /models abfragt.
Sechs ist eine unbequeme Zahl zum Veröffentlichen. Es ist auch die ehrliche.
Überschreibungen wirken pro Feld
Warum das im Alltag zählt, ist kleiner und langweiliger: Wer Kimi auf seinen Endpunkt in Festlandchina umstellen will, sollte dafür nicht alles andere über Kimi neu angeben müssen.
{ "providers": { "moonshot": { "baseUrl": "https://api.moonshot.cn/v1" } } }
Das ist die gesamte Änderung. Überschreibungen ganzer Einträge sind der Weg, auf dem Konfigurationsformate verrotten – jemand kopiert den ausgelieferten Block, um eine URL zu ändern, und zwei Releases später ist seine Kopie das Einzige, was zwischen ihm und einem Fix steht, den alle anderen längst bekommen haben.
Wo der Grundbestand aufhört
Schicht 0 verdient eine Anmerkung, weil sie diejenige ist, die Leute überrascht: Ein Anbieter, den Sie nie verbunden haben, hat trotzdem Modelle zum Anzeigen. Sie stammen aus pi-ai, der Wire-Schicht, die einen generierten Katalog dessen mitliefert, was sie kennt. Sie enthalten Kontextfenster, Preise und Reasoning-Stufen, und sie wissen rein gar nichts darüber, was Ihr Konto aufrufen darf – deshalb schlagen sowohl ein ausdrücklich festgehaltener Eintrag als auch alles, was die Erkennung zurückliefert, diese Einträge, und OHARNESS_NO_BUILTIN_MODELS=1 schaltet den Grundbestand vollständig ab.
Zwei Grenzen verhindern, dass dieser Grundbestand Schaden anrichtet.
Ein Modell wird nur einem Eintrag zugeordnet, dessen Protokoll zu der API passt, unter der pi-ai es katalogisiert. Die Modelle von Mistral sind unter der eigenen Conversations-API von pi-ai gelistet, also werden sie der Erkennung überlassen, statt in einer Form, die er nicht spricht, an einen OpenAI-kompatiblen Endpunkt geschickt zu werden. Die falsche Form zu senden ergibt einen 400er, den Sie debuggen dürfen, keine schlechtere Antwort, mit der Sie leben können.
Und wo die beiden Kataloge bei der ID eines Anbieters uneins sind, werden sie abgeglichen, indem man die jeweils andere benennt, statt zu raten:
{ "providers": { "moonshot": { "piProvider": "moonshotai" } } }
Ein Anbieter ohne Grundbestand und noch ohne Erkennung – ein lokaler Server, ein Gateway, für das niemand Namen mitliefert – erscheint in der Auswahl trotzdem als einzelne Zeile, die das Panel öffnet, in dem Sie ihn verbinden. Ein leerer Zustand, der sich selbst erklärt, ist besser als ein Anbieter, der einfach fehlt, bis irgendeine unsichtbare Bedingung erfüllt ist.
Nur das Protokoll ist es wert, benannt zu werden
Das Feld protocol eines Katalogeintrags benennt das Format, das sein Endpunkt spricht:
anthropic-messages openai-chat openai-responses
gemini bedrock vertex
openai-codex
openai-codex ist der Grund, diese Liste explizit zu führen, statt sie aus einem Anbieternamen abzuleiten. Es ist das Backend, mit dem die Codex CLI spricht, und es ist ein tatsächlich anderes Wire-Format als openai-responses, nicht dasselbe auf einem anderen Host: store wird abgelehnt, max_output_tokens wird nicht gesendet, und die Konto-ID reist in einem eigenen Header. Ein System, das riete „das ist OpenAI, also die OpenAI-Form“, läge damit auf drei verschiedene Arten falsch.
Die SDKs dahinter werden verzögert importiert, sodass eine Sitzung, die nur mit Anthropic spricht, die AWS- oder Google-Clients nie lädt.
Was sich nicht bewegt hat
Die Authentifizierung. Zugangsdaten werden pro Anfrage vom harnesseigenen AuthManager aufgelöst, denn ein Abo-Token, das beim Start gültig war, ist eine Stunde später nicht mehr gültig. Deshalb werden die API-Implementierungen von pi-ai direkt aufgerufen und erhalten einen bereits aufgelösten Schlüssel samt Headern, statt über deren Anbieter-Authentifizierung und Credential-Store zu laufen.
Darum werden manche Einträge gar nicht ausgeliefert. Bedrock und Vertex funktionieren als Protokolle, aber nur mit Zugangsdaten, die bereits in der Umgebung liegen – vollständige SigV4-Signierung und gcloud ADC leben genau in der Anbieterschicht, die dieses Harness für die Authentifizierung nicht nutzt. Azure OpenAI hat keine feste Base-URL zum Katalogisieren, weil der Endpunkt pro Deployment gilt. Beide kann jeder deklarieren, dessen Umgebung bereits eingerichtet ist; keiner von beiden wird als funktionierender Standard ausgeliefert, der stillschweigend keiner ist.
Das Muster unter alldem: Halten Sie die Fakten fest, die stillhalten, fragen Sie nach denen, die es nicht tun, und halten Sie den Unterschied in der Datei sichtbar, statt ihn in Versionshinweisen zu vergraben.
OHarness ist ein quelloffenes Agent-Harness unter MIT-Lizenz. Die Anbieterreferenz dokumentiert jede Schicht, Überschreibung und jedes Protokoll von oben, und die Anbieterübersicht listet, was heute im mitgelieferten Katalog steckt.