Resources/Chatbots, language, and model quality/How to Make an AI Chatbot Understand Moroccan Darija and Other Dialects

How to Make an AI Chatbot Understand Moroccan Darija and Other Dialects

I almost fine-tuned a local model for Moroccan dental support. Real examples written by experienced clinic assistants solved the harder problem first.

Mohamed Amine Saada, Forteuno Web

Published

A Moroccan clinic professional guides three conversation examples through a glass speech lens into one natural local response

A customer support chatbot can speak standard Arabic and still sound completely wrong in Moroccan Darija. The grammar may be acceptable. The meaning may even be correct. But the reply feels translated, misses local shorthand, or fails when the customer mixes Darija, French, Arabic, and Latin characters in one sentence. This problem also appears in regional Arabic dialects, African languages, Indian languages, Caribbean Creoles, Spanglish, and local slang that is underrepresented in general training data.

The best fix was not a bigger model. It was better examples from people who already knew how real patients speak.

01

What happened in my Moroccan dental support SaaS

I built a customer support SaaS for dental clinics in Morocco. At first I assumed dialect quality required fine-tuning a local model. That sounded like the technical answer: collect data, train a model, host it, and make Darija part of the weights. Before committing to that work, I tried a smaller intervention. We collected real support examples from assistants who had worked inside dental clinics. They knew the phrases patients use for pain, appointments, prices, emergencies, and follow-up. We placed those examples in the prompt context. The quality improved quickly.

The examples did more than translate vocabulary. They showed tone, intent, clinic policy, when to ask another question, and when to call a booking tool. That distinction matters. A dictionary can explain that a word refers to an appointment. A worked example shows how the assistant should respond when a patient uses that word while describing pain and asking for the earliest available time.

The same pattern held on a very different build: a translation agency wanted customers to submit an order, get a quote, and pay entirely inside a chat conversation, no upload page, no separate checkout. Its customers were Moroccan emigrants scattered across France, the US, and the Gulf, so a single thread could switch between Darija, French, Egyptian Arabic, and English mid-conversation. Across roughly 40 chatbot projects now, most for clinics and dental centers in Morocco and a handful for US companies, the language problem and the architecture problem turned out to be the same problem: a model that understands the words is not enough if the system around it cannot route, verify, and act correctly on what it understood.

Useful dialect examples connect local language to intent, tool use, and the next safe action.
Useful dialect examples connect local language to intent, tool use, and the next safe action.
02

What a strong few-shot example should contain

01The original customer message exactly as people write it, including spelling variation, code-switching, abbreviations, and Latin-character Darija.
02A short explanation of important local words and what they mean in that situation.
03The detected intent and any ambiguity the chatbot should resolve.
04The reasoning summary or decision path used to choose the next action. Do not expose private hidden chain-of-thought; record the useful decision criteria instead.
05The tool called, the arguments sent, and what should happen if the tool fails.
06The final reply written by a real speaker in the tone the business wants.
07The escalation rule for medical, financial, angry, uncertain, or sensitive requests.
03

Why code-switching breaks generic models, and what actually fixes it

Darija is already a blend of Arabic, French, Spanish, and Amazigh influence, so a single customer message routinely mixes languages inside one sentence. Fixing that is not about finding a bigger model. It is disciplined few-shot coverage of the mix, combined with picking a base model that is genuinely strong across Arabic, French, and English rather than one built primarily for English with Arabic bolted on. The agent also always replies in Arabic script, never Arabizi (Latin-character transliteration). Answers in Arabic letters produce fewer downstream errors and read more naturally to a Moroccan customer than transliterated text does.

One recurring failure is worth naming exactly, because it is not a vocabulary gap: a customer types نرف meaning roughly “I want to know” (from the Darija verb عرف, to know). In Arabizi the correct spelling keeps the numeral: n3rf, where the 3 stands in for the Arabic letter ع. When someone drops the numeral and types nerf, the message becomes visually and phonetically identical to the French word for “nerve.” A multilingual model with no specific bracing for this reads French and answers about nerves instead of recognizing the Darija intent. The fix is not a longer glossary. It is prompting the agent to treat this exact class of ambiguity, a Darija word colliding with a real word in another language once a numeral is dropped, as a signal to ask a one-line clarifying question rather than guess. That is the same discipline a human assistant applies without thinking. Left alone, a model will confidently pick the wrong language instead.

04

The architecture behind it: an orchestrator, not one long prompt

Once a chatbot needs to do more than answer questions, one long system prompt stops being a language problem and becomes an architecture problem. The order-and-payment build above used an orchestrator that routes each turn to a specialized sub-agent: one owns FAQs, one owns order creation and status, one owns payment, one owns greetings and small talk. Each sub-agent has a narrow prompt scoped to its own job and its own tools, exposed through MCP, some of which write directly into the client’s existing order platform: create an order, check a status, confirm a payment. The orchestrator composes their outputs into one reply. This keeps any single prompt short enough to stay reliable, and it means a change to the payment agent’s behavior cannot accidentally shift how the FAQ agent answers a pricing question.

Few-shot examples are injected at runtime inside this structure, not baked into one static system prompt. When a message arrives in Darija, the routing layer detects that and injects Darija examples scoped to the sub-agent handling that intent, not a fixed set glued to the top of every conversation. That keeps the context focused and makes it possible to fix one dialect edge case without touching every other behavior in the system.

05

The payment agent gets the least trust in the system

Any sub-agent connected to a tool that can create an order, move money, or write to a client’s live system is a genuine attack surface. Prompt injection has held the #1 spot on OWASP’s LLM Top 10 across every edition, and it gets more dangerous exactly when an LLM has tools that can send messages, call APIs, or make purchases: a successful injection lets an attacker use whatever the tool can do. In practice that means the payment and order-writing agents get the narrowest tool permissions available, structured output validation before anything executes, and an explicit confirmation step before an irreversible action goes through, rather than trusting the model’s own judgment on when an action is safe.

Source: OWASP Top 10 for LLM Applications

06

Start with a high escalation rate, and earn autonomy

Every one of these agents launches with a deliberately high escalation-to-human rate. The instinct to make an agent fully autonomous on day one is exactly what causes irreversible mistakes: a wrongly confirmed order, a booking that was never real, an answer a patient acts on. Autonomy gets earned incrementally, one resolved edge case at a time, until the agent reaches the highest hands-off rate that still holds up under real traffic. An agent that never escalates is not a sign of quality. As of 2026, I have not shipped one I would trust to run that way.

07

How to evaluate dialect quality

01Build a test set from real, anonymized conversations rather than polished translations.
02Include spelling variants, mixed scripts, voice-note transcripts, slang, incomplete sentences, and topic changes.
03Ask native speakers with customer support experience to score naturalness and correctness separately.
04Check task completion: did the chatbot book, retrieve, update, or escalate correctly?
05Track unsafe guesses and unnecessary escalation, not only pleasant wording.

In practice this runs as a growing regression set. Every real failure that shows up in testing becomes a permanent test case, split between per-agent evaluations (does the payment agent pick the right tool and arguments) and whole-conversation evaluations (does the orchestrated reply make sense end to end). Easy, well-understood cases get graded automatically by an LLM judge. Anything new, or anything the automated judge has not proven reliable on yet, gets scored manually. A native speaker only sits down to actually talk to the bot after that automated pass, because by then most of the obvious breakage has already been caught, and that review can focus on tone and naturalness instead of hunting for bugs.

For the Darija-specific agents I have kept GPT-4.1 as the production default rather than moving to a newer release, mainly on cost efficiency given comparable or better quality on this specific language task. It is not the strongest model at tool calling, which is exactly why tool-calling responsibility stays with narrow specialized agents instead of one general-purpose prompt asked to do everything at once. When benchmarking any model for Darija or another underrepresented dialect, general leaderboards are close to useless. Purpose-built Arabic benchmarks that specifically test dialect and script variation are a far better signal.

Source: Arabic LLM Broad Leaderboard (Silma AI)

Source: Awesome Arabic NLP (curated resource list)

Few-shot examples will not solve every language problem. Fine-tuning can help when the behavior must stay consistent across a large volume and the prompt has become too expensive or fragile. But I would not start there. I would first prove that good examples and a representative evaluation set can produce the behavior. That gives you cleaner data if you later decide to fine-tune.

Choose the lightest model adaptation method that solves the measured problem.

Few-shot vs. fine-tuning

See how to build the wider support system around the conversation.

AI chatbot setup guide

Continue exploring

Get started

Want help deciding what to automate first?

Discuss your process