Pesquisar

infrastructureblogia

Revolucionar as Traduções de Artigos de Blog com IA

Revolucionar as Traduções de Artigos de Blog com IA

Neste artigo, compartilho um script Python desenvolvido como uma prova de conceito (POC) para automatizar a tradução dos posts do meu blog, usando o modelo de linguagem GPT-4 da OpenAI. Este script foi especificamente projetado para processar arquivos Markdown, facilitando a gestão multilíngue dos meus artigos. As traduções estão disponíveis através do seletor de idioma no topo da página.

Início do Projeto: Unir IA e Automação para Meu Blog

Este projeto de automação da tradução dos meus artigos de blog foi iniciado pela minha crescente fascinação pela inteligência artificial. Inspirado pelas minhas experiências preliminares com as APIs OpenAI GPT-4 e Mistral AI, fui atraído pela ideia de concretizar essas tecnologias em um projeto prático, oferecendo um valor tangível ao meu blog. Não se tratava apenas de dominar as ferramentas de IA, mas também do desejo de fundir automação e inovação para enriquecer meu espaço digital.

O projeto transformou-se em uma aventura onde a IA não era apenas um tema para escrever, mas um parceiro ativo no desenvolvimento. A ideia de traduzir meus artigos de forma simples e eficiente com IA, ao mesmo tempo explorando suas capacidades de automação, abriu perspectivas fascinantes. Era uma oportunidade de transcender barreiras linguísticas, tornando meu conteúdo acessível a um público mais amplo, enquanto navegava no campo em constante evolução da inteligência artificial.

O Desafio

O desafio principal foi criar um script capaz de traduzir com precisão e preservar a formatação original dos artigos, nomeadamente os blocos de código, os links e as imagens. Outro desafio foi garantir que o script pudesse ser facilmente adaptado para suportar diferentes idiomas. Também deveria ser capaz de levar em conta esta estrutura:

├── content
   ├── about
   └── a-propos-du-blog-jls42.md
   ├── mentions
   └── mentions-legales.md
   ├── posts
   ├── blog
   └── nouveau-theme-logo.md
   ├── ia
   ├── poc-mistral-ai-mixtral.md
   ├── poc-openai-api-gpt4.md
   └── stable-difusion-aws-ec2.md
   ├── infrastructure
   └── infrastruture-as-code-serverless-ha-jls42-org.md
   └── raspberry-pi
       ├── glusterfs_distribue_replique_sur_raspberry_pi_via_ansible.md
       ├── initialisation-auto-de-raspbian-sur-raspberry-pi.md
       ├── installation-de-docker-sur-raspberry-pi-via-ansible.md
       └── installation-de-kubernetes-sur-raspberry-pi-via-ansible.md

A Solução: Um Script Inovador

Projetei um script Python que se apoia na API OpenAI GPT-4 para traduzir o texto preservando os elementos não textuais. Graças a uma série de regras de processamento e ao uso de placeholders, o script pode identificar e excluir os blocos de código e outros elementos não traduzíveis, garantindo que o conteúdo traduzido permaneça fiel ao original.

Principais Funcionalidades

  1. Tradução Precisa com GPT-4 : O script utiliza o modelo GPT-4 da OpenAI para traduzir o texto do francês para o inglês, assegurando a preservação da qualidade e nuance do conteúdo original.
  2. Preservação da Formatação : Os blocos de código, as URLs e os caminhos de imagem são identificados e deixados intactos durante a tradução, garantindo que a formatação original seja preservada.
  3. Flexibilidade Multilíngue : O script foi projetado para ser facilmente adaptável a diferentes idiomas de origem e destino, permitindo uma ampla variedade de aplicações multilíngues.
  4. Suporte a Arquivos Markdown : Capacidade de traduzir documentos escritos em Markdown, mantendo sua estrutura e formatação específicas.
  5. Automação da Tradução de Diretórios : Tradução automática dos arquivos Markdown encontrados em um diretório dado e seus subdiretórios, facilitando a gestão de grandes volumes de conteúdo.
  6. Inclusão de Nota de Tradução : Adiciona automaticamente uma nota de tradução ao final dos documentos traduzidos, indicando o modelo GPT usado para a tradução.
  7. Configuração e Personalização Fáceis : Parâmetros padrão personalizáveis para a chave da API, o modelo GPT, os idiomas de origem e destino, e os diretórios de arquivos, oferecendo grande flexibilidade de uso.
  8. Relatório de Desempenho : O script fornece um feedback sobre o tempo necessário para traduzir cada arquivo, permitindo monitorar seu desempenho.

