Type something to search...
人工智能对决:o3-mini、Gemini 2 Flash、Claude 3.5 Sonnet与DeepSeek,谁能拔得头筹?

人工智能对决:o3-mini、Gemini 2 Flash、Claude 3.5 Sonnet与DeepSeek,谁能拔得头筹?

OpenAI 最新的模型 o3-mini 于 1 月 31 日星期五发布,现在在 Cursor 中可用,Gemini 2 Flash 也很快就会跟上。

上周我对 DeepSeek V3、DeepSeek R1 和 Claude 3.5 Sonnet 进行了类似的测试。在那些测试中,我最终决定 Claude 3.5 Sonnet 在我的日常开发任务中表现优于两个 DeepSeek 模型,但现在这两个模型已经到来,我想进行类似的测试以查看它们的比较。我还会为了好玩而将两个 DeepSeek 模型也包含在测试中!

如果你对上周专注于 DeepSeek 的测试感兴趣,可以在这里查看:

任务

我们将对每个模型进行聊天、创作和代理模式的测试。目前,代理模式仅适用于Anthropic模型和OpenAI模型,因此我们暂时无法对其他模型进行代理模式的测试。

聊天

聊天任务是查看我的 CircleCI 部署配置,并解释在部署期间如何将我的静态 NextJS 资产上传到 Cloudflare。这是确切的提示:

Explain how I would get my static NextJS assets into Cloudflare during deploymentI explicitly provided the CircleCI config file as context.

我希望看到:

  1. 在部署期间将静态资产上传到 Cloudflare 的正确步骤
  2. 对我需要更改的 NextJS 配置的建议,以便实际使用 Cloudflare 作为静态资产的 CDN

o3-mini

o3-mini 帮我设置了 Cloudflare Pages,并使用 wrangler CLI 部署静态资产。除非我遗漏了什么,我认为 Cloudflare Pages 并不适合用作 CDN。它还提到了更新我网站的 DNS/设置反向代理,但没有详细说明。它也没有提到我需要进行的任何 NextJS 配置更新。

Claude 3.5 诗歌

诗歌引导我完成安装 AWS CLI 所需的步骤,并成功告知我需要这样设置我的 NextJS 配置:

const nextConfig = {
  output: 'standalone',
  assetPrefix: process.env.PUBLIC_ASSETS_BASE_URL,
  // ... other config
}

诗歌建议我使用 Cloudflare R2,并没有提到 Cloudflare Pages 作为选项。

Gemini 2 Flash

Gemini 建议使用 Cloudflare R2,并没有提到 Cloudflare Pages 作为选项。它提到我可能需要更新我的 assetPrefix,但没有详细说明。不过,它确实建议我在 NextJS 配置中使用以下内容:

const nextConfig = {
  // ...
  images: {
    domains: ['your-site-static-assets-production.r2.dev', 'your-site-static-assets-qa.r2.dev'],
  },
};

DeepSeek V3

DeepSeek V3 告诉我也要使用 Cloudflare R2,并且正确描述了如何更新我的 assetPrefix,这很好。然而,对于实际的上传,它建议编写 TypeScript 的辅助文件,然后通过 package.json 脚本在 CircleCI 中运行这些文件。虽然这样做并没有错,但似乎比使用 CLI 更复杂。

DeepSeek R1

R1 实际上有一个几乎与 Sonnet 完全相同的输出!当然,不包括它的区块。

Composer

对于 composer 任务,我提供了一个服务器操作的文件,我正在使用这个文件进行与雇主发布职位的招聘网站相关的项目。

给出的提示是:

Add proper pagination and search props to `getEmployers`. Should be able to fuzzy search name, use a page number and limit, and should return metadata containing how many records there are in total and if there are any more after this page

现有的服务器操作是:

export const getEmployers = actionClient.action(async () => {
  const profile = await getActiveProfileOrThrowError();
  if (profile.type !== "jobBoard") {
      throw new Error("Unauthorized");
  }
  const applications = await db.query.employerJobBoardApplications.findMany({
    where: eq(employerJobBoardApplications.jobBoardId, profile.id),
    with: {
      employer: true,
    },
  });
  return applications;
});

