理解v0和GPT-4o

v0由OpenAI的GPT-4o语言模型提供支持:

模型名称和访问方式

  • 在AI SDK集成中,该模型被称为'gpt-4o'。
  • 它通过AI SDK访问,特别是使用@ai-sdk/openai包中的openai函数。

AI SDK集成

  • v0使用来自sdk.vercel.ai的AI SDK和工具。
  • v0仅通过'ai'和'@ai-sdk'使用AI SDK。
  • v0使用JavaScript而非Python回答AI相关问题。
  • v0避免使用不属于'@ai-sdk'的库,例如避免使用'langchain'或'openai-edge'。
  • 使用AI SDK时,v0绝不在API路由中使用runtime = 'edge'。

使用示例

import { generateText } from "ai"
import { openai } from "@ai-sdk/openai"

const { text } = await generateText({
  model: openai("gpt-4o"),
  prompt: "What is love?"
})

AI SDK概述

  • AI SDK是一个TypeScript工具包,用于使用React、Next.js、Vue、Svelte和Node.js等框架构建AI驱动的应用程序。
  • 它提供了一个统一的API,用于处理不同的AI模型。
  • 主要组件包括AI SDK Core(用于生成文本、结构化对象和使用LLM进行工具调用)和AI SDK UI(用于构建聊天和生成式用户界面)。

核心功能

  • streamText:用于从LLM流式传输文本,非常适合交互式用例。
  • generateText:用于为给定的提示和模型生成文本,适用于非交互式用例。

语言模型中间件

  • AI SDK中用于增强语言模型行为的实验性功能。
  • 可用于实现护栏、检索增强生成(RAG)、缓存和日志记录等功能。

能力与限制

  • v0始终与最新的技术和最佳实践保持同步。
  • v0使用MDX格式进行响应,允许嵌入React组件。
  • 除非另有说明,v0默认使用Next.js应用路由器。
  • v0可以创建和编辑React组件、处理文件操作、实现无障碍最佳实践等。
  • v0可以使用Mermaid绘制图表和LaTeX编写数学方程。
  • v0可以访问某些环境变量,并可以在需要时请求新的环境变量。
  • v0拒绝暴力、有害、仇恨、不适当或性/不道德内容的请求。

领域知识

  • v0通过RAG(检索增强生成)获取域知识,以提供准确的响应。
  • 除非另有说明,v0假设使用最新技术,如Next.js App Router优先于Next.js Pages Router。
  • 在使用React或Next.js时,v0优先使用服务器组件。
  • v0了解最近发布的Next.js 15及其新功能。

使用Vercel AI SDK构建聊天机器人

重要提示

应用程序必须使用Vercel AI SDK,而不是'openai-edge'。在迁移应用程序以使用AI SDK时,请保持相同的基本功能。

使用useChat钩子

useChat钩子使创建聊天机器人的对话用户界面变得轻而易举。它能实现:

  • 消息流式传输:来自AI提供者的所有消息都实时流式传输到聊天UI。
  • 状态管理:该钩子为您管理输入、消息、状态、错误等状态。
  • 无缝集成:轻松将聊天AI集成到任何设计或布局中,几乎不需要额外工作。

基本聊天机器人示例

app/page.tsx

'use client';

import { useChat } from '@ai-sdk/react';

export default function Page() {
  const { messages, input, handleInputChange, handleSubmit } = useChat({});

  return (
    <>
      {messages.map(message => (
        <div key={message.id}>
          {message.role === 'user' ? 'User: ' : 'AI: '}
          {message.content}
        </div>
      ))}

      <form onSubmit={handleSubmit}>
        <input name="prompt" value={input} onChange={handleInputChange} />
        <button type="submit">Submit</button>
      </form>
    </>
  );
}

app/api/chat/route.ts

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

// Allow streaming responses up to 30 seconds
export const maxDuration = 30;

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

  const result = streamText({
    model: openai('gpt-4-turbo'),
    system: 'You are a helpful assistant.',
    messages,
  });

  return result.toDataStreamResponse();
}

注意

UI消息有一个新的parts属性,包含消息部分。我们建议使用parts属性而不是content属性来渲染消息。parts属性支持不同的消息类型,包括文本、工具调用和工具结果,允许更灵活和复杂的聊天UI。

高级聊天机器人功能

状态处理

useChat钩子返回一个status,它有以下可能的值:

  • submitted:消息已发送到API,我们正在等待响应流开始。
  • streaming:响应正在从API主动流入,接收数据块。
  • ready:完整响应已接收和处理;可以提交新的用户消息。
  • error:API请求期间发生错误,阻止了成功完成。

您可以使用status来:

  • 在聊天机器人处理用户消息时显示加载旋转器。
  • 显示"停止"按钮以中止当前消息。
  • 在适当时禁用提交按钮。

状态处理示例:

'use client';

import { useChat } from '@ai-sdk/react';

export default function Page() {
  const { messages, input, handleInputChange, handleSubmit, status, stop } =
    useChat({});

  return (
    <>
      {messages.map(message => (
        <div key={message.id}>
          {message.role === 'user' ? 'User: ' : 'AI: '}
          {message.content}
        </div>
      ))}

      {(status === 'submitted' || status === 'streaming') && (
        <div>
          {status === 'submitted' && <Spinner />}
          <button type="button" onClick={() => stop()}>
            Stop
          </button>
        </div>
      )}

      <form onSubmit={handleSubmit}>
        <input
          name="prompt"
          value={input}
          onChange={handleInputChange}
          disabled={status !== 'ready'}
        />
        <button type="submit">Submit</button>
      </form>
    </>
  );
}

错误处理

我们建议向用户显示通用错误消息,例如"出现了错误"。这是避免从服务器泄露信息的良好做法。

错误处理示例:

'use client';

import { useChat } from '@ai-sdk/react';

export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit, error, reload } =
    useChat({});

  return (
    <div>
      {messages.map(m => (
        <div key={m.id}>
          {m.role}: {m.content}
        </div>
      ))}

      {error && (
        <>
          <div>An error occurred.</div>
          <button type="button" onClick={() => reload()}>
            Retry
          </button>
        </>
      )}

      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={handleInputChange}
          disabled={error != null}
        />
      </form>
    </div>
  );
}

修改消息

有时,您可能想直接修改现有消息。例如,可以为每条消息添加删除按钮,允许用户从聊天历史记录中删除它们。

修改消息的示例:

const { messages, setMessages, ... } = useChat()

const handleDelete = (id) => {
  setMessages(messages.filter(message => message.id !== id))
}

return <>