图文教程:配置 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 列表中分别搜索 Vertex AI 和 Discovery Engine 快速找到这两个 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 功能这里给服务账号分配角色。特别注意这里非常具有迷惑性,就是服务账号详情页中的 权限 选项卡只能跳转到权限分析器,并不能分配角色权限。
找到服务账号并进入编辑页面添加角色。如果这里不显示你的服务账号,那么就点击 授予访问权限,然后在主账号这里粘贴你的服务账号的邮箱地址即可:
小结
本篇文章我们详细总结了 Vertex AI API 以及 Discovery Engine API 的启用和配置,以及代码使用中容易出现的错误和解决方案。
本文包含付费内容,需要会员权限才能查看完整内容。