用 langchaingo 接入 Google Vertex AI 生成文本嵌入向量:示例实战与源码解析
【免费下载链接】langchaingoLangChain for Go, the easiest way to write LLM-based programs in Go项目地址: https://gitcode.com/GitHub_Trending/la/langchaingo
导读
本文基于 langchaingo 仓库中的 Vertex AI Embedding 示例 展开,讲解如何在 Go 程序中通过 langchaingo 调用 Google Vertex AI 的文本嵌入(Embedding)服务,将自然语言文本转换为可供语义搜索、文本分类等任务使用的数值向量。读完本文,你将掌握环境变量配置、vertex.New客户端初始化、CreateEmbedding调用方式,并理解其背后的双层客户端设计与批量嵌入实现原理。
示例概述:这个程序做什么
仓库中的示例程序 vertex-embedding-example.go 是一个最小可运行的程序,核心流程只有四步:
- 从环境变量读取 Google Cloud 项目 ID 与区域(location);
- 使用 langchaingo 的 Vertex AI 客户端创建连接;
- 为文本
"I am a human"生成嵌入向量; - 将结果向量打印到控制台。
嵌入向量本质上是将文本映射为一个定长的浮点数数组(如 768 或 3072 维)。在向量空间中,语义相近的文本其向量距离更近,因此嵌入是语义搜索、文本分类、聚类、推荐等现代 NLP 任务的基石。
运行前准备:环境与认证
运行该示例前,需要满足以下前提:
- 一个已启用 Vertex AI API 的 Google Cloud 项目;
- 设置环境变量
VERTEX_PROJECT为你的 GCP 项目 ID; - 设置环境变量
VERTEX_LOCATION为 GCP 区域,例如us-central1(示例源码注释也建议不确定时使用us-central1); - 具备访问 Vertex AI 的认证凭据(见下文“认证方式”小节)。
配置完成后,在示例目录下直接运行:
go run vertex-embedding-example.go代码逐行解析
完整示例代码如下(来源:vertex-embedding-example.go):
// Set the VERTEX_PROJECT to your GCP project with Vertex AI APIs enabled. // Set VERTEX_LOCATION to a GCP location (region); if you're not sure about // the location, set us-central1 package main import ( "context" "fmt" "log" "os" "github.com/tmc/langchaingo/llms/googleai" "github.com/tmc/langchaingo/llms/googleai/vertex" ) func main() { ctx := context.Background() project := os.Getenv("VERTEX_PROJECT") location := os.Getenv("VERTEX_LOCATION") llm, err := vertex.New(ctx, googleai.WithCloudProject(project), googleai.WithCloudLocation(location)) if err != nil { log.Fatal(err) } embeddings, err := llm.CreateEmbedding(ctx, []string{"I am a human"}) if err != nil { log.Fatal(err) } fmt.Println(embeddings) }几个值得注意的要点:
- 导入路径是
github.com/tmc/langchaingo/llms/googleai/vertex,与面向 Gemini API Key 的llms/googleai包(提供者)区分开来:vertex子包面向 Google Cloud Vertex AI 平台,需要项目 ID 与区域信息; - 客户端配置通过函数式选项(
googleai.Option)注入:WithCloudProject设置项目 ID,WithCloudLocation设置区域; CreateEmbedding接受[]string文本切片、返回[][]float32,说明它天然支持批量文本输入;- 运行成功后会看到一行浮点数向量输出,例如
[[0.012345 ... -0.045678]]。
源码原理:为什么顶点客户端是“双客户端”
从源码结构看,Vertex 客户端的初始化并不像表面那样简单。查看 llms/googleai/vertex/new.go 中的New函数可以发现,它实际创建了两个底层客户端:
genai.NewClient(ctx, CloudProject, CloudLocation, ...):用于 Gemini 系列模型的对话、生成等能力;palmclient.New(ctx, CloudProject, CloudLocation, ...):专门用于嵌入请求。
其结构体定义(vertex.go 附近的Vertex类型)同时持有client *genai.Client与palmClient *palmclient.PaLMClient两个字段。源码注释明确说明了原因:
Right now, the Vertex Gemini SDK doesn't support embeddings; therefore, for embeddings we also hold a palmclient.
即:当前 Vertex 的 Gemini SDK 尚未支持嵌入能力,因此 langchaingo 为嵌入专门保留了 PaLM 客户端通道。这是理解该模块设计的关键事实。
嵌入请求的具体实现在 llms/googleai/vertex/embeddings.go:
func (g *Vertex) CreateEmbedding(ctx context.Context, texts []string) ([][]float32, error) { embeddings, err := g.palmClient.CreateEmbedding(ctx, &palmclient.EmbeddingRequest{ Input: texts, }) ... if len(texts) != len(embeddings) { return embeddings, fmt.Errorf("returned %d embeddings for %d texts", len(embeddings), len(texts)) } return embeddings, nil }实现中还有两层防御性校验:返回结果为空时抛出"empty response"错误;返回向量数量与输入文本数量不一致时抛出明确的数量不匹配错误。对应测试用例见 llms/googleai/vertex/embeddings_test.go,覆盖了单文本、多文本、空响应、数量不匹配、底层 API 错误、空输入等多种场景。
认证方式
除环境变量外,认证凭据可以通过函数式选项注入。查看 llms/googleai/option.go 可看到以下选项:
WithCredentialsFile(credentialsFile string):使用服务账号或刷新令牌 JSON 凭据文件认证;WithCredentialsJSON(credentialsJSON []byte):直接传入凭据 JSON 字节;WithHTTPClient/WithGRPCConn:自定义 HTTP 客户端或 gRPC 连接,后者常用于测试场景(见 option.go)。
Vertex 模式通常依赖 Google Cloud 默认凭据(如GOOGLE_APPLICATION_CREDENTIALS环境变量指向的服务账号 JSON),这部分由底层cloud.google.com/go/vertexai驱动。此外,DefaultOptions 中可见默认配置:默认嵌入模型为embedding-001、默认对话模型为gemini-2.0-flash、默认MaxTokens为 2048、默认温度为 0.5。
扩展用法:默认嵌入模型与批量嵌入
示例只嵌入了一条文本,但CreateEmbedding的签名支持批量输入。若需指定其他嵌入模型,可在初始化时追加googleai.WithDefaultEmbeddingModel(modelName)选项(定义见 option.go)。
另外需要说明:上文讨论的是Vertex(Google Cloud)路径;若你使用的是 Gemini API Key 而非 Vertex AI,则可以改用llms/googleai包的GoogleAI客户端,其嵌入实现在 llms/googleai/embeddings.go,走的是 Gemini Embedding Batch API。该实现有一个明确的工程细节:
The Gemini Embedding Batch API allows up to 100 documents per batch, so send a request every 100 documents and when we hit the last document.
即每条请求最多携带 100 个文档,代码会在每满 100 条以及遍历到最后一条时调用BatchEmbedContents分批发送,避免超出 API 上限,并把各批次结果合并后一次性返回。这一细节对需要嵌入大量文本的生产场景很有参考价值。
常见问题与排查建议
- 认证失败:确认 GCP 项目已启用 Vertex AI API,并确保运行环境的凭据(服务账号 JSON / ADC)对项目有
aiplatform相关权限; VERTEX_PROJECT/VERTEX_LOCATION为空:vertex.New会用空字符串创建客户端,通常在首次请求时失败。请先echo $VERTEX_PROJECT检查环境变量;- 返回
empty response错误:多发生在输入为空切片时,这是 embeddings.go 的显式校验逻辑; - 返回数量不匹配错误:底层服务返回的向量数少于输入文本数,可尝试减少单批文本数量后重试;
- 资源释放:
Vertex类型提供了Close()方法(见 vertex/new.go),关闭底层 genai 连接以避免 gRPC 连接泄漏,长驻服务中记得在退出时调用。
总结
通过 langchaingo 的llms/googleai/vertex包,你只需十几行 Go 代码即可把 Vertex AI 的文本嵌入能力接入自己的应用。理解其“Gemini 客户端 + PaLM 嵌入客户端”的双通道设计,以及分批调用、数量校验等实现细节,能帮助你在实际项目中更稳健地使用嵌入向量,为语义搜索、文本分类等下游任务打好数据基础。
【免费下载链接】langchaingoLangChain for Go, the easiest way to write LLM-based programs in Go项目地址: https://gitcode.com/GitHub_Trending/la/langchaingo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考