> How to build RAG over German and Hungarian content: multilingual embeddings, compound words, stemming, accents and per-language evals.
>
> Web page: https://balazscsorba.com/blog/multilingual-rag-german-hungarian · Language: English · Also available in: [Deutsch](https://balazscsorba.com/de/blog/multilingual-rag-german-hungarian.md) · [Magyar](https://balazscsorba.com/hu/blog/multilingual-rag-german-hungarian.md)
> Author: Balázs Csorba · Published: 2026-10-16 · Keywords: multilingual rag, german rag embeddings, hungarian nlp search, cross-lingual retrieval, multilingual embedding model, bge-m3 german, german compound words search, hungarian stemming postgres, multilingual-e5-large-instruct, qwen3 embedding multilingual

[Blog](https://balazscsorba.com/blog)/Retrieval & search

# Multilingual RAG for German and Hungarian: embeddings, compounds and cross-lingual search

How to build RAG over German and Hungarian content: multilingual embeddings, compound words, stemming, accents and per-language evals.

[Balázs Csorba](https://balazscsorba.com/about)·October 16, 2026·7 min read

-   RAG
-   Multilingual
-   Embeddings
-   German
-   Hungarian

![A German and a Hungarian query meeting in one multilingual vector space next to per-language keyword indexes, then a reranker and an answer.](https://balazscsorba.com/images/blog/multilingual-rag-german-hungarian/cover.webp?v=7cd64f5c9d)

## Key takeaways

-   A multilingual embedding model lets a German question find a Hungarian or English passage, but keyword search still needs per-language analysis.
-   German compounds and Hungarian suffixes break naive BM25: use decompounding for German and a Snowball stemmer for Hungarian.
-   Users type Hungarian and German without accents and umlauts; fold diacritics in the keyword index as well as storing the original text.
-   Store the language of every chunk and decide explicitly whether to filter, boost or mix languages at query time.
-   Leaderboards average across many languages; build a small eval set per language and a cross-lingual one before picking a model.

On this page

1.  [Why is multilingual RAG harder than English RAG?](https://balazscsorba.com/#why-multilingual-rag-is-harder)
2.  [Which index strategy should you choose?](https://balazscsorba.com/#index-strategies)
3.  [Which multilingual embedding models are worth testing?](https://balazscsorba.com/#multilingual-embedding-models)
4.  [How do German compound words break keyword search?](https://balazscsorba.com/#german-compounds)
5.  [What do Hungarian suffixes and accents need?](https://balazscsorba.com/#hungarian-suffixes-and-accents)
6.  [How should you use language metadata at query time?](https://balazscsorba.com/#language-metadata)
7.  [In which language should the model answer?](https://balazscsorba.com/#answer-language)
8.  [How do you evaluate multilingual retrieval?](https://balazscsorba.com/#evaluate-per-language)
9.  [Sources](https://balazscsorba.com/#sources)

Listen to this article

0:000:00

Most RAG tutorials assume English documents and English questions. Projects in Austria, Germany and Hungary rarely look like that: product data in German, support tickets in Hungarian, manuals in English, and users who ask in whichever language they think in, often without umlauts or accents. Retrieval that works in a demo quietly drops half the relevant passages.

This article covers the decisions that matter for German and Hungarian content: index strategy, multilingual embedding models, what German compounds and Hungarian suffixes do to keyword search, accent folding, language metadata, the answer language, and how to evaluate per language. The same patterns carry over to other morphologically rich languages.

## Why is multilingual RAG harder than English RAG?

Three problems stack up. First, morphology: German glues nouns into compounds (_Kaffeetasse_, _Druckluftschlauch_), and Hungarian is agglutinative, so one stem appears with many suffixes (_ház_, _házban_, _házainkban_: house, in the house, in our houses). Exact-match search misses most of those forms. Second, cross-lingual queries: a German question whose answer sits in an English manual finds nothing with keyword search. Third, mixed corpora: the same document in three languages can crowd the top results with near-duplicates.

## Which index strategy should you choose?

Strategy

How it works

Good for

Watch out

One multilingual index

One embedding model for all languages, language stored as metadata

Cross-lingual questions, mixed corpora

Keyword side still needs per-language analysis

Index per language

Separate indexes, query routed by detected language

Fully localized sites with parallel content

Misses answers that only exist in another language

Translate at index time

Everything translated into one pivot language

Small, valuable corpora in weakly supported languages

Cost, translation errors, lost exact terms

Translate the query

Query rewritten into each corpus language before search

Keyword-heavy search across languages

An extra LLM call per query

For most projects I start with one multilingual dense index plus a keyword index analyzed per language, combined with hybrid search as in [A production RAG pipeline, step by step](https://balazscsorba.com/blog/rag-pipeline-chunking-hybrid-search-reranking). It keeps the original text, handles cross-lingual questions on the dense side, and lets each language get the right keyword analysis.

The dense side bridges languages; the keyword side catches exact terms such as part numbers and names.

## Which multilingual embedding models are worth testing?

Model

Size

Max input

Notes

multilingual-e5-large-instruct

560M

512 tokens

Best public model in the MMTEB paper; 100 languages from XLM-R

BGE-M3

XLM-R based

8,192 tokens

100+ languages; dense, sparse and multi-vector output from one model

Qwen3 Embedding

0.6B / 4B / 8B

Long

Strong on multilingual and cross-lingual retrieval; matching rerankers

The [MMTEB paper](https://arxiv.org/abs/2502.13595) covers more than 500 tasks in over 250 languages, and found that while billion-parameter LLM-based models lead on some subsets, the best publicly available model overall was multilingual-e5-large-instruct with 560 million parameters. Its 512-token limit matters, though: chunks longer than that are silently truncated. [BGE-M3](https://arxiv.org/abs/2402.03216) handles up to 8,192 tokens and returns a sparse vector alongside the dense one, which gives you a learned keyword signal without a separate analyzer. The [Qwen3 Embedding](https://arxiv.org/abs/2506.05176) series comes in three sizes with matching rerankers.

Averages hide the languages you care about. A model that leads a multilingual leaderboard can still be mediocre on Hungarian technical text. Hosted APIs from the big providers are also multilingual; if data must stay in-house, see [self-hosting LLMs for GDPR](https://balazscsorba.com/blog/self-hosted-llm-gdpr-cost), and for storage, [pgvector or a vector database](https://balazscsorba.com/blog/pgvector-vs-vector-databases).

## How do German compound words break keyword search?

A user searching for _Schlauch_ expects to find _Druckluftschlauch_. A standard tokenizer sees one token and no match. The fix is decompounding at index time: split compounds into known parts and index both the parts and the whole word. Elasticsearch's [hyphenation decompounder](https://www.elastic.co/docs/reference/text-analysis/analysis-hyp-decomp-tokenfilter) uses hyphenation patterns to propose subwords and keeps only those in a word list; its documentation example splits _Kaffeetasse_ into _Kaffee_ and _tasse_. The filter is built on Lucene's compound word filter, which was designed for Germanic languages.

Dense embeddings handle compounds more gracefully, because the subword tokenizer already splits rare words. That is one more reason to run both: decompounded BM25 for exact parts, embeddings for meaning.

## What do Hungarian suffixes and accents need?

For Hungarian, the keyword side needs a stemmer that strips case endings and possessives, so _számlán_, _számlák_ and _számláimat_ meet at one stem. [Snowball](https://snowballstem.org/algorithms/) has stemmers for both Hungarian and German, and PostgreSQL ships Snowball dictionaries, so plain Postgres full-text search can do it. Add the `unaccent` extension, because users type _szamla_ for _számla_ and _Groesse_ or _Grosse_ for _Größe_.

```
-- PostgreSQL: one tsvector per chunk, analyzed in the chunk's own language
CREATE EXTENSION IF NOT EXISTS unaccent;

-- unaccent() is not IMMUTABLE, so wrap it for use in a generated column
CREATE FUNCTION unaccent_immutable(t text) RETURNS text
  LANGUAGE sql IMMUTABLE PARALLEL SAFE
  AS $$ SELECT public.unaccent('public.unaccent', t) $$;

ALTER TABLE chunks ADD COLUMN lang regconfig NOT NULL DEFAULT 'simple';
ALTER TABLE chunks ADD COLUMN tsv tsvector
  GENERATED ALWAYS AS (to_tsvector(lang, unaccent_immutable(text))) STORED;
CREATE INDEX chunks_tsv ON chunks USING gin (tsv);

-- Query in the user's language: 'hungarian', 'german' or 'english'
SELECT id, ts_rank(tsv, q) AS score
FROM chunks, websearch_to_tsquery('hungarian', unaccent('számláim')) AS q
WHERE tsv @@ q ORDER BY score DESC LIMIT 20;
```

**Watch for broken Hungarian characters**

Older Hungarian documents often contain _õ_ and _û_ (tilde) instead of _ő_ and _ű_ (double acute), a leftover of Latin-1 encodings. Normalize them before indexing, or stemming, embeddings and exact matches all treat them as different words.

## How should you use language metadata at query time?

Detect and store the language of every chunk at index time, not just of every document; manuals and tickets often mix languages. At query time you have three choices, and it pays to make them explicitly:

-   **Filter** to the user's language when every document exists in every language, as on a fully translated shop. This removes near-duplicates.
-   **Boost** the user's language but allow others, when some content only exists in one language, such as English-only manuals.
-   **Deduplicate** translations of the same source by a shared document id after retrieval, keeping the version in the user's language.

## In which language should the model answer?

Tell the model explicitly to answer in the language of the question, because a context full of English chunks pulls answers toward English. Keep quotes and citations in the source language and link the original passage, so a reader can check the claim, as in [grounding and citations](https://balazscsorba.com/blog/llm-hallucination-grounding-citations). Product names, part numbers and legal terms should not be translated at all.

## How do you evaluate multilingual retrieval?

Build the eval set from the start with the language mix you expect: questions in German against German documents, in Hungarian against Hungarian ones, and a cross-lingual slice where the answer only exists in another language. Include unaccented and misspelled queries, because that is how people type. Report recall per slice, not one number; the averaged score is exactly what hides a failing language. The metrics themselves are the same as in [Evaluating RAG](https://balazscsorba.com/blog/rag-evaluation-metrics).

```
# Illustrative eval slices; report recall@10 per slice, never only the average
EVAL = [
  {"q": "Wie lang ist die Garantie auf Druckluftschläuche?", "lang": "de", "gold": ["warranty-de#3"]},
  {"q": "mennyi a garancia a tomlokre",                  "lang": "hu", "gold": ["garancia-hu#2"]},   # no accents
  {"q": "Betriebstemperatur Kompressor K40",              "lang": "de", "gold": ["k40-manual-en#7"]}, # answer only in English
]
```

## Sources

1.  [Enevoldsen et al.: MMTEB: Massive Multilingual Text Embedding Benchmark (2025)](https://arxiv.org/abs/2502.13595)
2.  [Chen et al.: M3-Embedding (BGE-M3): Multi-Linguality, Multi-Functionality, Multi-Granularity (2024)](https://arxiv.org/abs/2402.03216)
3.  [Zhang et al.: Qwen3 Embedding: Advancing Text Embedding and Reranking Through Foundation Models (2025)](https://arxiv.org/abs/2506.05176)
4.  [Hugging Face: intfloat/multilingual-e5-large-instruct model card](https://huggingface.co/intfloat/multilingual-e5-large-instruct)
5.  [Elasticsearch Reference: Hyphenation decompounder token filter](https://www.elastic.co/docs/reference/text-analysis/analysis-hyp-decomp-tokenfilter)
6.  [PostgreSQL 18 Documentation: Text search dictionaries](https://www.postgresql.org/docs/current/textsearch-dictionaries.html)
7.  [Snowball: stemming algorithms by language](https://snowballstem.org/algorithms/)

## Frequently asked questions

Which embedding model is best for German and Hungarian?

Test on your own data. The MMTEB authors found the 560M-parameter multilingual-e5-large-instruct to be the best publicly available model on their multilingual benchmarks, while BGE-M3 and the Qwen3 Embedding series are strong newer options with longer inputs. Per-language scores can differ a lot from the average.

Should I translate everything into English before indexing?

Usually not. Translation adds cost and errors, loses exact terms and makes citations awkward. A multilingual embedding model plus per-language keyword search keeps the original text. Translation can still help for a small, high-value corpus in a language your models handle poorly.

How do I handle German compound words in search?

Split compounds into their parts at index time with a decompounding filter, such as the Elasticsearch hyphenation decompounder with a German word list, and keep the full compound too. Dense embeddings cope with compounds better, which is another reason to use hybrid search.

Does PostgreSQL support Hungarian full-text search?

Yes. PostgreSQL ships Snowball stemmers, and Snowball has stemmers for both Hungarian and German, so you can index with to\_tsvector using a hungarian or german configuration and add the unaccent extension for accent-insensitive matching.

In which language should the assistant answer?

In the language of the question, unless the user asks otherwise. Quote and cite the source in its original language, because a translated quote can no longer be checked against the document.

Written by Balázs Csorba

Senior fullstack & AI engineer in Styria, Austria – 10+ years of Vue, Nuxt, Node.js and PHP, now building tooling for AI agents.

[AI engineering & MCP servers →](https://balazscsorba.com/expertise/ai-engineer)[About me →](https://balazscsorba.com/about)

## More articles

-   [PDF parsing for RAG: layout pipelines, OCR and vision models compared](https://balazscsorba.com/blog/pdf-document-parsing-for-rag)
-   [Text-to-SQL with LLMs: schema context, read-only roles and validation that holds](https://balazscsorba.com/blog/text-to-sql-llm-guardrails)
-   [Embedding quantization: binary, int8 and Matryoshka vectors without losing retrieval quality](https://balazscsorba.com/blog/embedding-quantization-binary-matryoshka)
-   [GraphRAG and knowledge-graph RAG: when a graph beats vector search](https://balazscsorba.com/blog/graphrag-knowledge-graph-rag)

## Sounds like what you need?

Tell me about your project or role – I’d love to hear from you.

[Get in touch](mailto:contact@balazscsorba.com) [Connect on LinkedIn](https://www.linkedin.com/in/balazs-csorba)