Código do script

O código também está disponível aqui : Tradutor Markdown com IA

#!/usr/bin/env python3

import os
import argparse
import time
from openai import OpenAI
import re

# Initialisation de la configuration avec les valeurs par défaut
DEFAULT_API_KEY = 'votre-clé-api-par-défaut'
DEFAULT_MODEL = "gpt-4-1106-preview"
DEFAULT_SOURCE_LANG = 'fr'
DEFAULT_TARGET_LANG = 'en'
DEFAULT_SOURCE_DIR = 'content/posts'
DEFAULT_TARGET_DIR = 'traductions_en'

MODEL_TOKEN_LIMITS = {
    "gpt-4-1106-preview": 4096,
    "gpt-4-vision-preview": 4096,
    "gpt-4": 8192,
    "gpt-4-32k": 32768,
    "gpt-4-0613": 8192,
    "gpt-4-32k-0613": 32768
}

# Fonction de traduction
def translate_with_openai(text, client, args):
    """
    Traduit le texte donné du langage source au langage cible en utilisant l'API OpenAI.

    Args:
        text (str) : Le texte à traduire.
        client : L'objet client OpenAI.
        args : Les arguments contenant les informations sur le langage source, le langage cible et le modèle.

    Returns:
        str : Le texte traduit.
    """
    # Détecter et stocker les blocs de code
    code_blocks = re.findall(r'(^```[a-zA-Z]*\n.*?\n^```)', text, flags=re.MULTILINE | re.DOTALL)
    placeholders = [f"#CODEBLOCK{index}#" for index, _ in enumerate(code_blocks)]

    # Remplacer les blocs de code par des placeholders
    for placeholder, code_block in zip(placeholders, code_blocks):
        text = text.replace(code_block, placeholder)

    # Création du message pour l'API
    messages = [
        {"role": "system", "content": f"Translate the following text from {args.source_lang} to {args.target_lang}, ensuring that elements such as URLs, image paths, and code blocks (delimited by ```) are not translated. Leave these elements unchanged."},
        {"role": "user", "content": text}
    ]

    # Envoi de la demande de traduction
    response = client.chat.completions.create(
        model=args.model,
        messages=messages
    )

    # Obtenir le texte traduit et remplacer les placeholders par les blocs de code originaux
    translated_text = response.choices[0].message.content.strip()
    for placeholder, code_block in zip(placeholders, code_blocks):
        translated_text = translated_text.replace(placeholder, code_block)

    return translated_text

def add_translation_note(client, args):
    """
    Ajoute une note de traduction à un document.

    Args:
        client : Le client de traduction.
        args : Arguments supplémentaires.

    Returns:
        La note de traduction formatée.
    """
    # Note de traduction en français
    translation_note_fr = "Ce document a été traduit de la version française du blog par le modèle "
    # Traduire la note en langue cible
    translated_note = translate_with_openai(translation_note_fr + args.model, client, args)
    # Formatage de la note de traduction
    return f"\n\n**{translated_note}**\n\n"

# Traitement des fichiers Markdown
def translate_markdown_file(file_path, output_path, client, args):
    """
    Traduit le contenu d'un fichier markdown en utilisant l'API de traduction OpenAI et écrit le contenu traduit dans un nouveau fichier.

    Args:
        file_path (str): Chemin vers le fichier markdown d'entrée.
        output_path (str): Chemin vers le fichier de sortie où le contenu traduit sera écrit.
        client: Client de traduction OpenAI.
        args: Arguments supplémentaires pour le processus de traduction.

    Returns:
        None
    """
    print(f"Traitement du fichier : {file_path}")
    start_time = time.time()

    with open(file_path, 'r', encoding='utf-8') as f:
        content = f.read()

    translated_content = translate_with_openai(content, client, args)

    # Ajouter la note de traduction à la fin du contenu traduit
    translation_note = add_translation_note(client, args)
    translated_content_with_note = translated_content + translation_note

    with open(output_path, 'w', encoding='utf-8') as f:
        f.write(translated_content_with_note)

    end_time = time.time()
    print(f"Traduction terminée en {end_time - start_time:.2f} secondes.")

