Delphi에서 gRPC로 Google Cloud Natural Language 사용하기

· 컴포넌트

Google Cloud Natural Language는 비정형 텍스트를 읽고 그 안에 무엇이 있는지 알려줍니다. 문서의 전반적인 감정을 측정하고, 언급된 사람, 장소, 조직을 엔티티로 추출하고, 텍스트를 콘텐츠 분류 체계로 분류합니다. sgcWebSockets Enterprise 에디션은 TsgcGRPCClient 위에 형식화된 Natural Language gRPC 클라이언트를 함께 제공하므로, 외부 gRPC 런타임 없이 Delphi와 C++Builder에서 바로 language.googleapis.com 서비스에 접근할 수 있습니다.

작동 방식

Natural Language API는 gRPC 서비스로 제공되며, gRPC는 HTTP/2 위에 프레이밍된 Protocol Buffers 메시지입니다. sgcWebSockets는 이미 완전한 HTTP/2 스택을 함께 제공하므로, gRPC 클라이언트는 TLS를 통해 language.googleapis.com:443을 가리키는 TsgcHTTP2Client 전송 위에 위치합니다. TsgcGRPCClient는 프레이밍, 콘텐츠 타입, 상태 트레일러를 처리하고, 형식화된 유닛 sgcGRPC_Google_Language는 요청 및 응답 메시지를 처리합니다.

각 요청은 문서를 감쌉니다. 분석할 텍스트와 그 타입(일반 텍스트 또는 HTML), 그리고 선택적 언어 힌트입니다. 형식화된 클래스는 그 문서를 API가 기대하는 정확한 Protocol Buffers 와이어 레이아웃으로 직렬화하고, 응답을 바로 읽을 수 있는 속성으로 다시 파싱합니다. protobuf를 직접 조립하거나 필드 번호를 쫓을 필요가 전혀 없습니다.

인증은 Google Cloud 서비스 계정을 사용합니다. 자체 서명된 서비스 계정 JWT를 bearer 토큰으로 교환하여 모든 호출에 gRPC 메타데이터로 전송합니다. 그 토큰은 audience에 바인딩되므로, language.googleapis.com이 수락하도록 JWT는 Natural Language 엔드포인트를 대상으로 발급됩니다.

클라이언트 설정하기

Natural Language 호스트용 HTTP/2 전송을 만든 다음, TsgcGRPCClient를 거기에 연결하고 바이너리 protobuf 콘텐츠 타입을 선택합니다. 서비스 계정에서 획득한 bearer 토큰은 표준 authorization 헤더로 DefaultMetadata에 추가되어 모든 요청에 따라갑니다.

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;

감정 분석하기

감정 분석은 -1.0(부정)에서 +1.0(긍정)까지의 감정 점수(score)와, 문서가 담고 있는 감정 콘텐츠의 양을 반영하는 크기(magnitude)를 보고합니다. TsgcGRPCLanguageAnalyzeSentimentRequest를 만들고, 문서 내용을 설정하고, LanguageService에서 AnalyzeSentiment 메서드를 호출한 다음, 응답 바이트를 형식화된 응답에 로드합니다.

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;

엔티티 추출하기

엔티티 분석은 문서가 다루는 핵심적인 대상을 반환합니다. 응답은 엔티티의 목록이며, 각 엔티티는 Name, EntityType(사람, 위치, 조직 등), 그리고 엔티티가 텍스트에서 얼마나 중심적인지 순위를 매기는 Salience 점수를 가집니다. 형식화된 응답은 순회할 수 있는 인덱싱된 목록을 제공합니다.

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;

텍스트 분류하기

콘텐츠 분류는 문서를 Google의 카테고리 분류 체계로 정렬하며, 각각 /Computers & Electronics/Software 같은 NameConfidence 값을 가진 카테고리 목록을 반환합니다. 패턴은 동일합니다. TsgcGRPCLanguageClassifyTextRequest를 만들고, ClassifyText를 호출한 다음, CategoryCountCategory(i)TsgcGRPCLanguageClassifyTextResponse에서 카테고리를 읽습니다. 분류는 잘 작동하려면 어느 정도 분량의 텍스트가 필요하므로, 한 문장 이상을 공급하세요.

제공 범위

Natural Language gRPC 클라이언트는 sgcWebSockets Enterprise 에디션의 일부이며 Delphi와 C++Builder에서 Windows, macOS, Linux, iOS, Android에서 실행됩니다. 완전하고 바로 실행 가능한 샘플은 Demos\21.GRPC\14.Natural_Language에 있으며, 기반이 되는 클라이언트는 gRPC Client 제품 페이지에 문서화되어 있습니다.

질문이나 의견이 있으신가요? 문의하기. 코드를 작성한 사람들로부터 답변을 받게 됩니다.