In diesem Artikel teile ich ein Python-Skript, das als Proof of Concept (POC) entwickelt wurde, um die Übersetzung meiner Blogbeiträge zu automatisieren, indem das Sprachmodell GPT-4 von OpenAI verwendet wird. Dieses Skript ist speziell darauf ausgelegt, Markdown-Dateien in der Struktur meines Hugo-Blogs zu verarbeiten und die mehrsprachige Verwaltung meiner Artikel zu erleichtern. Sie sind verfügbar in Englisch, Spanisch und Chinesisch.
Projektbeginn: KI und Automatisierung für Mein Blog Vereinen
Dieses Projekt zur Automatisierung der Übersetzung meiner Blogartikel begann mit meiner wachsenden Faszination für künstliche Intelligenz. Inspiriert von meinen ersten Erfahrungen mit den APIs von OpenAI GPT-4 und Mistral AI, wurde ich von der Idee angezogen, diese Technologien in einem praktischen Projekt zu verwirklichen und damit einen greifbaren Mehrwert für meinen Blog zu schaffen. Es war nicht nur eine Suche nach dem Beherrschen von KI-Tools, sondern auch der Wunsch, Automatisierung und Innovation zu vereinen, um meinen digitalen Raum zu bereichern.
Dieses Projekt entwickelte sich zu einem Abenteuer, bei dem KI nicht nur ein Schreibthema war, sondern ein aktiver Partner in der Entwicklung. Die Idee, meine Artikel einfach und effizient mit KI zu übersetzen und dabei ihre Automatisierungsfähigkeiten zu erkunden, eröffnete faszinierende Perspektiven. Es war eine Gelegenheit, Sprachbarrieren zu überwinden, meinen Inhalt einem breiteren Publikum zugänglich zu machen und gleichzeitig in der sich ständig weiterentwickelnden Welt der künstlichen Intelligenz zu navigieren.
Die Herausforderung
Die Hauptaufgabe bestand darin, ein Skript zu erstellen, das mit hoher Genauigkeit übersetzt und das ursprüngliche Format der Artikel, insbesondere Codeblöcke, Links und Bilder, beibehält. Eine weitere Herausforderung bestand darin, sicherzustellen, dass das Skript leicht an verschiedene Sprachen anpassbar ist. Es musste auch in der Lage sein, folgende Struktur zu berücksichtigen:
├── 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
Die Lösung: Ein Innovatives Skript
Ich habe ein Python-Skript entwickelt, das auf der OpenAI GPT-4 API basiert, um den Text zu übersetzen und dabei nicht-textuelle Elemente zu bewahren. Durch eine Reihe von Verarbeitungsregeln und die Verwendung von Platzhaltern kann das Skript Codeblöcke und andere nicht zu übersetzende Elemente identifizieren und ausschließen, wodurch sichergestellt wird, dass der übersetzte Inhalt dem Original treu bleibt.
Hauptfunktionen
- Genaue Übersetzung mit GPT-4: Das Skript nutzt das GPT-4-Modell von OpenAI, um den Text vom Französischen ins Englische zu übersetzen, und stellt sicher, dass die Qualität und Nuance des Originalinhalts erhalten bleibt.
- Erhaltung des Formats: Codeblöcke, URLs und Bildpfade werden während der Übersetzung identifiziert und unverändert gelassen, was die Bewahrung des ursprünglichen Formats garantiert.
- Mehrsprachige Flexibilität: Das Skript ist so konzipiert, dass es leicht an verschiedene Quell- und Zielsprachen angepasst werden kann, was eine große Vielfalt an mehrsprachigen Anwendungen ermöglicht.
- Unterstützung für Markdown-Dateien: Fähigkeit, in Markdown geschriebene Dokumente zu übersetzen und deren spezifische Struktur und Formatierung beizubehalten.
- Automatisierung der Übersetzung von Verzeichnissen: Automatische Übersetzung von Markdown-Dateien, die in einem bestimmten Verzeichnis und seinen Unterverzeichnissen gefunden werden, was die Verwaltung großer Inhaltsmengen erleichtert.
- Integration einer Übersetzungsnotiz: Fügt automatisch eine Übersetzungsnotiz am Ende der übersetzten Dokumente hinzu, die das verwendete GPT-Modell für die Übersetzung angibt.
- Einfache Konfiguration und Anpassung: Anpassbare Standardeinstellungen für den API-Schlüssel, das GPT-Modell, die Quell- und Zielsprache sowie die Dateiverzeichnisse bieten eine hohe Flexibilität in der Anwendung.
- Leistungsbericht: Das Skript liefert ein Feedback über die Zeit, die für die Übersetzung jeder Datei benötigt wird, was die Überwachung seiner Leistung ermöglicht.
Skriptcode
Der Code ist auch hier verfügbar: AI-Powered Markdown Translator
#!/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()
Skriptübersicht
Modulimporte
Zunächst haben wir einige erforderliche Modulimporte wie os
, argparse
, time
und re
. Diese Module werden verwendet, um Dateioperationen durchzuführen, Befehlszeilenargumente zu analysieren, die Ausführungszeit zu messen und Such- und Ersetzungsoperationen auf Texten durchzuführen.
Konstanten
Als nächstes haben wir definierte Konstanten wie DEFAULT_API_KEY
, DEFAULT_MODEL
, DEFAULT_SOURCE_LANG
, DEFAULT_TARGET_LANG
, DEFAULT_SOURCE_DIR
und DEFAULT_TARGET_DIR
. Diese Konstanten repräsentieren die im Skript verwendeten Standardwerte, können jedoch durch Angabe von Befehlszeilenargumenten geändert werden.
Funktion translate_with_openai
Als nächstes haben wir die Funktion translate_with_openai
. Diese Funktion nimmt einen Text, ein OpenAI-Clientobjekt und Argumente als Parameter entgegen. Sie verwendet die OpenAI-API, um den Text aus der Quellsprache in die Zielsprache zu übersetzen. So funktioniert es:
- Die Funktion verwendet einen regulären Ausdruck, um Codeblöcke im Text zu erkennen und zu speichern. Diese Codeblöcke sind durch dreifache Backticks (
) begrenzt. Die Codeblöcke werden in einer Liste namens
code_blocks` gespeichert. - Als nächstes ersetzt die Funktion die Codeblöcke durch Platzhalter im Text. Die Platzhalter sind Zeichenfolgen der Form
#CODEBLOCK{index}#
, wobeiindex
den Index des entsprechenden Codeblocks in der Listecode_blocks
darstellt. - Die Funktion erstellt eine Nachricht für die OpenAI-API. Diese Nachricht enthält zwei Teile: eine Systemnachricht, die der API mitteilt, den Text aus der Quellsprache in die Zielsprache zu übersetzen und dabei Elemente wie URLs, Bildpfade und Codeblöcke unverändert zu lassen, und eine Benutzernachricht, die den zu übersetzenden Text enthält.
- Die Funktion sendet die Übersetzungsanfrage an die API unter Verwendung der Methode
client.chat.completions.create()
. Sie gibt an, welches Modell verwendet und welche Nachrichten übersetzt werden sollen. - Die Antwort der API enthält den übersetzten Text. Die Funktion extrahiert den übersetzten Text und ersetzt die Platzhalter durch die ursprünglichen Codeblöcke.
- Schließlich gibt die Funktion den übersetzten Text zurück.
Funktion add_translation_note
Als nächstes haben wir die Funktion add_translation_note
. Diese Funktion fügt einem Dokument eine Übersetzungsnotiz hinzu. Sie nimmt ein OpenAI-Clientobjekt und Argumente als Parameter entgegen. So funktioniert es:
- Die Funktion erstellt eine Übersetzungsnotiz auf Französisch unter Verwendung der Variable
translation_note_fr
. - Anschließend verwendet die Funktion die Funktion
translate_with_openai
, um die Übersetzungsnotiz unter Verwendung der OpenAI-API zu übersetzen. Die antranslate_with_openai
übergebenen Argumente enthalten die französische Übersetzungsnotiz und die weiteren Argumente. - Die Funktion formatiert die übersetzte Übersetzungsnotiz durch Hinzufügen von Formatierungszeichen.
- Schließlich gibt die Funktion die formatierte Übersetzungsnotiz zurück.
Funktion translate_markdown_file
Als nächstes haben wir die Funktion translate_markdown_file
. Diese Funktion nimmt den Pfad einer Eingabedatei im Markdown-Format, den Pfad einer Ausgabedatei, ein OpenAI-Clientobjekt und Argumente als Parameter entgegen. Sie übersetzt den Inhalt der Markdown-Datei unter Verwendung der OpenAI-Übersetzungs-API und schreibt den übersetzten Inhalt in die Ausgabedatei.
Dieses Skript hat nicht nur die Zugänglichkeit meiner Blogartikel verbessert, sondern auch den Weg für neue Automatisierungsmöglichkeiten im Bereich der mehrsprachigen Inhaltserstellung geebnet. Es ist ein Schritt hin zu einer breiteren und inklusiveren Wissensverbreitung. ## Nutzungserfahrung und Verarbeitungszeit
Anwendungsbeispiele
# 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é.
Verarbeitungszeit
- Englisch: Ungefähr 4 Minuten (248,70 Sekunden)
- Spanisch: Ungefähr 4,7 Minuten (284,05 Sekunden)
- Gesamtlaufzeit: Ungefähr 8,7 Minuten (532,75 Sekunden) Diese Zeiten zeigen die Effizienz und Geschwindigkeit des Skripts.
Ergebnisse
Sie können jetzt die Ergebnisse dieser übersetzten Inhaltserstellungen über diese Links abrufen:
Dieser Blogbeitrag ist eine Zusammenfassung meiner Erfahrungen mit der Übersetzungsautomatisierung durch KI. Es ist ein Beweis dafür, dass, wenn man Programmierung mit künstlicher Intelligenz kombiniert, die Möglichkeiten fast unbegrenzt sind und neue und spannende Horizonte im Bereich des Wissensaustauschs und der Inhaltszugänglichkeit eröffnen.
Dieses Dokument wurde von der Version fr in die Sprache de unter Verwendung des Modells gpt-4o übersetzt. Für weitere Informationen zum Übersetzungsprozess besuchen Sie https://gitlab.com/jls42/ai-powered-markdown-translator.