Passer au contenu

Parlez à une statue : créer une application multi-modale avec ElevenAgents

Building A Multi-Modal ElevenAgents-Powered Experience

Prenez une photo d'une statue. Identifiez les personnages représentés. Puis discutez avec eux en temps réel – chaque personnage s’exprime avec une voix distincte, fidèle à son époque.

C'est ce que vous pouvez créer avec les API Voice Design et Agent d'ElevenLabs. Dans cet article, nous expliquons l’architecture d’une application web mobile qui associe la vision par ordinateur à la génération de voix pour transformer des monuments publics en expériences interactives. Tout ce qui suit peut être reproduit avec les API et les exemples de code ci-dessous.

Passez le tutoriel – créez-le en une seule commande

Toute l’application ci-dessous a été créée à partir d’un seul prompt, testée et réussie en une fois dans Curseur avec Claude Opus 4.5 (high) à partir d’un projet NextJS vierge. Si vous voulez aller plus vite et créer la vôtre, collez ceci dans votre éditeur :

1We need to make an app that:
2- is optimised for mobile
3- allows the user to take a picture (of a statue, picture, monument, etc) that includes one or more people
4- uses an OpenAI LLM api call to identify the statue/monument/picture, characters within it, the location, and name
5- allows the user to check it's correct, and then do either a deep research or a standard search to get information about the characters and the statue's history, and it's current location
6- then create an ElevenLabs agent (allowing multiple voices), that the user can then talk to as though they're talking to the characters in the statue. Each character should use voice designer api to create a matching voice.
7The purpose is to be fun and educational.
8
9https://elevenlabs.io/docs/eleven-api/guides/cookbooks/voices/voice-design
10https://elevenlabs.io/docs/eleven-agents/quickstart 
11https://elevenlabs.io/docs/api-reference/agents/create


Vous pouvez aussi utiliser les Compétences des agents ElevenLabs au lieu de consulter la documentation. Ils sont basés sur la doc et peuvent donner des résultats encore meilleurs.

La suite de cet article détaille ce que produit ce prompt.

Comment ça marche

Le processus se déroule en cinq étapes :

  1. Prendre une photo
  2. Identifier l’œuvre et ses personnages (OpenAI)
  3. Rechercher l’histoire (OpenAI)
  4. Générer des voix uniques pour chaque personnage (ElevenAPI)
  5. Lancer une conversation vocale en temps réel via WebRTC (ElevenAgents)

Identifier la statue grâce à la vision

Quand un utilisateur photographie une statue, l’image est envoyée à un modèle OpenAI doté de capacités de vision. Un prompt système structuré extrait le nom de l’œuvre, l’emplacement, l’artiste, la date et – point clé – une description vocale détaillée pour chaque personnage. Le prompt système précise le format de sortie JSON attendu :

1{
2  "statueName": "string - name of the statue, monument, or artwork",
3  "location": "string - where it is located (city, country)",
4  "artist": "string - the creator of the artwork",
5  "year": "string - year completed or unveiled",
6  "description": "string - brief description of the artwork and its historical significance",
7  "characters": [
8    {
9      "name": "string - character name",
10      "description": "string - who this person was and their historical significance",
11      "era": "string - time period they lived in",
12      "voiceDescription": "string - detailed voice description for Voice Design API (include audio quality marker, age, gender, vocal qualities, accent, pacing, and personality)"
13    }
14  ]
15}

1const response = await openai.chat.completions.create({
2  model: "gpt-5.2",
3  response_format: { type: "json_object" },
4  messages: [
5    { role: "system", content: SYSTEM_PROMPT },
6    {
7      role: "user",
8      content: [
9        {
10          type: "text",
11          text: "Identify this statue/monument/artwork and all characters depicted.",
12        },
13        {
14          type: "image_url",
15          image_url: {
16            url: `data:image/jpeg;base64,${base64Data}`,
17            detail: "high",
18          },
19        },
20      ],
21    },
22  ],
23  max_completion_tokens: 2500,
24});

