> Source: https://builder.ema.ai/v2/agent-reference/multilingual-translation
> Title: Multilingual Translation Agent

# Multilingual Translation Agent

The Multilingual Translation Agent translates fields in your extraction rows into one or more target languages. For each source row it appends one **new** row per target language, carrying the translated content with the target `language_code` set. The original rows are preserved, so the output is the original dataset expanded with localized copies.

It belongs to the **Custom Agents** group: a set of pre-built, externally dispatched agents you select by ID instead of configuring an LLM loop yourself. Like every agent in this group, it runs as a Custom agent (`custom_agent`) — the agent service forwards the node's inputs to the custom-action service, which executes the agent and returns its output. See [Custom Agent](/builder/v2/agent-reference/custom) for how the `custom_agent` dispatch mechanism works.

> [INFO]
> **Availability.** This agent is enabled in all environments (`local`, `development`, `staging`, and `production`).

## When to use it

Use the Multilingual Translation Agent when you need a single body of content available in several locales — for example, localizing a set of extracted Q&A pairs or knowledge-base entries into French, Spanish, and German while keeping the originals. It commonly sits downstream of an [Extraction](/builder/v2/agent-reference/extraction) agent and upstream of the [QA Merge Agent](/builder/v2/agent-reference/qa-merge), which can deduplicate across the languages it produces.

## How it works

The agent runs in one of two modes, chosen by which input you provide:

-   **Extraction columns mode** — translate the fields you name in each row of `extraction_columns` into each language in `target_languages`. The output is the original rows plus one translated row per source row per target language.
-   **Text input mode** — translate a JSON array of `{text, target_languages, metadata}` items, where each item carries its own target languages. The output is a flat array of `{source_text, metadata, language_code, translated_text}` rows.

Target languages use BCP-47 codes that include a region subtag (for example `fr-FR`, `es-MX`, `de-DE` — not bare `fr`). Rows whose `language_code` already matches a requested target are skipped for that target, so the agent never re-translates content into its own language.

## Configuration

Add the agent to a workflow as a Custom agent and pin it by ID in `agent_config.type_config`:

```json
{ "custom_agent_id": "multilingual_translation_agent" }
```

It reads the following input keys. Most are provided as JSON-serialized strings (the convention for custom-agent inputs); `extraction_columns` may also be passed as an already-parsed array.

Input key

Required

Purpose

`extraction_columns`

Yes, unless `text_input` is set

The rows to translate — a JSON array of objects. Each object holds the fields named in `fields_to_translate` plus a `language_code`. Use this for extraction columns mode.

`target_languages`

Yes for extraction columns mode

JSON array of BCP-47 codes with a region subtag, e.g. `["fr-FR", "es-MX", "de-DE"]`. An empty array returns the input unchanged.

`fields_to_translate`

No

JSON array of the field names within each row to translate, e.g. `["source_text"]`. Fields not listed are copied verbatim onto the translated rows.

`text_input`

Yes for text input mode

Alternative to `extraction_columns`. A JSON array of `{text, target_languages, metadata}` objects. Use when there is no upstream extraction node. Must be a JSON array, not a plain string.

`model_config`

No

JSON-serialized EmaFusion™ model config (`{"selected_models": ["…"]}`). Omit to use the default model.

`batch_size`

No

Number of rows to translate per model call. Defaults to the agent's internal default when omitted.

## Output

The agent returns an object with a single `rows` key.

-   In **extraction columns mode**, `rows` is the original rows followed by the translated rows. Each translated row is a copy of its source row with the translated fields replaced and `language_code` set to the (normalized) target locale. If row-level flag fields such as `is_translated` are present, the agent sets them accordingly on the originals and copies.
-   In **text input mode**, `rows` is a flat array of objects shaped `{source_text, metadata, language_code, translated_text}`, one per (item, language) pair.

A downstream node reads the result via `{{<node_id>.output.rows}}`.

## Example

A node configured as:

```json
{ "custom_agent_id": "multilingual_translation_agent" }
```

with these inputs (extraction columns mode):

```json
{
  "extraction_columns": "[{\"source_text\": \"Hello\", \"language_code\": \"en-US\", \"metadata\": \"greeting\"}]",
  "target_languages": "[\"fr-FR\", \"es-MX\"]",
  "fields_to_translate": "[\"source_text\"]"
}
```

returns the original row plus one translated row per target language:

```json
{
  "rows": [
    { "source_text": "Hello", "language_code": "en-US", "metadata": "greeting" },
    { "source_text": "Bonjour", "language_code": "fr-fr", "metadata": "greeting" },
    { "source_text": "Hola", "language_code": "es-mx", "metadata": "greeting" }
  ]
}
```

## What's next

-   [Custom Agent](/builder/v2/agent-reference/custom) — how the `custom_agent` dispatch this agent runs on works.
-   [QA Merge Agent](/builder/v2/agent-reference/qa-merge) — deduplicate across the languages this agent produces.
-   [Agent Reference overview](/builder/v2/agent-reference) — the agent-type model, catalog, and shared execution engine.
