DanLevy.net

Zeit für LLM-Connection-Strings

Modell- & Provider-Konfiguration mit llm://-URLs vereinfachen

Update: Dieser Artikel führte zu einem Internet-Draft für das llm://-URI-Schema.

Erinnert ihr euch an die schlechten alten Zeiten, als die Verbindung zu einer Datenbank bedeutete, einen wild zusammengewürfelten Haufen von Umgebungsvariablen zu verwalten?

Es war ein Turm aus fragiler Konfiguration. DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME … oder hieß es doch DB_USERNAME? Ist es DB_PASS oder DB_PWD? Brauche ich diesmal die PG_*-Präfixe? Und wo zum Teufel kommt der Timeout hin?

Es war ein Kartenhaus, das jederzeit einstürzen konnte und deinen Production-Build in den Abgrund riss, nur weil du vergessen hattest, HOST großzuschreiben.

Dann hatte jemand die brillante Idee, einfach eine URL zu verwenden¹:

Terminal window
postgres://user:pass@host:5432/dbname

Ein String. Alles, was du brauchst. Universell parsbar. Portabel. Darf ich sagen … wunderschön?

Warum behandeln wir LLMs also, als wäre immer noch 1999?

Die Umgebungsvariablen-Explosion

Meine .env-Datei sieht gerade aus wie ein Friedhof vergessener API-Keys. OPENAI_API_KEY, ANTHROPIC_API_KEY, MISTRAL_API_KEY, GROQ_API_KEY. Und bei Azure fang ich gar nicht erst an – du brauchst einen Endpunkt, einen Deployment-Namen, eine API-Version und einen Key, nur um „Hallo” zu sagen.

Es ist nicht nur hässlich, es ist Reibung. Jedes Mal, wenn ich ein Modell tauschen oder einen neuen Anbieter testen will, schreibe ich Initialisierungscode um, jage Dokumentation nach bestimmten Parameternamen und füge drei weitere Zeilen zu meiner Umgebungskonfiguration hinzu.

Was, wenn wir einfach … die DB-URL-Idee klauen ausleihen?

LLM-Connection-Strings

Stell dir vor, du konfigurierst dein gesamtes Modell-Interface mit einer einzigen Zeile:

Terminal window
llm://api.openai.com/gpt-5.2?reasoning_effort=none&temp=0.7&max_tokens=1500
llm://api.z.ai/glm-4.7?top_p=0.9&cache=true


Anatomie eines LLM-Connection-Strings

Die Bestandteile eines LLM-Connection-Strings

Das Schema ist llm://. Der Host ist die API-Basis-URL des Providers. Der Pfad ist der Modellname. Und die Query-Parameter erledigen all die Laufzeitoptionen, die sonst deinen Code zumüllen.

Auth nötig? Super, füg sie hinzu.

Genau wie bei postgres:// können wir die Authentifizierung direkt einbauen:

Terminal window
llm://app-name:sk-proj-123456@api.openai.com/gpt-5.2?reasoning_effort=none&temp=0.7

Hinweis: Ja, Zugangsdaten in URLs können ein Sicherheitsrisiko sein, wenn du sie in öffentliche Logs einfügst. Aber moderne Logging-Dienste scrubben diese Muster recht gut, und mal ehrlich – behandelst du deine .env-Datei viel besser? Prüfen, bereinigen und mit Vorsicht verwenden.

Resilienz? Warum zum Teufel nicht.

Viele Datenbankbibliotheken unterstützen Round-Robin-Failover durch Angabe mehrerer Hosts. Warum sollten unsere KI-Agenten nicht dieselbe Zuverlässigkeit haben?

Terminal window
llms://primary.gpt,backup.gpt/gpt-6?temp=0.9

Das s in llms:// ist kein Tippfehler. Es steht für Plural. Wenn primary.gpt hängt, wiederholt der Client automatisch mit backup.gpt. Keine komplexe Router-Logik nötig.

Ein String mit allem – vom Auth über den Endpunkt bis zu deinen Hyperparametern.

Alternative Formate

Ich bin nicht auf llm:// festgenagelt. Das konkrete Schema ist weniger wichtig als der Standard selbst.

Ich könnte mir eine Welt vorstellen, in der wir zur Kürze providerspezifische Schemas verwenden, aber die Standardstruktur beibehalten:

Terminal window
ollama://localhost:11434/llama3
vercel://anthropic/sonnet-4.5?temp=0.8&web_search={"maxUses":3}
bedrock://us-west-2.aws/anthropic/sonnet-4.5?temp=0.8&cacheControl=ephemeral

Unabhängig von der genauen Syntax sind die Kernvorteile unbestreitbar:

  1. Portabilität: Kopiere deine gesamte Konfiguration von einem lokalen Skript in einen Cloud-Worker.
  2. CLI-tauglich: Übergib ein einziges Argument an deine Skripte. my-agent --model "llm://..." schlägt my-agent --model gpt-4 --temp 0.7 --key $KEY --host ....
  3. Sprachunabhängig: Jede Programmiersprache hat einen robusten URL-Parser. Validierung, Parsing und Bereinigung bekommen wir geschenkt.
Die Datenbankwelt hat Jahrzehnte gebraucht, um das zu kapieren.
Zum Glück sind das in KI-Zeitlinien nur etwa ein halbes Vibe-Jahr her.

Das Fazit

Wir brauchen keinen weiteren komplexen Konfigurationsstandard oder eine neue YAML-basierte Manifest-Datei. Wir müssen nur das eine Werkzeug nutzen, das seit 30 Jahren für den Rest des Internets funktioniert.

Hören wir auf, das Rad neu zu erfinden, und fangen wir an, unsere LLM-Verbindungen mit demselben Respekt zu behandeln wie unsere Datenbanken. Deine .env-Datei (und dein Verstand) werden es dir danken.

Ein chaotischer Umgebungsvariablen-Schubladenschrank