Skip to main content
Une transcription, ce ne sont pas des notes. C’est la réunion à nouveau, mais plus longue à lire qu’à subir en direct. Ce que les gens veulent vraiment après coup tient en peu de choses : qu’avons-nous décidé, qui s’est engagé à faire quoi, et qu’est-ce qui reste ouvert. Ce tutoriel construit cela, et relie chaque élément à la seconde exacte où il a été énoncé, pour que vous puissiez aller réécouter la partie sur laquelle vous n’êtes pas d’accord :
Chemin faisant, nous allons :
  1. Transcrire un enregistrement avec /audio/transcriptions
  2. Demander des horodatages, que tous les modèles ne fournissent pas
  3. Extraire décisions et actions selon un schéma
  4. Composer avec le fait que la transcription ne dit jamais qui parle
  5. Découper un long enregistrement sans perdre le fil du temps

Préparation

Vous avez besoin de Python 3.9 ou plus récent, du paquet requests, et d’une clé d’API Venice. Consultez Générer une clé d’API si vous n’en avez pas. Apportez n’importe quel enregistrement de conversation, en wav, mp3, m4a, flac, aac, mp4, ogg ou webm.

1. Transcrire l’enregistrement

/audio/transcriptions est compatible avec OpenAI et accepte un envoi multipart. Le fichier doit être une véritable partie de fichier, car le base64 n’est pas accepté sur ce point de terminaison.
La transcription est facturée à la durée de l’audio, pas à la quantité de ce qui y est dit, ce qui rend le coût d’une réunion facile à prévoir avant même de la lancer : Appelez GET /models?type=asr pour obtenir la liste actuelle plutôt que de figer celle-ci, car le catalogue évolue.

2. Demander les horodatages

Ce sont les horodatages qui rendent les notes vérifiables, donc c’est le choix le plus important, et le comportement par défaut ne vous les donnera pas :
nvidia/parakeet-tdt-0.6b-v3 est le modèle par défaut, et il accepte timestamps=true puis l’ignore. Aucune erreur ni avertissement, juste une réponse qui ne contient que text. Si vous avez besoin des horodatages, demandez un modèle qui les renvoie et vérifiez que la clé est bien là.
Quand un modèle renvoie effectivement des horodatages, timestamps est un objet plutôt qu’une liste, et la clé à l’intérieur dépend du modèle. Whisper groupe par phrase, Scribe par mot :
Les segments au niveau de la phrase sont de la bonne taille pour ce travail. Les horodatages par mot sont utiles pour les sous-titres et trop fins pour y accrocher une décision. Nous aplatirons ces segments en lignes précédées chacune d’un instant, ce qui est tout ce dont le modèle a besoin pour les citer plus tard :

3. Extraire les notes

Décrivez les notes voulues comme un schéma, pour que le résultat soit un enregistrement et non de la prose à analyser :
disable_thinking est là pour la même raison qui vaut dans toute étape d’extraction. Le schéma décide déjà de la forme de la réponse, alors payer un modèle de raisonnement pour délibérer là-dessus n’apporte rien et rend le coût de chaque exécution différent du précédent. Extraction de données structurées à partir de documents mesure cette différence. Lancez-le sur un standup de cinquante-trois secondes et les notes reviennent avec le chronomètre attaché :
Chaque spoken_at est réel. Sautez à 19,6 secondes et vous entendez la phrase qui a créé la tâche.
Donnez au modèle des lignes sans horodatage et chaque spoken_at revient à 0. Le champ est requis, le modèle n’a rien à y mettre, et un champ requis est une instruction de produire quelque chose plutôt qu’une invitation à dire qu’il ne sait pas. Cela vaut la peine de s’en souvenir dès qu’un schéma semble fonctionner : la forme correcte n’est pas la même chose que les valeurs correctes.

4. Personne n’est identifié

Deux choses dans cette sortie sont fausses, et elles viennent toutes deux du même endroit. La responsable du déploiement est May. Son nom est Mei. La reconnaissance vocale est au plus mauvais sur les noms propres, et c’est justement des noms dont l’attribution a besoin, donc c’est l’échec que vous devriez attendre plutôt que le coup de malchance. Le dernier élément est unassigned, bien que quelqu’un l’ait clairement pris en charge. La phrase était « I’ll ask legal today and report back tomorrow », et la transcription enregistre les mots sans enregistrer qui les a prononcés. Ce second point n’est pas un bug que vous pouvez corriger. Aucun modèle de transcription Venice n’effectue de diarisation, donc il n’y a pas de champ speaker à saisir chez aucun d’eux. La transcription est un flux de texte sans voix, et les tâches ne peuvent être attribuées que lorsqu’un nom est prononcé à voix haute, comme dans « Tomas, can you put the deprecation notice in the changelog ». Le premier, vous pouvez le corriger en disant au modèle qui était dans la salle :
May se résout en Mei Lin parce que le modèle a désormais une courte liste sur laquelle s’aligner, et les responsables sont des noms complets que votre outil de suivi peut retrouver. Le troisième élément reste non attribué, à raison. Une liste des participants corrige les confusions d’audition, et rien ne récupère l’information que l’enregistrement n’a jamais portée.
Si vous avez besoin d’une véritable attribution des locuteurs, capturez-la en amont plutôt que de l’inférer en aval. Les outils de conférence peuvent enregistrer une piste par participant, et transcrire chaque piste séparément vous donne les locuteurs gratuitement, au prix d’une requête par personne.

5. Plus long qu’une seule requête

Les envois sont plafonnés à 25 Mo, ce qui arrive plus vite qu’on ne le pense pour de l’audio non compressé, et une longue réunion mérite de toute façon d’être découpée pour qu’un seul échec ne vous coûte pas toute la transcription. Pour les fichiers WAV, la bibliothèque standard suffit, sans besoin de ffmpeg :
Le décalage, c’est tout l’intérêt. Chaque fragment est transcrit comme s’il commençait à zéro, donc ses horodatages doivent être ramenés sur la chronologie de l’enregistrement d’origine avant que le modèle ne les voie. C’est à cela que sert l’argument offset de timed_lines :
Découpez le même standup en morceaux de vingt secondes et le chronomètre reste honnête aux jointures. Les mots, non :
Une seule phrase a été prononcée là : « Tomas, can you put the deprecation notice in the changelog by Friday? ». La coupe est tombée en plein milieu, donc le nom est parti dans une requête et la question dans une autre. Whisper a interprété le nom orphelin comme une question, a inventé un awesome. pour combler le trou en fin de fragment, et a transformé une ligne en trois. Les horodatages sont toujours corrects, et l’étape des notes retrouve toujours la tâche. Ce qu’elle perd, c’est le nom, or c’est de cela que dépend l’attribution.
Un découpage à durée fixe interrompt quelqu’un à chaque frontière. Vingt secondes est assez court pour tomber en pleine phrase presque à tous les coups ; dix minutes le rend rare mais pas impossible, et cela finira par tomber sur la phrase qui attribue le travail. Découper aux silences évite proprement le problème et nécessite un outil capable de trouver les creux, comme ffmpeg ou pydub. Ne découpez que lorsque le fichier l’exige vraiment.
Les formats compressés ne peuvent pas être découpés ainsi, car on ne peut pas couper un MP3 sur une frontière de trame avec la bibliothèque standard. Utilisez ffmpeg pour ceux-là :

Assembler le tout

Étapes suivantes

  • Publiez les actions dans votre outil de suivi, en utilisant les noms de responsables que la liste des participants a permis de résoudre.
  • Faites relire le résumé avec la Synthèse vocale pour les personnes qui ont manqué l’appel.
  • Effectuez des recherches parmi les réunions passées en stockant les transcriptions avec les Embeddings.
  • Laissez un agent décider quand transcrire et quand répondre à partir des notes qu’il possède déjà, avec Construire un agent qui utilise des outils avec l’appel de fonctions.

Reconnaissance vocale

Référence pour le point de terminaison des transcriptions.

Extraction de données structurées à partir de documents

La même extraction pilotée par un schéma, appliquée aux fichiers.

Réponses structurées

Comment json_schema contraint une réponse.

Clonage de voix

Donnez au résumé une voix qui lui est propre.