Vercel AI Agent SDK 为何重要

Vercel AI Agent SDK 代表了开发人员构建自主 AI 工作流的范式转变。与仅响应提示的传统聊天机器人不同,代理可以将复杂的任务分解为多个步骤,验证其工作并不断迭代直至完成。

Vercel AI Agent SDK 的独特之处

内置流媒体

无需复杂的 WebSocket 设置,即可实时传输代理的想法、操作和结果

原生 Next.js 集成

专为 Next.js 设计,支持 App Router 和服务器组件

工具调用抽象

自动处理 OpenAI/Anthropic 工具调用协议的简单函数定义

ToolLoopAgent 类

新的统一界面可自动处理工具执行循环,减少 40% 的样板代码,并为您管理上下文、停止条件和消息数组

工具执行批准

具有 needsApproval 标志的原生人机交互模式,非常适合代码部署或数据删除等敏感操作

增强型流媒体

改进了背压支持,通过 onError 回调更好地处理错误,并使用 experimental_transform 进行自定义流转换

代码审查是 AI 代理的理想之选,因为它需要多个连续的步骤:分析代码结构、检查错误、根据代码规范进行验证、运行测试以及生成反馈。手动代码审查每个 PR 需要 30-45 分钟,而 AI 代理只需 5-10 分钟即可完成审查,且质量相当。将 AI 驱动的自动化集成到您的开发工作流程中, 可以显著提高团队的工作效率。

快速启动:47 分钟设置

本教程将帮助您在 47 分钟内从零开始部署 AI 代码审查代理。我们将构建一个包含沙盒验证、流式 UI 和 GitHub 集成的完整系统。如果您需要帮助实现可用于生产的 Web 应用程序 ,我们的团队擅长 Next.js 和 AI 集成。

步骤 1:安装依赖项(3 分钟)

# Install Vercel AI SDK v6 Beta with OpenAI
npm install ai@beta @ai-sdk/openai@beta @ai-sdk/react@beta zod

# Install E2B sandbox for code execution
npm install @e2b/sdk

# Note: Pin to specific versions in production as v6 is in beta
# and APIs may change in patch releases

第 2 步:创建代理 API 路由(15 分钟)

创建 app/api/review/route.ts

import { openai } from '@ai-sdk/openai';
import { streamText, tool, stepCountIs, UIMessage, convertToModelMessages } from 'ai';
import { z } from 'zod';
import { Sandbox } from '@e2b/sdk';

export const runtime = 'edge';
export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages }: { messages: UIMessage[] } = await req.json();

  const result = streamText({
    model: openai('gpt-4o'),
    system: 'Expert code reviewer analyzing bugs, security, and best practices',
    messages: convertToModelMessages(messages),
    stopWhen: stepCountIs(5), // v6: Multi-step tool execution
    tools: {
      validateCode: tool({
        description: 'Execute code in sandbox',
        inputSchema: z.object({ code: z.string() }), // v6: inputSchema
        execute: async ({ code }) => {
          const sandbox = await Sandbox.create();
          try {
            const result = await sandbox.runCode(code);
            return { success: !result.error, output: result.stdout };
          } finally {
            await sandbox.close();
          }
        },
      }),
    },
  });

  return result.toUIMessageStreamResponse(); // v6: UI message response
}

步骤 3:构建前端(20 分钟)

创建 app/review/page.tsx

'use client';

import { useChat } from '@ai-sdk/react'; // v6: new import path
import { useState } from 'react';