def translate_directory(input_dir, output_dir, client, args):
    """
    Traduit tous les fichiers markdown dans le répertoire d'entrée et ses sous-répertoires.

    Args:
        input_dir (str): Chemin vers le répertoire d'entrée.
        output_dir (str): Chemin vers le répertoire de sortie.
        client: Objet client de traduction.
        args: Arguments supplémentaires pour la traduction.

    Returns:
        None
    """
    for root, dirs, files in os.walk(input_dir, topdown=True):
        # Exclure les dossiers qui commencent par "traductions_"
        dirs[:] = [d for d in dirs if not d.startswith("traductions_")]

        for file in files:
            if file.endswith('.md'):
                file_path = os.path.join(root, file)
                base, _ = os.path.splitext(file)
                # Ajouter le nom du modèle utilisé dans le nom du fichier de sortie
                output_file = f"{base}-{args.model}-{args.target_lang}.md"
                relative_path = os.path.relpath(root, input_dir)
                output_path = os.path.join(output_dir, relative_path, output_file)

                os.makedirs(os.path.dirname(output_path), exist_ok=True)

                if not os.path.exists(output_path):
                    translate_markdown_file(file_path, output_path, client, args)
                    print(f"Fichier '{file}' traité.")


def main():
    """
    Fonction principale pour traduire les fichiers Markdown.

    Args:
        --source_dir (str): Répertoire source contenant les fichiers Markdown.
        --target_dir (str): Répertoire cible pour sauvegarder les traductions.
        --model (str): Modèle GPT à utiliser.
        --target_lang (str): Langue cible pour la traduction.
        --source_lang (str): Langue source pour la traduction.
    """
    parser = argparse.ArgumentParser(description="Traduit les fichiers Markdown.")
    parser.add_argument('--source_dir', type=str, default=DEFAULT_SOURCE_DIR, help='Répertoire source contenant les fichiers Markdown')
    parser.add_argument('--target_dir', type=str, default=DEFAULT_TARGET_DIR, help='Répertoire cible pour sauvegarder les traductions')
    parser.add_argument('--model', type=str, default=DEFAULT_MODEL, help='Modèle GPT à utiliser')
    parser.add_argument('--target_lang', type=str, default=DEFAULT_TARGET_LANG, help='Langue cible pour la traduction')
    parser.add_argument('--source_lang', type=str, default=DEFAULT_SOURCE_LANG, help='Langue source pour la traduction')

    args = parser.parse_args()

    openai_api_key = os.getenv('OPENAI_API_KEY', DEFAULT_API_KEY)
    with OpenAI(api_key=openai_api_key) as client:
        translate_directory(args.source_dir, args.target_dir, client, args)

if __name__ == "__main__":
    main()

Olhar mais de perto o script

Importações de módulos

Antes de tudo, temos algumas importações de módulos necessárias, tais como os, argparse, time e re. Esses módulos são usados para realizar operações no sistema de arquivos, analisar argumentos de linha de comando, medir o tempo de execução e executar operações de busca e substituição de texto.

Constantes

Em seguida, temos constantes definidas, tais como DEFAULT_API_KEY, DEFAULT_MODEL, DEFAULT_SOURCE_LANG, DEFAULT_TARGET_LANG, DEFAULT_SOURCE_DIR e DEFAULT_TARGET_DIR. Essas constantes representam os valores padrão usados no script, mas podem ser modificadas especificando argumentos na linha de comando.

Função translate_with_openai

