前端也能写 AI Agent?用 Vercel AI SDK 十分钟跑通你的第一个智能助手

552 阅读4分钟

每次看到 Python 开发者用 LangChain 花式调 AI,是不是都有一瞬间的"要不要切语言"?

完全不用。你天天写的 TypeScript,已经足够做出一个能理解上下文、会调工具、流式吐字的 AI Agent。而且不用从零搭管道、不用自己写 SSE,Vercel AI SDK 把这些脏活全干了。

今天用十分钟,从零跑到一个能叫得出名字的 AI 助手。


Vercel AI SDK 是什么(一句话版)

它是一个 TypeScript 的 AI 工具包,帮你做三件事:

  1. 对接大模型:不管用的是 OpenAI、Claude、Gemini,还是国产模型,一个 model 参数切换
  2. 处理流式返回:不需要手写 SSE/WebSocket,SDK 帮你把 token 流转成 React 状态
  3. 工具调用(Tool Calling):让 AI 能调你的函数、查你的数据库、调你的 API

它和 Mastra、LangGraph.js 的关系可以这样理解:

框架一句话适合谁
Vercel AI SDKAI 能力的前端封装刚入门、想快速出效果
Mastra生产级 Agent 框架要做可观测、可测试的 AI 功能
LangGraph.js图编排复杂工作流多 Agent 协作、条件分支推理

先用 Vercel AI SDK 把门推开,后面两个自然就懂了。


环境准备

npx create-next-app@latest ai-agent-demo --typescript --tailwind --eslint --app --src-dir
cd ai-agent-demo
npm install ai @ai-sdk/openai

项目跑在 Next.js App Router 上,API Route 放后端逻辑、React 组件处理前端状态分层,这是 Vercel AI SDK 最舒服的姿势。

国产模型用户:@ai-sdk/openai 兼容所有 OpenAI 接口规范的模型。DeepSeek / 通义千问 / MoonShot 等只要在创建实例时改 baseURLapiKey 即可,后面会有示例。


第一个 Demo:流式聊天

这个 Demo 分两步:写一个 API Route,再写一个聊天组件。

1. API Route

路径 src/app/api/chat/route.ts

import { streamText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";

// 如果用国产模型,改这里的 baseURL 和 apiKey
const openai = createOpenAI({
  baseURL: "https://api.deepseek.com/v1",  // DeepSeek 示例
  apiKey: process.env.DEEPSEEK_API_KEY!,
});

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

  const result = streamText({
    model: openai("deepseek-chat"),
    system: "你是一个友好的前端技术助手,回答尽量简洁、带代码示例。",
    messages,
  });

  return result.toDataStreamResponse();
}

streamText 是 SDK 核心 API 之一。你只需要给它 modelmessages 和可选的 system prompt,它自己搞定流式管道,toDataStreamResponse() 直接返回一个标准 HTTP Response。

2. 前端聊天组件

路径 src/app/page.tsx

"use client";

import { useChat } from "ai/react";

export default function ChatPage() {
  const { messages, input, handleInputChange, handleSubmit } = useChat({
    api: "/api/chat",
  });

  return (
    <div className="max-w-2xl mx-auto p-4 flex flex-col h-screen">
      <h1 className="text-xl font-bold mb-4">🤖 前端 AI 助手</h1>

      {/* 消息列表 */}
      <div className="flex-1 overflow-y-auto space-y-3 mb-4">
        {messages.map((m) => (
          <div
            key={m.id}
            className={`p-3 rounded-lg ${
              m.role === "user"
                ? "bg-blue-100 ml-12"
                : "bg-gray-100 mr-12"
            }`}
          >
            {m.content}
          </div>
        ))}
      </div>

      {/* 输入框 */}
      <form onSubmit={handleSubmit} className="flex gap-2">
        <input
          value={input}
          onChange={handleInputChange}
          placeholder="问个前端问题..."
          className="flex-1 p-2 border rounded-lg"
        />
        <button
          type="submit"
          className="px-4 py-2 bg-blue-500 text-white rounded-lg"
        >
          发送
        </button>
      </form>
    </div>
  );
}