我希望看到以下几点:

  1. 它识别到其他服务器操作也使用 zod 模式,因此它也应该使用
  2. 元数据有效地计算
  3. 它正确地在连接的表中进行模糊搜索名称

o3-mini

o3-mini 花了一些时间,但在 zod schema 部分做得很好,并且也意识到应该使用内连接来搜索雇主的名称。然而,它选择使用原始 SQL 来实现模糊搜索,这显然不是 Drizzle 提供的最类型安全的方式:

if (search) {
  conditions.push(sql`"employer"."name" ILIKE ${`%${search}%`}`);
}

let totalRecords: number;
if (search) {
  const totalCountRes = await db
    .select({ count: sql<number>`count(*)` })
    .from(employerJobBoardApplications)
    .innerJoin(
      employers,
      eq(employerJobBoardApplications.employerId, employers.id),
    )
    .where(and(...conditions));
  totalRecords = Number(totalCountRes[0]?.count ?? 0);
} else {
  const totalCountRes = await db
    .select({ count: sql<number>`count(*)` })
    .from(employerJobBoardApplications)
    .where(baseCondition);
  totalRecords = Number(totalCountRes[0]?.count ?? 0);
}

我也不喜欢它在这一部分没有找到重用更多代码的方法。总体来说,不算出色,但可以进一步改进。

Claude 3.5 诗歌

诗歌正确地识别到另一个服务器操作使用了 zod 模式,并且也使用了一个,所以我很高兴看到这一点。它在搜索和计数之间共享了 where 逻辑,这一点也很好。不过,它并没有完全正确地使用 Drizzle ORM:

const where = [eq(employerJobBoardApplications.jobBoardId, profile.id)];
if (search) {
  where.push(
    ilike(employerJobBoardApplications.employer.name, `%${search}%`),
  );
}
const [applications, totalCount] = await Promise.all([
  db.query.employerJobBoardApplications.findMany({
    where: and(...where),
    with: {
      employer: true,
    },
    limit,
    offset,
  }),
  db.query.employerJobBoardApplications.count({
    where: and(...where),
  }),
]);

可以看到它在搜索和计数之间共享了 where 逻辑,但 where 并不是这样工作的。它应该添加一个内连接,并对连接的表应用 where 子句。我提示使用内连接,之后它就正常工作了。

Gemini 2 Flash

Gemini 2 Flash 取得了一定的成功,并且速度非常快。它使用了 zod schema,但像 Sonnet 一样,它没有正确执行内连接。

const [applications, total] = await Promise.all([
  db.query.employerJobBoardApplications.findMany({
    where: and(...whereConditions),
    with: {
      employer: true,
    },
    limit,
    offset,
  }),
  db
    .select({
      count: sql<number>`count(*)`.mapWith(Number),
    })
    .from(employerJobBoardApplications)
    .where(and(...whereConditions))
    .limit(1)
    .then((res) => res[0]?.count ?? 0),
]);

DeepSeek V3

DeepSeek V3 正确使用了 zod schema,但在模糊搜索中未能使用内连接。它也没有找到一个好的方法来在搜索和计数之间共享 where 逻辑,因此只是重复了逻辑:

// Get the total count
const totalCount = await db
  .select({ count: sql<number>`count(*)` })
  .from(employerJobBoardApplications)
  .where(
    and(
      eq(employerJobBoardApplications.jobBoardId, profile.id),
      search
        ? ilike(employerJobBoardApplications.employer.name, `%${search}%`)
        : undefined,
    ),
  )
  .then((res) => res[0]?.count ?? 0);

// Get paginated results
const applications = await db.query.employerJobBoardApplications.findMany({
  where: and(
    eq(employerJobBoardApplications.jobBoardId, profile.id),
    search
      ? ilike(employerJobBoardApplications.employer.name, `%${search}%`)
      : undefined,
  ),
  with: {
    employer: true,
  },
  limit,
  offset,
});

DeepSeek R1

R1与其他模型一样,正确使用了zod模式。不幸的是,尽管它进行了额外的思考,但与其他模型一样,它也没有正确执行内连接。它还需要进一步的提示,以更好地共享where逻辑:

// Main query with pagination and search
const data = await db.query.employerJobBoardApplications.findMany({
  where: (apps, { and, eq, or }) =>
    and(
      eq(apps.jobBoardId, profile.id),
      search ? ilike(apps.employer.name, `%${search}%`) : undefined,
    ),
  with: {
    employer: true,
  },
  offset,
  limit,
});

