在 Delphi 中通过 gRPC 使用 Google Cloud Natural Language

· 组件

Google Cloud Natural Language 读取非结构化文本并告诉你其中有什么。它衡量一篇文档的整体情感,将其提到的人物、地点和组织作为实体提取出来,并将文本分类到一个内容分类体系中。sgcWebSockets Enterprise 版本在 TsgcGRPCClient 之上提供了一个强类型 Natural Language gRPC 客户端,因此你可以直接从 Delphi 和 C++Builder 访问 language.googleapis.com 服务,无需任何外部 gRPC 运行时。

工作原理

Natural Language API 作为一个 gRPC 服务对外提供,而 gRPC 是通过 HTTP/2 封帧的 Protocol Buffers 消息。sgcWebSockets 已经提供了完整的 HTTP/2 栈,因此 gRPC 客户端运行在一个指向 language.googleapis.com:443、基于 TLS 的 TsgcHTTP2Client 传输之上。TsgcGRPCClient 处理封帧、内容类型和状态尾部;强类型单元 sgcGRPC_Google_Language 处理请求和响应消息。

每个请求都封装一个文档:要分析的文本加上它的类型(纯文本或 HTML)以及一个可选的语言提示。这些强类型类将该文档序列化为 API 期望的精确 Protocol Buffers 传输布局,并将回复解析回随取随用的属性。你从不需要手工组装 protobuf 或追查字段号。

身份验证使用一个 Google Cloud 服务账号。一个自签名的服务账号 JWT 被换取为一个 bearer 令牌,随后作为 gRPC 元数据随每个调用一起发送。由于该令牌是受众绑定的,因此该 JWT 是针对 Natural Language 端点签发的,以便被 language.googleapis.com 接受。

设置客户端

为 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(正面)的情绪分数,以及一个反映文档承载多少情绪内容的幅度。构建一个 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 的类别分类体系,返回一个类别列表,每个类别带有一个 Name(例如 /Computers & Electronics/Software)和一个 Confidence 值。模式是相同的:构建一个 TsgcGRPCLanguageClassifyTextRequest,调用 ClassifyText,然后用 CategoryCountCategory(i)TsgcGRPCLanguageClassifyTextResponse 读取类别。分类需要相当数量的文本才能良好工作,因此请喂给它多于一句话的内容。

可用性

Natural Language gRPC 客户端是 sgcWebSockets Enterprise 版本的一部分,可在 Windows、macOS、Linux、iOS 和 Android 上、在 Delphi 和 C++Builder 上运行。一个完整、开箱即用的示例位于 Demos\21.GRPC\14.Natural_Language,底层客户端的文档请见gRPC Client 产品页面

有问题或反馈?联系我们。你会收到来自编写这段代码的人的回复。