Gemini Search Grounding
使用 Google Search Grounding,并将回答片段与网页来源关联。
Gemini Search Grounding 让支持该能力的 Gemini 模型使用 Google Search 获取近期信息,并通过 groundingMetadata 把回答片段与网页来源关联起来。
Grounding 不只是“打开搜索开关”。客户程序还需要读取查询、来源和文本片段之间的映射,才能在界面中展示可核对的引用。
协议支持不代表模型支持
Generate Content 可以表达 Google Search 工具,但实际可用范围取决于当前模型和账户。请先在模型广场确认模型,再以 Gemini Generate Content Reference 为准。
发起 Grounding 请求
Gemini 原生路径从站点 Origin 拼接 /v1beta,不能在已经包含 /v1 的 Base URL 后再次拼接 /v1beta:
curl --request POST \
'https://api.agtcloud.cn/v1beta/models/MODEL_ID:generateContent' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer your-api-key' \
--data '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "今天有哪些值得关注的人工智能新闻?请给出来源。"
}
]
}
],
"tools": [
{
"google_search": {}
}
]
}'模型会判断是否需要搜索,并可能生成一个或多个搜索查询。不要假设每次启用工具都会产生 Grounding Metadata。
Grounding 的处理流程
1. 提交问题和搜索工具
将用户问题放入 contents[].parts,并在 tools 中启用 Google Search。
2. 读取回答文本
从候选的 content.parts 中读取模型生成的文本,不要假设始终只有一个候选或一个 Part。
3. 读取 Grounding Metadata
保存搜索查询、网页来源以及回答片段与来源索引的关联。
4. 展示可点击引用
根据片段结束位置插入引用标记,或在回答旁展示来源卡片,让用户可以返回原网页核对。
理解 groundingMetadata
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{"text": "根据近期报道,相关进展包括……"}
]
},
"groundingMetadata": {
"webSearchQueries": [
"人工智能 新闻 今天"
],
"groundingChunks": [
{
"web": {
"uri": "https://example.com/article",
"title": "来源标题"
}
}
],
"groundingSupports": [
{
"segment": {
"startIndex": 0,
"endIndex": 12,
"text": "根据近期报道"
},
"groundingChunkIndices": [0]
}
]
}
}
]
}| 字段 | 客户端用途 |
|---|---|
webSearchQueries | 记录模型实际使用的搜索查询,便于排障和解释搜索范围 |
groundingChunks | 保存网页 URI、标题等来源信息 |
groundingSupports | 将回答文本片段映射到一个或多个来源索引 |
响应可能没有其中某些字段,客户端需要使用可选访问和空数组作为默认值。
在文本中插入引用
插入引用时,应按 segment.endIndex 从大到小处理,避免前一次插入改变后续位置:
function addCitations(text, supports = [], chunks = []) {
const sorted = [...supports].sort(
(a, b) => (b.segment?.endIndex ?? 0) - (a.segment?.endIndex ?? 0),
);
for (const support of sorted) {
const endIndex = support.segment?.endIndex;
if (endIndex == null) continue;
const links = (support.groundingChunkIndices ?? [])
.map((index) => {
const source = chunks[index]?.web;
return source?.uri ? `[${index + 1}](${source.uri})` : null;
})
.filter(Boolean);
if (links.length > 0) {
text = `${text.slice(0, endIndex)}${links.join('')}${text.slice(endIndex)}`;
}
}
return text;
}在浏览器渲染模型返回内容时,应使用安全的 Markdown 或 HTML 处理方式,并为外部链接添加新标签页安全属性。
失败与降级
| 现象 | 处理方式 |
|---|---|
没有 groundingMetadata | 正常显示回答,同时明确本次没有可展示的 Grounding 来源 |
| 来源索引越界 | 忽略失效关联并记录脱敏响应,不插入错误链接 |
| 文本位置不匹配 | 改为回答末尾来源列表,不在错误位置插入引用 |
| 搜索失败 | 根据响应错误决定有限重试或降级为非搜索回答 |
| 来源内容冲突 | 展示多方来源和日期,让用户判断,不隐藏重要分歧 |
上线前检查
- 当前模型支持 Google Search Grounding。
- Gemini Endpoint 使用站点 Origin,不产生
/v1/v1beta。 - 回答文本、查询、来源和片段映射分别保存。
- 引用索引无效时不会导致页面崩溃。
- 外部网页内容不会被直接当作可信业务指令。
- 没有来源时不会生成虚假 Citation。
如果应用使用 Chat 而不是 Gemini 原生结构,请改用目标模型明确支持的 Chat 搜索字段,不要直接复制 groundingMetadata 解析器。