Pour une photo de la statue de Boudica sur Westminster Bridge, à Londres, la réponse ressemble à ceci :

1{
2  "statueName": "Boudica and Her Daughters",
3  "location": "Westminster Bridge, London, UK",
4  "artist": "Thomas Thornycroft",
5  "year": "1902",
6  "description": "Bronze statue depicting Queen Boudica riding a war chariot with her two daughters, commemorating her uprising against Roman occupation of Britain.",
7  "characters": [
8    {
9      "name": "Boudica",
10      "description": "Queen of the Iceni tribe who led an uprising against Roman occupation",
11      "era": "Ancient Britain, 60-61 AD",
12      "voiceDescription": "Perfect audio quality. A powerful woman in her 30s with a deep, resonant voice and a thick Celtic British accent. Her tone is commanding and fierce, with a booming quality that projects authority. She speaks at a measured, deliberate pace with passionate intensity."
13    },
14    // Other characters in the statue
15  ]
16}

Rédiger des descriptions de voix efficaces

La qualité de la description vocale détermine directement la qualité de la voix générée. Le guide de prompts Voice Design explique cela en détail, mais les éléments clés à inclure sont : marqueur de qualité audio (« Qualité audio parfaite. »), âge et genre, ton/timbre (profond, résonnant, rocailleux), accent précis (« fort accent celtique britannique » plutôt que simplement « britannique »), et rythme. Plus la description est précise, plus le résultat est fidèle – « une New-Yorkaise fatiguée d’une soixantaine d’années avec un humour sec » donnera toujours un meilleur résultat que « une voix féminine âgée ».

Quelques points à retenir du guide : utilisez « fort » plutôt que « marqué » pour décrire l’accent, évitez les termes vagues comme « étranger », et pour les personnages fictifs ou historiques, vous pouvez suggérer des accents réels comme inspiration (ex. : « une reine celte antique avec un fort accent britannique, voix royale et autoritaire »).

Créer des voix de personnages avec Voice Design

L’ API Voice Design génère de nouvelles voix synthétiques à partir de descriptions textuelles – pas besoin d’échantillon ou de clonage. C’est idéal pour les personnages historiques sans enregistrement audio.

Le processus se fait en deux étapes.

Générer des aperçus

1const { previews } = await elevenlabs.textToVoice.design({
2  modelId: "eleven_multilingual_ttv_v2",
3  voiceDescription: character.voiceDescription,
4  text: sampleText,
5});

Le paramètre texte est important. Un texte d’exemple plus long et adapté au personnage (plus de 50 mots) donne des résultats plus stables – adaptez le dialogue au personnage plutôt que d’utiliser une salutation générique. Le guide de prompts Voice Design détaille cela davantage.

Enregistrer la voix

Une fois les aperçus générés, choisissez-en un et créez une voix permanente :

1const voice = await elevenlabs.textToVoice.create({
2  voiceName: `StatueScanner - ${character.name}`,
3  voiceDescription: character.voiceDescription,
4  generatedVoiceId: previews[0].generatedVoiceId,
5});

Pour les statues à plusieurs personnages, la création des voix se fait en parallèle. Les voix de cinq personnages sont générées en à peu près le même temps qu’une seule :

1const results = await Promise.all(
2  characters.map((character) => createVoiceForCharacter(character))
3);

Créer un agent ElevenLabs multi-voix

Une fois les voix créées, l’étape suivante consiste à configurer un agent ElevenLabs capable de passer d’une voix de personnage à l’autre en temps réel.

1const agent = await elevenlabs.conversationalAi.agents.create({
2  name: `Statue Scanner - ${statueName}`,
3  tags: ["statue-scanner"],
4  conversationConfig: {
5    agent: {
6      firstMessage,
7      language: "en",
8      prompt: {
9        prompt: systemPrompt,
10        temperature: 0.7,
11      },
12    },
13    tts: {
14      voiceId: primaryCharacter.voiceId,
15      modelId: "eleven_v3",
16      supportedVoices: otherCharacters.map((c) => ({
17        voiceId: c.voiceId,
18        label: c.name,
19        description: c.voiceDescription,
20      })),
21    },
22    turn: {
23      turnTimeout: 10,
24    },
25    conversation: {
26      maxDurationSeconds: 600,
27    },
28  },
29});

