.webp&w=3840&q=95)
ElevenLabs partners with the UK Government on voice AI safety research
UK AI Security Institute researchers will explore the implications of AI voice technology
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.
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 :
| 1 | We 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. |
| 7 | The purpose is to be fun and educational. |
| 8 | |
| 9 | https://elevenlabs.io/docs/eleven-api/guides/cookbooks/voices/voice-design |
| 10 | https://elevenlabs.io/docs/eleven-agents/quickstart |
| 11 | https://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.
Le processus se déroule en cinq étapes :
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 | } |
| 1 | const 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 | } |
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 »).
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.
| 1 | const { 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.
Une fois les aperçus générés, choisissez-en un et créez une voix permanente :
| 1 | const 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 :
| 1 | const results = await Promise.all( |
| 2 | characters.map((character) => createVoiceForCharacter(character)) |
| 3 | ); |
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.
| 1 | const 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 | }); |
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.
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 :
| 1 | const multiCharacterRules = ` |
| 2 | MULTI-CHARACTER DYNAMICS: |
| 3 | You are playing ALL ${characters.length} characters simultaneously. |
| 4 | Make 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 | |
| 15 | The goal is for users to feel like they are witnessing a real exchange |
| 16 | between people who happen to include them. |
| 17 | `; |
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.
| 1 | const { token } = await client.conversationalAi.conversations.getWebrtcToken({ |
| 2 | agentId, |
| 3 | }); |
| 1 | import { useConversation } from "@elevenlabs/react"; |
| 2 | |
| 3 | const 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 | |
| 13 | await 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.
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 :
| 1 | const 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 |
| 6 | including location, visiting hours, and recent news about the artwork.`, |
| 7 | }); |
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.
Les API utilisées dans ce projet –Conception de voix,ElevenAgents, et OpenAI – sont toutes disponibles dès maintenant.
.webp&w=3840&q=95)
UK AI Security Institute researchers will explore the implications of AI voice technology

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.