Modelos de IA cobram por token — e token é, basicamente, pedaço de texto. Quando o mesmo parágrafo de instrução aparece duas ou três vezes no payload, você paga por ele duas ou três vezes, sem nenhum benefício. Esta ferramenta analisa o payload e devolve um relatório detalhado: onde estão as repetições, quantos caracteres estão sendo desperdiçados e quanto seria economizado removendo as cópias extras.

O campo hasMeaningfulDuplication é o atalho principal: se for true, há repetição relevante no payload. Use-o como condição para logar ou agir — sem precisar examinar o restante da resposta.

Endpoint

POST /api/externalAPIs/public/payloadDedup/analyzePayload

Parâmetros

payload
object | string
required

O payload que você quer analisar. Aceita dois formatos:

  • Mensagens (padrão)

  • Texto direto

Array de mensagens no mesmo formato usado pela OpenAI. É o formato padrão deste codebase.

{
  "messages": [
    { "role": "system", "content": "<system_instructions>...</system_instructions>" },
    { "role": "user",   "content": "<dialogue_instructions>...</dialogue_instructions>" }
  ]
}
options.minBlockLength
number
default: "100"

Tamanho mínimo de um trecho para ser analisado. Trechos muito curtos (como títulos ou rótulos) são ignorados automaticamente.

options.normalizeWhitespace
boolean
default: "true"

Quando ativado, ignora diferenças de espaçamento na comparação. Dois trechos idênticos exceto por quebras de linha extras são tratados como duplicata.

options.semanticNormalization
boolean
default: "true"

Quando ativado, ignora maiúsculas/minúsculas, acentos, formatação markdown e pontuação na comparação. Dois trechos com o mesmo conteúdo semântico — mesmo que escritos de formas levemente diferentes — são tratados como duplicata.

options.minSavingsPercent
number
default: "3"

Percentual mínimo de economia para a flag hasMeaningfulDuplication ser marcada como true. Abaixo desse limite, a duplicação é considerada irrelevante.

options.compact
boolean
default: "false"

Quando true, retorna apenas as cinco métricas globais — sem duplicateGroups nem summary. Ideal para checks rápidos em produção ou análise em lote onde o detalhamento completo não é necessário.

Exemplo

curl --location 'localhost:8080/api/externalAPIs/public/payloadDedup/analyzePayload' \
--header 'Authorization: Bearer {{TOKEN}}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "payload": {
    "messages": [
      {
        "role": "system",
        "content": "<system_instructions>\n<context>\nSomos um assistente de captura de dados de formularios a partir de conversas com IA. Um JSON Schema sera fornecido com as diretrizes de extracao para cada propriedade. Nao invente nem assuma nenhuma informacao.\n</context>\n<instruction>\n- Analise cuidadosamente todo o conteudo fornecido.\n- Siga ESTRITAMENTE os ENUMs definidos no schema.\n- Se um campo tiver ENUM, retorne apenas um dos valores listados exatamente como estao.\n- NUNCA invente ou assuma informacoes nao fornecidas.\n</instruction>\n<manager_instructions>\nNUNCA invente ou preencha valores quando o dado nao estiver explicito no dialogo (incluindo resumos fieis em mensagens de sistema). Isso vale inclusive para campos com valores permitidos (listas fechadas): nao escolha um item da lista sem evidencia no dialogo. Se um campo nao for mencionado ou nao puder ser extraido com certeza, retorne null para esse campo. Nao use placeholders como none@none.com ou 0000000000.\n\nSomente confirme uma escolha se os quatro campos (Campus + Escola + Modalidade + Curso) existirem juntos na mesma linha da tabela oficial. Nunca combine campos de linhas diferentes. Se o contexto permitir mais de uma linha possivel, considere o resultado ambiguo e retorne null para os campos incertos.\n</manager_instructions>\n</system_instructions>"
      },
      {
        "role": "user",
        "content": "<dialogue_instructions>\nA seguir o dialogo entre usuario e o agente de IA que devera ser analisado:\n[{\"role\":\"user\",\"content\":\"Quero me matricular em Engenharia de Software presencial na PUCPR Curitiba.\"},{\"role\":\"assistant\",\"content\":\"Confirmo: Campus Curitiba, EP - Escola Politecnica, Graduacao Presencial, Engenharia de Software. Esta correto?\"}]\n\nNUNCA invente ou preencha valores quando o dado nao estiver explicito no dialogo (incluindo resumos fieis em mensagens de sistema). Isso vale inclusive para campos com valores permitidos (listas fechadas): nao escolha um item da lista sem evidencia no dialogo. Se um campo nao for mencionado ou nao puder ser extraido com certeza, retorne null para esse campo. Nao use placeholders como none@none.com ou 0000000000.\n</dialogue_instructions>\n<previous_form_values>\nEstado ja persistido no sistema para o formulario:\n- campus: Curitiba\n- escola: EP - Escola Politecnica\n- modalidade: Graduacao Presencial\n- curso: Engenharia de Software\n\nSomente confirme uma escolha se os quatro campos (Campus + Escola + Modalidade + Curso) existirem juntos na mesma linha da tabela oficial. Nunca combine campos de linhas diferentes. Se o contexto permitir mais de uma linha possivel, considere o resultado ambiguo e retorne null para os campos incertos.\n</previous_form_values>"
      }
    ]
  },
  "options": {
    "minBlockLength": 100,
    "minSavingsPercent": 3
  }
}'