注意 useChat 这个 hook:它内部维护了 messages 数组、输入框状态,token 到了自动追加到数组末尾、自动渲染。你甚至不用知道 SSE 是什么。

跑起来:

npm run dev

打开 http://localhost:3000,随便问个问题,几行代码的聊天机器人就工作了。


进阶:让 AI 会"动手"

纯聊天是第一步,真正有用的是让 AI 调用你的函数:查数据库、调 API、读文件。这就是 Tool Calling。

场景:做一个帮忙查天气的 Agent

import { streamText, tool, stepCountIs } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
import { z } from "zod";

const openai = createOpenAI({
  baseURL: "https://api.deepseek.com/v1",
  apiKey: process.env.DEEPSEEK_API_KEY!,
});

// Tool 定义:查天气
const getWeather = tool({
  description: "获取指定城市的实时天气。当用户问天气相关问题时调用。",
  inputSchema: z.object({
    city: z.string().describe("城市名称,例如:北京"),
  }),
  execute: async ({ city }) => {
    // 模拟天气数据,实际接天气 API 即可
    const conditions = ["晴", "多云", "小雨", "阴"];
    const temp = Math.floor(Math.random() * 20) + 5;
    const cond = conditions[Math.floor(Math.random() * conditions.length)];

    return {
      city,
      temperature: `${temp}°C`,
      condition: cond,
    };
  },
});

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

  const result = streamText({
    model: openai("deepseek-chat"),
    system: "你是一个助手。当被问到天气时,使用 getWeather 工具获取数据后回复。",
    messages,
    tools: { getWeather },
    stopWhen: stepCountIs(3), // 最多 3 轮工具调用
  });

  return result.toDataStreamResponse();
}

代码里两个关键 API:

tool() 定义一个工具。description 告诉 AI 什么时候用它,inputSchema 用 Zod 定义参数(SDK 自动转 JSON Schema 给模型),execute 是你的业务逻辑。

stepCountIs(3) 限制最多跑 3 轮:AI 调工具 → 工具返回结果 → AI 根据结果继续推理。不加这个限制,复杂任务可能无限循环。

前端代码不用改,useChat 自己处理 tool calling 的中间状态。

Tool Calling 本质是模型和你的函数之间的"握手协议"。模型看到用户问题,根据 description 判断该不该调工具 → 如果调,按 inputSchema 的格式给你结构化的参数 → 你执行函数 → 结果塞回对话上下文 → 模型根据结果继续回答。这套机制在 Vercel AI SDK 里是自动的,你只需要写好 tool()


三个框架的「递进路线」

回到开头那张表。写完上面的 Demo 之后,你大概能感觉到 Vercel AI SDK 的特点:把 AI 能力包装成前端开发者熟悉的范式。useChatuseStatetool() 像定义 API handler。

它的责任范围止步于"单个 Agent 的单次对话"。当你需要这些能力时,就该往上走了:

你的需求适合框架
对话聊天、简单工具调用Vercel AI SDK
需要 Agent 记忆、RAG、生产可观测Mastra
多 Agent 协作、条件分支决策、复杂工作流LangGraph.js

不是非此即彼的关系,它们可以组合。你用 Vercel AI SDK 写 Agent 的核心逻辑,用 Mastra 加可观测性,用 LangGraph.js 编排多个 Agent 的协作流程。这三个套在一起,就是一个完整的 AI 工程栈。

关键是第一步:先用 Vercel AI SDK 把第一个 Agent 跑起来。剩下的路,跑起来了自然就知道往哪走。


总结

前端做 AI Agent 不是什么跨界,是你本来就有的 TypeScript 能力,换了个应用场景而已。

缺的不是 Python,只是十分钟。

你项目中有什么场景想用 AI Agent 来解决?评论区聊聊,根据需求量大的一种,下期出一个完整实战。


相关资源: