From c9ffc580d6ab7183691335d7701a076c8a9e03a1 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Tue, 11 Aug 2026 16:36:54 -0300 Subject: [PATCH] Plano: workflows de exemplo de AI Agent para agendamento (Klingo, ClinicAll, SysLife) Co-Authored-By: Claude Sonnet 5 --- ...11-workflows-exemplo-agente-agendamento.md | 428 ++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 docs/superpowers/plans/2026-08-11-workflows-exemplo-agente-agendamento.md diff --git a/docs/superpowers/plans/2026-08-11-workflows-exemplo-agente-agendamento.md b/docs/superpowers/plans/2026-08-11-workflows-exemplo-agente-agendamento.md new file mode 100644 index 0000000..0731f34 --- /dev/null +++ b/docs/superpowers/plans/2026-08-11-workflows-exemplo-agente-agendamento.md @@ -0,0 +1,428 @@ +# Workflows de Exemplo de AI Agent para Agendamento (Klingo, ClinicAll, SysLife) Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task (não subagent-driven-development — as tasks são chamadas de API do n8n via MCP, não commits de código; não há diff de git pra revisar por task). Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Construir 3 workflows de exemplo de AI Agent (um por provider — Klingo, ClinicAll, SysLife), cada um conectando via webhook Z-PRO/GChat num agente conversacional com acesso a todas as tools do respectivo MCP Server de agendamento já existente, todos validados estruturalmente (0 erros) e deixados **inativos de propósito** (sem clínica real de nenhum dos três providers). + +**Architecture:** Réplica do esqueleto já usado nos 3 workflows de exemplo de confirmação de agenda (Klingo/ClinicAll/SysLife, seções 18-20 do runbook): `Webhook` (contrato Z-PRO/GChat) → `Extrair campos do webhook` (`Set`) → `AI Agent` com `OpenAI Chat Model` (credencial real compartilhada) + `Postgres Chat Memory` (credencial placeholder) + `MCP Client Tool` conectado ao MCP Server de agendamento do provider, com `include: "all"` (diferente dos exemplos de confirmação, que filtravam tools específicas — aqui o agente precisa de todas as tools do provider pra completar um agendamento). Nenhum sub-workflow novo é criado — os MCP Servers de agendamento já existem e são só referenciados pela URL do endpoint MCP. + +**Tech Stack:** n8n (`devn8n.gtigrupo.com.br`), MCP tools do n8n (`n8n_create_workflow`, `n8n_update_partial_workflow`, `n8n_validate_workflow`), MCP Servers de agendamento já existentes (Klingo `3eiFEnfOTLnutP78`, ClinicAll `igaKjoHcPNYRAxPS`, SysLife `TYu78UqIUr2yCBHK`). + +## Global Constraints + +- Nenhum sub-workflow de tool é criado ou modificado nesta rodada — só os 3 workflows de agente e a conexão `MCP Client Tool` que aponta pros servidores já existentes. +- Contrato do webhook Z-PRO/GChat idêntico ao já documentado na seção 6 do runbook e reaproveitado nos 3 exemplos de confirmação: `body.protocol`→`sessionId`, `body.entrada`→`mensagem`, `body.contactName`→`nomeContato`, `body.number`→`telefone`. +- `OpenAI Chat Model` usa a credencial real e compartilhada já em uso em produção e nos exemplos de confirmação: `openAiApi` id `29vMIDah5DTIhUYJ`, nome "GPT" — não é credencial inventada. +- `Postgres Chat Memory` usa credencial placeholder (`PLACEHOLDER_SEM_CREDENCIAL`) — sem cliente real, sem banco provisionado, mesma disciplina dos exemplos de confirmação. +- `MCP Client Tool` de cada workflow usa `include: "all"` (não `"selected"` como nos exemplos de confirmação) — o agente de agendamento precisa de todas as tools do provider pra completar um fluxo de ponta a ponta. +- Webhook paths distintos por provider, pra não colidir entre si nem com os exemplos de confirmação já existentes: `agendamento-klingo-exemplo`, `agendamento-clinicall-exemplo`, `agendamento-syslife-exemplo`. +- Os 3 workflows ficam **inativos de propósito** ao final deste plano — sem clínica real de nenhum provider e sem credencial Postgres válida, ativá-los só geraria execuções com erro. +- O `systemMessage` do agente do Klingo precisa avisar explicitamente sobre a limitação real conhecida: `consultar_horarios` sempre retorna `SLOT_MAPPING_UNAVAILABLE` — o agente deve informar isso ao paciente em vez de inventar horários ou tentar chamar `agendar` sem um `slotId` real. + +Spec de referência: `docs/superpowers/specs/2026-08-11-workflows-exemplo-agente-agendamento-design.md` + +--- + +### Task 1: Workflow de exemplo "Agendamento - GChat - Klingo (exemplo)" + +**Interfaces:** +- Consumes: MCP Server de agendamento Klingo (`3eiFEnfOTLnutP78`, path `mcp-server-klingo`, tools `consultar_horarios` + `agendar`). +- Produces: workflow `Agendamento - GChat - Klingo (exemplo)`. + +- [ ] **Step 1: Criar o workflow (webhook + AI Agent + modelo + memória)** + +`n8n_create_workflow`: + +```json +{ + "name": "Agendamento - GChat - Klingo (exemplo)", + "nodes": [ + { + "id": "webhook", + "name": "Webhook GChat", + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [0, 0], + "parameters": { "httpMethod": "POST", "path": "agendamento-klingo-exemplo", "responseMode": "lastNode", "options": {} } + }, + { + "id": "extrair-campos", + "name": "Extrair campos do webhook", + "type": "n8n-nodes-base.set", + "typeVersion": 3.4, + "position": [224, 0], + "parameters": { + "assignments": { + "assignments": [ + { "name": "sessionId", "type": "string", "value": "={{ $json.body.protocol }}" }, + { "name": "mensagem", "type": "string", "value": "={{ String($json.body.entrada || '').trim() }}" }, + { "name": "nomeContato", "type": "string", "value": "={{ $json.body.contactName }}" }, + { "name": "telefone", "type": "string", "value": "={{ $json.body.number }}" } + ] + } + } + }, + { + "id": "ai-agent", + "name": "AI Agent", + "type": "@n8n/n8n-nodes-langchain.agent", + "typeVersion": 2.1, + "position": [448, 0], + "parameters": { + "text": "={{ $json.mensagem }}", + "systemMessage": "Você é um assistente de agendamento de consultas médicas, via WhatsApp, para uma clínica que usa o sistema Klingo. Seu trabalho: 1) entender o que o paciente quer agendar; 2) usar a tool consultar_horarios para ver horários disponíveis. ATENÇÃO — limitação real conhecida desta integração: consultar_horarios pode retornar o erro SLOT_MAPPING_UNAVAILABLE, porque a API do Klingo não documenta publicamente o formato de cada horário individual. Se isso acontecer, informe educadamente ao paciente que a consulta de horários está temporariamente indisponível por essa integração e que ele será atendido de outra forma — nunca invente um horário nem um slotId; 3) se consultar_horarios funcionar e devolver um slotId real, use a tool agendar com esse slotId e os demais dados do paciente para concluir o agendamento; 4) responda sempre em português, de forma clara e cordial." + } + }, + { + "id": "openai-chat-model", + "name": "OpenAI Chat Model", + "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", + "typeVersion": 1.3, + "position": [448, -160], + "parameters": { "model": { "mode": "id", "value": "gpt-4o-mini" }, "builtInTools": {}, "options": {} }, + "credentials": { "openAiApi": { "id": "29vMIDah5DTIhUYJ", "name": "GPT" } } + }, + { + "id": "memoria", + "name": "Memória da Sessão (Postgres)", + "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat", + "typeVersion": 1.4, + "position": [448, 160], + "parameters": { "sessionIdType": "customKey", "sessionKey": "={{ $json.sessionId }}", "tableName": "n8n_chat_histories", "contextWindowLength": 20 }, + "credentials": { "postgres": { "id": "PLACEHOLDER_SEM_CREDENCIAL", "name": "Postgres - (sem cliente real)" } } + } + ], + "connections": { + "Webhook GChat": { "main": [[{ "node": "Extrair campos do webhook", "type": "main", "index": 0 }]] }, + "Extrair campos do webhook": { "main": [[{ "node": "AI Agent", "type": "main", "index": 0 }]] }, + "OpenAI Chat Model": { "ai_languageModel": [[{ "node": "AI Agent", "type": "ai_languageModel", "index": 0 }]] }, + "Memória da Sessão (Postgres)": { "ai_memory": [[{ "node": "AI Agent", "type": "ai_memory", "index": 0 }]] } + } +} +``` + +Anotar o `id` retornado. + +- [ ] **Step 2: Conectar o MCP Client Tool com todas as tools do MCP Klingo** + +`n8n_update_partial_workflow`, numa única chamada atômica: + +```json +{ + "id": "", + "operations": [ + { + "type": "addNode", + "node": { + "id": "mcp-client-klingo-agendamento", + "name": "MCP Klingo Agendamento", + "type": "@n8n/n8n-nodes-langchain.mcpClientTool", + "typeVersion": 1, + "position": [448, 320], + "parameters": { + "endpointUrl": "https://devn8n.gtigrupo.com.br/mcp/mcp-server-klingo", + "authentication": "none", + "include": "all" + } + } + }, + { "type": "addConnection", "source": "MCP Klingo Agendamento", "target": "AI Agent", "sourceOutput": "ai_tool", "targetIndex": 0 } + ] +} +``` + +- [ ] **Step 3: Validar** + +`n8n_validate_workflow`. Esperado: `errorCount: 0` (warnings de +credencial `postgres` placeholder são aceitáveis). + +- [ ] **Step 4: Deixar inativo** + +Não ativar — sem clínica Klingo real nem credencial Postgres válida. + +--- + +### Task 2: Workflow de exemplo "Agendamento - GChat - ClinicAll (exemplo)" + +**Interfaces:** +- Consumes: MCP Server de agendamento ClinicAll (`igaKjoHcPNYRAxPS`, path `mcp-server-clinicall`, 8 tools). +- Produces: workflow `Agendamento - GChat - ClinicAll (exemplo)`. + +- [ ] **Step 1: Criar o workflow (webhook + AI Agent + modelo + memória)** + +`n8n_create_workflow`: + +```json +{ + "name": "Agendamento - GChat - ClinicAll (exemplo)", + "nodes": [ + { + "id": "webhook", + "name": "Webhook GChat", + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [0, 0], + "parameters": { "httpMethod": "POST", "path": "agendamento-clinicall-exemplo", "responseMode": "lastNode", "options": {} } + }, + { + "id": "extrair-campos", + "name": "Extrair campos do webhook", + "type": "n8n-nodes-base.set", + "typeVersion": 3.4, + "position": [224, 0], + "parameters": { + "assignments": { + "assignments": [ + { "name": "sessionId", "type": "string", "value": "={{ $json.body.protocol }}" }, + { "name": "mensagem", "type": "string", "value": "={{ String($json.body.entrada || '').trim() }}" }, + { "name": "nomeContato", "type": "string", "value": "={{ $json.body.contactName }}" }, + { "name": "telefone", "type": "string", "value": "={{ $json.body.number }}" } + ] + } + } + }, + { + "id": "ai-agent", + "name": "AI Agent", + "type": "@n8n/n8n-nodes-langchain.agent", + "typeVersion": 2.1, + "position": [448, 0], + "parameters": { + "text": "={{ $json.mensagem }}", + "systemMessage": "Você é um assistente de agendamento de consultas médicas, via WhatsApp, para uma clínica que usa o sistema ClinicAll. Seu trabalho: 1) entender o que o paciente quer agendar (especialidade, convênio, profissional, procedimento), usando as tools especialidade, convenio, profissional e procedimento conforme necessário pra resolver os códigos certos; 2) confirmar/consultar o paciente com a tool paciente; 3) usar consultar_horarios para ver os horários livres de uma unidade+profissional — cada horário livre já é um registro existente, identificado por um idAgenda; 4) para concluir, chamar agendar passando EXATAMENTE o idAgenda do horário livre escolhido no passo anterior — agendar não cria um registro novo do zero, ele concilia (atualiza) esse mesmo idAgenda com os dados do paciente/procedimento/convênio. Nunca invente um idAgenda; 5) responda sempre em português, de forma clara e cordial." + } + }, + { + "id": "openai-chat-model", + "name": "OpenAI Chat Model", + "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", + "typeVersion": 1.3, + "position": [448, -160], + "parameters": { "model": { "mode": "id", "value": "gpt-4o-mini" }, "builtInTools": {}, "options": {} }, + "credentials": { "openAiApi": { "id": "29vMIDah5DTIhUYJ", "name": "GPT" } } + }, + { + "id": "memoria", + "name": "Memória da Sessão (Postgres)", + "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat", + "typeVersion": 1.4, + "position": [448, 160], + "parameters": { "sessionIdType": "customKey", "sessionKey": "={{ $json.sessionId }}", "tableName": "n8n_chat_histories", "contextWindowLength": 20 }, + "credentials": { "postgres": { "id": "PLACEHOLDER_SEM_CREDENCIAL", "name": "Postgres - (sem cliente real)" } } + } + ], + "connections": { + "Webhook GChat": { "main": [[{ "node": "Extrair campos do webhook", "type": "main", "index": 0 }]] }, + "Extrair campos do webhook": { "main": [[{ "node": "AI Agent", "type": "main", "index": 0 }]] }, + "OpenAI Chat Model": { "ai_languageModel": [[{ "node": "AI Agent", "type": "ai_languageModel", "index": 0 }]] }, + "Memória da Sessão (Postgres)": { "ai_memory": [[{ "node": "AI Agent", "type": "ai_memory", "index": 0 }]] } + } +} +``` + +Anotar o `id` retornado. + +- [ ] **Step 2: Conectar o MCP Client Tool com todas as tools do MCP ClinicAll** + +`n8n_update_partial_workflow`, numa única chamada atômica: + +```json +{ + "id": "", + "operations": [ + { + "type": "addNode", + "node": { + "id": "mcp-client-clinicall-agendamento", + "name": "MCP ClinicAll Agendamento", + "type": "@n8n/n8n-nodes-langchain.mcpClientTool", + "typeVersion": 1, + "position": [448, 320], + "parameters": { + "endpointUrl": "https://devn8n.gtigrupo.com.br/mcp/mcp-server-clinicall", + "authentication": "none", + "include": "all" + } + } + }, + { "type": "addConnection", "source": "MCP ClinicAll Agendamento", "target": "AI Agent", "sourceOutput": "ai_tool", "targetIndex": 0 } + ] +} +``` + +- [ ] **Step 3: Validar** + +`n8n_validate_workflow`. Esperado: `errorCount: 0`. + +- [ ] **Step 4: Deixar inativo** + +Não ativar — sem clínica ClinicAll real nem credencial Postgres válida. + +--- + +### Task 3: Workflow de exemplo "Agendamento - GChat - SysLife (exemplo)" + +**Interfaces:** +- Consumes: MCP Server de agendamento SysLife (`TYu78UqIUr2yCBHK`, path `mcp-server-syslife`, 7 tools). +- Produces: workflow `Agendamento - GChat - SysLife (exemplo)`. + +- [ ] **Step 1: Criar o workflow (webhook + AI Agent + modelo + memória)** + +`n8n_create_workflow`: + +```json +{ + "name": "Agendamento - GChat - SysLife (exemplo)", + "nodes": [ + { + "id": "webhook", + "name": "Webhook GChat", + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [0, 0], + "parameters": { "httpMethod": "POST", "path": "agendamento-syslife-exemplo", "responseMode": "lastNode", "options": {} } + }, + { + "id": "extrair-campos", + "name": "Extrair campos do webhook", + "type": "n8n-nodes-base.set", + "typeVersion": 3.4, + "position": [224, 0], + "parameters": { + "assignments": { + "assignments": [ + { "name": "sessionId", "type": "string", "value": "={{ $json.body.protocol }}" }, + { "name": "mensagem", "type": "string", "value": "={{ String($json.body.entrada || '').trim() }}" }, + { "name": "nomeContato", "type": "string", "value": "={{ $json.body.contactName }}" }, + { "name": "telefone", "type": "string", "value": "={{ $json.body.number }}" } + ] + } + } + }, + { + "id": "ai-agent", + "name": "AI Agent", + "type": "@n8n/n8n-nodes-langchain.agent", + "typeVersion": 2.1, + "position": [448, 0], + "parameters": { + "text": "={{ $json.mensagem }}", + "systemMessage": "Você é um assistente de agendamento de consultas médicas, via WhatsApp, para uma clínica que usa o sistema SysLife. Siga esta ordem: 1) use a tool especialidade para identificar a especialidade desejada pelo paciente; 2) use a tool medico para listar os médicos daquela especialidade/origem; 3) em qualquer ordem, use as tools convenio, paciente e procedimento conforme necessário pra resolver os códigos de convênio/plano, os dados do paciente (CPF, matrícula ou celular) e o procedimento/valor; 4) use consultar_horarios (tool Horario) para ver os horários disponíveis do médico escolhido; 5) para concluir, chame agendar com todos os códigos já resolvidos nos passos anteriores (data, hora, número da consulta, origem, paciente, convênio, plano, tabela de procedimento, procedimento, médico, especialidade, celular) — nunca invente um código que não veio de uma das tools anteriores; 6) responda sempre em português, de forma clara e cordial." + } + }, + { + "id": "openai-chat-model", + "name": "OpenAI Chat Model", + "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", + "typeVersion": 1.3, + "position": [448, -160], + "parameters": { "model": { "mode": "id", "value": "gpt-4o-mini" }, "builtInTools": {}, "options": {} }, + "credentials": { "openAiApi": { "id": "29vMIDah5DTIhUYJ", "name": "GPT" } } + }, + { + "id": "memoria", + "name": "Memória da Sessão (Postgres)", + "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat", + "typeVersion": 1.4, + "position": [448, 160], + "parameters": { "sessionIdType": "customKey", "sessionKey": "={{ $json.sessionId }}", "tableName": "n8n_chat_histories", "contextWindowLength": 20 }, + "credentials": { "postgres": { "id": "PLACEHOLDER_SEM_CREDENCIAL", "name": "Postgres - (sem cliente real)" } } + } + ], + "connections": { + "Webhook GChat": { "main": [[{ "node": "Extrair campos do webhook", "type": "main", "index": 0 }]] }, + "Extrair campos do webhook": { "main": [[{ "node": "AI Agent", "type": "main", "index": 0 }]] }, + "OpenAI Chat Model": { "ai_languageModel": [[{ "node": "AI Agent", "type": "ai_languageModel", "index": 0 }]] }, + "Memória da Sessão (Postgres)": { "ai_memory": [[{ "node": "AI Agent", "type": "ai_memory", "index": 0 }]] } + } +} +``` + +Anotar o `id` retornado. + +- [ ] **Step 2: Conectar o MCP Client Tool com todas as tools do MCP SysLife** + +`n8n_update_partial_workflow`, numa única chamada atômica: + +```json +{ + "id": "", + "operations": [ + { + "type": "addNode", + "node": { + "id": "mcp-client-syslife-agendamento", + "name": "MCP SysLife Agendamento", + "type": "@n8n/n8n-nodes-langchain.mcpClientTool", + "typeVersion": 1, + "position": [448, 320], + "parameters": { + "endpointUrl": "https://devn8n.gtigrupo.com.br/mcp/mcp-server-syslife", + "authentication": "none", + "include": "all" + } + } + }, + { "type": "addConnection", "source": "MCP SysLife Agendamento", "target": "AI Agent", "sourceOutput": "ai_tool", "targetIndex": 0 } + ] +} +``` + +- [ ] **Step 3: Validar** + +`n8n_validate_workflow`. Esperado: `errorCount: 0`. + +- [ ] **Step 4: Deixar inativo** + +Não ativar — sem clínica SysLife real nem credencial Postgres válida. + +--- + +### Task 4: Atualizar o runbook e commit + +**Interfaces:** +- Consumes: os 3 workflow ids criados nas Tasks 1–3. + +- [ ] **Step 1: Adicionar seção 22 ao runbook** + +Adicionar em `docs/n8n-agendamento-runbook.md`, após a seção 21, uma +seção "22. Workflows de exemplo de AI Agent para Agendamento (Klingo, +ClinicAll, SysLife)" cobrindo: o motivo (os MCP Servers de agendamento +existiam sem workflow de agente cliente, diferente da confirmação), +os 3 ids de workflow criados, a correção do número real de tools de +cada provider (Klingo 2, ClinicAll 8, SysLife 7 — não os 8 do Klingo +Telefonia que tinha sido citado por engano antes), a limitação real do +Klingo (`SLOT_MAPPING_UNAVAILABLE`) e como o `systemMessage` lida com +ela, e o status "estrutura pronta, inativos de propósito — falta +clínica real de qualquer um dos três providers". + +- [ ] **Step 2: Atualizar a tabela da seção 21 (opcional, se fizer sentido)** + +Adicionar uma linha na tabela comparativa da seção 21 com o id do +workflow de agendamento de exemplo de cada provider, complementando as +linhas já existentes de confirmação — só se isso não deixar a tabela +poluída; caso contrário, deixar a seção 22 autocontida sem tocar na 21. + +- [ ] **Step 3: Commit** + +```bash +cd "D:\PROJETOS\KLINGO-CLINICAL-SYSLIFE-GCHAT-AGENDAMENTO" +git add docs/n8n-agendamento-runbook.md +git commit -m "docs: registra workflows de exemplo de AI Agent para agendamento (Klingo, ClinicAll, SysLife) + +Co-Authored-By: Claude Sonnet 5 " +``` + +--- + +## Observação sobre execução + +Mesma disciplina dos planos anteriores: validar +(`n8n_validate_workflow`) depois de cada workflow criado/modificado. +Os 3 workflows deste plano ficam **intencionalmente inativos** ao +final — sem clínica real de nenhum dos três providers e sem credencial +Postgres válida, ativá-los só geraria execuções com erro. O +`systemMessage` do Klingo é o único que precisa de atenção redobrada: +ele documenta uma limitação real da API (não um bug desta +implementação) — não simplificar nem remover esse aviso ao escrever o +texto final.