Resposta

{
  "totalCharacters": 2460,
  "duplicatedCharacters": 1470,
  "savingsCharacters": 735,
  "savingsPercent": 29.88,
  "hasMeaningfulDuplication": true,

  "duplicateGroups": [
    {
      "text": "NUNCA invente ou preencha valores quando o dado nao estiver explicito no dialogo (incluindo resumos fieis em mensagens de sistema). Isso vale inclusive para campos com valores permitidos (listas fechadas): nao escolha um item da lista sem evidencia no dialogo. Se um campo nao for mencionado ou nao puder ser extraido com certeza, retorne null para esse campo. Nao use placeholders como none@none.com ou 0000000000.",
      "textPreview": "NUNCA invente ou preencha valores quando o dado nao estiver explicito no dialogo (incluindo resumos f",
      "charCount": 425,
      "occurrenceCount": 2,
      "wastedCharacters": 425,
      "occurrences": [
        { "messageIndex": 0, "role": "system", "tagPath": ["system_instructions", "manager_instructions"], "charOffset": 412 },
        { "messageIndex": 1, "role": "user",   "tagPath": ["dialogue_instructions"], "charOffset": 378 }
      ]
    },
    {
      "text": "Somente confirme uma escolha se os quatro campos (Campus + Escola + Modalidade + Curso) existirem juntos na mesma linha da tabela oficial. Nunca combine campos de linhas diferentes. Se o contexto permitir mais de uma linha possivel, considere o resultado ambiguo e retorne null para os campos incertos.",
      "textPreview": "Somente confirme uma escolha se os quatro campos (Campus + Escola + Modalidade + Curso) existirem ju",
      "charCount": 305,
      "occurrenceCount": 2,
      "wastedCharacters": 305,
      "occurrences": [
        { "messageIndex": 0, "role": "system", "tagPath": ["system_instructions", "manager_instructions"], "charOffset": 840 },
        { "messageIndex": 1, "role": "user",   "tagPath": ["previous_form_values"], "charOffset": 528 }
      ]
    }
  ],

  "summary": {
    "messageCount": 2,
    "blockCount": 9,
    "duplicateGroupCount": 2,
    "recommendation": "~735 chars duplicados em 2 grupos (29.88% do payload)"
  }
}

Campos da Resposta

totalCharacters
integer

Total de caracteres analisados no payload completo.

duplicatedCharacters
integer

Quantos desses caracteres aparecem em trechos repetidos.

savingsCharacters
integer

Quantos caracteres seriam eliminados mantendo só uma cópia de cada trecho repetido.

savingsPercent
number

Percentual de economia sobre o total. Ex: 12.40 significa que 12,4% do payload é repetição.

hasMeaningfulDuplication
boolean

true quando a economia supera o limite mínimo configurado. Use este campo como flag principal para decidir se vale agir.

duplicateGroups
array

Lista de grupos de trechos repetidos, ordenada do maior desperdício para o menor. Omitido quando compact: true.

summary
object

Resumo agregado, ideal para logging rápido. Omitido quando compact: true.

Erros

CódigoDescrição
400payload ausente ou em formato inválido
500Erro interno do servidor