export default function CodeReviewPage() {
  const [code, setCode] = useState('');
  const { messages, sendMessage, isLoading } = useChat({ // v6: sendMessage
    api: '/api/review',
  });

  return (
    <div className="container mx-auto p-6">
      <h1 className="text-3xl font-bold mb-6">AI Code Review</h1>

      <textarea
        value={code}
        onChange={(e) => setCode(e.target.value)}
        className="w-full h-64 p-4 border rounded-lg font-mono"
        placeholder="Paste your code here..."
      />

      <button
        onClick={() => sendMessage({ text: code })} // v6: sendMessage API
        disabled={isLoading}
        className="mt-4 px-6 py-2 bg-blue-600 text-white rounded-lg"
      >
        {isLoading ? 'Reviewing...' : 'Review Code'}
      </button>

      <div className="mt-8 space-y-4">
        {messages.map((msg) => (
          <div key={msg.id} className="p-4 rounded-lg bg-gray-50">
            {/* v6: messages have parts array */}
            {msg.parts.map((part, i) => {
              if (part.type === 'text') {
                return <div key={i} className="prose">{part.text}</div>;
              }
              if (part.type === 'tool-validateCode') {
                return <pre key={i}>{JSON.stringify(part, null, 2)}</pre>;
              }
            })}
          </div>
        ))}
      </div>
    </div>
  );
}

后端: 更改 parametersinputSchemamaxStepsstopWhen: stepCountIs(5)toDataStreamResponse()toUIMessageStreamResponse()

前端:@ai-sdk/react 导入,使用 sendMessage({text: '...'}) 代替 append() ,并通过 msg.parts[] 数组访问消息内容

步骤 4:部署到 Vercel(7 分钟)

# Deploy to Vercel
npx vercel --prod

# Add environment variables in dashboard:
# OPENAI_API_KEY, E2B_API_KEY

E2B 沙盒验证

沙盒验证对于生产环境的 AI 代理至关重要。如果没有沙盒验证,您就只能信任 AI 生成的代码在您的环境中运行,这会带来重大的安全风险。E2B 提供隔离的执行环境,确保代码安全运行。

文件系统访问: 恶意代码可以读取敏感文件或删除数据

网络请求: 代码可能会将数据泄露到外部服务器

资源耗尽: 无限循环可能导致服务器崩溃

依赖注入: 可能安装恶意软件包

高级沙盒配置

import { Sandbox } from '@e2b/sdk';

// Create sandbox with custom configuration
const sandbox = await Sandbox.create({
  template: 'nodejs',
  timeout: 30000, // 30 seconds max
  envVars: { NODE_ENV: 'test' },
});

// Execute with safety checks
const result = await sandbox.runCode(code, 'javascript', {
  networkAccess: false,    // Restrict network
  cpuLimit: '1000m',       // Limit CPU
  memoryLimit: '512Mi',    // Limit memory
});

// Always cleanup
await sandbox.close();

流式 UI 和实时更新

流式 UI 将用户体验从“等待和期盼”转变为“实时查看进度”。开发人员可以准确看到 AI 的分析内容,从而将感知等待时间缩短 60%。这对于代码审查尤为重要,因为分析可能需要 15-30 秒——如果没有流式 UI,用户通常会以为流程卡住了而放弃。

  • 内置流媒体,无需任何配置
  • 网络问题的自动重试和错误处理
  • 用户研究显示响应时间加快 60%
  • 调试代理的实时工具调用可见性

实现流

'use client';

import { useChat } from '@ai-sdk/react'; // v6: new import path

export default function StreamingReview() {
  const { messages, isLoading } = useChat({
    api: '/api/review',
    // v6: Tool calls are accessed via message.parts array
  });

  return (
    <div className="h-screen flex flex-col">
      <div className="flex-1 overflow-y-auto p-6 space-y-4">
        {messages.map((msg) => (
          <div key={msg.id}>
            {msg.parts.map((part, i) => {
              if (part.type === 'text') {
                return <div key={i}>{part.text}</div>;
              }
              // Handle tool parts like tool-validateCode
              if (part.type.startsWith('tool-')) {
                return <div key={i} className="text-sm text-gray-500">
                  Tool: {part.type.replace('tool-', '')}
                </div>;
              }
            })}
          </div>
        ))}
      </div>

      {isLoading && (
        <div className="p-4 bg-blue-50 border-t">
          <div className="flex items-center gap-2">
            <div className="animate-spin size-4 border-2
                          border-blue-600 border-t-transparent
                          rounded-full" />
            <span className="text-sm">Analyzing code...</span>
          </div>
        </div>
      )}
    </div>
  );
}

生产就绪模式

