Gemini 3.1 Pro 用 Vercel AI SDK 接结构化输出,我踩过的坑

如果你在用 Vercel AI SDK(@ai-sdk/google)接 Gemini 3.1 Pro 或其他 Gemini 3 系列模型,想同时用结构化输出(structured output)和工具调用(function calling / code execution),有一组兼容性问题会在毫无预兆的情况下让你收到莫名其妙的报错。

我把 GitHub Issues 里关于 Gemini 3.1 Pro 结构化输出这段历史扒了出来,从报错信息到修复时间线到当前仍然存在的问题,尽量说完整。

先说最重要的结论

结构化输出 + 工具调用,只有 Gemini 3 系列(含 3.1 Pro)支持。 Gemini 2.x 系列一律不支持这个组合。这不是 SDK 的 bug,是模型本身的设计限制。

如果你用的是 Gemini 2.5 Pro/Flash 或者 2.0 Flash,同时开结构化输出和任何形式的工具(不管是代码执行还是自定义 function),都会报错。

什么是结构化输出

简单回顾一下。结构化输出(Structured Output)是指让模型按照你指定的 JSON Schema 格式返回结果,而不是自由文本。在 Vercel AI SDK 里,通常用 Output.object() 配合 Zod schema 实现:

import { generateText, Output } from 'ai';
import { google } from '@ai-sdk/google';
import { z } from 'zod';

const result = await generateText({
  model: google('gemini-3.1-pro-preview'),
  output: Output.object({
    schema: z.object({
      sentiment: z.enum(['positive', 'negative', 'neutral']),
      confidence: z.number(),
      summary: z.string(),
    }),
  }),
  prompt: '分析这段用户评价的情感倾向...',
});

console.log(result.output);
// { sentiment: 'positive', confidence: 0.92, summary: '...' }

结构化输出在做数据提取、分类、API 响应格式化等场景非常有用。问题出在你想在结构化输出的同时让模型调用工具的时候。

Issue #11466:Code Execution + Structured Output

2025 年 12 月 30 日,开发者 @ruchernchong 在 Vercel AI SDK 仓库提了 issue #11466。

复现代码:

import { generateText, Output } from 'ai';
import { google } from '@ai-sdk/google';
import { z } from 'zod';

const result = await generateText({
  model: google('gemini-3-flash-preview'),
  tools: {
    code_execution: google.tools.codeExecution(),
  },
  output: Output.object({
    schema: z.object({
      answer: z.number(),
      explanation: z.string(),
    }),
  }),
  prompt: '计算前50个质数的和,展示计算过程。',
});

// 期望得到 { answer: 5117, explanation: '...' }
// 实际抛出 AI_NoOutputGeneratedError: No output generated.
console.log(result.output);

报错信息:AI_NoOutputGeneratedError: No output generated.

Google 官方文档明确写了 Gemini 3 系列支持结构化输出和 Code Execution 同时使用。但在 Vercel AI SDK 里跑就是报错。

根因分析: SDK 把 google.tools.codeExecution() 错误地归类为"客户端工具"(client tool),而不是 Google 的"内置工具"(provider tool)。客户端工具和结构化输出的交互逻辑不同,导致 SDK 在处理 Gemini 返回的响应时找不到结构化输出的内容,抛出 NoOutputGenerated