// Total count query
const [countResult] = await db
  .select({
    count: sql<number>`count(*)`,
  })
  .from(employerJobBoardApplications)
  .where(
    and(
      eq(employerJobBoardApplications.jobBoardId, profile.id),
      search
        ? ilike(employerJobBoardApplications.employer.name, `%${search}%`)
        : undefined,
    ),
  );pla

代理模式

对于代理模式测试,我想让模型执行一个更复杂的多步骤任务。我有一个 项目模板库,我想添加的一个功能是新用户的入职流程,因此我将其用于代理任务。提示是:

Add an onboarding flow to this project. To do this, add a boolean `isOnboardingComplete`, string `onboardingPersona`, json string array `onboardingTopics` to the user table. A dialog should appear on logging in if onboarding hasn't been done. It should have a form and form elements for those two selections. On submit, it should set the onboarding values via server action using next-safe-action.

用户表在 Drizzle ORM 模式文件中定义,因此代理预计会去查找并进行相关更改,而不需要我明确提及。当然,我也希望流程能够正常工作,并演示 next-safe-action 的使用方式,与我在项目其他部分的用法一致。

o3-mini

o3-mini 的表现并不理想。它运行得相当慢,我认为这主要是由于思考时间,而不是像 DeepSeek 那样的网络延迟问题(这里也只是推测)。不过,如果输出结果不错,这种情况是可以原谅的!

然而,事实并非如此。首先,我必须尝试两次,以确保它实际上成功完成:从输出的外观来看,它似乎在生成结束时可能被截断了:

I'll now update the user table schema to disable the linter error on the generic call for the JSON column. This update adds an ESLint disable comment on the onboardingTopics definition, which uses Drizzle ORM's .$type generic.
I'll apply the changes

看起来最后一句话被截断了,因此我想对输出的判断保持谨慎,以防它实际上只是没有完成它想要做的事情。但在第二次运行时,似乎它只是省略了最后一句话的标点符号。

查看它实际生成的内容,出现了一些令人惊讶的问题。最大的问题是,在我的第二次尝试中,它似乎在生成过程中半途而废,竟然说出“对于对话,你可以这样实现”,并给出一些带占位符的示例实现,但并没有真正完成任务。

在第一次尝试中,它确实完成了任务,但存在明显的问题:

  1. 它将文件放在了我的 monorepo 的根目录,而不是 next-app 目录。我到目前为止还没有需要为任何模型指定任何与 monorepo 相关的约束。
  2. 它创建了一个 global.d.ts 文件来定义 drizzle-orm 和其他包的类型,这根本不应该需要(我认为这是因为它在没有类型定义的根目录创建了文件)。
  3. 它创建的服务器操作没有像项目中的其他服务器操作那样使用 zod 模式,但除了这一点,它确实正确使用了 next-safe-action 包。
  4. 它创建的对话组件正确使用了 Shadcn UI 组件,但使用了内联 style 属性,而不是项目中其余部分的 tailwind 类。

所以看起来它在 monorepo 设置上确实遇到了困难。

Claude 3.5 诗篇

诗篇正确地进行了架构更改,因此那部分是成功的。为了实现对话框,它选择将整个应用程序包装在一个包装组件中,结构如下:

export function OnboardingWrapper({ children }: Props) {
  const { isOpen } = useOnboarding();
  return (
    <>
      <OnboardingDialog isOpen={isOpen} />
      {children}
    </>
  );
}

这并不差,然而,useOnboarding 钩子看起来是这样的:

import { useEffect, useState } from "react";
import { getUser } from "../actions/user";

export function useOnboarding() {
  const [isOpen, setIsOpen] = useState(false);
  useEffect(() => {
    const checkOnboarding = async () => {
      const user = await getUser();
      if (user && !user.isOnboardingComplete) {
        setIsOpen(true);
      }
    };
    checkOnboarding();
  }, []);
  return {
    isOpen,
  };
}

这里有一个问题:useOnboarding 钩子直接使用了服务器操作,这在钩子中是无法做到的。我想知道模型是否假设服务器操作是通过 next-safe-action 实现的,因此直接使用是可以的,所以我在这里给它半分。

