Skip to content

Tibetan Translator V1

TenzinGayche edited this page Dec 17, 2025 · 1 revision

Tibetan Translator V1 (Commentary-Based)

The original tibetan_translator module provides a commentary-driven translation pipeline for Tibetan Buddhist texts.


🎯 Overview

This version uses traditional scholarly commentaries to guide translation. It:

  1. Translates 3 commentaries in parallel
  2. Combines them into a unified interpretation
  3. Generates translation based on combined commentary
  4. Evaluates and refines iteratively
  5. Extracts glossary terms

🏗️ Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                      tibetan_translator Workflow                             │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│                              ┌─────────┐                                     │
│                              │  START  │                                     │
│                              └────┬────┘                                     │
│                                   │                                          │
│         ┌─────────────────────────┼─────────────────────────┐               │
│         │                         │                         │               │
│         ▼                         ▼                         ▼               │
│  ┌──────────────┐         ┌──────────────┐         ┌──────────────┐        │
│  │ commentary_  │         │ commentary_  │         │ commentary_  │        │
│  │ translator_1 │         │ translator_2 │         │ translator_3 │        │
│  └──────┬───────┘         └──────┬───────┘         └──────┬───────┘        │
│         │                         │                         │               │
│         └─────────────────────────┼─────────────────────────┘               │
│                                   │                                          │
│                                   ▼                                          │
│                         ┌─────────────────┐                                 │
│                         │   aggregator    │                                 │
│                         │                 │                                 │
│                         │ Combines into   │                                 │
│                         │ unified comment │                                 │
│                         └────────┬────────┘                                 │
│                                  │                                          │
│                                  ▼                                          │
│                    ┌──────────────────────────┐                             │
│                    │  translation_generator   │◄────────────┐               │
│                    │                          │             │               │
│                    │  Uses commentary to      │             │               │
│                    │  generate translation    │             │               │
│                    └────────────┬─────────────┘             │               │
│                                 │                           │               │
│                                 ▼                           │               │
│                    ┌──────────────────────────┐             │               │
│                    │   llm_call_evaluator     │             │               │
│                    │                          │             │               │
│                    │  • Language check        │             │               │
│                    │  • Content evaluation    │             │               │
│                    │  • Format verification   │             │               │
│                    └────────────┬─────────────┘             │               │
│                                 │                           │               │
│                          ┌──────┴──────┐                    │               │
│                          │ route_      │                    │               │
│                          │ translation │                    │               │
│                          └──────┬──────┘                    │               │
│                                 │                           │               │
│               ┌─────────────────┼─────────────────┐         │               │
│               │                 │                 │         │               │
│               ▼                 ▼                 │         │               │
│          "Accepted"      "Rejected + Feedback"───┴─────────┘               │
│               │                                                             │
│               ▼                                                             │
│     ┌─────────────────┐                                                     │
│     │ generate_       │                                                     │
│     │ glossary        │                                                     │
│     └────────┬────────┘                                                     │
│              │                                                              │
│              ▼                                                              │
│          ┌───────┐                                                          │
│          │  END  │                                                          │
│          └───────┘                                                          │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

📦 Module Structure

tibetan_translator/
├── __init__.py          # Package exports
├── cli.py               # Command-line interface
├── config.py            # Configuration (API keys, model settings)
├── llm_provider.py      # LLM provider abstraction (V1 only!)
├── models.py            # Pydantic models
├── prompts.py           # Prompt templates
├── utils.py             # Utilities and LLM setup
├── workflow.py          # LangGraph workflow definition
└── processors/
    ├── __init__.py
    ├── commentary.py    # Commentary translation functions
    ├── translation.py   # Translation generation
    ├── evaluation.py    # Quality evaluation
    ├── formatting.py    # Format checking (deprecated)
    ├── glossary.py      # Glossary extraction
    └── post_translation.py

🔄 Workflow Nodes

1. Commentary Translators (Parallel)

Three parallel nodes translate commentaries:

def commentary_translator_1(state: State):
    """Translate first commentary with expertise focus."""
    if not state['commentary1']:
        return {"commentary1": None, "commentary1_translation": None}
    
    prompt = get_commentary_translation_prompt(
        state['sanskrit'], 
        state['source'], 
        state['commentary1'],
        language=state.get('language', 'English')
    )
    return {
        "commentary1": state['commentary1'], 
        "commentary1_translation": state['commentary1']
    }

2. Aggregator

Combines translated commentaries:

def aggregator(state: State):
    """Combine commentaries based on availability."""
    # Logic:
    # - If no commentaries → create source analysis
    # - If one commentary → use directly
    # - If multiple → combine using LLM
    
    combined = ""
    if has_commentary1:
        combined += f"Commentary 1:\n{state['commentary1_translation']}\n\n"
    if has_commentary2:
        combined += f"Commentary 2:\n{state['commentary2_translation']}\n\n"
    if has_commentary3:
        combined += f"Commentary 3:\n{state['commentary3_translation']}\n\n"
    
    # Use thinking LLM for analysis
    response = llm_thinking.invoke(prompt_messages)
    
    return {"combined_commentary": commentary_content, 
            "commentary_source": "traditional"}

3. Translation Generator

Generates or refines translation:

def translation_generator(state: State):
    """Generate improved translation based on commentary and feedback."""
    
    if state.get("feedback_history"):
        # Improvement mode - address feedback
        prompt = get_translation_improvement_prompt(...)
        msg = llm.invoke(prompt)
    else:
        # Initial translation mode
        if is_source_focused:
            prompt = get_enhanced_translation_prompt(...)
        else:
            prompt = get_initial_translation_prompt(...)
        
        # Use thinking LLM for primary translation
        thinking_response = llm_thinking.invoke(prompt)
    
    return {
        "translation": [...new_translation...],
        "plaintext_translation": plain_translation,
        "itteration": current_iteration + 1
    }

