
Create Multi-Language Reports with Your AI Agent
Episode 7: Build A Personal AI Agent
A Practical Guide for Evaluators and M&E Professionals
Why Multi-Language Reporting Matters
In international development, reports often need to reach diverse stakeholders who speak different languages. This tutorial shows you how to build an AI agent that automatically translates and generates evaluation reports in multiple languages, saving hours of manual translation work.
Part 1: Understanding Multi-Language Requirements
Common Language Scenarios in M&E:
| Scenario | Target Languages | Stakeholders |
|---|---|---|
| International NGO | English, French, Spanish, Arabic | Donors, Country Offices |
| EU Program | English, French, German, Italian | European Commission, Partners |
| African Development | English, French, Portuguese, Swahili | Regional Governments, Communities |
| Latin American NGO | Spanish, Portuguese, English | Local Communities, International Donors |
Part 2: Setting Up the Multi-Language System
Step 1: Install Required Libraries
pip install googletrans==4.0.0-rc1 deep-translator pandas openpyxl anthropicTranslation Library Guide:
googletrans: Free Google Translate API (good for basic translations)
deep-translator: Supports multiple translation providers
anthropic: For AI-powered translation with context awareness
Step 2: Language Configuration
# language_config.py
# Define supported languages and their configurations
LANGUAGES = {
'en': {
'name': 'English',
'code': 'en',
'header': 'Performance Report',
'footer': 'End of Report'
},
'fr': {
'name': 'French',
'code': 'fr',
'header': 'Rapport de Performance',
'footer': 'Fin du Rapport'
},
'es': {
'name': 'Spanish',
'code': 'es',
'header': 'Informe de Desempeño',
'footer': 'Fin del Informe'
},
'pt': {
'name': 'Portuguese',
'code': 'pt',
'header': 'Relatório de Desempenho',
'footer': 'Fim do Relatório'
},
'ar': {
'name': 'Arabic',
'code': 'ar',
'header': 'تقرير الأداء',
'footer': 'نهاية التقرير'
},
'sw': {
'name': 'Swahili',
'code': 'sw',
'header': 'Ripoti ya Utendaji',
'footer': 'Mwisho wa Ripoti'
}
}
# Common phrases used in reports
REPORT_PHRASES = {
'en': {
'executive_summary': 'Executive Summary',
'performance_overview': 'Performance Overview',
'achievements': 'Key Achievements',
'challenges': 'Challenges',
'recommendations': 'Recommendations',
'next_steps': 'Next Steps',
'off_track': 'Off Track',
'on_track': 'On Track',
'at_risk': 'At Risk'
},
'fr': {
'executive_summary': 'Résumé Exécutif',
'performance_overview': 'Aperçu de la Performance',
'achievements': 'Réalisations Clés',
'challenges': 'Défis',
'recommendations': 'Recommandations',
'next_steps': 'Prochaines Étapes',
'off_track': 'Hors Piste',
'on_track': 'Sur la Bonne Voie',
'at_risk': 'À Risque'
},
'es': {
'executive_summary': 'Resumen Ejecutivo',
'performance_overview': 'Resumen de Desempeño',
'achievements': 'Logros Clave',
'challenges': 'Desafíos',
'recommendations': 'Recomendaciones',
'next_steps': 'Próximos Pasos',
'off_track': 'Fuera de Curso',
'on_track': 'En Curso',
'at_risk': 'En Riesgo'
},
'pt': {
'executive_summary': 'Resumo Executivo',
'performance_overview': 'Visão Geral do Desempenho',
'achievements': 'Principais Conquistas',
'challenges': 'Desafios',
'recommendations': 'Recomendações',
'next_steps': 'Próximos Passos',
'off_track': 'Fora do Alvo',
'on_track': 'No Caminho Certo',
'at_risk': 'Em Risco'
}
}Part 3: Building the Translation Agent
1. Translation Functions
from googletrans import Translator
from deep_translator import GoogleTranslator
import time
class TranslationAgent:
"""Handles translation of reports into multiple languages."""
def __init__(self, translator_type='google'):
self.translator_type = translator_type
if translator_type == 'google':
self.translator = GoogleTranslator(source='auto', target='en')
else:
self.translator = Translator()
def translate_text(self, text, source_lang='en', target_lang='es'):
"""Translate text from source to target language."""
if not text or len(text.strip()) == 0:
return ""
# Handle very long texts by splitting
if len(text) > 5000:
return self._translate_long_text(text, source_lang, target_lang)
try:
if self.translator_type == 'google':
result = self.translator.translate(text, source=source_lang, target=target_lang)
return result
else:
self.translator = Translator()
result = self.translator.translate(text, src=source_lang, dest=target_lang)
return result.text
except Exception as e:
print(f"Translation error: {e}")
return text
def _translate_long_text(self, text, source_lang, target_lang):
"""Split and translate long texts."""
parts = text.split('\n\n')
translated_parts = []
for part in parts:
if len(part) > 4000:
# Further split if needed
sub_parts = part.split('. ')
translated_sub = []
for sub in sub_parts:
translated_sub.append(self.translate_text(sub, source_lang, target_lang))
time.sleep(0.1) # Avoid rate limiting
translated_parts.append('. '.join(translated_sub))
else:
translated_parts.append(self.translate_text(part, source_lang, target_lang))
time.sleep(0.1)
return '\n\n'.join(translated_parts)
def translate_report_sections(self, report_data, target_languages):
"""Translate all sections of a report into multiple languages."""
translated_reports = {}
for lang_code in target_languages:
print(f"Translating to {LANGUAGES[lang_code]['name']}...")
translated = {}
for section, content in report_data.items():
if isinstance(content, str):
translated[section] = self.translate_text(content, 'en', lang_code)
elif isinstance(content, list):
translated[section] = [
self.translate_text(item, 'en', lang_code)
for item in content
]
elif isinstance(content, dict):
translated[section] = {
key: self.translate_text(value, 'en', lang_code)
for key, value in content.items()
}
else:
translated[section] = content
translated_reports[lang_code] = translated
return translated_reports2. AI-Powered Translation with Context
import anthropic
import os
class AIEnhancedTranslator:
"""Uses Claude AI for context-aware translation."""
def __init__(self, api_key=None):
self.client = anthropic.Anthropic(api_key=api_key or os.getenv('ANTHROPIC_API_KEY'))
def translate_with_context(self, text, source_lang='English', target_lang='French',
context='M&E performance report'):
"""Translate with awareness of M&E context."""
prompt = f"""
You are a professional translator specializing in M&E reports.
Translate the following text from {source_lang} to {target_lang}.
CONTEXT: {context}
SOURCE TEXT:
{text}
Requirements:
1. Maintain technical M&E terminology accuracy
2. Preserve formatting (headings, bullet points, etc.)
3. Keep the same tone (formal/professional)
4. Don't add or remove content
5. Use standard M&E terminology in target language
TRANSLATION:
"""
response = self.client.messages.create(
model="claude-3-sonnet-20240229",
max_tokens=2000,
temperature=0.2,
messages=[{"role": "user", "content": prompt}]
)
return response.content[0].text
def translate_report_ai(self, report_content, target_langs, context_info):
"""Complete report translation with AI."""
translations = {}
for lang, lang_info in target_langs.items():
print(f"AI translating to {lang_info['name']}...")
translations[lang] = self.translate_with_context(
report_content,
'English',
lang_info['name'],
context_info
)
return translationsPart 4: Building the Multi-Language Report Generator
Complete Multi-Language Agent
# multi_language_agent.py
import pandas as pd
from datetime import datetime
import json
class MultiLanguageReportGenerator:
"""Generates reports in multiple languages."""
def __init__(self, languages=['en', 'fr', 'es'], use_ai=False):
self.languages = languages
self.translator = TranslationAgent()
self.ai_translator = AIEnhancedTranslator() if use_ai else None
self.reports = {}
def generate_report_content(self, indicator_data, period='weekly'):
"""Generate raw report content in English."""
# Prepare data summary
df = pd.DataFrame(indicator_data)
metrics = self._calculate_metrics(df)
content = {
'title': f"{period.capitalize()} Performance Report",
'date': datetime.now().strftime('%Y-%m-%d'),
'executive_summary': self._generate_summary(metrics, df),
'performance_overview': self._generate_overview(metrics),
'achievements': self._get_top_performers(df),
'challenges': self._get_bottom_performers(df),
'recommendations': self._generate_recommendations(df),
'next_steps': self._generate_next_steps(metrics),
'data_table': self._generate_data_table(df),
'footer': "Generated by AI Agent for M&E"
}
return content
def _calculate_metrics(self, df):
"""Calculate key metrics from data."""
metrics = {
'total_indicators': len(df),
'on_track': len(df[df['status'] == 'on_track']) if 'status' in df else 0,
'at_risk': len(df[df['status'] == 'at_risk']) if 'status' in df else 0,
'off_track': len(df[df['status'] == 'off_track']) if 'status' in df else 0,
'avg_achievement': df['achievement'].mean() if 'achievement' in df else 0,
'categories': df['category'].nunique() if 'category' in df else 0
}
return metrics
def _generate_summary(self, metrics, df):
"""Generate executive summary."""
return f"""This report covers {metrics['total_indicators']} indicators across {metrics['categories']} program areas.
Overall achievement is at {metrics['avg_achievement']:.1f}% with {metrics['on_track']} indicators on track,
{metrics['at_risk']} at risk, and {metrics['off_track']} off track."""
def _generate_overview(self, metrics):
"""Generate performance overview section."""
return {
'total_indicators': metrics['total_indicators'],
'on_track_count': metrics['on_track'],
'at_risk_count': metrics['at_risk'],
'off_track_count': metrics['off_track'],
'average_achievement': f"{metrics['avg_achievement']:.1f}%"
}
def _get_top_performers(self, df):
"""Get top performing indicators."""
if 'achievement' in df:
top = df.nlargest(3, 'achievement')
return [f"{row['indicator_name']}: {row['achievement']:.0f}%"
for _, row in top.iterrows()]
return ["No achievement data available"]
def _get_bottom_performers(self, df):
"""Get bottom performing indicators."""
if 'achievement' in df:
bottom = df.nsmallest(3, 'achievement')
return [f"{row['indicator_name']}: {row['achievement']:.0f}%"
for _, row in bottom.iterrows()]
return ["No achievement data available"]
def _generate_recommendations(self, df):
"""Generate recommendations based on data."""
recs = []
if 'status' in df:
off_track = df[df['status'] == 'off_track']
if len(off_track) > 0:
recs.append("Address off-track indicators with focused interventions")
if len(df[df['status'] == 'at_risk']) > 0:
recs.append("Provide additional support to at-risk indicators")
recs.append("Continue monitoring all indicators regularly")
recs.append("Update data collection methods where needed")
return recs
def _generate_next_steps(self, metrics):
"""Generate next steps section."""
steps = []
if metrics['off_track'] > 0:
steps.append(f"Review {metrics['off_track']} off-track indicators")
if metrics['at_risk'] > 0:
steps.append(f"Develop action plans for {metrics['at_risk']} at-risk indicators")
steps.append("Schedule follow-up review in 4 weeks")
return steps
def _generate_data_table(self, df):
"""Generate data table."""
return df[['indicator_name', 'target', 'actual', 'achievement', 'status']].to_dict('records')
def generate_report(self, indicator_data, period='weekly', languages=None):
"""Generate multi-language report."""
languages = languages or self.languages
# Step 1: Generate English content
print("Generating English report content...")
english_content = self.generate_report_content(indicator_data, period)
# Step 2: Format as text for translation
report_text = self._format_for_translation(english_content)
# Step 3: Translate to target languages
translations = {}
for lang_code in languages:
if lang_code == 'en':
translations[lang_code] = english_content
else:
print(f"Translating to {LANGUAGES[lang_code]['name']}...")
if self.ai_translator:
translated = self.ai_translator.translate_with_context(
report_text,
'English',
LANGUAGES[lang_code]['name'],
'M&E performance report'
)
translations[lang_code] = self._parse_translated(translated)
else:
translations[lang_code] = self.translator.translate_report_sections(
english_content,
[lang_code]
)[lang_code]
self.reports = translations
return translations
def _format_for_translation(self, content):
"""Format content for translation."""
text = f"""
Title: {content['title']}
Date: {content['date']}
Executive Summary:
{content['executive_summary']}
Performance Overview:
- Total Indicators: {content['performance_overview']['total_indicators']}
- On Track: {content['performance_overview']['on_track_count']}
- At Risk: {content['performance_overview']['at_risk_count']}
- Off Track: {content['performance_overview']['off_track_count']}
- Average Achievement: {content['performance_overview']['average_achievement']}
Key Achievements:
{chr(10).join(content['achievements'])}
Challenges:
{chr(10).join(content['challenges'])}
Recommendations:
{chr(10).join(content['recommendations'])}
Next Steps:
{chr(10).join(content['next_steps'])}
"""
return text
def _parse_translated(self, translated_text):
"""Parse translated text back into structured format."""
# Simple parsing - in production, use more robust parsing
sections = translated_text.split('\n\n')
parsed = {
'title': sections[0] if sections else 'Title',
'date': datetime.now().strftime('%Y-%m-%d')
}
for section in sections:
if 'Summary' in section:
parsed['executive_summary'] = section.replace('Executive Summary:', '').strip()
elif 'Performance' in section:
parsed['performance_overview'] = section.replace('Performance Overview:', '').strip()
return parsed
def save_reports(self, output_dir='multi_language_reports'):
"""Save all reports to files."""
import os
os.makedirs(output_dir, exist_ok=True)
for lang_code, content in self.reports.items():
filename = f"{output_dir}/report_{datetime.now().strftime('%Y%m%d')}_{lang_code}.json"
with open(filename, 'w', encoding='utf-8') as f:
json.dump(content, f, indent=2, ensure_ascii=False)
print(f"Saved: {filename}")
return self.reports
def generate_text_reports(self, output_dir='multi_language_reports'):
"""Generate text format reports for easy reading."""
import os
os.makedirs(output_dir, exist_ok=True)
for lang_code, content in self.reports.items():
filename = f"{output_dir}/report_{datetime.now().strftime('%Y%m%d')}_{lang_code}.txt"
with open(filename, 'w', encoding='utf-8') as f:
f.write("=" * 50 + "\n")
f.write(f"{content.get('title', 'Report')}\n")
f.write("=" * 50 + "\n\n")
f.write(f"Date: {content.get('date', '')}\n\n")
f.write("EXECUTIVE SUMMARY\n")
f.write("-" * 20 + "\n")
f.write(content.get('executive_summary', '') + "\n\n")
f.write("PERFORMANCE OVERVIEW\n")
f.write("-" * 20 + "\n")
overview = content.get('performance_overview', {})
if isinstance(overview, dict):
for key, value in overview.items():
f.write(f"{key}: {value}\n")
f.write("\n")
f.write("=" * 50 + "\n")
print(f"Saved text report: {filename}")Part 5: Complete Usage Examples
Example 1: Generate Multi-Language Report
# Create sample indicator data
sample_data = [
{'indicator_name': 'Children Vaccinated', 'target': 5000, 'actual': 4800,
'achievement': 96, 'status': 'on_track', 'category': 'Health', 'date': '2024-01-15'},
{'indicator_name': 'Teachers Trained', 'target': 200, 'actual': 180,
'achievement': 90, 'status': 'on_track', 'category': 'Education', 'date': '2024-01-15'},
{'indicator_name': 'Schools Reached', 'target': 100, 'actual': 85,
'achievement': 85, 'status': 'at_risk', 'category': 'Education', 'date': '2024-01-15'},
{'indicator_name': 'Community Events', 'target': 50, 'actual': 40,
'achievement': 80, 'status': 'at_risk', 'category': 'Community', 'date': '2024-01-15'},
{'indicator_name': 'Health Centers', 'target': 30, 'actual': 20,
'achievement': 67, 'status': 'off_track', 'category': 'Health', 'date': '2024-01-15'}
]
# Initialize the report generator
generator = MultiLanguageReportGenerator(
languages=['en', 'fr', 'es', 'pt'],
use_ai=False # Use Google Translate
)
# Generate reports
print("Generating multi-language reports...")
reports = generator.generate_report(sample_data, period='weekly')
# Save reports
generator.save_reports()
generator.generate_text_reports()
print("\nReports generated successfully in: English, French, Spanish, Portuguese")
Example 2: AI-Enhanced Translation
# Using AI for context-aware translation
def generate_ai_translated_report():
generator = MultiLanguageReportGenerator(
languages=['en', 'fr', 'es', 'pt', 'ar'],
use_ai=True # Use Claude AI
)
# Generate report
reports = generator.generate_report(sample_data, period='monthly')
# Save with AI translations
generator.save_reports('ai_translated_reports')
generator.generate_text_reports('ai_translated_reports')
print("AI-enhanced translations complete!")
print("Languages: English, French, Spanish, Portuguese, Arabic")
generate_ai_translated_report()
Part 6: Advanced Features
1. Language Detection
from langdetect import detect
def detect_language(text):
"""Detect the language of given text."""
try:
lang_code = detect(text)
return LANGUAGES.get(lang_code, {}).get('name', lang_code)
except:
return "Unknown"
# Example usage
sample_text = "This is a performance report for the education program."
print(f"Detected language: {detect_language(sample_text)}")
2. HTML Report Generation
def generate_html_report(content, lang_code):
"""Generate HTML version of the report."""
lang_info = LANGUAGES.get(lang_code, {'name': 'English', 'code': 'en'})
html = f"""
<!DOCTYPE html>
<html lang="{lang_code}">
<head>
<meta charset="UTF-8">
<title>{content.get('title', 'Report')}</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; }}
h1 {{ color: #1a1a2e; border-bottom: 3px solid #4a9eff; }}
h2 {{ color: #4a9eff; }}
.section {{ margin: 20px 0; }}
.highlight {{ background: #f8f9fa; padding: 10px; }}
</style>
</head>
<body>
<h1>{content.get('title', 'Performance Report')}</h1>
<p><strong>Date:</strong> {content.get('date', '')}</p>
<p><strong>Language:</strong> {lang_info['name']}</p>
<div class="section">
<h2>Executive Summary</h2>
<p>{content.get('executive_summary', '')}</p>
</div>
<div class="section highlight">
<h2>Performance Overview</h2>
{f"<p>{content.get('performance_overview', '')}</p>" if isinstance(content.get('performance_overview'), str) else ""}
</div>
<div class="section">
<h2>Key Achievements</h2>
<ul>
{''.join(f'<li>{item}</li>' for item in content.get('achievements', []))}
</ul>
</div>
<div class="section">
<h2>Challenges</h2>
<ul>
{''.join(f'<li>{item}</li>' for item in content.get('challenges', []))}
</ul>
</div>
<div class="section highlight">
<h2>Recommendations</h2>
<ul>
{''.join(f'<li>{item}</li>' for item in content.get('recommendations', []))}
</ul>
</div>
<div class="section">
<h2>Next Steps</h2>
<ul>
{''.join(f'<li>{item}</li>' for item in content.get('next_steps', []))}
</ul>
</div>
<hr>
<p style="color: #666; font-size: 12px;">{content.get('footer', '')}</p>
</body>
</html>
"""
return html
# Save HTML reports
def save_html_reports(reports):
for lang_code, content in reports.items():
html = generate_html_report(content, lang_code)
with open(f'report_{lang_code}.html', 'w', encoding='utf-8') as f:
f.write(html)
print(f"Saved HTML report for {LANGUAGES[lang_code]['name']}")
Troubleshooting Translation Issues
| Issue | Solution |
|---|---|
| Rate limit exceeded | Add delays between API calls (time.sleep) |
| M&E terminology lost | Use AI translation with context prompt |
| Special characters not showing | Use UTF-8 encoding for file operations |
| API key error | Check ANTHROPIC_API_KEY environment variable |
Best Practices for Multi-Language M&E Reports
- Standardize Terminology: Create a glossary of M&E terms for consistent translation
- Maintain Formatting: Keep headings, bullets, and structure consistent across languages
- Human Review: Have native speakers review critical reports
- Use Context: Provide context to AI translators for better technical accuracy
- Version Control: Track changes across language versions
- Automate Workflow: Integrate translation into reporting pipeline
Next Steps: Advanced Localization
- Cultural Adaptation: Adapt content for cultural context (not just translation)
- Local Scripts: Support for non-Latin scripts (Arabic, Hindi, Chinese)
- Translation Memory: Store translations to reuse common phrases
- Voice-Activated Reports: Generate audio versions of reports
- Real-Time Translation: Translate dashboards on the fly
Master Multi-Language Reporting for M&E
The AI Agents for Evaluators Certificate teaches you to build complete M&E solutions including multi-language reporting, automated translation, and international stakeholder management.
What you will learn:
- Build multi-language reporting pipelines
- Use AI for context-aware translation
- Generate reports in 5+ languages
- Handle cultural adaptation and localization
Course Features: 32 lectures · Lifetime access · Certificate included · 241 students enrolled
Enroll Now – $249 Lifetime Access
Bundle with AI in M&E course and save 30%
This guide is part of the AI Agents for Evaluators series. Continue your learning journey with the full certificate course above.