在客户端首次加载时调用服务器操作也不是很好,这意味着对话框不会立即出现,而是在 getUser 解析后闪现出来。

对话框组件本身相当不错,并且正确使用了 next-safe-action。它识别到我在前端使用 Shadcn UI,因此尝试使用 Select 组件,尽管我还没有添加它,但这是一个快速的修复。

它创建的服务器操作是相当正确的,但使用 next-safe-action 的语法有点不对。虽然这不是大问题,但我认为它应该能够查看项目中的其他用法,以匹配已经使用的模式。

总体而言,这是一个不错的输出,但钩子设置是不可用的,我需要要求它重做那部分。

DeepSeek 和 Gemini 2 Flash

DeepSeek 和 Gemini 模型目前不支持 Cursor 中的代理模式,因此我们将来需要对此进行回顾。

结论

我对 o3-mini 充满了期待,并且对 Gemini 2 Flash 的表现也很感兴趣,但我惊讶地发现,在实际开发使用中,两者都没有让我感到惊艳。事实上,所有模型在这些任务上似乎都有些挣扎,甚至包括 Claude 3.5 Sonnet。我对这些测试结果感到更加惊讶,因为针对这些模型发布了许多编码基准——到目前为止,我在实践中还没有看到与这些基准相匹配的结果。

因此,最终在代理模式下,o3-mini 在单一代码库的设置中确实表现不佳。由于我非常喜欢单一代码库,并且大部分时间使用代理模式,所以我现在肯定会继续使用 Claude 3.5 Sonnet!

现在我们等待完整的 o3 模型在本季度晚些时候发布(希望如此)。

Related Posts

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

AI 研究报告和论文写作 合并两个系统指令以获得两个模型的最佳效果 Perplexity AI 的 Deep Research 工具提供专家级的研究报告,而 OpenAI 的 ChatGPT-o3-mini-high 擅长推理。我发现你可以将它们结合起来生成令人难以置信的论文,这些论文比任何一个模型单独撰写的都要好。你只需要将这个一次性提示复制到 **

阅读更多
让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

Non members click here作为一名软件开发人员,多年来的一个发现总是让我感到惊讶,那就是人们还在 Excel

阅读更多
使用 ChatGPT 搜索网络功能的 10 种创意方法

使用 ChatGPT 搜索网络功能的 10 种创意方法

例如,提示和输出 你知道可以使用 ChatGPT 的“搜索网络”功能来完成许多任务,而不仅仅是基本的网络搜索吗? 对于那些不知道的人,ChatGPT 新的“搜索网络”功能提供实时信息。 截至撰写此帖时,该功能仅对使用 ChatGPT 4o 和 4o-mini 的付费会员开放。 ![](https://images.weserv.nl/?url=https://cdn-im

阅读更多
掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

10 个常见问题解答 本文是我推出的一个名为“10 个常见问题解答”的新系列的一部分。在本系列中,我旨在通过回答关于该主题的十个最常见问题来分解复杂的概念。我的目标是使用简单的语言和相关的类比,使这些想法易于理解。 图片来自 [Solen Feyissa](https://unsplash.com/@solenfeyissa?utm_source=medium&utm_medi

阅读更多
在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和科技这样一个动态的行业中,保持领先意味着不断提升你的技能。无论你是希望深入了解人工智能模型性能、掌握数据分析,还是希望通过人工智能转变传统领域如法律,这些课程都是你成功的捷径。以下是一个精心策划的高价值课程列表,可以助力你的职业发展,并让你始终处于创新的前沿。 1. 生成性人工智能简介课程: [生成性人工智能简介](https://genai.works

阅读更多
揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

在AI军备竞赛中分辨事实与虚构 DeepSeek AI真的是它所宣传的游戏规则改变者,还是仅仅聪明的营销和战略炒作?👀 虽然一些人将其视为AI效率的革命性飞跃,但另一些人则认为它的成功建立在借用(甚至窃取的)创新和可疑的做法之上。传言称,DeepSeek的首席执行官在疫情期间像囤积卫生纸一样囤积Nvidia芯片——这只是冰山一角。 从其声称的550万美元培训预算到使用Open

阅读更多
Type something to search...