Back to blog
Prompt Engineering

Multilingual LLM Prompts: Armenian, Russian and English Without Behavior Drift

Keep policy invariant

Review every locale

Original LANG-CONTRACT-7 architecture
Language changes presentation, not permission
Primary nodepolicy and locale
Routing modeLANG-CONTRACT-7
StatusPUBLISHED
Three language variants converge on one policy and validation route
LANG_CONTRACT_7_V01: language variants pass through one invariant policy and evidence check.
TERMINAL_PREVIEW.LOG
$ prompt --contract LANG-CONTRACT-7
> compare: invariant rules / locale templates
> validate: evidence / schema / route
> route: answer / clarify / refuse / review
Architecture, validation, failure modes and production checks

A translated prompt can be fluent while changing what the assistant is allowed to do. A Russian instruction may say “ask for clarification”, an English variant may say “infer the missing field”, and an Armenian variant may omit the rule entirely. The problem is behavioral equivalence, not word-for-word translation.

This guide is about one narrow engineering question: how to maintain the same decision rules across Armenian, Russian and English prompts. For the wider system, see prompt engineering, AI automation and the AI specialist guide for Armenia. Related guides cover system prompts as contracts and structured output validation.

Problem and requirements

Imagine a synthetic support assistant that reads a customer request and proposes a reply draft. It may summarize the issue, quote an approved policy and request a missing order identifier. It must not promise a refund, reveal another customer's data or execute a change. The language of the request must not change these boundaries.

Define acceptance in terms of observable routes: answer with approved evidence, ask a clarification question, refuse an out-of-scope request, or send a case to human review. Keep the response language appropriate to the user, but make authorization, required evidence, output fields and escalation independent of locale. Armenian content needs review by a qualified human before an Armenian public page or production prompt is released.

Original LANG-CONTRACT-7 architecture

This is an illustrative design, not a measured result or a claim about any deployed customer system.

01 INTENT classify task and requested language 02 POLICY load one versioned invariant rule set 03 LOCALE select a reviewed language template 04 EVIDENCE retrieve only permitted current material 05 GENERATE produce a typed draft and route code 06 VALIDATE compare output with policy and evidence 07 ROUTE deliver, clarify, refuse or review

The invariant contract should be stored once as structured rules, with locale-specific wording attached by stable rule IDs. For example, refund.promise.denied is a policy decision; the Armenian, Russian and English sentences explaining it are presentation. Changing one translation cannot silently change the decision.

Minimal contract and pseudocode

const policy = loadPolicy("support-v3"); const locale = detectSupportedLocale(request.text); const template = loadReviewedTemplate(locale, policy.version); const evidence = retrieveAllowedSources(request.actor, request.topic); const draft = await model.generate({ policy, template, evidence }); const parsed = responseSchema.parse(draft); if (!policy.allows(parsed.route, request.actor)) return review("route"); if (!claimsSupported(parsed.claims, evidence)) return review("evidence"); return renderInLocale(parsed, locale);

detectSupportedLocale, claimsSupported and renderInLocale represent application-owned functions. The model's own declaration that it followed policy is not validation. Templates and policy versions belong in each decision receipt so a regression can be reproduced.

Components and failure modes

BoundaryDrift exampleRequired route
Language detectionMixed Armenian and Russian text is treated as EnglishAsk or choose a declared fallback; preserve the original input
Policy translation“May draft” becomes “may send”Reject unreviewed template change
EvidenceA locale has an older policy documentHold until the current approved source is available
Structured outputOne language omits review_requiredReject schema-invalid draft
AuthorizationA localized phrase implies broader account accessDeny based on actor scope outside the model
Human handoffRefusal text hides the actual escalation routeEmit stable route code and review receipt

Do not translate identifiers, permissions or source revisions as free prose. Treat user supplied text and retrieved documents as data, even when they contain instructions in another language. A prompt saying “ignore the previous rules” in any script remains untrusted input.

Testing and production check

Build a fixture set with the same intents in all three languages: normal answer, missing identifier, forbidden action, stale source, mixed-language input and prompt injection. Human reviewers should confirm semantic equivalence of the fixtures and localized responses. Assert the same route code, authorization decision, required fields and source revision for each parallel case. Wording may differ; decision boundaries should not.

Run the suite whenever the policy, template, model, retrieval corpus or output schema changes. Inspect mismatches by rule ID, not only aggregate accuracy. Keep a rollback path to the last reviewed policy and templates. At release, check the version manifest, fixture coverage, human review of Armenian wording, source freshness, logging boundaries and escalation owner. These are acceptance criteria, not promised performance numbers.

For a project review, request a technical audit. The function calling error guide explains how to validate any downstream tool proposal separately from the language layer.

CODE_BLOCK.TXT
const policy = loadPolicy("support-v3");
const template = loadReviewedTemplate(locale, policy.version);
const draft = await generate(policy, template, evidence);
return validateRouteAndClaims(draft, policy, evidence);