2026 年 1 月 1 日,有开发者提了修复 PR(#11486),把 codeExecution 从客户端工具改成了内置工具。1 月 7 日修复合进了主分支,issue 关闭。

Issue #11947:自定义工具 + Structured Output

2026 年 1 月 22 日,另一位开发者 @tpiros 提了 issue #11947,问题稍微不同。

他用的是 gemini-2.5-flash + 自定义工具 + Output.object()

const { output } = await generateText({
  model: google("gemini-2.5-flash"),
  tools: {
    weather: tool({
      description: 'Get the weather for a location',
      inputSchema: z.object({ location: z.string() }),
      execute: async ({ location }) => {
        return { temperature: 72, condition: 'sunny' };
      },
    }),
  },
  output: Output.object({
    schema: z.object({
      summary: z.string(),
      recommendation: z.string(),
    }),
  }),
  stopWhen: stepCountIs(5),
  prompt: 'What should I wear in San Francisco today?',
});

报错:APICallError: Function calling with a response mime type: 'application/json' is unsupported

这个报错来自 Google 的 API 端,不是 SDK 端。意思是:Gemini 2.5 Flash 不支持在返回 JSON 格式(结构化输出要求 response_mime_type: application/json)的同时执行 function calling。

维护者 @aayush-kapoor 回复说这是预期行为——Google 的文档写了只有 Gemini 3 系列支持这个组合。Issue 被关了。

但提 issue 的人指出了一个实际问题:Vercel AI SDK 自己的文档里用的代码示例就是不能跑的,因为示例里用了 Gemini 2.5 模型。Vercel 的文档没有标注 Gemini 3 独占这个特性。

另一个还没完全修好的问题

2026 年 2 月 19 日,有人在 #11466 下面追加评论说:@ai-sdk/google-vertex(Vertex AI 版本的 provider)在用 streamText 配合结构化输出时仍然有 AI_NoOutputGeneratedError。截至那条评论的时间点,这个问题还没被修。

也就是说,如果你用的是 Vertex AI 而不是 Google AI Studio 的 API,在流式输出 + 结构化输出的组合下可能还有问题。

另一个隐蔽的坑:generateObject vs generateText + Output.object()

这是在 issue 讨论中发现的。Vercel AI SDK v6 做了一个架构变更:建议开发者从 generateObject 迁移到 generateText + Output.object() 的写法。但迁移之后有人发现同样的输入,generateObject 能跑通,generateText + Output.object() 就报错。

开发者 @liby 做了一个 A/B 测试:

// 这个能跑通
const { object } = await generateObject({
  model: google('gemini-3-flash'),
  schema: mySchema,
  system: SYSTEM_PROMPT,
  messages: [{ role: 'user', content: userPrompt }],
  temperature: 0,
});

// 这个报 AI_NoObjectGeneratedError
const { output } = await generateText({
  model: google('gemini-3-flash'),
  output: Output.object({ schema: mySchema }),
  system: SYSTEM_PROMPT,
  messages: [{ role: 'user', content: userPrompt }],
  temperature: 0,
});

相同的 model、相同的 schema、相同的 prompt,一个成功一个失败。最终确认原因和 Vercel AI Gateway 的 finishReason 返回值有关——Gateway 返回了 undefined,导致 SDK 不去解析输出。

如果你在从 v5 迁移到 v6,这个坑值得注意。

兼容性速查表

这张表我反复确认过,来源是 Google 官方文档 + 实际测试:

模型 结构化输出 + Code Execution + Google Search + 自定义 Function
gemini-3.1-pro-preview
gemini-3-pro-preview
gemini-3-flash-preview
gemini-2.5-pro
gemini-2.5-flash
gemini-2.0-flash ✓*

*gemini-2.0-flash 的结构化输出需要在 schema 里显式指定 propertyOrdering,否则 JSON 字段顺序可能不对。

临时绕过方案

如果你暂时没法升级到 Gemini 3 系列,但需要结构化输出:

方案一:用 generateObject 代替 generateText + Output.object()generateObject 在 Gemini 2.5 上是能用的,代价是没法同时调工具。

方案二:分步处理。先让模型调用工具拿到结果(不开结构化输出),再发一次请求让模型把结果格式化成 JSON(开结构化输出但不带工具)。两次 API 调用,但能绕过限制。

方案三:直接升级模型到 Gemini 3 系列。如果你的应用对模型版本没有硬性要求,这是最干净的解法。

SDK 版本建议

如果你用 @ai-sdk/google:确保升到 3.x 及以上版本(#11466 的修复在这之后)。

如果你用 @ai-sdk/google-vertex:截至写这篇文章时(2026 年 2 月),流式结构化输出可能还有问题,建议先用非流式(generateText 而不是 streamText)或者关注后续 patch。

兼容性矩阵会随 SDK 和模型版本变化。上线前查一下 @ai-sdk/google 的 changelog 和 release notes 是个好习惯。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容