DEV Community

Cover image for Building Translation Pipelines: Technical Implementation of MTPE vs Human Translation Workflows
Diogo Heleno
Diogo Heleno

Posted on • Originally published at m21global.com

Building Translation Pipelines: Technical Implementation of MTPE vs Human Translation Workflows

Building Translation Pipelines: Technical Implementation of MTPE vs Human Translation Workflows

As a developer working on international products, you've probably hit the translation bottleneck. Your product is ready for global markets, but the localization workflow is manual, slow, and doesn't scale with your release cycles.

I recently worked on automating translation workflows for a SaaS platform, and learned that the choice between Machine Translation Post-Editing (MTPE) and human translation isn't just about quality and cost — it's about building the right technical infrastructure for each content type.

Understanding the Technical Difference

MTpe and human translation require completely different automation approaches:

MTPE Pipeline:

# Example GitHub Actions workflow for MTPE
name: MTPE Translation Pipeline
on:
  push:
    paths: ['src/locales/en/**']

jobs:
  translate:
    steps:
      - name: Extract new strings
        run: i18next-scanner
      - name: Machine translate
        uses: google-translate-action
      - name: Queue for human review
        run: curl -X POST translation-service/review-queue
Enter fullscreen mode Exit fullscreen mode

Human Translation Pipeline:

# Human translation requires different tooling
name: Human Translation Pipeline
steps:
  - name: Generate translation packages
    run: create-xliff-bundles
  - name: Send to translation management system
    run: upload-to-tms
  - name: Wait for completion webhook
    # This could take days, not minutes
Enter fullscreen mode Exit fullscreen mode

The fundamental difference is timing and automation level. MTPE can be mostly automated with human checkpoints, while human translation requires more manual coordination.

Content Classification for Automation

Before building your pipeline, classify your content programmatically. Here's how I approach it:

// Content classification for translation workflow
const classifyContent = (content) => {
  const riskIndicators = {
    high: ['legal', 'medical', 'safety', 'terms', 'privacy'],
    medium: ['marketing', 'landing', 'sales'],
    low: ['docs', 'internal', 'help', 'faq']
  };

  const contentPath = content.filePath.toLowerCase();

  if (riskIndicators.high.some(term => contentPath.includes(term))) {
    return { method: 'human', priority: 'high' };
  }

  if (riskIndicators.medium.some(term => contentPath.includes(term))) {
    return { method: 'human', priority: 'medium' };
  }

  if (content.repetitiveScore > 0.7) {
    return { method: 'mtpe', level: 'light' };
  }

  return { method: 'mtpe', level: 'full' };
};
Enter fullscreen mode Exit fullscreen mode

API Integration Patterns

Most translation services offer APIs, but they work differently:

Machine Translation APIs

// Google Translate API - synchronous
const translateText = async (text, targetLang) => {
  const response = await translate.translate(text, targetLang);
  return response[0];
};

