Gemini Embedding 把文本变成可比较的数字向量,本身不生成问答回复。做文档检索时,用文档任务生成资料向量,用查询任务生成问题向量,再在同一向量空间中比较。下面固定使用 gemini-embedding-001,给出三条演示资料的 Python 检索代码,重点检查任务类型、维度、归一化和来源对应。
代码依据为 2026 年 10 月 1 日读取的官方文档;本文没有使用读者的 API 密钥运行请求,也没有把示例排序写成实测结果。调用可能产生费用,模型可用性和额度以自己账号为准。

先分清模型、任务类型和回答模型
Gemini Embeddings 官方指南当前同时列出 gemini-embedding-2 和仍可用于纯文本的 gemini-embedding-001。本文选后者,是为了固定一个文本检索示例;换模型时必须重新生成文档向量,不能因为长度相同就把不同模型输出混在一起。
| 输入 | 本文任务类型 | 作用 |
|---|---|---|
| 待搜索的文档片段 | RETRIEVAL_DOCUMENT | 建立文档侧表示 |
| 用户搜索问题 | RETRIEVAL_QUERY | 建立查询侧表示 |
| 检索出的原文和问题 | 不由 Embedding 生成回答 | 如需要自然语言答案,另交给回答模型 |
两侧任务类型不同,是检索用途的配对,不等于可以混用两个模型。普通文本相似度、分类、聚类有各自任务类型,不应把同一套配置机械套进全部应用。
准备 SDK 和三条可核对资料
在独立 Python 环境安装 google-genai 和 numpy:python -m pip install -U google-genai numpy。通过运行环境设置 GEMINI_API_KEY,代码从环境读取;不要把密钥写入脚本、上传文档或打印出来。记录安装版本和模型名,便于重现。
示例资料如下,全部为虚构设备说明:
- doc_a:设备 A 的保修期为 12 个月,保修凭购买凭证办理。
- doc_b:设备 A 的包装内含一条充电线和一本说明书。
- doc_c:设备 B 需要在首次使用前充电两小时。
问题固定为“设备 A 保修多久,需要什么凭证?”。预期有用原文为 doc_a;这是人工验收目标,不是预先伪造的 API 输出。
生成配对向量并排序
import os
import numpy as np
from google import genai
from google.genai import types
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
model = "gemini-embedding-001"
dimension = 768
docs = [
("doc_a", "设备 A 的保修期为 12 个月,保修凭购买凭证办理。"),
("doc_b", "设备 A 的包装内含一条充电线和一本说明书。"),
("doc_c", "设备 B 需要在首次使用前充电两小时。"),
]
def embed(texts, task):
response = client.models.embed_content(
model=model,
contents=texts,
config=types.EmbedContentConfig(
task_type=task, output_dimensionality=dimension
),
)
if not response.embeddings or len(response.embeddings) != len(texts):
raise ValueError("返回向量数量与输入数量不符")
values = np.array([e.values for e in response.embeddings], dtype=float)
if values.shape != (len(texts), dimension) or not np.isfinite(values).all():
raise ValueError("向量维度或数值不合法")
lengths = np.linalg.norm(values, axis=1, keepdims=True)
if (lengths == 0).any():
raise ValueError("零向量不能计算余弦相似度")
return values / lengths
document_vectors = embed([text for _, text in docs], "RETRIEVAL_DOCUMENT")
query = "设备 A 保修多久,需要什么凭证?"
query_vector = embed([query], "RETRIEVAL_QUERY")[0]
scores = document_vectors @ query_vector
for index in np.argsort(-scores):
source_id, text = docs[int(index)]
print(source_id, round(float(scores[index]), 6), text)
print("shape:", document_vectors.shape)
print("norms:", np.linalg.norm(document_vectors, axis=1))
代码为文档生成三条向量,为问题生成一条向量,保留原始 doc_id 和文本的对应关系。官方指南说明,gemini-embedding-001 在使用非 3072 维输出时需要手动归一化;这里请求 768 维,并逐条除以向量长度。归一化后的内积等于余弦相似度,所以按 scores 从大到小排序。
官方指南也提醒,新模型 gemini-embedding-2 的截短输出可自动归一化,行为与 -001 不同。迁移时应重新核对任务配置、返回向量数量及嵌入空间,本文代码不能直接当成所有版本的通用模板。
检查结果,避免“返回了向量就算成功”
- 先看 shape 是否为 (3, 768),每条归一化向量的 norm 是否接近 1;数量或维度不符先停止。
- 查看第一条是否为 doc_a,原文是否同时包含“12 个月”和“购买凭证”。如果不是,记录实际排序和问法,检查文档内容、任务类型以及模型是否一致。
- 换成“设备 A 包装里有什么”,人工目标为 doc_b;再问“设备 C 保修多久”,现有资料没有依据,不能因 top-1 总有结果就声称找到答案。
- 保存 query、排名、doc_id、原文和实际分数。分数用于这次配置下的相对排序,不把某个固定值解释成“答案有多少概率正确”。
如果继续做 RAG 问答,回答模型只应使用检索到的原文,并输出可回查的 doc_id。是否需要拒答不能仅靠一条随意设置的余弦阈值;应加入无答案问题,用实际问题集核对相关性与误报。
落入向量库前,保存这几个字段
每个片段至少保存 doc_id、片段文本、来源位置、文档版本、嵌入模型名、维度和分段配置。向量库集合维度必须与 768 一致。以后更换模型或分段规则时,新建索引并重嵌入,用同一问题集比较,再切换检索入口。
API 报模型不存在、权限不足或额度问题时,先看真实错误与账号可用模型;不要静默切换模型后继续往旧库写向量。输入太长时按当前模型限制重新分段,也不要用截断文本掩盖丢失条款。
相关问答
可以直接用 Embedding 回答“保修多久”吗?
不可以。返回值是向量;它能帮助找到相关资料,最后的“12 个月,需要购买凭证”来自原文或另一个回答模型,不能从向量某几个数字读出。
向量长度相同,为什么换模型还要重新建库?
长度只说明坐标数量一致,不证明坐标的语义一致。应固定同一嵌入模型及兼容配置生成文档和查询,迁移后重新嵌入并验证结果。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30273.html