4. LLM Call Evaluator

Evaluates translation quality:

def llm_call_evaluator(state: State):
    """Evaluate translation quality AND formatting."""
    
    # 1. Check if translation is in target language
    language_check = check_translation_language(state['translation'][-1], language)
    
    if not language_check.is_target_language:
        return {"grade": "bad", "is_target_language": False, ...}
    
    # 2. Verify against commentary
    verification = verify_against_commentary(
        state['translation'][-1], 
        state['combined_commentary']
    )
    
    # 3. Full evaluation
    evaluation = llm.with_structured_output(Feedback).invoke(prompt)
    
    return {
        "grade": evaluation.grade,
        "formated": evaluation.format_matched,
        "feedback_history": [...updated...],
    }

5. Route Translation

Routes based on quality:

def route_translation(state: State):
    """Route based on translation quality and formatting."""
    if state["grade"] == "great" and state["formated"]:
        return "Accepted"
    elif state["itteration"] >= MAX_TRANSLATION_ITERATIONS:
        return "Accepted"
    else:
        return "Rejected + Feedback"

6. Generate Glossary

Extracts terminology:

def generate_glossary(state: State):
    """Extract glossary terms from final translation."""
    prompt = get_glossary_extraction_prompt(
        source=state['source'],
        combined_commentary=state['combined_commentary'],
        final_translation=state['translation'][-1],
        language=state.get('language', 'English')
    )
    
    glossary = llm.with_structured_output(GlossaryExtraction).invoke(prompt)
    
    return {"glossary": glossary.entries}

📊 State Fields

class State(TypedDict):
    # Translations
    translation: List[str]              # History of translations
    plaintext_translation: str          # Plain text version
    
    # Commentaries
    commentary1: str                    # Input commentary 1
    commentary2: str                    # Input commentary 2
    commentary3: str                    # Input commentary 3
    commentary1_translation: str        # Translated commentary 1
    commentary2_translation: str        # Translated commentary 2
    commentary3_translation: str        # Translated commentary 3
    combined_commentary: str            # Unified commentary
    commentary_source: str              # "traditional" or "source_analysis"
    
    # Source
    source: str                         # Tibetan source text
    sanskrit: str                       # Sanskrit reference
    language: str                       # Target language
    
    # Feedback
    feedback_history: List[str]         # All feedback
    format_feedback_history: List[str]  # Format-specific feedback
    
    # Analysis
    key_points: List[KeyPoint]          # Key points from commentary
    glossary: List[GlossaryEntry]       # Extracted terms
    
    # Control
    itteration: int                     # Translation iteration count
    format_iteration: int               # Format correction iteration
    formated: bool                      # Format status

🚀 Usage

Command Line

python -m tibetan_translator.cli \
    --input input_data.json \
    --output output_results.jsonl \
    --batch_size 8 \
    --preprocess

Python API

from tibetan_translator import optimizer_workflow

# Prepare initial state
state = {
    "source": "བོད་ཀྱི་བསྡུད་མ་འདུག",
    "sanskrit": "Buddhist text in Sanskrit",
    "commentary1": "Commentary 1 explanation",
    "commentary2": "Commentary 2 explanation",
    "commentary3": "Commentary 3 explanation",
    "language": "English",
    "feedback_history": [],
    "format_feedback_history": [],
    "itteration": 0,
    "format_iteration": 0,
    "formated": False,
    "glossary": [],
    "translation": [],
    "key_points": [],
    "combined_commentary": "",
    "commentary_source": "",
    "plaintext_translation": "",
    "commentary1_translation": "",
    "commentary2_translation": "",
    "commentary3_translation": "",
}

# Run workflow
result = optimizer_workflow.invoke(state)

# Access results
final_translation = result["translation"][-1]
glossary = result["glossary"]
print(f"Translation: {final_translation}")
print(f"Glossary entries: {len(glossary)}")

📥 Input Format

{
    "root": "Tibetan root text",
    "sanskrit": "Corresponding Sanskrit text",
    "commentary_1": "First commentary",
    "commentary_2": "Second commentary",
    "commentary_3": "Third commentary",
    "language": "English"
}

📤 Output Format

{
    "translation": ["Final English translation"],
    "commentary1_translation": "Translated commentary 1",
    "commentary2_translation": "Translated commentary 2",
    "commentary3_translation": "Translated commentary 3",
    "combined_commentary": "Unified commentary",
    "glossary": [
        {
            "tibetan_term": "བྱང་ཆུབ་སེམས",
            "translation": "bodhicitta",
            "context": "The mind of enlightenment",
            "category": "philosophical"
        }
    ],
    "plaintext_translation": "Plain text version"
}

⚙️ Configuration

config.py Settings

# API Configuration
ANTHROPIC_API_KEY = os.environ.get("ANTHROPIC_API_KEY")

# Model Configuration
MODEL_NAME = "claude-3-5-sonnet-latest"
MAX_TOKENS = 8192

# Translation Settings
MAX_TRANSLATION_ITERATIONS = 3  # Max refinement iterations
MAX_FORMAT_ITERATIONS = 2       # Max format correction iterations
PRESERVE_SOURCE_FORMATTING = True

🔗 Related Pages

Clone this wiki locally