Tous les produits
Search
Centre de documentation

Alibaba Cloud Service Mesh:Manage LLM traffic with ASM

Dernière mise à jour :Aug 11, 2026

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 :

  1. Conversion au format de complétion de chat compatible OpenAI.

  2. Injection de la clé API depuis la configuration LLMProvider.

  3. Mise à niveau de la connexion de HTTP vers HTTPS.

  4. 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 :

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.

  1. Enregistrez le contenu suivant sous le nom sleep.yaml :

    Contenu YAML

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sleep
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sleep
      labels:
        app: sleep
        service: sleep
    spec:
      ports:
      - port: 80
        name: http
      selector:
        app: sleep
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sleep
      template:
        metadata:
          labels:
            app: sleep
        spec:
          terminationGracePeriodSeconds: 0
          serviceAccountName: sleep
          containers:
          - name: sleep
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/curl:asm-sleep
            command: ["/bin/sleep", "infinity"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
    ---
  2. 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).

  1. 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.

  2. Appliquez le manifeste à votre instance ASM :

    kubectl --kubeconfig=${PATH_TO_ASM_KUBECONFIG} apply -f LLMProvider.yaml
  3. 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.com en HTTP simple sans spécifier de chemin, de modèle ou de clé API. Le sidecar ASM renseigne ces champs à partir de la configuration LLMProvider, 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

  1. 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.com

    La première règle correspond aux requêtes incluant un en-tête user-type: subscriber et les achemine via la règle de routage vip-route. La deuxième règle agit comme règle par défaut pour toutes les autres requêtes.

  2. 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 :

  1. Mettez à jour LLMProvider.yaml avec 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>
  2. 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

  1. 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>
  2. 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.

  1. 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
  2. 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 :

  1. 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: 50

    Ajustez les valeurs de weight pour contrôler la répartition du trafic. Les poids sont relatifs -- 50/50 répartit le trafic de manière égale, tandis que 80/20 envoie 80 % vers DashScope et 20 % vers Moonshot.

  2. 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
|