> Source: https://builder.ema.ai/v2/agent-reference/qa-merge
> Title: QA Merge Agent

# QA Merge Agent

The QA Merge Agent deduplicates and merges question/answer (Q&A) pairs. It embeds each question, clusters near-duplicates by semantic similarity, and uses an LLM to decide which clustered pairs are genuinely the same question — marking duplicates rather than silently dropping them, so the original rows stay traceable. It runs in two phases: first it self-deduplicates the incoming pairs, then it deduplicates them against an optional set of existing pairs.

> [WARNING]
> **Not "Agent QA."** This is a Q&A-merge utility for cleaning up question/answer datasets. It is unrelated to any call-center "Agent QA" quality-assurance product. Don't conflate the two.

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 QA Merge Agent to clean up a generated or extracted Q&A set before it lands in a knowledge base — removing near-duplicate questions, consolidating overlapping answers, and (optionally) reconciling duplicates that came from translation. It commonly runs downstream of an [Extraction](/builder/v2/agent-reference/extraction) agent and the [Multilingual Translation Agent](/builder/v2/agent-reference/multilingual-translation): translation produces localized copies, and this agent reconciles them.

## How it works

The agent processes pairs in two phases:

1.  **Self-deduplication** — embeds and clusters the incoming pairs by question similarity, then asks the LLM to confirm which clustered pairs are truly duplicates of one another.
2.  **Deduplication against existing** — compares the survivors against any `existing_qa_json` you supply, so newly generated pairs that already exist are flagged.

Two deduplication strategies are available, selected by `dedup_across_languages`:

-   **Off (default)** — clusters by embedding similarity, then splits clusters by language, so the agent only deduplicates within the same language. It sets the `is_duplicate` and `duplicate_question` fields.
-   **On** — uses translation-family relationships to group, keeps one item per language for the same question/answer, and additionally sets the `is_translated` and `is_duplicate_across_languages` fields.

## 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": "qa_merge_agent" }
```

It reads the following input keys.

Input key

Required

Purpose

`extraction_columns`

Yes

The new Q&A rows to deduplicate — objects carrying at least `question` and `answer`. Rows missing either are dropped. When no usable rows remain, the agent returns an empty result.

`existing_qa_json`

No

JSON-serialized array of already-processed Q&A rows to deduplicate the new rows against (phase 2).

`selected_models`

No

JSON-serialized array (or list) of EmaFusion™ model IDs used for the LLM duplicate-confirmation step. Omit to use the default.

`similarity_threshold`

No

Cosine-similarity cutoff for clustering candidate duplicates. Defaults to `0.91`.

`embed_model`

No

Embedding model used to vectorize questions. Defaults to `text-embedding-ada-002`.

`dedup_across_languages`

No

Whether to reconcile duplicates across languages. Parsed from a string: `"true"`/`"yes"`/`"1"`/`"on"` enable it; anything else (including unset) leaves it off.

## Output

The agent returns an object with a single `rows` key containing every processed Q&A pair — both the unique pairs and the ones marked as duplicates (duplicates are flagged, not removed, so you can audit the merge). Each row carries:

Field

Meaning

`question`, `answer`

The Q&A pair.

`source_citation`, `category`, `page`, `file_name`

Provenance carried through from the input.

`language_code`

The pair's language.

`reliability_score`, `recommended_changes`, `changes_needed`

Quality signals carried through from the input.

`is_duplicate`

Whether this pair was identified as a duplicate.

`duplicate_question`

The question this pair duplicates (populated only when `is_duplicate` is true).

`is_translated`, `is_duplicate_across_languages`

Present only when `dedup_across_languages` is on.

`duplicate_answer_id`

Present only when the input rows carried a grouping ID (as produced by the Multilingual Translation Agent), preserved so cross-language grouping survives the merge.

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

## Example

A node configured as:

```json
{ "custom_agent_id": "qa_merge_agent" }
```

with these inputs:

```json
{
  "extraction_columns": "[{\"question\": \"How do I reset my password?\", \"answer\": \"Use the reset link.\", \"language_code\": \"en-US\"}, {\"question\": \"How can I reset my password?\", \"answer\": \"Click the reset link.\", \"language_code\": \"en-US\"}]",
  "similarity_threshold": "0.91"
}
```

returns both pairs, with the second flagged as a duplicate of the first:

```json
{
  "rows": [
    {
      "question": "How do I reset my password?",
      "answer": "Use the reset link.",
      "language_code": "en-US",
      "is_duplicate": false,
      "duplicate_question": ""
    },
    {
      "question": "How can I reset my password?",
      "answer": "Click the reset link.",
      "language_code": "en-US",
      "is_duplicate": true,
      "duplicate_question": "How do I reset my password?"
    }
  ]
}
```

## What's next

-   [Custom Agent](/builder/v2/agent-reference/custom) — how the `custom_agent` dispatch this agent runs on works.
-   [Multilingual Translation Agent](/builder/v2/agent-reference/multilingual-translation) — produces the localized rows this agent reconciles.
-   [Agent Reference overview](/builder/v2/agent-reference) — the agent-type model, catalog, and shared execution engine.