A seguir, temos a função translate_with_openai. Esta função recebe um texto, um objeto cliente OpenAI e argumentos como parâmetros. Ela usa a API OpenAI para traduzir o texto da língua de origem para a língua de destino. Veja como funciona:

  1. A função usa uma expressão regular para detectar e armazenar os blocos de código no texto. Esses blocos de código são delimitados por três backticks (). Les blocs de code sont stockés dans une liste appelée code_blocks`.
  2. Em seguida, a função substitui os blocos de código por placeholders no texto. Os placeholders são cadeias da forma #CODEBLOCK{index}#, onde index é o índice do bloco de código correspondente na lista code_blocks.
  3. A função cria uma mensagem para a API OpenAI. Essa mensagem contém duas partes: uma mensagem de sistema que instrui a API a traduzir o texto da língua de origem para a língua de destino deixando elementos como URLs, caminhos de imagem e blocos de código inalterados, e uma mensagem do usuário que contém o texto a ser traduzido.
  4. A função envia a solicitação de tradução para a API usando o método client.chat.completions.create(). Ela especifica o modelo a ser usado e as mensagens a serem traduzidas.
  5. A resposta da API contém o texto traduzido. A função recupera o texto traduzido e substitui os placeholders pelos blocos de código originais.
  6. Por fim, a função retorna o texto traduzido.

Função add_translation_note

Em seguida, temos a função add_translation_note. Esta função adiciona uma nota de tradução a um documento. Ela recebe um objeto cliente OpenAI e argumentos como parâmetros. Veja como funciona:

  1. A função cria uma nota de tradução em francês usando a variável translation_note_fr.
  2. Em seguida, a função usa a função translate_with_openai para traduzir a nota de tradução usando a API OpenAI. Os argumentos passados a translate_with_openai incluem a nota de tradução em francês e os demais argumentos.
  3. A função formata a nota de tradução traduzida adicionando caracteres de formatação.
  4. Por fim, a função retorna a nota de tradução formatada.

Função translate_markdown_file

Em seguida, temos a função translate_markdown_file. Esta função recebe o caminho de um arquivo Markdown de entrada, o caminho de um arquivo de saída, um objeto cliente OpenAI e argumentos como parâmetros. Ela traduz o conteúdo do arquivo Markdown usando a API de tradução OpenAI e escreve o conteúdo traduzido no arquivo de saída.

Este script não só melhorou a acessibilidade dos meus artigos de blog, como também abriu caminho para novas possibilidades de automação na área de criação de conteúdo multilíngue. É um passo à frente rumo a um compartilhamento mais amplo e inclusivo do conhecimento.

Experiência de Uso e Tempo de Processamento

Exemplos de Uso

# Création des répertoires cibles
jls42@Boo:~/blog/jls42$ mkdir content/traductions_en content/traductions_es

###############################################
# Demande de traduction à l'IA vers l'anglais #
###############################################
jls42@Boo:~/blog/jls42$ python3 translate.py --source_dir content/ --target_dir content/traductions_en
Traitement du fichier : content/posts/ia/stable-difusion-aws-ec2.md
Traduction terminée en 21.57 secondes.
Fichier 'stable-difusion-aws-ec2.md' traité.
Traitement du fichier : content/posts/ia/poc-openai-api-gpt4.md
Traduction terminée en 34.87 secondes.
Fichier 'poc-openai-api-gpt4.md' traité.
Traitement du fichier : content/posts/ia/poc-mistral-ai-mixtral.md
Traduction terminée en 62.47 secondes.
Fichier 'poc-mistral-ai-mixtral.md' traité.
Traitement du fichier : content/posts/raspberry-pi/installation-de-kubernetes-sur-raspberry-pi-via-ansible.md
Traduction terminée en 46.37 secondes.
Fichier 'installation-de-kubernetes-sur-raspberry-pi-via-ansible.md' traité.
Traitement du fichier : content/posts/raspberry-pi/installation-de-docker-sur-raspberry-pi-via-ansible.md
Traduction terminée en 10.08 secondes.
Fichier 'installation-de-docker-sur-raspberry-pi-via-ansible.md' traité.
Traitement du fichier : content/posts/raspberry-pi/initialisation-auto-de-raspbian-sur-raspberry-pi.md
Traduction terminée en 17.17 secondes.
Fichier 'initialisation-auto-de-raspbian-sur-raspberry-pi.md' traité.
Traitement du fichier : content/posts/blog/nouveau-theme-logo.md
Traduction terminée en 12.91 secondes.
Fichier 'nouveau-theme-logo.md' traité.
Traitement du fichier : content/posts/infrastructure/infrastruture-as-code-serverless-ha-jls42-org.md
Traduction terminée en 12.64 secondes.
Fichier 'infrastruture-as-code-serverless-ha-jls42-org.md' traité.
Traitement du fichier : content/mentions/mentions-legales.md
Traduction terminée en 11.90 secondes.
Fichier 'mentions-legales.md' traité.
Traitement du fichier : content/about/a-propos-du-blog-jls42.md
Traduction terminée en 18.72 secondes.
Fichier 'a-propos-du-blog-jls42.md' traité.

################################################
# Demande de traduction à l'IA vers l'espagnol #
################################################
jls42@Boo:~/blog/jls42$ python3 translate.py --source_dir content/ --target_dir content/traductions_es --target_lang es
Traitement du fichier : content/posts/ia/stable-difusion-aws-ec2.md
Traduction terminée en 33.19 secondes.
Fichier 'stable-difusion-aws-ec2.md' traité.
Traitement du fichier : content/posts/ia/poc-openai-api-gpt4.md
Traduction terminée en 25.24 secondes.
Fichier 'poc-openai-api-gpt4.md' traité.
Traitement du fichier : content/posts/ia/poc-mistral-ai-mixtral.md
Traduction terminée en 58.78 secondes.
Fichier 'poc-mistral-ai-mixtral.md' traité.
Traitement du fichier : content/posts/raspberry-pi/installation-de-kubernetes-sur-raspberry-pi-via-ansible.md
Traduction terminée en 17.64 secondes.
Fichier 'installation-de-kubernetes-sur-raspberry-pi-via-ansible.md' traité.
Traitement du fichier : content/posts/raspberry-pi/installation-de-docker-sur-raspberry-pi-via-ansible.md
Traduction terminée en 19.60 secondes.
Fichier 'installation-de-docker-sur-raspberry-pi-via-ansible.md' traité.
Traitement du fichier : content/posts/raspberry-pi/initialisation-auto-de-raspbian-sur-raspberry-pi.md
Traduction terminée en 37.12 secondes.
Fichier 'initialisation-auto-de-raspbian-sur-raspberry-pi.md' traité.
Traitement du fichier : content/posts/blog/nouveau-theme-logo.md
Traduction terminée en 18.91 secondes.
Fichier 'nouveau-theme-logo.md' traité.
Traitement du fichier : content/posts/infrastructure/infrastruture-as-code-serverless-ha-jls42-org.md
Traduction terminée en 30.73 secondes.
Fichier 'infrastruture-as-code-serverless-ha-jls42-org.md' traité.
Traitement du fichier : content/mentions/mentions-legales.md
Traduction terminée en 13.14 secondes.
Fichier 'mentions-legales.md' traité.
Traitement du fichier : content/about/a-propos-du-blog-jls42.md
Traduction terminée en 11.24 secondes.
Fichier 'a-propos-du-blog-jls42.md' traité.

Tempo de Processamento

  • Inglês : Cerca de 4 minutos (248.70 segundos)
  • Espanhol : Cerca de 4,7 minutos (284.05 segundos)
  • Total acumulado : Cerca de 8,7 minutos (532.75 segundos) Esses tempos demonstram a eficiência e a rapidez do script.

Resultados

Nota : Este exemplo ilustra o funcionamento do script na antiga estrutura Hugo do blog. O blog desde então foi migrado para Astro com uma nova arquitetura multilíngue. As traduções agora são acessíveis através do seletor de idioma integrado.

Esta postagem do blog é um resumo da minha experiência em automação de tradução com IA. É a prova de que, ao combinar programação com inteligência artificial, as possibilidades são quase ilimitadas, abrindo novos e empolgantes horizontes na área do compartilhamento de conhecimento e na acessibilidade de conteúdo.

Este documento foi traduzido da versão fr para a língua pt usando o modelo gpt-5-mini. Para mais informações sobre o processo de tradução, consulte https://gitlab.com/jls42/ai-powered-markdown-translator