Package Information
Documentation
n8n-nodes-orchestrator-agent
Intelligent multi-agent routing node for n8n — classifies incoming messages and routes them to the correct sub-agent using LLM, Embeddings, Vector Store (RAG), or a Hybrid approach.
What it does
The Orchestrator Agent sits at the top of your multi-agent system. It receives a user message, decides which specialized sub-agent should handle it, and routes the execution to the correct output branch — all in a single node.
User message → [Orchestrator Agent] → Branch 0 (Sales Agent)
→ Branch 1 (Support Agent)
→ Branch 2 (Scheduling Agent)
→ Branch 3 (FAQ Agent)
→ ... up to N agents
→ Fallback (optional)
Each branch connects to its own sub-agent workflow. The orchestrator never processes the message itself — it only routes.
Installation
In n8n, go to Settings → Community Nodes → Install and enter:
n8n-nodes-orchestrator-agent
Routing Methods
1. LLM Classification (default)
Uses a Chat Model (GPT-4, Claude, Gemini, etc.) with structured output to classify the message. Best accuracy. Requires a Chat Model sub-node.
2. Semantic Similarity (Embeddings)
Embeds the user message and computes cosine similarity against pre-computed embeddings for each agent's description. Fastest and cheapest. Requires an Embeddings sub-node.
3. Vector Store (RAG)
Queries a pre-indexed vector database (Supabase, Pinecone, Qdrant, etc.) to find the best matching agent. Good for large agent sets. Requires a Vector Store sub-node.
4. Hybrid — Vector Store + LLM (Most Accurate)
The vector store narrows down the top N candidate agents → the LLM picks the winner from those candidates. Combines the precision of semantic indexing with the reasoning depth of an LLM. Requires both a Vector Store and a Chat Model sub-node.
5. Contextual Hybrid — Session-Aware Routing (Best for Multi-turn Conversations)
Extends Hybrid with full session awareness: reads the user's current agent from memory history, includes the last N routing turns in the LLM prompt, and supports per-scenario routing rules ("observations") embedded in the vector store metadata. Requires a Vector Store, a Chat Model, and a Memory sub-node.
Routing Strategies — Detailed Guide
1. LLM Classification
When to use: Messages with complex intent, ambiguity between agents, or when you need Extended Analysis fields (emotion, intent, etc.) extracted in the same call.
Required sub-nodes: Chat Model
How it works:
- Builds a structured output schema from your agent list
- Sends system prompt + conversation history + user message to the LLM
- LLM returns the agent index + confidence + reasoning in a single JSON response
Configuration:
- No vector store needed — the LLM sees all agent names and descriptions directly
- Use System Prompt Prefix to inject business rules that override LLM behavior
- Use Extended Analysis Schema to extract extra fields (emotion, intent, urgency) in the same LLM call
Best for: 2–8 agents, complex messages, when accuracy matters more than cost.
2. Semantic Similarity (Embeddings)
When to use: High-volume routing where cost and speed are critical. Works well when agent descriptions are distinct enough.
Required sub-nodes: Embeddings
How it works:
- Embeds the user message using the connected Embeddings model
- Computes cosine similarity against pre-computed embeddings for each agent's description + example phrases
- Routes to the highest-scoring agent
Configuration:
- Add Example Phrases to each agent (one per line) — the more phrases, the better the embedding coverage
- No vector store or LLM needed
Best for: Speed-critical flows, simple intent separation, cost optimization.
3. Vector Store (RAG)
When to use: Large agent sets (8+), when you have many example phrases per agent that don't fit in a prompt, or when you want semantic search over a curated knowledge base.
Required sub-nodes: Vector Store
How it works:
- Queries the vector store with the user message
- Retrieves the top-K most similar documents
- Identifies the agent via the
agentNamemetadata field of the best-scoring document
Configuration:
| Parameter | Description | Default |
|---|---|---|
| Agent Field in Vector Store | Metadata field that identifies the agent (agentName) |
agentName |
| Vector Search Depth | Number of documents retrieved per query | 10 |
| Relevance Score Mode | Similarity (Supabase, Pinecone, Qdrant) or Distance (Chroma, FAISS) |
similarity |
Document format:
content: "quero cancelar minha assinatura"
metadata: { "agentName": "Cancelamento Agent" }
Best for: 8+ agents, pre-indexed phrase libraries, when LLM cost is a concern.
4. Hybrid — Vector Store + LLM
When to use: When you need the accuracy of semantic search combined with the reasoning depth of an LLM. The most accurate strategy for static routing scenarios.
Required sub-nodes: Vector Store + Chat Model
How it works:
- Vector store retrieves the top N candidate agents (default: 3)
- LLM receives only those N candidates (not the full agent list) and picks the winner
- The LLM sees each candidate's name, description, semantic score, and matched phrase
Configuration:
| Parameter | Description | Default |
|---|---|---|
| Agent Field in Vector Store | Metadata field that identifies the agent | agentName |
| Vector Search Depth | Documents retrieved from VS per query | 10 |
| Relevance Score Mode | Similarity or Distance | similarity |
| Finalist Agents for LLM | How many top candidates are passed to the LLM | 3 |
Document format: same as Vector Store (RAG).
Output includes:
"vectorStoreCandidates": [
{ "name": "Cancelamento Agent", "score": 0.912 },
{ "name": "FAQ Agent", "score": 0.641 }
]
Best for: Production flows where routing accuracy is critical and the agent set is stable.
5. Contextual Hybrid — Session-Aware Routing
When to use: Multi-turn conversations where the user moves between agents across messages. When a user in the middle of a scheduling flow asks something that sounds like general support, the router should know they're already in scheduling and keep them there (unless a routing rule says otherwise).
Required sub-nodes: Vector Store + Chat Model + Memory (Postgres or Redis)
How it works:
- Reads the last N routing decisions from memory → builds session history
- Extracts the current agent from the last
[routed to: X]memory entry - Vector store retrieves top N candidates — each document can carry an
observationrouting rule in its metadata - LLM receives: session history + current agent context + candidates + routing rules
- LLM makes a context-aware decision, treating routing rules as mandatory overrides
- Memory is updated with
[routed to: X | confidence: 0.94]for the next turn
Configuration:
| Parameter | Description | Default |
|---|---|---|
| Agent Field in Vector Store | Metadata field that identifies the agent | agentName |
| Vector Search Depth | Documents retrieved per query | 10 |
| Relevance Score Mode | Similarity or Distance | similarity |
| Finalist Agents for LLM | Candidates passed to the LLM | 3 |
| Observation Field in Vector Store | Metadata field containing routing rules | observation |
Output includes sessionContext:
"orchestrator": {
"routedTo": "Agendamento",
"sessionContext": "Agendamento",
"confidence": 0.94,
"vectorStoreCandidates": [...]
}
Memory format after each turn:
human: "Qual horário tem disponível?"
ai: "[routed to: Agendamento | confidence: 0.94]"
Session history shown to LLM:
=== SESSION HISTORY (last 3 interactions) ===
Turn -3: [Atendimento Inicial] — "oi" (91%)
Turn -2: [Agendamento] — "quero marcar consulta" (97%)
Turn -1: [Agendamento] — "qual horário?" (89%)
=== END SESSION HISTORY ===
Best for: WhatsApp/chatbot flows with multiple stages, pipelines where the user progresses through agents, any scenario requiring flow persistence.
Note: The Memory sub-node does not show visual execution in the n8n UI for community nodes — this is a known n8n SDK limitation. The session history IS being read and used. Check
$json.orchestrator.sessionContextto confirm.
Importing Documents for Contextual Hybrid
The Contextual Hybrid strategy uses the same vector store as Hybrid, but each document can optionally carry an observation field in its metadata. This field contains a routing rule that the LLM treats as a mandatory override when deciding between candidates.
Document format
content: "Qual horário ainda tem disponível?"
metadata: {
"agentName": "Agendamento",
"observation": "Se o usuário está no fluxo de Agendamento, mantenha aqui mesmo que a pergunta pareça de Atendimento Inicial."
}
The observation field is optional. Documents without it work exactly like regular Hybrid documents. Only add an observation when you want to enforce a specific routing behavior for a given scenario.
How to write good observations
Observations should describe when to override the default semantic match. Write them as conditional rules:
| Situation | Example observation |
|---|---|
| Keep user in current flow | "Se o usuário está em Agendamento, mantenha aqui mesmo que a pergunta pareça geral." |
| Redirect from one agent to another | "Se o usuário mencionou agendamento anteriormente, priorize o Agente de Agendamento." |
| Prevent wrong routing | "Não redirecione para Atendimento Inicial se o usuário já está em um sub-agente especializado." |
| Handle ambiguous cases | "Perguntas sobre preço durante o fluxo de vendas devem permanecer no Agente de Vendas." |
Rules for observations
- Write in the same language the LLM understands (match your system prompt language)
- Be specific — vague observations are ignored
- One observation per document — focus it on the context of that specific phrase
- Not every document needs an observation — use only where default semantic routing fails
n8n workflow to insert Contextual Hybrid documents
Use a Code node to generate the documents and a Supabase Vector Store node in Insert mode:
const documents = [
// === Agendamento Agent — without observation (standard routing) ===
{
content: "quero marcar uma consulta",
agentName: "Agendamento",
},
{
content: "como agendar um horário",
agentName: "Agendamento",
},
// === Agendamento Agent — with observation (session-aware routing) ===
{
content: "qual horário ainda tem disponível?",
agentName: "Agendamento",
observation: "Se o usuário já está no fluxo de Agendamento, mantenha aqui mesmo que a pergunta pareça de Atendimento Inicial.",
},
{
content: "posso remarcar para outro dia?",
agentName: "Agendamento",
observation: "Se o usuário está em Agendamento, não redirecione para Suporte — remarcar é parte do fluxo de agendamento.",
},
// === Atendimento Inicial Agent ===
{
content: "oi, boa tarde",
agentName: "Atendimento Inicial",
},
{
content: "olá, tudo bem?",
agentName: "Atendimento Inicial",
observation: "Se o usuário já está em qualquer sub-agente especializado, não redirecione para cá por uma saudação.",
},
// === Suporte Agent ===
{
content: "estou com um problema",
agentName: "Suporte",
},
{
content: "não está funcionando",
agentName: "Suporte",
},
];
return documents.map(doc => ({
json: {
pageContent: doc.content,
metadata: {
agentName: doc.agentName,
...(doc.observation ? { observation: doc.observation } : {}),
},
},
}));
Supabase Vector Store node configuration:
- Mode:
Insert Documents - Table Name:
agent_routes - Query Name:
match_agent_routes - Connect an Embeddings sub-node
The
observationfield is stored as part of themetadataJSONB column — no schema changes required if you already have theagent_routestable from the setup SQL above.
Verifying observations are stored
After inserting, check in the Supabase SQL Editor:
select content, metadata->>'agentName' as agent, metadata->>'observation' as observation
from agent_routes
where metadata->>'observation' is not null
order by id desc
limit 10;
Sub-node Connections
| Sub-node | Used by | Required? |
|---|---|---|
| Chat Model | LLM, Hybrid, Contextual Hybrid | Yes (for those modes) |
| Embeddings | Embeddings mode | Yes |
| Vector Store | Vector Store, Hybrid, Contextual Hybrid | Yes (for those modes) |
| Memory | LLM, Hybrid, Contextual Hybrid | Optional (required for session context in Contextual Hybrid) |
| Tools | LLM | Optional |
| Output Parser | LLM, Hybrid, Contextual Hybrid | Optional |
Configuring Sub-Agents
In the node panel, add each sub-agent with:
- Name — must match the
agentNamevalue in your vector store documents exactly (case-sensitive) - Description — what types of messages this agent handles
- Example Phrases (optional) — one phrase per line; helps the LLM and embeddings make better decisions
Example:
Name: Cancelamento Agent
Description: Handles subscription cancellations, refund requests, and churn prevention
Phrases: quero cancelar minha assinatura
como peço reembolso
não quero mais o plano
Output Data
Each output branch receives the original input fields plus routing metadata:
{
"action": "sendMessage",
"sessionId": "abc123",
"chatInput": "quero cancelar meu plano",
"orchestrator": {
"routedTo": "Cancelamento Agent",
"routedIndex": 2,
"confidence": 0.97,
"reasoning": "User explicitly requests cancellation.",
"inputText": "quero cancelar meu plano",
"latencyMs": 1243
}
}
Extended Analysis Schema
With LLM or Hybrid routing, you can instruct the LLM to extract additional analysis fields in the same call as routing — no extra LLM request needed.
In the Extended Analysis Schema field, paste a JSON Schema with the fields you want:
{
"required": ["perfil_emocional", "intencao_detectada"],
"properties": {
"perfil_emocional": {
"type": "string",
"enum": ["frustrado", "ansioso", "curioso", "vulneravel", "neutro"],
"description": "Emotional profile detected in the message"
},
"intencao_detectada": {
"type": "string",
"enum": ["novo_agendamento", "cancelamento", "duvida_servico", "indefinida"],
"description": "Primary intent detected"
},
"urgencia": {
"type": "string",
"enum": ["alta", "media", "baixa"]
}
}
}
The fields appear at the top level of $json alongside the routing metadata:
{
"chatInput": "preciso cancelar urgente, estou muito insatisfeito",
"perfil_emocional": "frustrado",
"intencao_detectada": "cancelamento",
"urgencia": "alta",
"orchestrator": { ... }
}
Supabase Vector Store Setup
Acesse seu projeto no Supabase → SQL Editor, cole o bloco abaixo e clique em Run. Isso cria tudo que o n8n precisa para funcionar.
Atenção ao modelo de embedding: o SQL abaixo usa dimensão
1536, compatível com OpenAItext-embedding-ada-002etext-embedding-3-small. Se usar outro modelo, ajustevector(1536)e o parâmetroquery_embedding vector(1536)na função antes de rodar.
Modelo Dimensão OpenAI text-embedding-ada-0021536OpenAI text-embedding-3-small1536OpenAI text-embedding-3-large3072text-embedding-004768Cohere embed-v31024
-- =====================================================
-- Orchestrator Agent — Supabase Vector Store Setup
-- Cole tudo isso no SQL Editor e clique em Run.
-- =====================================================
-- 1. Habilitar a extensão pgvector
create extension if not exists vector;
-- 2. Criar a tabela de documentos
create table if not exists agent_routes (
id bigserial primary key,
content text not null,
metadata jsonb not null default '{}',
embedding vector(1536)
);
-- 3. Índice HNSW para busca vetorial rápida (melhor recall que IVFFlat)
create index if not exists agent_routes_embedding_hnsw_idx
on agent_routes
using hnsw (embedding vector_cosine_ops)
with (m = 16, ef_construction = 64);
-- 4. Índice GIN para filtros por metadata (agentName)
create index if not exists agent_routes_metadata_gin_idx
on agent_routes using gin (metadata);
-- 5. Índice direto no campo agentName para lookups exatos
create index if not exists agent_routes_metadata_agent_idx
on agent_routes ((metadata->>'agentName'));
-- 6. Função de busca — configure o campo "Query Name" no nó Supabase Vector Store do n8n para "match_agent_routes"
create or replace function match_agent_routes (
query_embedding vector(1536),
match_count int default null,
filter jsonb default '{}'
)
returns table (
id bigint,
content text,
metadata jsonb,
similarity float
)
language plpgsql volatile
as $$
#variable_conflict use_column
begin
set local hnsw.ef_search = 40;
return query
select
id,
content,
metadata,
1 - (agent_routes.embedding <=> query_embedding) as similarity
from agent_routes
where metadata @> filter
order by agent_routes.embedding <=> query_embedding
limit match_count;
end;
$$;
Verificar se funcionou
Após rodar o SQL acima, execute este bloco para confirmar que tudo foi criado corretamente:
-- Inserir uma linha de teste
insert into agent_routes (content, metadata, embedding)
values ('teste', '{"agentName": "Teste"}', array_fill(0.1, array[1536])::vector);
-- Buscar e verificar (deve retornar 1 linha com similarity ≈ 1.0)
select content, metadata, similarity
from match_agent_routes(array_fill(0.1, array[1536])::vector, 1, '{}');
-- Limpar
delete from agent_routes where content = 'teste';
Other Vector Store Providers
PostgreSQL (pgvector direto)
Se você tem um PostgreSQL próprio (sem Supabase), o setup é idêntico — só muda a conexão no n8n.
1. Instale a extensão pgvector no seu Postgres:
create extension if not exists vector;
2. Rode o mesmo SQL do Supabase (tabela agent_routes, índices e função match_agent_routes) na sua instância PostgreSQL.
3. Configure o nó no n8n:
- Nó: Supabase Vector Store (funciona com qualquer Postgres + pgvector)
- Credencial: aponte para sua URL PostgreSQL
- Table Name:
agent_routes - Query Name:
match_agent_routes - Score Type:
Similarity
O nó Supabase Vector Store do n8n usa pgvector internamente — funciona com qualquer Postgres que tenha a extensão instalada, não só com o Supabase.
Qdrant
Qdrant é um banco vetorial dedicado, mais rápido que pgvector para grandes volumes.
1. Suba o Qdrant (Docker ou Qdrant Cloud):
docker run -d --name qdrant -p 6333:6333 -p 6334:6334 qdrant/qdrant
2. Crie a collection via API REST:
curl -X PUT http://localhost:6333/collections/agent_routes \
-H 'Content-Type: application/json' \
-d '{
"vectors": {
"size": 1536,
"distance": "Cosine"
}
}'
Ajuste
"size"conforme o modelo de embedding usado:
- OpenAI
text-embedding-ada-002/3-small→1536- OpenAI
text-embedding-3-large→3072text-embedding-004→768
3. Configure o nó no n8n:
- Nó: Qdrant Vector Store
- Credencial: URL do Qdrant + API Key (se configurada)
- Collection Name:
agent_routes - Score Type:
Similarity
4. Para inserir documentos, use o nó Qdrant Vector Store em modo Insert Documents com um sub-nó de Embeddings conectado — o n8n cria os pontos automaticamente com o campo agentName no payload.
Redis (Redis Stack)
Redis com Redis Stack inclui busca vetorial via módulo RediSearch. Boa opção se já usa Redis na infraestrutura.
1. Suba o Redis Stack (Docker ou Redis Cloud):
docker run -d --name redis-stack \
-p 6379:6379 \
-p 8001:8001 \
redis/redis-stack:latest
redis/redis-stackjá inclui RediSearch. Oredissimples não tem busca vetorial.
2. Nenhuma criação de schema manual — o n8n cria o índice automaticamente na primeira inserção.
3. Configure o nó no n8n:
- Nó: Redis Vector Store
- Credencial: host + porta do Redis Stack
- Index Name:
agent_routes - Score Type:
Similarity
4. Para inserir documentos, use o nó Redis Vector Store em modo Insert Documents com um sub-nó de Embeddings conectado.
Score Type no Redis: Redis usa distância coseno e retorna similaridade (0–1, maior = melhor). Use
Similarity.
Comparativo de providers
| Provider | Melhor para | Score Type | Schema manual? |
|---|---|---|---|
| Supabase / PostgreSQL | Projetos já no Postgres, SQL familiar | Similarity | Sim (SQL acima) |
| Qdrant | Alto volume, busca mais rápida, filtros avançados | Similarity | Sim (API REST) |
| Redis Stack | Infraestrutura já com Redis, baixa latência | Similarity | Não |
| Pinecone | Escala massiva, serverless | Similarity | Não |
| Chroma | Local/dev, sem infraestrutura | Distance | Não |
Importing Content to the Vector Store
Cada linha inserida na tabela agent_routes representa um exemplo de frase que deve rotear para um agente específico. O Vector Store aprende a associar mensagens similares ao agente correto com base nesses exemplos.
Formato obrigatório
Cada documento precisa ter exatamente dois campos:
| Campo | Tipo | O que colocar |
|---|---|---|
content |
text |
Uma frase de exemplo que deve rotear para esse agente |
metadata.agentName |
text (dentro do JSONB) |
O nome exato do sub-agente configurado no node (case-sensitive) |
O campo
embeddingé preenchido automaticamente pelo n8n quando você usa o nó Supabase Vector Store em modo Insert — você não precisa gerar o vetor manualmente.
Regras críticas
✅ Correto
content: "quero cancelar minha assinatura"
metadata: { "agentName": "Cancelamento Agent" }
❌ Errado — agentName não bate com o nome no node
content: "quero cancelar minha assinatura"
metadata: { "agentName": "cancelamento" } ← minúsculo, diferente do node
❌ Errado — metadata sem o campo agentName
content: "quero cancelar minha assinatura"
metadata: { "agent": "Cancelamento Agent" } ← campo errado
❌ Errado — content vazio ou genérico demais
content: "ajuda" ← muito vago, confunde o modelo
metadata: { "agentName": "Cancelamento Agent" }
Quantas frases por agente?
| Agentes | Frases por agente | Total |
|---|---|---|
| 4–6 | 10–20 | 40–120 |
| 7–10 | 15–25 | 105–250 |
| 10+ | 20–30 | 200–300+ |
Dicas para melhor precisão:
- Use frases reais dos seus usuários (mais eficaz)
- Varie o estilo — formal, informal, abreviado, com erros de digitação
- Inclua casos ambíguos entre agentes (o modelo aprende os limites)
- Nunca repita a mesma frase para dois agentes diferentes
Document Structure
| Field | Purpose |
|---|---|
content |
A phrase or example message that should route to this agent |
metadata.agentName |
Exact name of the sub-agent (must match node config) |
Method 1 — n8n Workflow (Recommended)
Create a separate n8n workflow to insert your routing documents. Here is the node setup:
Nodes in the workflow:
- Manual Trigger or Schedule Trigger
- Code node — generates the documents array
- Supabase Vector Store node (Insert mode) — inserts with embeddings
Code node example:
// Returns all routing documents for your agents
const documents = [
// === Cancelamento Agent ===
{ content: "quero cancelar minha assinatura", agentName: "Cancelamento Agent" },
{ content: "como faço para cancelar meu plano", agentName: "Cancelamento Agent" },
{ content: "quero pedir reembolso", agentName: "Cancelamento Agent" },
{ content: "não quero mais renovar", agentName: "Cancelamento Agent" },
{ content: "como encerro minha conta", agentName: "Cancelamento Agent" },
// === Agendamento Agent ===
{ content: "quero marcar uma consulta", agentName: "Agendamento Agent" },
{ content: "como agendar um horário", agentName: "Agendamento Agent" },
{ content: "preciso remarcar meu agendamento", agentName: "Agendamento Agent" },
{ content: "qual o próximo horário disponível", agentName: "Agendamento Agent" },
{ content: "quero agendar para amanhã", agentName: "Agendamento Agent" },
// === FAQ Agent ===
{ content: "quais são os horários de funcionamento", agentName: "FAQ Agent" },
{ content: "como funciona o serviço", agentName: "FAQ Agent" },
{ content: "quais planos vocês oferecem", agentName: "FAQ Agent" },
{ content: "qual é o preço", agentName: "FAQ Agent" },
{ content: "vocês aceitam cartão de crédito", agentName: "FAQ Agent" },
// === Suporte Agent ===
{ content: "estou com problema técnico", agentName: "Suporte Agent" },
{ content: "o sistema não está funcionando", agentName: "Suporte Agent" },
{ content: "não consigo fazer login", agentName: "Suporte Agent" },
{ content: "minha senha não funciona", agentName: "Suporte Agent" },
{ content: "o aplicativo travou", agentName: "Suporte Agent" },
];
return documents.map(doc => ({
json: {
pageContent: doc.content,
metadata: { agentName: doc.agentName }
}
}));
Supabase Vector Store node configuration:
- Mode:
Insert Documents - Table Name:
agent_routes - Query Name:
match_agent_routes - Content Column:
content - Metadata Column:
metadata - Connect an Embeddings sub-node (OpenAI, Cohere, etc.)
Method 2 — Direct SQL with Pre-computed Embeddings
If you already have embeddings, insert directly via SQL:
insert into agent_routes (content, metadata, embedding)
values
(
'quero cancelar minha assinatura',
'{"agentName": "Cancelamento Agent"}',
'[0.021, -0.013, ...]' -- your 1536-dimension vector
);
Method 3 — Bulk Insert via Supabase API
Use the Supabase REST API or client library to batch insert:
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(SUPABASE_URL, SUPABASE_SERVICE_KEY);
const rows = [
{ content: 'quero cancelar', metadata: { agentName: 'Cancelamento Agent' }, embedding: [...] },
// ...
];
const { error } = await supabase.from('agent_routes').insert(rows);
n8n Node Configuration Reference
Routing Method: LLM Classification
| Parameter | Description | Default |
|---|---|---|
| System Prompt Prefix | Business rules injected before the routing prompt — the LLM treats these as mandatory | — |
| Extended Analysis Schema | JSON Schema for extra fields to extract alongside the routing decision | — |
| Retry on Parse Failure | Retries with stricter JSON instructions if LLM output fails to parse | true |
Routing Method: Vector Store (RAG)
| Parameter | Description | Default |
|---|---|---|
| Agent Field in Vector Store | Metadata field that identifies the agent (agentName) |
agentName |
| Vector Search Depth | Documents retrieved per query | 10 |
| Relevance Score Mode | Similarity or Distance |
similarity |
Routing Method: Hybrid
| Parameter | Description | Default |
|---|---|---|
| Agent Field in Vector Store | Metadata field used to identify the agent | agentName |
| Vector Search Depth | How many documents to retrieve from vector store per query | 10 |
| Relevance Score Mode | How your vector store reports relevance scores | similarity |
| Finalist Agents for LLM | How many top candidates the vector store selects for the LLM | 3 |
Routing Method: Contextual Hybrid
| Parameter | Description | Default |
|---|---|---|
| Agent Field in Vector Store | Metadata field that identifies the agent | agentName |
| Vector Search Depth | Documents retrieved per query | 10 |
| Relevance Score Mode | Similarity or Distance | similarity |
| Finalist Agents for LLM | Candidates passed to the LLM | 3 |
| Observation Field in Vector Store | Metadata field containing per-scenario routing rules | observation |
Score Type by provider:
- Similarity (higher = better): Supabase/pgvector, Pinecone, Qdrant
- Distance (lower = better): Chroma, FAISS (L2 distance)
Output Options
| Parameter | Description |
|---|---|
| Include Routing Metadata | Adds $json.orchestrator with routing details, confidence, and latency |
| Extended Analysis Schema | JSON Schema for extra fields the LLM populates in the same call |
| Pass Full Input to Outputs | Merges all input fields into the routed output item |
| Retry on Parse Failure | Retries once with stricter JSON instructions if LLM output fails to parse |
| Enable Fallback | Adds an extra output branch for low-confidence or unmatched messages |
| Min Confidence Threshold | Routes to Fallback if confidence is below this value (0.0–1.0) |
Architecture Overview
┌─────────────────────────────────────────────────┐
│ Orchestrator Agent Node │
│ │
│ ┌──────────┐ ┌──────────────────────────┐ │
│ │ Input │───▶│ resolveExecuteParams │ │
│ │ message │ │ (reads all parameters) │ │
│ └──────────┘ └──────────┬───────────────┘ │
│ │ │
│ ┌──────────────▼─────────────┐ │
│ │ Routing Strategy │ │
│ │ embeddings / vectorStore │ │
│ │ hybrid / llm │ │
│ └──────────────┬─────────────┘ │
│ │ │
│ ┌───────────────────▼────────────────┐ │
│ │ Output Branches │ │
│ │ [0] [1] [2] ... [N] [Fallback] │ │
│ └────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
Frequently Asked Questions
Q: The vector store sub-node doesn't show execution in n8n's UI — is it working?
Yes. This is an n8n SDK limitation: community nodes that call sub-nodes via getInputConnectionData() do not trigger the visual sub-node execution tracking panel. The vector store is being called — check $json.orchestrator.vectorStoreCandidates in the output item for confirmation. In Hybrid mode it shows each candidate and its score:
"vectorStoreCandidates": [
{ "name": "Cancelamento Agent", "score": 0.912 },
{ "name": "FAQ Agent", "score": 0.641 },
{ "name": "Suporte Agent", "score": 0.483 }
]
Q: How do I know which agent was chosen?
Check $json.orchestrator.routedTo (agent name), $json.orchestrator.routedIndex (0-based index), and $json.orchestrator.confidence (0.0–1.0).
Q: Can I use a different vector store besides Supabase?
Yes. Pinecone, Qdrant, Chroma, FAISS, and any other n8n-compatible vector store works. Just make sure your documents have the agentName field in metadata, and configure the Score Type to match your provider.
Q: How many tokens does Hybrid mode consume?
The LLM only sees the top N candidates (typically 3), not all agents. For a typical message with 3 candidates and brief descriptions, expect ~300–600 input tokens + ~50 output tokens per routing call.
Q: Can I use Extended Analysis Schema with Vector Store mode (not Hybrid)?
No. Extended Analysis Schema requires an LLM call. Use Hybrid mode (Vector Store + LLM) to get both RAG accuracy and extended analysis.
License
MIT © Growsales AI