从延迟、成本、可靠性等生产约束对两款主流模型实测对比,为工程师选型决策提供真实数据。
这是对 Gemini 2.5 Flash 和 Claude 3.7 Sonnet 在 Agent 引擎中的一次评估。
为 Ozigi 选择 LLM 时,我有一条简单的原则:不要根据基准测试排行榜做决定。v2 发布后,在收集反馈的过程中,一位用户建议我使用 Claude 模型,因为它在内容生成方面比 Gemini 更出色。这个建议听起来很诱人,但我必须根据生产流水线中四个不可妥协的约束来选择模型。
大多数“Gemini vs Claude”对比评估的是编程、推理和创意写作等通用能力。如果你正在构建通用产品,这些指标确实很有用。但我做的不是通用产品。Ozigi 是一个内容引擎:你向它提供 URL、PDF 或原始笔记,它会返回一个结构化的三天社交媒体营销活动,以 JSON payload 的形式交给前端,前端再将其直接映射成 UI 卡片。
这种明确的业务场景让评估过程比我预想的更简单:两个模型,四项约束。其中三项都有一个明确的胜者。
这是 Ozigi Changelog 系列的第三篇文章。如果你想了解 Ozigi 诞生的背景,可以先阅读我是如何通过 vibe coding 写出这个后来演变成 Ozigi 的内部工具,以及介绍模块化架构的 v2 changelog——这次模型选型正是建立在该架构之上的。
下面是完整的 Architecture Decision Record。
Ozigi 的核心 API route 会执行以下操作:
随后,前端会执行:
const parsed = JSON.parse(responseText);
setCampaign(parsed.campaign);
没有 middleware,没有 schema validation,也没有针对正常路径的 error recovery。直接解析,然后塞进 React state。
正是这一行代码,让模型选择变得至关重要。
要求:模型每次都必须返回有效的 JSON object——不能用 Markdown 代码围栏包裹,不能在前面添加对话式开场白,也不能凭空多写一个会导致 JSON.parse() 失败的尾随逗号。
目标 schema 如下:
{
"campaign": [
{ "day": 1, "x": "...", "linkedin": "...", "discord": "..." },
{ "day": 2, "x": "...", "linkedin": "...", "discord": "..." },
{ "day": 3, "x": "...", "linkedin": "...", "discord": "..." }
]
}
它会在三天内为三个平台生成九篇帖子,每个字段都是必填项。UI 会把每个字段渲染成一张独立卡片,并提供编辑、复制和发布操作。缺少 key 时不会抛出可见错误,只会悄无声息地渲染出一张空卡片。
这里具体比较的是采用 responseSchema 强制约束的 Gemini,与通过 prompt 要求输出 JSON 的 Claude,而不是比较两个模型结构化输出能力的上限。Claude 的 tool use 配合 tool_choice: {type: "tool"},同样可以在 decoding layer 强制执行 schema,并达到相当的可靠性。这里真正相关的约束是:在我现有的技术栈中,哪一种强制机制既可用又切实可行。下文还会进一步说明。
我针对这一 schema,分别对两个模型运行了 500 次自动化生成测试,统计响应能够被 JSON.parse() 无异常接受的比例。
11.5% 的差距会直接转化为真实用户遇到的 UI 异常状态。对于一项核心功能来说,这是我无法接受的。
使用 Gemini 的 responseSchema 可以彻底消除这个问题。根据 Google 的 controlled generation 文档,这项功能会从物理上阻止模型返回不符合 schema 的输出。它不是 prompt 层面的指导,而是在 decoding layer 强制执行的。下面是 Ozigi 的生产实现:schema 只需在 route 顶部定义一次,然后直接附加到模型配置中:
const distributionSchema = {
type: "OBJECT" as const,
properties: {
campaign: {
type: "ARRAY" as const,
description: "A list of 3 daily social media posts.",
items: {
type: "OBJECT" as const,
properties: {
day: { type: "INTEGER" as const, description: "Day number (1, 2, or 3)" },
x: { type: "STRING" as const, description: "Content for X/Twitter." },
linkedin: { type: "STRING" as const, description: "Content for LinkedIn." },
discord: { type: "STRING" as const, description: "Content for Discord." },
},
required: ["day", "x", "linkedin", "discord"],
},
},
},
required: ["campaign"],
};
const model = vertex_ai.getGenerativeModel({
model: "gemini-2.5-flash",
generationConfig: {
responseMimeType: "application/json",
responseSchema: distributionSchema,
},
});
现在,response.text() 在结构上可以保证是有效 JSON。JSON.parse() 不会再因为字段缺失、尾随逗号或对话式开场白而失败——模型从物理上就无法生成这些内容。Claude 的 tool use 和 function calling 也能提供类似的保证,但它需要采用明显不同的集成架构。使用 Vertex SDK 时,只需添加一个配置块。
要求:Ozigi 提供一个免费、无需身份验证的 sandbox。任何人都可以在不注册的情况下生成完整的三天营销活动。
这彻底改变了模型选型的经济账。如果输出质量足够高,付费套餐用户可能愿意等待 20 秒。但一个通过我那些古怪营销手段发现产品的匿名用户不会。他们会在第 10 秒关掉标签页,而且很遗憾,可能再也不会回来。
我通过 Vercel serverless functions,也就是我的生产环境,使用标准的 10,000-token 输入 payload 对两个模型进行了基准测试:
测试方法:每个模型发送 100 次请求,从调用 Vercel function 开始,一直测量到完整响应返回为止。结果会受到环境影响,仅用于方向性对比,不应被视为绝对基准。
这种差距在不同 payload 大小下依然存在。Gemini Flash 始终能在 10~15 秒内完成,而 Claude 3.7 Sonnet 在相同环境、相同输入下始终超过 20 秒。
采用 streaming 后,这一差距会显著缩小:用户可以在 2~3 秒内看到首批 token。Streaming 会彻底改变用户对等待时间的感知。不过,这是正在推进的 v4 架构事项。对于一条不使用 streaming、同时面向公共 sandbox 的流水线来说,3.5 倍的延迟差异不仅是工程决策,也是产品决策。
胜者:Gemini Flash——对于不采用 streaming 的公共 sandbox 来说,两者差距悬殊。
要求:用户可以直接上传 PDF 和图片作为上下文。流水线必须能够处理它们,不能依赖外部预处理步骤。
通过 Vertex AI Node.js SDK 使用 Gemini 时,整个 PDF 流水线如下:
// /app/api/generate/route.ts
if (file && file.size > 0) {
const arrayBuffer = await file.arrayBuffer();
const base64Data = Buffer.from(arrayBuffer).toString("base64");
parts.push({
inlineData: {
data: base64Data,
mimeType: file.type, // "application/pdf", "image/jpeg", etc.
},
});
}
const result = await model.generateContent({
contents: [{ role: "user", parts: parts }],
});
可以看到,SDK 能够原生处理 buffer。Gemini 会将 PDF 与文本 prompt 一起作为 multipart request 的一部分直接读取——不需要 OCR,不需要预处理,也不需要单独调用其他服务。Google 的 multimodal 文档也确认,Gemini 从一开始就被设计为能够通过 inlineData 原生处理 PDF 和图片 buffer。
本文的早期版本曾声称,Claude 在摄取 PDF 时需要额外的 OCR 步骤。这是错误的。Claude 的 Messages API 确实支持通过 document content block 直接摄取原生 base64 PDF——不需要 OCR 预处理,也不需要外部服务。它的模式在结构上与 Vertex AI 的 inlineData 相似,只是字段名称不同。
这里真正的约束是生态系统,而不是能力。我评估的是现有 Vertex AI 环境中通过 Google Model Garden 提供的 Claude 3.7 Sonnet。切换到 Claude 原生 PDF 摄取,就意味着必须完全迁移到 Anthropic Messages API——不同的 provider、不同的 SDK、不同的计费体系。对于我已经在运行的技术栈来说,Vertex AI 路径更简单。
胜者:Gemini——仅针对这套技术栈。两个模型都支持原生多模态摄取,不需要外部 OCR。Gemini 的优势在于生态适配,而不是基础能力上的差异。
要求:生成的社交媒体帖子必须像真人写的。具体来说,它们必须能够通过 AI 内容检测,并避开那些会让 AI 文案立刻露馅的可预测节奏模式。
在基础表现上,Claude 在这项约束中完胜。我们对 50 篇技术帖子进行了内部盲测 A/B 评估,评分标准是务实的句式结构,以及是否缺少典型的 AI 用语。Claude 3.7 Sonnet 的“真人节奏质量评分”为 9.5/10,而 Gemini Flash 的基础评分为 5.5/10。
这是一个非常明显的差距,而且涉及的正是 Ozigi 的核心价值主张。
因为这个差距可以通过工程手段弥补。
我们构建了 Banned Lexicon——一种注入 system prompt 层的程序化约束,专门对那些容易让 AI 文案被识别出来的词汇模式施加明确限制。你可以在 Ozigi 文档中看到完整实现:
THE BANNED LEXICON: You are strictly forbidden from using the
following words or their variations: delve, testament, tapestry,
crucial, vital, landscape, realm, unlock, supercharge, revolutionize,
paradigm, seamlessly, navigate, robust, cutting-edge, game-changer.
再配合明确的节奏工程:
BURSTINESS (CADENCE): Write with high burstiness. Do not use
perfectly balanced, medium-length sentences. Mix extremely short,
punchy sentences (2-4 words) with longer, detailed explanations.
PERPLEXITY: Avoid predictable adjectives. Use strong, active verbs
and concrete nouns. Talk like a pragmatic subject matter expert
explaining a concept to people, not a marketer selling a product.
FORMATTING RESTRAINT: You are limited to a MAXIMUM of 1 emoji per
post. Use a maximum of 2 highly relevant hashtags per post.
启用这些约束后,Gemini 的真人节奏评分会从 5.5 提升至 9.2,进入可接受范围,与 Claude 的基础得分 9.5 已经非常接近。
关键洞察是:Claude 的语气优势是默认优势,而不是绝对优势。Gemini 的输出在 prompt 约束下更容易塑造。对于语气控制就是整个产品核心的使用场景来说,这种可塑性比更高的基础分更有价值。
胜者:Gemini + 工程约束。语气差距可以弥补,其他约束中的延迟和 JSON 稳定性差距则无法弥补。
Ozigi 目前仍是一个公共 sandbox,每个能够触发生成的匿名页面访问,都会产生一笔由产品承担的 API 调用费用。Ozigi 还处于商业化之前的阶段,因此这一点非常重要。
价格数据来自 Google Cloud Vertex AI 定价和 Anthropic API 定价。
专业建议:在做出生产决策前,请核实现行费率——过去一年里,两家的价格都已经调整过多次。
输入成本相差 40 倍,输出成本相差 50 倍。对于一个没有收入的免费层产品来说,能否可持续地运营公共 sandbox,决定了你究竟能不能拥有一条转化漏斗。
这是一份坦诚的 ADR。下面这些情况会改变我的答案。
当 Ozigi 最终转为付费产品后,延迟和成本会变成次要因素。与免费 demo 中的匿名用户相比,已登录的付费套餐用户更可能愿意等待 20 秒来获得高质量输出。这是一笔完全不同的 UX 账。在这种情况下,Claude 更高的基础语气质量会变得更有吸引力。届时,我会用经济性换取更高的输出基线,而这笔交易可能值得。
当 streaming 得到实现后,针对 Claude 的延迟论点会被显著削弱。Claude 3.7 Sonnet 通过 streaming 实现的 time-to-first-token 很有竞争力。用户在 2~3 秒内看到第一篇帖子出现,与盯着进度条等待 21 秒,是完全不同的产品体验。Streaming 已经列入 roadmap。
如果你想深入了解支撑这些决策的流水线测试方式,可以参阅我们如何在 Next.js 中使用 Playwright 对 AI Agent 进行 E2E 测试。
Gemini 在六个维度中的五个维度胜出。Claude 只赢了一项——基础语气质量——而这一差距可以通过 prompt engineering 弥补。
如果你正在构建与 Ozigi 类似的产品,那么在选择 API 并开始开发之前,值得先审视以下约束:
1. 你的 UI 是否依赖结构化输出? 如果前端会对原始模型响应调用 JSON.parse(),你需要的是 API 层的 schema enforcement,而不是在 prompt 中客客气气地要求模型遵守格式。Vertex AI 的 responseSchema、Claude 配合强制 tool_choice 的 tool use,以及 OpenAI 的 structured outputs,都会在 decoding layer 强制执行约束。问题不在于哪个模型支持它——大多数模型都支持——而在于哪一种强制执行路径最适合你现有的技术栈。
2. 你是否提供免费层或公共 sandbox? 如果答案是肯定的,那么延迟和成本就是影响转化率的产品决策,而不仅仅是影响利润率的基础设施决策。
3. 你的使用场景是否需要多模态输入? 现在,大多数主流模型都支持原生摄取 PDF 和图片,不需要外部预处理。在假设自己需要更换 provider 或增加基础设施之前,先梳理清楚它在你现有 API provider 中的具体集成方式。
4. 基础模型最薄弱的地方在哪里,这个差距能否通过工程手段弥补? Claude 的语气优势是真实存在的,但它并不是生成真人感文案的唯一路径。prompt 层的工程约束,可以弥补那些只看基础基准测试时似乎难以逾越的差距。
最适合你产品的模型,通常不是综合得分最高的那个,而是在那些真正无法绕开的约束上,失败次数最少的那个。
完整的 Ozigi 架构——包括 generate API route、Banned Lexicon 实现和 Vertex AI 配置——已经在 GitHub 上开源。
在线 context engine 位于 ozigi.app。
这份 ADR 还有一个交互式版本,其中包含使用 Chart.js 绘制的各项基准测试可视化图表。
Ozigi 目前正在招募 User Experience Tester,希望大家能针对产品使用体验和有待改进之处提供真实反馈。
我们在 GitHub 上还有一些开放 issue,欢迎社区参与贡献。顺带一提,这款 App 到目前为止完全是通过 vibe coding 完成的,所以我们也欢迎 vibe coded contribution!
你也可以发送邮件至 okolodumebi@gmail.com。
正在开发什么很酷的东西?欢迎在评论区聊聊!
部分评论可能只有登录后的访客才能看到。请登录查看全部评论。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。