
Building Multilingual AI That Actually Works in Arabic and English
The real engineering behind Arabic + English AI systems — tokenization traps, RTL rendering, dialect vs MSA, retrieval with mixed-script queries, embeddings that respect both languages, and the eval sets nobody publishes.
Most 'multilingual' AI systems work in English and pretend the rest is a translation problem. That's wrong for Arabic — a language with rich morphology, RTL rendering, dialect fragmentation, and mixed-script real-world text. Making Arabic + English work in one system means picking embeddings trained on both, normalizing script and diacritics deliberately, handling MSA and dialects (Egyptian, Gulf, Levantine, Maghrebi) as first-class citizens, evaluating with Arabic-specific test sets, and doing the UI work RTL demands. This article is the field guide from actually shipping bilingual AI to Arabic-speaking users.
- Choose embeddings trained on Arabic (BGE-M3, multilingual-e5-large, Cohere multilingual v3) — not English-only models translated.
- Normalize Arabic script deliberately: alef variants, taa marbuta, hamza — but preserve diacritics when they change meaning.
- Treat MSA and each major dialect as separate retrieval targets; users write in dialect, docs are in MSA.
- Mixed-script queries (Arabizi, code-switching) are the default in the Arab world — handle them.
- RTL is not a CSS toggle; it's a layout and typography discipline.
- Build Arabic eval sets yourself — public ones are thin and misleading.
The default trap: English-first, bolt-on translation
The most common architecture I see: English embeddings, English prompts, and a translation layer at the boundary. It looks bilingual. It performs terribly.
- Translation loses idiom and context; retrieval matches the wrong docs.
- Prompts written in English don't leverage the model's Arabic reasoning capacity.
- The translation step adds latency and cost on every call.
- Users who code-switch ("ابعت لي report عن Q3") get bounced.
The right architecture treats Arabic as a first-class language throughout the pipeline.
Picking embeddings that actually see Arabic
| Model | Arabic quality | Dim | Cost | Notes |
|---|---|---|---|---|
| BGE-M3 | Excellent | 1024 | Open-source | Best OSS multilingual as of 2026 |
| multilingual-e5-large | Very good | 1024 | Open-source | Fast, small footprint |
| Cohere embed-multilingual-v3 | Excellent | 1024 | $0.10/1M tokens | Best managed option |
| OpenAI text-embedding-3-large | Good | 3072 | $0.13/1M tokens | English-first, decent Arabic |
| text-embedding-3-small (English) | Poor | 1536 | $0.02/1M tokens | Avoid for Arabic |
Benchmark on your data, not just MIRACL or MTEB. See vector databases compared 2026 for the storage layer.
Arabic normalization — a deliberate choice, not a default
The temptation is to run every Arabic string through the same normalizer. That's often wrong. Some normalizations preserve meaning; others destroy it.
| Normalization | Do it? | Why |
|---|---|---|
| Unify alef variants (أ إ آ → ا) | Usually yes | Improves recall; users type without hamza |
| Taa marbuta → haa (ة → ه) | Sometimes | Egyptian dialect writes this; MSA doesn't |
| Remove diacritics (tashkeel) | For search, yes | Docs rarely have them; keep for TTS |
| Remove tatweel (ـ) | Yes | Purely cosmetic |
| Unicode NFC normalization | Always | Handles precomposed vs decomposed forms |
| Lowercase Latin chars in mixed text | Yes | For BM25 hybrid retrieval |
import re, unicodedata
def normalize_arabic(text: str) -> str:
text = unicodedata.normalize("NFC", text)
text = re.sub(r"[أإآ]", "ا", text)
text = re.sub(r"[ً-ْ]", "", text) # tashkeel
text = text.replace("ـ", "") # tatweel
text = re.sub(r"s+", " ", text).strip()
return textMSA vs dialect — the retrieval problem nobody talks about
Users write in dialect. Documentation is in MSA. Retrieval fails silently.
Real example: a user asks عايز اعمل ايه لو الفاتورة ما وصلتش؟ (Egyptian). Your KB has a section titled الإجراءات في حالة عدم استلام الفاتورة (MSA). Cosine similarity: mediocre.
Two production patterns work:
- Query rewriting: run the user query through a small model that produces both the original and an MSA rewrite; retrieve on both, union results.
- Dialect-tagged index: enrich each chunk with dialect-equivalent phrasings at ingestion. Costs more storage; huge recall win.
Details in RAG that actually works — same principles, applied to language variance.
Code-switching and Arabizi
Arab users routinely code-switch and write Arabic in Latin script (Arabizi: eb3at le report). Your system should handle both without users learning to speak 'properly' for the model.
- Detect script mix at query time; route through both an Arabic and an English embedding if confidence is split.
- Maintain a small Arabizi → Arabic phrase dictionary for common domain terms; expand queries before embedding.
- In prompts, tell the model explicitly: 'Users may mix Arabic and English. Understand both. Answer in the primary language of the user's question.'
Prompt engineering for bilingual models
Structured system prompts in the target language outperform English prompts by 5–15% on Arabic tasks, in every eval I've run. Write two versions of your system prompt; route by user language.
For agents that call tools, keep the tool schema in English (that's what APIs LLMs can use covers) but keep the reasoning and user-facing responses in the user's language.
RTL: layout discipline, not a CSS one-liner
dir="rtl" flips text. It doesn't fix your icons, your padding shortcuts, your date formats, or your table columns.
- Use logical CSS properties (
margin-inline-start, notmargin-left). - Mirror directional icons (arrows, chevrons) — not calendars, not chart axes labeled with digits.
- Numbers in Arabic UI: decide once between Western Arabic (0–9) and Eastern Arabic (٠–٩); mixing is unprofessional.
- Date formats: Arabic locales expect Hijri as a secondary display in many contexts — offer both.
- Test with actual Arabic text; Lorem Ipsum RTL previews lie about line heights.
Evaluation: build your own set
Public Arabic eval sets (MMLU-Arabic, ARC-Arabic) test general reasoning. They tell you almost nothing about your product's retrieval quality or generation quality on your domain.
Build a golden set of 100–500 real questions per dialect you support. Annotate expected answers, expected retrieved chunks, and dialect. Run this set on every model swap. Use the evaluation framework from evaluating LLMs and classical ML.
Cost patterns for bilingual systems
- Arabic tokenizes to ~1.5–2× more tokens than English for the same meaning — budget accordingly.
- Choose tokenizers thoughtfully: cl100k_base handles Arabic reasonably; older tokenizers explode it.
- For pure translation tasks, cheaper models often suffice; reserve premium models for reasoning.
- See LLM cost dashboard in BigQuery to attribute cost by user language.
Observability for multilingual systems
Track separate metrics per language:
- Retrieval hit-rate per dialect group.
- Answer quality (human eval) per dialect group.
- Fall-through rate — how often the model responds in the wrong language.
- Escalation rate — how often users switch languages mid-conversation (signal that your system is failing).
Wire into your general observability stack from observability for AI systems.
Deployment: keep latency honest
Non-English inference is often served from fewer regions. Check your provider's Arabic-region latency; a Middle East user routed to US-East is 250ms of network before any compute.
For self-hosted models, one region in EU-Central + one in EU-South covers most of North Africa and the Levant acceptably. GCC users benefit from an ME-Central deployment.
The pattern that ships
- Multilingual embedding model (BGE-M3 or Cohere v3).
- Deliberate Arabic normalization at ingestion + query time.
- Query rewrite between dialect and MSA.
- Language-specific prompts routed by detected language.
- Hybrid retrieval (dense + BM25) for mixed-script robustness.
- Golden eval set per dialect, run on every deploy.
- Metrics segmented by language, always.
Building something similar?
I help teams ship production-grade AI agents, n8n workflows, and data platforms. Let's talk about what you're building.
Work with me
Islam Gamal
AI, Data & Automation Engineer. I design and ship production AI agents, n8n workflows, and cloud data platforms — with a focus on reliability, cost, and measurable business impact. Founder of Tashghil and Tek bil Arabi.
More from Islam Gamal
RAG That Actually Works: Chunking, Hybrid Search, Reranking, and Evals
The full production playbook: why naïve RAG demos die on the second question, how to chunk, index, retrieve, rerank, cite, evaluate, and cost-engineer a retrieval-augmented system that survives real users.
Vector Databases in 2026: pgvector vs Pinecone vs Qdrant vs Weaviate vs Milvus
A hands-on 2026 comparison of the five vector databases I actually ship — pricing, latency, hybrid search, filtering, sharding, re-embed cost, and the decision tree I use in client architecture reviews.
Prompt Engineering for Agents: A Structured, Testable, Version-Controlled Approach
Prompt engineering isn't vibes. Treat prompts like code — with schemas, versions, evals, diffs, and rollback. The full production workflow that scales past a single developer, with copy-paste patterns for structured output, few-shot design, LLM-as-judge, and prompt registries.
Browse every article by Islam Gamal on the author page.