// DeepL API - better for European languages
const deepLTranslate = async (text, targetLang) => {
  const response = await fetch('https://api-free.deepl.com/v2/translate', {
    method: 'POST',
    headers: { 'Authorization': `DeepL-Auth-Key ${apiKey}` },
    body: new URLSearchParams({
      text,
      target_lang: targetLang,
      formality: 'default'
    })
  });
  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Human Translation Management

// TMS integration - asynchronous with webhooks
const submitForHumanTranslation = async (content) => {
  const job = await tms.createJob({
    content,
    workflow: 'translate-review-approve',
    deadline: calculateDeadline(content.priority),
    webhookUrl: `${process.env.BASE_URL}/translation-complete`
  });

  // Store job reference for status tracking
  await db.translations.create({
    jobId: job.id,
    status: 'in_progress',
    contentId: content.id
  });
};
Enter fullscreen mode Exit fullscreen mode

Quality Assurance Integration

Different workflows need different QA approaches:

// Automated QA for MTPE
const validateMTPE = (original, translated) => {
  const issues = [];

  // Check for untranslated technical terms
  const techTerms = extractTechnicalTerms(original);
  techTerms.forEach(term => {
    if (translated.includes(term) && !isInGlossary(term)) {
      issues.push(`Possibly untranslated term: ${term}`);
    }
  });

  // Validate placeholder consistency
  const originalPlaceholders = original.match(/\{\{.*?\}\}/g) || [];
  const translatedPlaceholders = translated.match(/\{\{.*?\}\}/g) || [];

  if (originalPlaceholders.length !== translatedPlaceholders.length) {
    issues.push('Placeholder mismatch detected');
  }

  return issues;
};
Enter fullscreen mode Exit fullscreen mode

Cost and Time Optimization

Track metrics to optimize your pipeline:

// Translation analytics
const trackTranslationMetrics = {
  mtpe: {
    avgTimePerWord: 0.1, // seconds
    avgCostPerWord: 0.05, // USD
    qualityScore: 0.85
  },
  human: {
    avgTimePerWord: 15, // seconds
    avgCostPerWord: 0.15, // USD
    qualityScore: 0.98
  }
};

// Decision algorithm
const chooseTranslationMethod = (content) => {
  const wordCount = content.split(' ').length;
  const deadline = content.deadline;

  const mtpeTime = wordCount * trackTranslationMetrics.mtpe.avgTimePerWord;
  const humanTime = wordCount * trackTranslationMetrics.human.avgTimePerWord;

  if (deadline < humanTime && content.riskLevel !== 'high') {
    return 'mtpe';
  }

  return 'human';
};
Enter fullscreen mode Exit fullscreen mode

Language Pair Considerations

Not all language pairs work equally well with machine translation:

// Language pair performance matrix
const mtpePerformance = {
  'en-es': { quality: 0.9, confidence: 'high' },
  'en-fr': { quality: 0.88, confidence: 'high' },
  'en-pt': { quality: 0.85, confidence: 'high' },
  'en-zh': { quality: 0.75, confidence: 'medium' },
  'en-ar': { quality: 0.65, confidence: 'low' }
};

const shouldUseMTPE = (sourceLang, targetLang, contentType) => {
  const pairKey = `${sourceLang}-${targetLang}`;
  const performance = mtpePerformance[pairKey];

  if (!performance || performance.confidence === 'low') {
    return false;
  }

  return contentType !== 'marketing' && contentType !== 'legal';
};
Enter fullscreen mode Exit fullscreen mode

Monitoring and Rollback

Build monitoring into your translation pipeline:

// Quality monitoring
const monitorTranslationQuality = async () => {
  const recentTranslations = await db.translations
    .where('created_at', '>', Date.now() - 86400000) // Last 24h
    .select();

  const qualityIssues = recentTranslations.filter(
    t => t.quality_score < 0.7
  );

  if (qualityIssues.length > recentTranslations.length * 0.1) {
    // Alert: Quality degradation detected
    await slack.send({
      channel: '#engineering',
      text: `Translation quality alert: ${qualityIssues.length} issues detected`
    });
  }
};
Enter fullscreen mode Exit fullscreen mode

Implementation Roadmap

  1. Week 1-2: Implement content classification and basic MTPE for low-risk content
  2. Week 3-4: Set up human translation workflow for high-risk content
  3. Week 5-6: Add quality monitoring and A/B testing
  4. Week 7+: Optimize based on metrics and user feedback

The key is starting with clear content classification and building automation around that decision tree. As the original article on MTPE vs human translation points out, the choice isn't binary — most projects need both approaches for different content types.

Building this pipeline correctly saves weeks of manual work per release cycle and scales with your international growth. Start with the technical foundation, then optimize based on real usage data.

Have you implemented translation automation in your projects? What challenges did you face with content classification or quality monitoring?

Top comments (0)