Changement de voix en temps réel

Le tableau supportedVoices indique à l’agent quelles voix sont disponibles. La plateforme Agents gère automatiquement le changement de voix – quand la réponse du LLM indique qu’un autre personnage parle, le moteur TTS attribue ce passage à la bonne voix.

Concevoir des prompts pour des conversations de groupe

Pour que plusieurs personnages donnent l’impression d’un vrai groupe – et pas seulement d’un échange de questions/réponses – il faut concevoir le prompt avec soin :

1const multiCharacterRules = `
2MULTI-CHARACTER DYNAMICS:
3You are playing ALL ${characters.length} characters simultaneously.
4Make this feel like a group conversation, not an interview.
5
6- Characters should interrupt each other:
7  "Actually, if I may -" / "Wait, I must say -"
8
9- React to what others say:
10  "Well said." / "I disagree with that..." / "Always so modest..."
11
12- Have side conversations:
13  "Do you remember when -" / "Tell them about the time you -"
14
15The goal is for users to feel like they are witnessing a real exchange
16between people who happen to include them.
17`;

Voix en temps réel via WebRTC

La dernière étape concerne la connexion client. ElevenLabs Agents prend en charge WebRTC pour des conversations vocales à faible latence – nettement plus rapide que les connexions via WebSocket, ce qui rend les échanges plus naturels.

Côté serveur : obtenir un jeton de conversation

1const { token } = await client.conversationalAi.conversations.getWebrtcToken({
2    agentId,
3});

Côté client : démarrer la session

1import { useConversation } from "@elevenlabs/react";
2
3const conversation = useConversation({
4  onConnect: () => setIsSessionActive(true),
5  onDisconnect: () => setIsSessionActive(false),
6  onMessage: (message) => {
7    if (message.source === "ai") {
8      setMessages((prev) => [...prev, { role: "agent", text: message.message }]);
9    }
10  },
11});
12
13await conversation.startSession({
14  agentId,
15  conversationToken: token,
16  connectionType: "webrtc",
17});

Le hook useConversation gère la capture audio, le streaming, la détection d’activité vocale et la lecture.

Approfondir la recherche avec la recherche web

Pour les utilisateurs qui souhaitent plus de contexte historique avant de commencer la conversation, vous pouvez ajouter un mode recherche avancée avec l’outil de recherche web d’OpenAI :

1const response = await openai.responses.create({
2  model: "gpt-5.2",
3  instructions: RESEARCH_SYSTEM_PROMPT,
4  tools: [{ type: "web_search_preview" }],
5  input: `Research ${identification.statueName}. Search for current information
6including location, visiting hours, and recent news about the artwork.`,
7});

Ce que nous avons appris

Ce projet montre qu’en combinant plusieurs modalités d’IA – texte, recherche, vision et audio – on peut créer des expériences qui relient le monde numérique et le monde réel. Il reste beaucoup à explorer avec les agents multi-modaux, et nous aimerions voir plus de personnes s’en emparer pour l’éducation, le travail ou le loisir.

Commencez à créer

Les API utilisées dans ce projet –Conception de voix,ElevenAgents, et OpenAI – sont toutes disponibles dès maintenant.

Découvrez les articles de l'équipe ElevenLabs

Developer
How to use Skills

How to use Agent Skils

Agent Skills are one of the highest-leverage ways to use LLMs. They provide the appropriate context for the task you want to accomplish in a repeatable manner. 

ElevenLabs

Créez avec l'audio AI de la plus haute qualité.

Se lancer gratuitement

Vous avez déjà un compte ? Se connecter