Skip to Content
Mélodium 0.10.1 is now available!
DocsExemplesServeur de chat LLM

Serveur de chat LLM

Source: 01_text_llm_chat

Un serveur HTTP qui accepte des prompts en texte brut via POST /chat et renvoie la réponse du LLM token par token en flux. La connexion au LLM est déclarée comme modèle et partagée entre toutes les requêtes concurrentes.

Exécution

melodium run 01_text_llm_chat/Compo.toml --api_key sk-... --model claude-sonnet-4-6
Note

api_key est ici une clé d’API Anthropic, puisque model est défini sur un modèle Claude.

$ curl -X POST http://127.0.0.1:8080/chat -d "What is Mélodium?" Mélodium is a dataflow programming language…

Fonctionnement

ChatLlm encapsule RemoteLlm avec un backend, un system prompt et une limite de tokens fixes :

model ChatLlm(const api_key: string, const model: string) : RemoteLlm { backend = "anthropic" api_key = |wrap<string>(api_key) base_url = "" model = model system = "You are a helpful assistant. Answer concisely." max_tokens = 512 temperature = _ top_p = _ timeout = _ }

Le champ backend sélectionne le fournisseur ("anthropic", "openai", etc.) ; changer de fournisseur revient uniquement à modifier backend et model dans la définition du modèle. Le reste du pipeline n’est pas affecté.

Deux modèles sont instanciés au démarrage : le HttpServer et ChatLlm. Le traitement startup se déclenche une fois au lancement du programme, et son trigger est transmis à la fois à start (qui lie le socket du serveur) et au message de log de démarrage :

treatment main( const api_key: string, const model: string = "claude-sonnet-4-6", const port: u16 = 8080 ) model server: HttpServer(host=|from_ipv4(|localhost_ipv4()), port=port) model llm: ChatLlm(api_key=api_key, model=model) { startup() start[http_server=server]() logStarted: logInfoMessage(label="server", message="LLM chat server started") startup.trigger -> start.trigger startup.trigger -> logStarted.trigger

main treatment diagram Voir dans Compositeur Studio

Envoyer le statut et les en-têtes avant lecture du corps

Chaque connection a besoin d’un statut et d’en-têtes envoyés avant que le corps de la réponse ne commence à être diffusé. bodyTrigger se déclenche dès l’arrivée du premier octet de la requête, et ce signal Block<void> unique se propage simultanément vers status et headers via emit et trigger :

connection[http_server=server](method=|post(), route="/chat") status: emit<HttpStatus>(value=|ok()) headers: emit<StringMap>(value=|map([])) bodyTrigger: trigger<byte>() connection.data -> bodyTrigger.stream,start --> status.trigger,emit -> connection.status bodyTrigger.start --------> headers.trigger,emit -> connection.headers chat[llm=llm]() connection.data -> chat.data,data -> connection.data

Le sous-traitement chat

Chaque connexion entrante est traitée par le sous-traitement chat, qui est un pipeline direct en trois étapes :

treatment chat[llm: RemoteLlm]() input data: Stream<byte> output data: Stream<byte> { decode() llmStream[llm=llm]() encode() llmPrompt: logInfos(label="llm") llmErrors: logErrors(label="llm") Self.data -> decode.data,text -> llmStream.prompt,token -> encode.text,data -> Self.data decode.text -> llmPrompt.messages llmStream.error -> llmErrors.messages }
  • decode convertit les octets bruts de la requête en texte UTF-8
  • llmStream envoie le texte comme prompt et émet les tokens sous forme de Stream<string> à mesure qu’ils arrivent
  • encode convertit chaque token en octets et les transmet directement dans connection.data

Comme llmStream émet les tokens en flux, ils atteignent la réponse HTTP au fur et à mesure de leur production, sans tampon et sans logique asynchrone explicite.

Le texte du prompt et les erreurs LLM sont transmis indépendamment aux loggers (logInfos, logErrors) via des connexions séparées, sans interrompre le flux de tokens.

Explication vidéo

Dépendances

[dependencies] std = "0.10.1" # flux de base, journalisation, structures de données http = "0.10.1" # serveur et client HTTP net = "0.10.1" # utilitaires d'adresses IP encoding = "0.10.1" # encodage / décodage UTF-8 ml = "0.10.1" # inférence LLM, STT, TTS et modèles locaux