Les applications qui appellent des API de grands modèles de langage (LLM) gèrent généralement les protocoles spécifiques aux fournisseurs, la gestion des identifiants et la configuration TLS directement dans le code applicatif. Lorsque vous changez de fournisseur ou que vous acheminez différents niveaux d'utilisateurs vers différents modèles, ces modifications se répercutent sur l'ensemble de votre base de code. Alibaba Cloud Service Mesh (ASM) déplace cette complexité vers l'infrastructure du maillage : configurez deux ressources personnalisées Kubernetes -- LLMProvider et LLMRoute -- et le sidecar ASM gère automatiquement la conversion de protocole, l'injection de clé API, la mise à niveau TLS et le routage du trafic. Votre application envoie des requêtes HTTP simples sans logique spécifique au fournisseur.
Avec la gestion du trafic LLM dans ASM, vous pouvez mettre en œuvre l'accès canari, le routage pondéré et des capacités d'observabilité :
Routage par en-tête de requête : Acheminez les requêtes vers différents modèles en fonction des en-têtes -- par exemple, dirigez les abonnés vers un modèle premium tandis que les autres utilisateurs utilisent un modèle standard.
Répartition du trafic par poids : Distribuez les requêtes entre plusieurs fournisseurs LLM pour une migration progressive ou une comparaison A/B.
Surveillance du trafic LLM : Suivez les métriques spécifiques aux LLM via les tableaux de bord d'observabilité intégrés d'ASM.
Fonctionnement
ASM introduit deux définitions de ressources personnalisées (CRD) qui fonctionnent conjointement pour gérer le trafic LLM :
|**Ressource**
|
**Rôle**
|
**Appliqué à**
| | --- | --- | --- | |
`LLMProvider`
|
Définit un service LLM backend : hôte, chemin d'API, modèle et clé API
|
Plan de contrôle ASM (`--kubeconfig=${PATH_TO_ASM_KUBECONFIG}`)
| |
`LLMRoute`
|
Contrôle la distribution des requêtes entre les fournisseurs, avec prise en charge de la correspondance basée sur les en-têtes et du routage pondéré
|
Plan de contrôle ASM (`--kubeconfig=${PATH_TO_ASM_KUBECONFIG}`)
|
Flux de requête : Lorsqu'un pod envoie une requête HTTP simple au nom d'hôte d'un fournisseur LLM, le sidecar ASM intercepte la requête et réalise automatiquement les actions suivantes :
Conversion au format de complétion de chat compatible OpenAI.
Injection de la clé API depuis la configuration
LLMProvider.Mise à niveau de la connexion de HTTP vers HTTPS.
Transmission de la requête à l'endpoint du fournisseur.
Cela signifie que votre application envoie une requête HTTP POST minimale -- aucun chemin d'API, aucun identifiant, aucune configuration TLS. Le sidecar complète tous les champs à partir de la spécification LLMProvider.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Une instance ASM (v1.21.6.88 ou version ultérieure) avec un cluster ajouté
Des politiques d'injection de sidecar configurées pour le namespace cible
Un compte Alibaba Cloud Model Studio avec une clé API valide -- consultez Obtenir une clé API
(Scénario 2 uniquement) Un compte Moonshot AI avec une clé API valide -- consultez la Plateforme ouverte Moonshot AI
Configurer l'environnement de test
Déployez un client de test et configurez un fournisseur LLM de base avant d'exécuter l'un ou l'autre scénario.
Étape 1 : Déployer l'application de test sleep
Le pod sleep sert de client pour envoyer des requêtes de test aux fournisseurs LLM via le maillage.
-
Enregistrez le contenu suivant sous le nom
sleep.yaml: -
Appliquez le manifeste à votre cluster ACK :
kubectl apply -f sleep.yaml
Étape 2 : Configurer le fournisseur Model Studio
Créez une ressource LLMProvider qui indique à ASM comment atteindre Alibaba Cloud Model Studio (DashScope).
-
Enregistrez le contenu suivant sous le nom
LLMProvider.yaml. Remplacez<your-dashscope-api-key>par votre clé API Model Studio.apiVersion: istio.alibabacloud.com/v1beta1 kind: LLMProvider metadata: name: dashscope-qwen spec: host: dashscope.aliyuncs.com path: /compatible-mode/v1/chat/completions configs: defaultConfig: openAIConfig: model: qwen1.5-72b-chat # Qwen open-source series model apiKey: <your-dashscope-api-key>Pour obtenir la liste complète des modèles open source Qwen disponibles, consultez Génération de texte - Modèles open source Qwen.
-
Appliquez le manifeste à votre instance ASM :
kubectl --kubeconfig=${PATH_TO_ASM_KUBECONFIG} apply -f LLMProvider.yaml -
Vérifiez la configuration en envoyant une requête de test depuis le pod
sleep:kubectl exec deployment/sleep -it -- curl --location 'http://dashscope.aliyuncs.com' \ --header 'Content-Type: application/json' \ --data '{ "messages": [ {"role": "user", "content": "Please introduce yourself."} ] }'Une réponse réussie se présente comme suit :
{ "choices": [ { "message": { "role": "assistant", "content": "Hello! I am Qwen, a pre-trained language model developed by Alibaba Cloud..." }, "finish_reason": "stop", "index": 0 } ], "model": "qwen1.5-72b-chat", "usage": { "prompt_tokens": 12, "completion_tokens": 130, "total_tokens": 142 } }La requête cible
http://dashscope.aliyuncs.comen HTTP simple sans spécifier de chemin, de modèle ou de clé API. Le sidecar ASM renseigne ces champs à partir de la configurationLLMProvider, effectue la mise à niveau vers HTTPS et transmet la requête à DashScope. Étant donné que Model Studio est compatible avec le protocole OpenAI, la réponse suit le format standard de complétion de chat.
Scénario 1 : Acheminer les requêtes vers différents modèles par en-tête
Acheminez les utilisateurs de niveau abonné vers le modèle qwen-turbo tandis que tous les autres utilisateurs utilisent le modèle par défaut qwen1.5-72b-chat. La décision de routage est basée sur l'en-tête de requête user-type.
Créer la règle de routage
-
Enregistrez le contenu suivant sous le nom
LLMRoute.yaml:apiVersion: istio.alibabacloud.com/v1beta1 kind: LLMRoute metadata: name: dashscope-route spec: host: dashscope.aliyuncs.com # Must match the LLMProvider host rules: - name: vip-route matches: - headers: user-type: exact: subscriber # Match requests with this header value backendRefs: - providerHost: dashscope.aliyuncs.com - backendRefs: - providerHost: dashscope.aliyuncs.comLa première règle correspond aux requêtes incluant un en-tête
user-type: subscriberet les achemine via la règle de routagevip-route. La deuxième règle agit comme règle par défaut pour toutes les autres requêtes. -
Appliquez la règle de routage à votre instance ASM :
kubectl --kubeconfig=${PATH_TO_ASM_KUBECONFIG} apply -f LLMRoute.yaml
Assigner un modèle à chaque route
Mettez à jour le LLMProvider pour spécifier différents modèles pour la route par défaut et la route vip-route :
-
Mettez à jour
LLMProvider.yamlavec le contenu suivant :apiVersion: istio.alibabacloud.com/v1beta1 kind: LLMProvider metadata: name: dashscope-qwen spec: host: dashscope.aliyuncs.com path: /compatible-mode/v1/chat/completions configs: defaultConfig: openAIConfig: model: qwen1.5-72b-chat # Default: open-source model apiKey: <your-dashscope-api-key> routeSpecificConfigs: vip-route: # Override for subscriber requests openAIConfig: model: qwen-turbo # Subscribers use qwen-turbo apiKey: <your-dashscope-api-key> -
Appliquez la mise à jour :
kubectl --kubeconfig=${PATH_TO_ASM_KUBECONFIG} apply -f LLMProvider.yaml
Tester le routage
Envoyez deux requêtes -- l'une sans l'en-tête (route par défaut) et l'autre avec l'en-tête user-type: subscriber (route VIP) :
# Default route: uses qwen1.5-72b-chat
kubectl exec deployment/sleep -it -- curl --location 'http://dashscope.aliyuncs.com' \
--header 'Content-Type: application/json' \
--data '{
"messages": [
{"role": "user", "content": "Please introduce yourself."}
]
}'
# Subscriber route: uses qwen-turbo
kubectl exec deployment/sleep -it -- curl --location 'http://dashscope.aliyuncs.com' \
--header 'Content-Type: application/json' \
--header 'user-type: subscriber' \
--data '{
"messages": [
{"role": "user", "content": "Please introduce yourself."}
]
}'
Résultat attendu :
{"choices":[{"message":{"role":"assistant","content":"Hello! I am Qwen, a pre-trained language model developed by Alibaba Cloud. My purpose is to assist users in generating various types of text, such as articles, stories, poems, and answering questions by leveraging my extensive knowledge and understanding of context. Although I'm an AI, I don't have a physical body or personal experiences like human beings do, but I've been trained on a vast corpus of text data, which allows me to engage in conversations, provide information, or help with various tasks to the best of my abilities. So, feel free to ask me anything, and I'll do my best to provide helpful and informative responses!"},"finish_reason":"stop","index":0,"logprobs":null}],"object":"chat.completion","usage":{"prompt_tokens":12,"completion_tokens":130,"total_tokens":142},"created":1720680044,"system_fingerprint":null,"model":"qwen1.5-72b-chat","id":"chatcmpl-1c33b950-3220-9bfe-9066-xxxxxxxxxxxx"}
{"choices":[{"message":{"role":"assistant","content":"Hello, I'm Qwen, a large language model from Alibaba Cloud. As an AI assistant, my goal is to help users get accurate and useful information, and to solve their problems and confusions. I can provide knowledge in various fields, engage in conversation, and even create text. Please note that all the content I provide is based on the data I was trained on and may not include the latest events or personal information. If you have any questions, feel free to ask me at any time!"},"finish_reason":"stop","index":0,"logprobs":null}],"object":"chat.completion","usage":{"prompt_tokens":11,"completion_tokens":85,"total_tokens":96},"created":1720683416,"system_fingerprint":null,"model":"qwen-turbo","id":"chatcmpl-9cbc7c56-06e9-9639-a50d-xxxxxxxxxxxx"}
Vérifiez le champ model dans chaque réponse. La requête par défaut renvoie "model": "qwen1.5-72b-chat", tandis que la requête d'abonné renvoie "model": "qwen-turbo".
Scénario 2 : Répartir le trafic entre les fournisseurs avec un routage pondéré
Répartissez le trafic à 50/50 entre Alibaba Cloud Model Studio (DashScope) et Moonshot AI. Ce modèle est utile pour migrer progressivement entre les fournisseurs ou comparer les performances des modèles côte à côte.
Étape 1 : Configurer le fournisseur Moonshot
-
Enregistrez le contenu suivant sous le nom
LLMProvider-moonshot.yaml. Remplacez<your-moonshot-api-key>par votre clé API Moonshot AI.apiVersion: istio.alibabacloud.com/v1beta1 kind: LLMProvider metadata: name: moonshot spec: host: api.moonshot.cn # Must be unique across all LLMProviders path: /v1/chat/completions configs: defaultConfig: openAIConfig: model: moonshot-v1-8k stream: false apiKey: <your-moonshot-api-key> -
Appliquez le manifeste :
kubectl --kubeconfig=${PATH_TO_ASM_KUBECONFIG} apply -f LLMProvider-moonshot.yaml
Étape 2 : Créer un service LLM virtuel
Créez un service Kubernetes comme point d'entrée unique pour les requêtes LLM. Ce service ne possède aucun pod de support -- le sidecar ASM achemine toutes les requêtes vers les fournisseurs LLM définis dans le LLMRoute.
-
Enregistrez le contenu suivant sous le nom
demo-llm-server.yaml:apiVersion: v1 kind: Service metadata: name: demo-llm-server namespace: default spec: ports: - name: http port: 80 protocol: TCP targetPort: 80 selector: app: none type: ClusterIP -
Appliquez le manifeste :
kubectl apply -f demo-llm-server.yaml
Étape 3 : Configurer le routage pondéré
Créez un LLMRoute qui distribue le trafic de manière égale entre DashScope et Moonshot :
-
Enregistrez le contenu suivant sous le nom
LLMRoute.yaml:apiVersion: istio.alibabacloud.com/v1beta1 kind: LLMRoute metadata: name: demo-llm-server namespace: default spec: host: demo-llm-server rules: - name: migrate-rule backendRefs: - providerHost: dashscope.aliyuncs.com weight: 50 - providerHost: api.moonshot.cn weight: 50Ajustez les valeurs de
weightpour contrôler la répartition du trafic. Les poids sont relatifs --50/50répartit le trafic de manière égale, tandis que80/20envoie 80 % vers DashScope et 20 % vers Moonshot. -
Appliquez la règle de routage :
kubectl --kubeconfig=${PATH_TO_ASM_KUBECONFIG} apply -f LLMRoute.yaml
Tester le routage pondéré
Envoyez plusieurs requêtes au service virtuel demo-llm-server et observez les réponses :
kubectl exec deployment/sleep -it -- curl --location 'http://demo-llm-server' \
--header 'Content-Type: application/json' \
--data '{
"messages": [
{"role": "user", "content": "Please introduce yourself."}
]
}'
Exécutez la commande plusieurs fois. Certaines réponses proviennent de Moonshot (identifiées par "model": "moonshot-v1-8k" et le nom de l'assistant Kimi), tandis que d'autres proviennent de DashScope (identifiées par "model": "qwen1.5-72b-chat" et le nom de l'assistant Qwen).
Résultat attendu :
{"id":"cmpl-cafd47b181204cdbb4a4xxxxxxxxxxxx","object":"chat.completion","created":1720687132,"model":"moonshot-v1-8k","choices":[{"index":0,"message":{"role":"assistant","content":"Hello! I am an AI language model named Kimi. My main function is to help people generate human-like text. I can write articles, answer questions, provide advice, and more. I am trained on a massive amount of text data, so I can generate a wide variety of text. My goal is to help people communicate more effectively and solve problems."},"finish_reason":"stop"}],"usage":{"prompt_tokens":11,"completion_tokens":59,"total_tokens":70}}
{"choices":[{"message":{"role":"assistant","content":"Hello! I am Qwen, a pre-trained language model developed by Alibaba Cloud. My purpose is to assist users in generating various types of text, such as articles, stories, poems, and answering questions by leveraging my extensive knowledge and understanding of context. Although I'm an AI, I don't have a physical body or personal experiences like human beings do, but I've been trained on a vast corpus of text data, which allows me to engage in conversations, provide information, or help with various tasks to the best of my abilities. So, feel free to ask me anything, and I'll do my best to provide helpful and informative responses!"},"finish_reason":"stop","index":0,"logprobs":null}],"object":"chat.completion","usage":{"prompt_tokens":12,"completion_tokens":130,"total_tokens":142},"created":1720687164,"system_fingerprint":null,"model":"qwen1.5-72b-chat","id":"chatcmpl-2443772b-4e41-9ea8-9bed-xxxxxxxxxxxx"}
Le résultat montre que les requêtes sont distribuées de manière égale entre Moonshot et Alibaba Cloud Model Studio.
Référence des ressources et des espaces réservés
Ressources Kubernetes
|**Fichier YAML**
|
**Kind**
|
**Nom**
|
**Appliqué à**
| | --- | --- | --- | --- | |
`sleep.yaml`
|
ServiceAccount, Service, Deployment
|
sleep
|
Cluster ACK (`kubectl apply`)
| |
`LLMProvider.yaml`
|
LLMProvider
|
dashscope-qwen
|
Instance ASM (`--kubeconfig`)
| |
`LLMProvider-moonshot.yaml`
|
LLMProvider
|
moonshot
|
Instance ASM (`--kubeconfig`)
| |
`LLMRoute.yaml`
|
LLMRoute
|
dashscope-route / demo-llm-server
|
Instance ASM (`--kubeconfig`)
| |
`demo-llm-server.yaml`
|
Service
|
demo-llm-server
|
Cluster ACK (`kubectl apply`)
|
Espaces réservés
Remplacez les espaces réservés suivants par vos valeurs réelles avant d'appliquer les manifestes YAML :
|**Espace réservé**
|
**Description**
|
**Exemple**
| | --- | --- | --- | |
`
|
Clé API pour Alibaba Cloud Model Studio
|
sk-xxxxxxxxxxxxx
| |
`
|
Clé API pour Moonshot AI
|
sk-xxxxxxxxxxxxx
| |
`${PATH_TO_ASM_KUBECONFIG}`
|
Chemin vers le fichier kubeconfig de l'instance ASM
|
~/.kube/asm-config
|