Google Cloud Natural Language sobre gRPC no Delphi

· Componentes

O Google Cloud Natural Language lê texto não estruturado e diz o que há nele. Ele mede o sentimento geral de um documento, extrai as pessoas, lugares e organizações que menciona como entidades, e classifica o texto em uma taxonomia de conteúdo. A edição Enterprise do sgcWebSockets inclui um cliente Natural Language gRPC tipado sobre o TsgcGRPCClient, para que você possa alcançar o serviço language.googleapis.com diretamente do Delphi e do C++Builder sem nenhum runtime gRPC externo.

Como funciona

A API Natural Language é exposta como um serviço gRPC, e o gRPC são mensagens Protocol Buffers encapsuladas sobre HTTP/2. O sgcWebSockets já vem com uma pilha HTTP/2 completa, então o cliente gRPC se apoia em um transporte TsgcHTTP2Client apontado para language.googleapis.com:443 sobre TLS. O TsgcGRPCClient trata o enquadramento, o tipo de conteúdo e os trailers de status; a unidade tipada sgcGRPC_Google_Language trata as mensagens de requisição e resposta.

Cada requisição encapsula um documento: o texto a analisar mais seu tipo (texto simples ou HTML) e uma dica de idioma opcional. As classes tipadas serializam esse documento para o layout exato do protocolo Protocol Buffers que a API espera, e analisam a resposta de volta em propriedades prontas para leitura. Você nunca monta um protobuf à mão nem persegue números de campo.

A autenticação usa uma conta de serviço do Google Cloud. Um JWT autoassinado de conta de serviço é trocado por um token bearer, que é então enviado como metadado gRPC em cada chamada. Como esse token é vinculado à audiência, o JWT é emitido para o endpoint do Natural Language para que seja aceito por language.googleapis.com.

Configurando o cliente

Crie um transporte HTTP/2 para o host do Natural Language, então anexe um TsgcGRPCClient a ele e selecione o tipo de conteúdo protobuf binário. O token bearer obtido da conta de serviço é adicionado ao DefaultMetadata como um cabeçalho authorization padrão, para que acompanhe cada requisição.

uses
  sgcHTTP2_Client, sgcGRPC_Client, sgcGRPC_Types, sgcGRPC_Google_Language;

var
  HTTP2: TsgcHTTP2Client;
  GRPC: TsgcGRPCClient;
begin
  HTTP2 := TsgcHTTP2Client.Create(nil);
  HTTP2.Host := 'language.googleapis.com';
  HTTP2.Port := 443;
  HTTP2.TLS  := True;

  GRPC := TsgcGRPCClient.Create(nil);
  GRPC.Client := HTTP2;
  GRPC.ChannelOptions.ContentType := grpcProto;
  GRPC.ChannelOptions.Compression := grpcNoCompression;

  // bearer token from the service-account JWT exchange
  GRPC.DefaultMetadata.Add('authorization', 'Bearer ' + Token);

  HTTP2.Active := True;
end;

Analisando sentimento

A análise de sentimento reporta uma pontuação emocional de -1.0 (negativa) a +1.0 (positiva) e uma magnitude que reflete quanto conteúdo emocional o documento carrega. Monte um TsgcGRPCLanguageAnalyzeSentimentRequest, defina o conteúdo do documento, chame o método AnalyzeSentiment no LanguageService, então carregue os bytes da resposta em uma resposta tipada.

var
  oRequest: TsgcGRPCLanguageAnalyzeSentimentRequest;
  oResponse: TsgcGRPCResponse;
  oResult: TsgcGRPCLanguageAnalyzeSentimentResponse;
begin
  oRequest := TsgcGRPCLanguageAnalyzeSentimentRequest.Create;
  try
    oRequest.Document.DocType := 1; // PLAIN_TEXT
    oRequest.Document.Content := 'sgcWebSockets makes gRPC in Delphi easy.';

    oResponse := GRPC.Call('google.cloud.language.v1.LanguageService',
      'AnalyzeSentiment', oRequest.ToBytes);

    if oResponse.StatusCode = grpcOK then
    begin
      oResult := TsgcGRPCLanguageAnalyzeSentimentResponse.Create;
      try
        oResult.LoadFromBytes(oResponse.Data);
        ShowMessage('Score: ' + FloatToStr(oResult.DocumentSentiment.Score) +
          '  Magnitude: ' + FloatToStr(oResult.DocumentSentiment.Magnitude));
      finally
        oResult.Free;
      end;
    end;
  finally
    oRequest.Free;
  end;
end;

Extraindo entidades

A análise de entidades retorna as coisas relevantes de que um documento trata. A resposta é uma lista de entidades, cada uma com um Name, um EntityType (pessoa, local, organização e assim por diante) e uma pontuação de Salience que classifica quão central a entidade é para o texto. A resposta tipada fornece uma lista indexada para você percorrer.

var
  oRequest: TsgcGRPCLanguageAnalyzeEntitiesRequest;
  oResponse: TsgcGRPCResponse;
  oResult: TsgcGRPCLanguageAnalyzeEntitiesResponse;
  i: Integer;
begin
  oRequest := TsgcGRPCLanguageAnalyzeEntitiesRequest.Create;
  try
    oRequest.Document.DocType := 1; // PLAIN_TEXT
    oRequest.Document.Content := Memo1.Text;

    oResponse := GRPC.Call('google.cloud.language.v1.LanguageService',
      'AnalyzeEntities', oRequest.ToBytes);

    oResult := TsgcGRPCLanguageAnalyzeEntitiesResponse.Create;
    try
      oResult.LoadFromBytes(oResponse.Data);
      for i := 0 to oResult.EntityCount - 1 do
        Memo2.Lines.Add(oResult.Entity(i).Name + ' (type ' +
          IntToStr(oResult.Entity(i).EntityType) + ', salience ' +
          FloatToStr(oResult.Entity(i).Salience) + ')');
    finally
      oResult.Free;
    end;
  finally
    oRequest.Free;
  end;
end;

Classificando texto

A classificação de conteúdo organiza um documento na taxonomia de categorias do Google, retornando uma lista de categorias cada uma com um Name como /Computers & Electronics/Software e um valor de Confidence. O padrão é o mesmo: monte um TsgcGRPCLanguageClassifyTextRequest, chame ClassifyText, então leia as categorias de TsgcGRPCLanguageClassifyTextResponse com CategoryCount e Category(i). A classificação precisa de uma quantidade razoável de texto para funcionar bem, então forneça mais do que uma única frase.

Disponibilidade

O cliente Natural Language gRPC faz parte da edição Enterprise do sgcWebSockets e roda em Windows, macOS, Linux, iOS e Android, em Delphi e C++Builder. Um exemplo completo e pronto para executar está em Demos\21.GRPC\14.Natural_Language, e o cliente subjacente está documentado na página do produto gRPC Client.

Dúvidas ou comentários? Entre em contato. Você receberá uma resposta das pessoas que escreveram o código.