"Por que essa NF-e foi rejeitada com codigo 539?" Em vez do consultor abrir 5 telas, ler 3 manuais e ligar pro suporte, ele digita a duvida no Protheus e o assistente responde — em portugues claro, com referencia ao manual oficial e link pra rotina afetada.

E possivel hoje, custa pouco, e este artigo mostra exatamente como construir.

O caso de uso

Empresa B com 40 consultores fiscais usando Protheus. Cada um abre ~12 chamados/mes para o time de TI sobre "como configurar regra X no FISA170", "o que significa erro Y na NFe", "como simular cenario Z". Custo do TI absorvendo isso: ~480h/mes. Solucao: assistente embutido no Protheus que resolve 70% dos casos antes de virar chamado.

Arquitetura ponta a ponta

sequenceDiagram actor U as Usuario Protheus participant P as Protheus
(AdvPL/TLPP) participant M as Middleware Node
(API Gateway) participant L as LLM
(OpenAI/Anthropic) participant K as Knowledge Base
(opcional - RAG) U->>P: Pergunta no campo
"como ajustar regra X?" P->>M: POST /assistant
{user, query, context} M->>M: Auth + rate limit
+ log (audit) M->>K: Busca docs relevantes
(opcional) K-->>M: Top 3 chunks M->>L: chat.completions
system + context + query L-->>M: Resposta em PT-BR M->>M: Sanitiza output
+ filtra dados sensiveis M-->>P: { answer, sources, tokens } P-->>U: Mostra na tela
+ link pra rotina

Por que middleware Voce nao chama OpenAI/Anthropic direto do Protheus. Razoes: (1) chave de API nao deve viver no Protheus, (2) precisa de rate limit por usuario, (3) precisa de audit pra LGPD, (4) prompt engineering muda sem precisar buildar RPO.

Endpoint AdvPL/TLPP que chama o middleware

No Protheus, criamos uma User Function que envia a pergunta ao middleware:

#include "totvs.ch"
#include "tlpp-core.th"

User Function ARCHASK()
    Local cQuery    := Space(255)
    Local cAnswer   := ""
    Local oRest     := Nil
    Local cBody     := ""
    Local cUrl      := SuperGetMv("MV_AIURL", .F., "https://ai.archtecgroup.com.br/assistant")
    Local cToken    := SuperGetMv("MV_AITOKEN", .F., "")
    Local oResponse := JsonObject():New()

    // Tela simples pra usuario digitar pergunta
    @ 0,0 To 200,500 Dialog oDlg Title "Assistente ArchTec"
    @ 010,010 Get cQuery Size 240,10
    @ 030,010 Button "Perguntar" Size 60,15 Action _AskAI()
    Activate Dialog oDlg Centered
Return Nil

Static Function _AskAI()
    cBody := '{"user":"' + AllTrim(cUserName) + ;
             '","module":"' + cModulo + ;
             '","query":"' + EncodeUTF8(AllTrim(cQuery)) + '"}'

    oRest := FwRest():New(cUrl)
    oRest:setPath("/")
    oRest:setPostParams(cBody)
    oRest:setHeader("Authorization", "Bearer " + cToken)
    oRest:setHeader("Content-Type", "application/json; charset=UTF-8")

    If oRest:Post()
        oResponse:fromJson(oRest:getResult())
        cAnswer := oResponse["answer"]
        MsgInfo(cAnswer, "Resposta")
    Else
        MsgStop("Falha ao consultar IA: " + oRest:getLastError(), "Erro")
    EndIf
Return

Middleware Node (API Gateway pra IA)

Servidor leve que recebe do Protheus, autentica, injeta system prompt, chama LLM, sanitiza:

// middleware/server.js
const express = require('express');
const Anthropic = require('@anthropic-ai/sdk');
const rateLimit = require('express-rate-limit');

const app = express();
app.use(express.json());

const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

// Rate limit por usuario Protheus
app.use('/assistant', rateLimit({
    windowMs: 60_000,
    max: 30,
    keyGenerator: (req) => req.body?.user || req.ip
}));

// Bearer auth simples (token compartilhado entre Protheus e middleware)
app.use((req, res, next) => {
    const token = req.headers.authorization?.replace('Bearer ', '');
    if (token !== process.env.PROTHEUS_TOKEN) {
        return res.status(401).json({ error: 'unauthorized' });
    }
    next();
});