从原型到生产环境的迁移需要实现错误处理、重试逻辑、速率限制和监控。生产环境的 AI 代理必须能够妥善处理网络故障,通过速率限制防止滥用,并提供成本和性能的可视性。我们的自动化服务可以帮助您构建强大的生产级 AI 系统,并根据您的业务需求进行扩展。

错误处理和重试

export async function POST(req: Request) {
  try {
    const { messages }: { messages: UIMessage[] } = await req.json();

    // Validate input
    if (!messages || messages.length === 0) {
      return new Response('Invalid messages', { status: 400 });
    }

    const result = streamText({
      model: openai('gpt-4o'),
      messages: convertToModelMessages(messages),
      tools: { ... },
      stopWhen: stepCountIs(10), // v6: stopWhen instead of maxSteps
      maxRetries: 3, // Retry on failures
      onError: ({ error }) => {
        console.error('Agent error:', error);
        if (error.message.includes('rate_limit')) {
          return 'Rate limit exceeded. Try again soon.';
        }
        return 'Error during review. Please try again.';
      },
    });

    return result.toUIMessageStreamResponse(); // v6: UI message response
  } catch (error) {
    return new Response('Server error', { status: 500 });
  }
}

速率限制

import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';

// 10 requests per minute
const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(10, '1 m'),
});

export async function POST(req: Request) {
  const ip = req.headers.get('x-forwarded-for') || 'anonymous';
  const { success } = await ratelimit.limit(ip);

  if (!success) {
    return new Response('Rate limit exceeded', { status: 429 });
  }

  // Continue with review...
}

成本优化

GPT-4o

每条评论 0.20 美元 • 复杂的评论

受到推崇的

GPT-4o-迷你

$0.05/条评论 • 简单评论

预算

GitHub 集成

将您的 AI 代码审查代理与 GitHub 集成,以自动审查拉取请求、发表评论和更新状态检查。

GitHub Webhook

import { Octokit } from '@octokit/rest';

const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });

export async function POST(req: Request) {
  const payload = await req.json();

  if (payload.action === 'opened') {
    const pr = payload.pull_request;

    // Get PR files
    const { data: files } = await octokit.pulls.listFiles({
      owner: payload.repository.owner.login,
      repo: payload.repository.name,
      pull_number: pr.number,
    });

    // Review each file
    for (const file of files) {
      const review = await reviewCode(file.patch);

      // Post review comment
      await octokit.pulls.createReviewComment({
        owner: payload.repository.owner.login,
        repo: payload.repository.name,
        pull_number: pr.number,
        body: review.summary,
        path: file.filename,
        line: review.line,
      });
    }
  }

  return new Response('OK');
}

GitHub 操作

创建 .github/workflows/ai-review.yml

name: AI Code Review

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run AI Review
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: |
          curl -X POST https://your-app.vercel.app/api/review \
            -H "Content-Type: application/json" \
            -d '{"pr_number": ${{ github.event.pull_request.number }}}'

最佳实践与陷阱

从常见错误中吸取教训,并为可靠的 AI 代理实施经过实战检验的模式。

无超时限制: 始终设置 maxSteps 和请求超时以防止无限循环

盲目信任人工智能输出: 切勿在没有沙盒验证的情况下执行人工智能生成的代码

缺少错误处理: API 调用失败。优雅地处理错误并提供反馈

无速率限制: 没有限制,恶意用户可以耗尽您的 API 配额

长系统提示: 保持提示简洁以降低令牌成本

生产清单

通过重试实现错误处理

使用 maxRetries 和自定义错误处理程序

添加每个用户/IP 的速率限制

使用 Upstash Redis 防止滥用

设置 maxSteps 和超时

防止无限循环和失控成本

使用沙盒验证来执行代码

切勿在生产环境中运行不受信任的代码

准备好运送您的 AI 代理了吗?

现在,您已掌握使用 Vercel AI SDK v6 构建生产级 AI 代码审查代理所需的一切。从全新的 ToolLoopAgent 类到沙盒验证和 GitHub 集成,您已了解顶级工程团队所使用的模式。我们的实施已处理超过 50,000 个拉取请求,准确率超过 95%,帮助工程团队在保持严格质量标准的同时,将交付速度提高了 30%。