老胡茶室
老胡茶室

图文教程:配置 Google Cloud Vertex AI 与 Discovery Engine API 并排错

冯宇

为了更好的 AI 对话效果,老胡茶室决定改用 Google Cloud Vertex AI + Discovery Engine Rank 的方案提高 AI 对话的质量,但是在使用的过程中出现了各种各样的小问题。比如这几种:

  • Error: Unable to detect a Project Id in the current environment.
  • Permission ‘aiplatform.endpoints.predict’ denied on resource
  • Error: 7 PERMISSION_DENIED: Permission ‘discoveryengine.rankingConfigs.rank’ denied on resource

本文将以图文方式讲解如何启用 Vertex AI 与 Discovery Engine 以及设置对应的权限。以及相关的错误如何排错。

启用 API

要想使用 Vertex AI API 与 Discovery Engine API,需要在 Google Cloud 的 Project 设置中开启对应的 API。

打开 API 和服务页面

打开 API 列表

可以直接在 API 列表中分别搜索 Vertex AI 和 Discovery Engine 快速找到这两个 API 并启用

搜索要启用的API

启用 API

最终效果类似于下图所示:

最终效果

创建服务账号

NOTE: 由于 Vertex AI API 和 Discovery Engine API 均不支持 API KEY 方式认证,必须使用服务账号的方式认证,所以我们需要创建服务账号,并且保存好凭据,一旦丢失无法找回,只能重新生成。

生成服务账号的方式可以在 API 和服务 这个页面左边的 凭据 进入,操作如下图所示:

凭据页面

创建服务账号

创建服务账号

重要:最重要的一步来了,建议上面的步骤选择 创建并继续,因为服务账号必须授权,否则一旦错过了,就只能在后续阶段手工授权了(后续排错内容会讲)。

完成创建服务账号

之后点击创建的服务账号,找到 密钥 选项卡,创建一个新的密钥,我们使用 JSON 格式:

创建密钥

保存密钥

至此整个 Google Cloud 配置部分已经完成,下面我们讲解如何在代码中使用。

示例代码

首先是 Vertex AI,我们以 nodejs 代码为例,可以直接参考官方示例。但是如果你的环境不方便将 JSON 文件打包到产品包中发布(比如 Vercel 在线构建源码并发布的流程),可以考虑将 JSON 文件内容注入到环境变量使用。

例如注入下面的环境变量:

GOOGLE_APPLICATION_CREDENTIALS_CONTENT={"type":"service_account","project_id":"...","private_key_id":"...","private_key":"-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n","client_email":"...",...}

可以通过直接 shell export 环境变量的形式(注意转义处理特殊字符)或者 .env 的形式注入,然后在代码中这么使用:

import { VertexAI } from "@google-cloud/vertexai";

const credentials = JSON.parse(
  process.env.GOOGLE_APPLICATION_CREDENTIALS_CONTENT
);
const projectId = credentials.project_id;

const vertexAI = new VertexAI({
  authOptions: {
    projectId: projectId,
    credentials: credentials,
  },
});

在 Langchain.js 中使用也是类似:

import { ChatVertexAI } from "@langchain/google-genai";

const credentials = JSON.parse(
  process.env.GOOGLE_APPLICATION_CREDENTIALS_CONTENT
);
const projectId = credentials.project_id;

const llm = new ChatVertexAI({
  authOptions: {
    projectId: projectId,
    credentials: credentials,
  },
});

对于 Discovery Engine API 也是类似的用法:

import { RankServiceClient } from "@google-cloud/discoveryengine";

const credentials = JSON.parse(
  process.env.GOOGLE_APPLICATION_CREDENTIALS_CONTENT
);
const projectId = credentials.project_id;
const location = "global";

const client = new RankServiceClient({
  credentials: credentials,
  projectId: projectId,
});

排错

以下内容总结了我们在实际开发中遇到的错误,总结出来以避免后来人踩坑。

错误一: 没传 Project ID 属性

Error: Unable to detect a Project Id in the current environment.
To learn more about authentication and Google APIs, visit:
https://cloud.google.com/docs/authentication/getting-started

虽然 credentials JSON 文件中包含了 project_id 属性的,但是 google 的 SDK 在解析传入的 credentials 对象的时候,是不会解析 Project ID 的,因此按照上述代码的示例,所以需要 Project ID 的部分,必须自己手工解析出来 projectId 然后传入 SDK。

错误二: 额外设置了环境变量 GOOGLE_API_KEY

Error: Google request failed with status code 401: [{
  "error": {
    "code": 401,
    "message": "API keys are not supported by this API. Expected OAuth2 access token or other authentication credentials that assert a principal. See https://cloud.google.com/docs/authentication",
    "status": "UNAUTHENTICATED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "CREDENTIALS_MISSING",
        "domain": "googleapis.com",
        "metadata": {
          "method": "google.cloud.aiplatform.v1.PredictionService.StreamGenerateContent",
          "service": "aiplatform.googleapis.com"
        }
      }
    ]
  }
}

如果之前使用 Gemini 之类的服务,可能会习惯设置一个 GOOGLE_API_KEY 环境变量。不幸的是,Vertex AI 和 Discovery Engine 不支持使用 API KEY 方式访问服务,如果设置了 GOOGLE_API_KEY,那么就会出现这个错误。

可以取消这个环境变量。如果真的要同时使用的话,可以考虑重命名一个新的变量,将 API KEY 以参数形式传递给 SDK 以避免变量冲突。

错误三: 未设置服务账号的权限

Permission 'aiplatform.endpoints.predict' denied on resource xxxxxx
Error: 7 PERMISSION_DENIED: Permission 'discoveryengine.rankingConfigs.rank' denied on resource xxxx

这两种错误都是没有给服务账号分配对应的权限导致的,第一个错误可以通过分配角色 Vertex AI User 解决,第二个错误可以通过分配角色 Discovery Engine Admin 解决。也可以创建自定义角色,分配需要的权限。

如果在创建服务账号的时候,错过了分配角色的步骤,那么可以在 IAM 功能这里给服务账号分配角色。特别注意这里非常具有迷惑性,就是服务账号详情页中的 权限 选项卡只能跳转到权限分析器,并不能分配角色权限。

进入 IAM 和管理

找到服务账号并进入编辑页面添加角色。如果这里不显示你的服务账号,那么就点击 授予访问权限,然后在主账号这里粘贴你的服务账号的邮箱地址即可:

找到服务账号

分配角色

小结

本篇文章我们详细总结了 Vertex AI API 以及 Discovery Engine API 的启用和配置,以及代码使用中容易出现的错误和解决方案。

付费内容

本文包含付费内容,需要会员权限才能查看完整内容。