const SYSTEM_PROMPT = `Voce e um assistente especializado em TOTVS Protheus,
focado em duvidas tecnicas sobre Configurador de Tributos (CFGTRIB/FISA170),
emissao de NF-e/NFC-e e modulos fiscais. Responda em portugues brasileiro,
em ate 5 paragrafos. Quando relevante, cite a rotina Protheus exata
(ex: FISA170, MATA001) e nunca invente parametros que voce nao tem certeza.`;

app.post('/assistant', async (req, res) => {
    const { user, module, query } = req.body;
    if (!query || query.length < 5) {
        return res.status(400).json({ error: 'query muito curta' });
    }

    try {
        const result = await anthropic.messages.create({
            model: 'claude-sonnet-4-6',
            max_tokens: 1024,
            system: SYSTEM_PROMPT,
            messages: [
                { role: 'user', content: `[Modulo: ${module}] ${query}` }
            ]
        });

        const answer = result.content[0].text;

        // Audit pra LGPD
        await logAudit({ user, module, query, tokens: result.usage });

        res.json({
            answer,
            tokens_in: result.usage.input_tokens,
            tokens_out: result.usage.output_tokens
        });
    } catch (err) {
        console.error('LLM error:', err.message);
        res.status(500).json({ error: 'falha ao consultar assistente' });
    }
});

app.listen(8080, () => console.log('AI middleware rodando :8080'));

Custos reais

Com Claude Sonnet 4.6 (modelo bom-custo) a precificacao em maio/2026:

ItemPor consulta1.000 consultas/mes
Tokens entrada (~500)~US$ 0.0015US$ 1.50
Tokens saida (~400)~US$ 0.006US$ 6.00
Total LLMUS$ 0.0075US$ 7.50
Hosting middleware (VPS basico)US$ 5.00
Total mes~US$ 13 (~R$ 70)

Se o assistente resolve 700 chamados/mes (cada chamado custaria ~30min de TI = ~R$ 50 de custo direto), economia liquida ~R$ 35.000/mes. ROI absurdo.

LGPD: o que voce precisa fazer

Cuidado Mesmo "duvidas tecnicas" podem vazar dados pessoais sem voce perceber: usuario digita "por que NF-e do CPF 123.456.789-00 foi rejeitada?" e voce envia pra OpenAI/Anthropic. Isso e tratamento de dado pessoal.

Mitigacoes obrigatorias:

  1. Sanitizacao na entrada: regex pra mascarar CPF, CNPJ, RG, email, telefone antes de enviar pro LLM.
  2. Anthropic Zero Data Retention (ZDR): contratual, garante que prompts nao sao armazenados pra treino. OpenAI tem equivalente em planos enterprise.
  3. Termo de uso interno: usuario aceita que duvidas sao processadas por IA externa.
  4. Audit log imutavel: quem perguntou o que, quando.
  5. Region pinning: solicite servidor LLM em regiao com nivel de protecao adequado (LGPD-compliant).

Proximos passos: RAG com base de conhecimento

O proximo nivel e injetar contexto da sua empresa. Em vez do LLM responder com conhecimento generico, ele recebe trechos relevantes do seu wiki/documentacao antes de responder.

flowchart LR A[Pergunta] --> B[Embedding
texto-vetor] B --> C[(pgvector
busca top 3)] C --> D[Chunks relevantes] D --> E[LLM com contexto] E --> F[Resposta especifica] style E fill:#3B82F6,color:#fff

Stack recomendada: Postgres + pgvector (ja temos PG no Protheus), embeddings com text-embedding-3-small da OpenAI (US$ 0.02/1M tokens — pratico free), retrieval top-K, e o LLM responde com base nesse contexto.

Esse passo extra e relevante quando voce quer que o assistente saiba especificamente as customizacoes do seu Protheus. Sem isso, o assistente sabe TOTVS padrao, nao sabe sua TES interna chamada 510_REVENDA_ESPECIAL.

Fale conosco se quer um POC do assistente fiscal rodando em 2 semanas no seu ambiente.

Sua empresa esta preparada?

Nossa consultoria especializada em TOTVS Protheus pode acelerar sua adequacao.

Falar com Especialista