Ligações Internas Semânticas por IA: guia completo
Instalar, configurar e explorar as ligações internas semânticas por embeddings de IA: indexação, sugestões, âncoras, rollback e worker CLI.
Apresentação
O DataFirefly Ligações Internas Semânticas por IA (dfaisemanticlinks) constrói a ligação interna da sua loja PrestaShop a partir de embeddings vetoriais. Cada produto, categoria e página CMS é transformado em vetor por um fornecedor de IA (Mistral ou OpenAI), os vetores são comparados por semelhança de cosseno, e o módulo propõe ligações contextuais com âncoras extraídas verbatim do texto de origem. Valida as sugestões uma a uma ou em lote, e cada ligação inserida pode ser retirada cirurgicamente graças a um marcador único data-dfasl.
O módulo não faz nenhuma chamada de IA no front-office: as semelhanças são pré-calculadas e as ligações validadas são escritas diretamente nas descrições. Impacto no desempenho: zero.
Pré-requisitos
- PrestaShop 8.0 a 9.x (PrestaShop 1.7 não suportado)
- PHP 8.1, 8.2 ou 8.3
- MySQL 5.7+ / MariaDB 10.3+
- Uma chave API Mistral (console.mistral.ai) ou OpenAI (platform.openai.com)
- Acesso CLI recomendado para catálogos com mais de 1 000 entidades (cron)
Instalação
- Back-office → Módulos → Gestor de módulos → Instalar um módulo.
- Carregue
dfaisemanticlinks.zipe clique em Instalar. - O módulo cria 5 tabelas com o prefixo
dfasl_(embedding, queue, suggestion, inserted_link, job) e um menu Ligações IA com 4 separadores: Painel, Sugestões, Ligações inseridas, Parâmetros.
A desinstalação elimina de forma limpa as 5 tabelas e todas as variáveis de configuração DFASL_*. Exporte os seus dados antes se quiser conservá-los.
Configuração
1. Fornecedor de embeddings
Separador Parâmetros, primeiro bloco:
- Fornecedor: Mistral (mistral-embed, 1024 dimensões, por defeito, alojamento na UE) ou OpenAI (text-embedding-3-small, 1536 dimensões).
- Chave API: cole a chave do fornecedor selecionado.
- Testar a ligação: o botão envia uma cadeia de teste e mostra as dimensões recebidas. Valide sempre a chave aqui antes de lançar uma indexação.
Se mudar de fornecedor depois de uma indexação, as dimensões vetoriais mudam (1024 vs. 1536). O módulo convidá-lo-á a relançar um Reindexar tudo: os vetores antigos são sobrescritos, mas as ligações já inseridas permanecem.
2. Indexação
- Tipos indexados: produtos, categorias, páginas CMS, cada um ativável de forma independente.
- Comprimento mínimo (por defeito 200 caracteres): os conteúdos demasiado curtos depois da limpeza do HTML são ignorados.
- Tamanho do lote (por defeito 20): número de itens enviados por pedido à API. Uma única chamada de embedding por lote.
- Reindexação automática (por defeito ativada): cada modificação de produto/categoria/CMS recoloca a entidade na fila através de hooks. Desative-a temporariamente durante uma importação CSV massiva.
3. Sugestões e inserção
- Limiar de semelhança (por defeito 0,78): os pares abaixo do limiar são ignorados. Desça para 0,72 para mais sugestões, suba para 0,82 para mais rigor.
- Ligações máximas por página (por defeito 5): proteção contra a sobreotimização SEO.
- Estratégia de âncora: n-gramas otimizados (por defeito) ou título em bruto do destino.
Os embeddings do Mistral e do OpenAI são multilingues e funcionam bem em português. A extração de âncoras trabalha por n-gramas literais: pense em escrever descrições que retomem naturalmente os títulos dos seus produtos e categorias, sem os quais o módulo recorre ao título em bruto do destino.
Primeira indexação
- Separador Painel → botão Reindexar tudo: todas as entidades ativas dos tipos ativados são colocadas na fila, em todos os idiomas ativos.
- Clique em Processar um lote tantas vezes quantas forem necessárias (catálogos pequenos), ou lance o worker CLI (ver mais abaixo).
- Em cada lote: extração + limpeza do texto, chamada de embedding em lote, armazenamento do vetor, e depois cálculo das sugestões por semelhança de cosseno.
O painel mostra continuamente: entidades totais, embeddings ativos, sugestões pendentes, ligações ativas, e os estados da fila (Pendente, Em curso, Terminado, Com erro).
Custo indicativo: 1 000 produtos em 3 idiomas ≈ 1,5 milhões de tokens ≈ 0,15 € (Mistral) ou 0,03 $ (OpenAI). A deteção por hash SHA-256 faz com que as reindexações seguintes só paguem os conteúdos realmente modificados.
Validar as sugestões
Separador Sugestões: tabela paginada com, por linha, a origem, o destino, a pontuação de semelhança, a âncora proposta, um excerto de contexto, e os botões Inserir / Rejeitar.
Escolher a âncora
O gerador de âncoras extrai os n-gramas (2 a 6 palavras) do título de destino presentes verbatim no corpo de origem, ordenados do mais longo para o mais curto. O menu pendente lista todos os candidatos; a opção Personalizar abre um campo livre. A âncora por defeito é o n-grama mais longo encontrado, em geral 3 ou 4 palavras que incluem as palavras-chave principais do destino.
Inserção
Na inserção, o módulo liga a primeira ocorrência da âncora que ainda não esteja numa etiqueta a, code ou pre (padrões PCRE SKIP/FAIL). Se não existir nenhuma ocorrência livre, é acrescentado no fundo da descrição um parágrafo de recurso com a classe dfasl-related. Cada ligação recebe um atributo data-dfasl com um identificador único de 36 caracteres.
Ações em massa
Marque várias linhas (caixa no cabeçalho da coluna para selecionar tudo) e depois Inserir a seleção ou Rejeitar a seleção. Paginação de 50 linhas.
Retirar uma ligação (rollback)
Separador Ligações inseridas: lista paginada das ligações ativas com origem, destino, âncora, data, colaborador. O botão Retirar elimina unicamente a etiqueta a data-dfasl com esse identificador: o texto da âncora fica intacto, nenhum outro elemento HTML é tocado, e a ligação é marcada como retirada na base de dados.
Worker CLI e cron
Para catálogos volumosos, use o worker em linha de comandos:
php modules/dfaisemanticlinks/bin/analyze.php [opções]
--shop=N: visa uma loja precisa (multiloja).--enqueue-all: recoloca todas as entidades ativas na fila antes de processar.--loop: repete enquanto restarem itens pendentes.--max-batches=N: limita o número de lotes por execução (segurança anti-runaway).--sleep=N: pausa em segundos entre lotes (limites de taxa da API).
Cron recomendado a cada 15 minutos:
*/15 * * * * php /caminho/para/prestashop/modules/dfaisemanticlinks/bin/analyze.php --loop --max-batches=50 --sleep=1
O worker reinicializa automaticamente as entradas bloqueadas no estado « Em curso » há mais de 30 minutos (falha de uma execução anterior), marca os itens falhados com a mensagem de erro da API, e continua a processar o resto do lote.
Reindexação automática
Os hooks actionObjectProductUpdateAfter, actionObjectCategoryUpdateAfter e actionObjectCmsUpdateAfter recolocam a entidade modificada na fila em todos os idiomas ativos. Os hooks de eliminação purgam embeddings e sugestões em cascata. O hash de conteúdo SHA-256 evita qualquer chamada à API se o texto real não tiver mudado (por exemplo uma simples alteração de stock).
Multiloja e multilingue
Os embeddings são delimitados por trio (entidade, idioma, loja). As sugestões nunca atravessam as fronteiras linguísticas nem de loja. A configuração (chave API, limiar, tipos indexados) pode diferir por loja através do seletor de contexto multiloja padrão do PrestaShop.
Resolução de problemas
« Chave API não configurada » ou erro no teste de ligação
Verifique que a chave corresponde ao fornecedor selecionado na lista pendente (uma chave Mistral não funciona com o provider OpenAI e vice-versa) e que dispõe de créditos. Os erros detalhados da API são registados em Parâmetros avançados → Registos (PrestaShopLogger).
Alguns itens ficam no estado « Em curso »
Um worker foi provavelmente interrompido. Espere 30 minutos (reposição automática) ou clique em Esvaziar a fila e relance depois Reindexar tudo.
Poucas ou nenhumas sugestões geradas
Três causas frequentes: limiar de semelhança demasiado alto (experimente 0,72), conteúdos demasiado curtos (abaixo do comprimento mínimo), ou catálogo demasiado homogéneo/heterogéneo. Verifique também que os tipos de entidades pretendidos estão ativados nos Parâmetros.
A âncora proposta é o título em bruto do destino
É o modo de recurso: nenhum n-grama do título de destino aparece verbatim no corpo de origem. Escolha uma âncora personalizada ou enriqueça a descrição de origem.
Arquitetura técnica
- PHP 8.1+ estrito, PSR-4 sob o namespace DataFirefly/AiSemanticLinks/ mapeado em
src/ - Controladores de administração legacy
ModuleAdminController(compatibilidade estável PS8/PS9) - Minicontentor de serviços próprio (independente do container Symfony)
- Vetores em BLOB float32 empacotado little-endian + norma L2 pré-calculada
- 5 tabelas:
dfasl_embedding,dfasl_queue,dfasl_suggestion,dfasl_inserted_link,dfasl_job - Código-fonte sem cifragem, pronto para override