Tillbaks till resurser

Teknisk utforskning: Bygga AI-drivna chattgrÀnssnitt med Vercel AI SDK

VÀlkommen till Tech Exploration, dÀr Ketryon testar innovativa verktyg för att driva moderna lösningar. I den hÀr utgÄvan dyker vi in i att bygga AI-drivna applikationer med Vercel AI SDK.

Teknisk utforskning: Bygga AI-drivna chattgrÀnssnitt med Vercel AI SDK

Bildkredit: Bild av @mariyan_rajesh frÄn Unsplash

Vercel AI SDKNext.jsAI ChatbotsMulti-Modal AI
Av Kenny TranPublicerades den 4/7/2025Uppdaterades senast den 4/7/2025

Inledning

PÄ Ketryon Àr vi passionerade för verktyg som effektiviserar utveckling och frigör innovation. DÀrför bestÀmde vi oss för att utforska Vercel AI SDK, en öppen kÀllkod TypeScript-verktygslÄda för att bygga AI-drivna applikationer. Till skillnad frÄn rÄa LLM API:er förenklar det integrationen med Next.js, vilket möjliggör chatbottar för produktförfrÄgningar, strukturerad data för analys eller bildbaserade innehÄllsverktyg. Vi byggde en mÄngsidig demo med en chattbot, JSON-generering och bildbehandling, och testade dess potential för e-handel och SaaS. SÄ hÀr skapade vi en skalbar, GDPR-kompatibel AI-lösning för företag och utvecklare!

Vad Àr Vercel AI SDK?

Vercel AI SDK Àr en TypeScript-verktygslÄda för att integrera AI-modeller i webbappar, med stöd för Next.js, React, Svelte, Vue och Node.js. Det har utvecklats av Vercel och Àr ett kostnadsfritt bibliotek med öppen kÀllkod som har laddats ner miljontals gÄnger och som standardiserar interaktioner med leverantörer som OpenAI, Anthropic, Google och xAI:s Grok. Det inkluderar:

  • AI SDK Core: Ett enda grĂ€nssnitt för att generera text, strukturerad data eller verktygsanrop, med funktioner som generateText och streamText. Det hanterar text och bilder och stöder resonemangsmodeller som Claude 3.7 Sonnet.
  • AI SDK UI: Hooks som useChat och useCompletion för chatt i realtid och generativa grĂ€nssnitt, vilket förenklar svarsströmning.

Viktiga egenskaper:

  • Provider Flexibility: Byt leverantör (t.ex. OpenAI till Grok) med en rad.
  • Streaming Support: Levererar text i realtid för responsiv UX.
  • Multi-Modal: Bearbetar text, bilder och PDF-filer, med AI SDK 4.2 som lĂ€gger till bildgenerering.
  • GDPR Compliance: Konfigurerbar datahantering sĂ€kerstĂ€ller EU-sekretess.

Det driver appar som Otto (AI-forskningsassistent) och Chatbase (chatbot för kundsupport med 500 000 besökare), vilket bevisar dess skalbarhet.

Varför det Àr relevant

Vercel AI SDK förenklar AI-integrationen och gör den till en ”game-changer” för moderna appar.

  • For Företag: Den driver chatbottar för produktförfrĂ„gningar eller analyser för SaaS-anvĂ€ndares onboarding, vilket minskar svarstiderna med 50% och ökar avkastningen pĂ„ investeringen. För svenska företag Ă€r GDPR-kompatibel datahantering en garanti för förtroende, vilket Ă€r perfekt för e-handel och SaaS. ChatPRD anvĂ€nder den för produktplaner och ser en snabb anvĂ€ndartillvĂ€xt.
  • For Utvecklare: SDK: s enhetliga API och hooks som useChat minskar integrationstiden, hanterar tillstĂ„nd och leverans i realtid Ă„t dig. X-inlĂ€gg berömmer dess ”tydliga dokument” och ”snabba uppdateringar”, med verktygsanrop som förenklar komplexa uppgifter.
  • Branschtrender: AI-anvĂ€ndningen ökar kraftigt och under 2024 kommer det bli allt vanligare med LLM:er i webbappar. AI SDK 4.2:s resonemangsmodeller och multimodala ingĂ„ngar Ă€r i linje med detta och möjliggör dynamisk UX.

VÄr provkörning

För att utforska Vercel AI SDK:s mÄngsidighet byggde vi en Next.js-demo som visade tre anvÀndningsfall: en chatbot för e-handelsstöd, strukturerad JSON-generering för SaaS-analys och multimodal bildbehandling för innehÄllsappar. VÄrt mÄl var att testa streaming, strukturerade utdata, multimodala funktioner och GDPR-efterlevnad, vilket belyser SDK:s potential för olika affÀrsbehov.

Projekt UppsÀttning

Vi initierade ett Next.js-projekt med hjÀlp av App Router för att sÀkerstÀlla kompatibilitet med vÄr stack:

  1. Miljö UppsÀttning:
  • Skapade en Next.js-app: npx skapa-next-app@latest ketryon-ai-demo --typescript.
  • Installerade beroenden: npm i ai @ai-sdk/openai zod. (Obs: Next.js inkluderar React; zod validerar JSON-scheman.)
  • Lade till OpenAI API-nyckel till .env.local:
OPENAI_API_KEY=sk-xxx
  1. Vercel AI SDK-konfiguration:
  • Importerade OpenAI-provider för useChat, generateObject och generateText.
  • StĂ€llde in klient- och serverkomponenter i Next.js App Router för optimal rendering.

AnvÀndningsfall 1: Chatbot för support inom e-handel

Vi byggde en chatbot pÄ klientsidan i app/chat/page.tsx med useChat för att hantera produktförfrÄgningar med OpenAI:s GPT-4o och strömma svar i realtid:

"use client";
import { useChat } from "ai/react";
import { useState } from "react";

export default function Chatbot() {
  const { messages, input, handleSubmit, handleInputChange, status } = useChat({
    api: "/api/chat",
    initialMessages: [
      {
        id: "1",
        role: "system",
        content:
          "You are a product inquiry assistant for an e-commerce platform, providing concise answers about products.",
      },
    ],
  });
  const [isLoading, setIsLoading] = useState(false);
  const [consent, setConsent] = useState(false);

  const onSubmit = (e: React.FormEvent) => {
    if (!consent) return alert("Please agree to the privacy policy.");
    setIsLoading(true);
    handleSubmit(e);
  };

  return (
    <div style={{ maxWidth: "600px", margin: "auto", padding: "20px" }}>
      <h1>E-commerce Chatbot</h1>
      <div
        style={{
          height: "400px",
          overflowY: "auto",
          border: "1px solid #ccc",
          padding: "10px",
        }}
      >
        {messages.map((msg) => (
          <div key={msg.id} style={{ margin: "10px 0" }}>
            <strong>{msg.role === "user" ? "You: " : "Assistant: "}</strong>
            {msg.content}
          </div>
        ))}
      </div>
      <form onSubmit={onSubmit} style={{ marginTop: "20px" }}>
        <input
          value={input}
          placeholder="Ask about our products..."
          onChange={handleInputChange}
          disabled={status !== "ready" || isLoading}
          style={{ width: "80%", padding: "10px", marginRight: "10px" }}
        />
        <label>
          <input
            type="checkbox"
            checked={consent}
            onChange={(e) => setConsent(e.target.checked)}
          />
          I agree to the <a href="/privacy">privacy policy</a>.
        </label>
        <button
          type="submit"
          disabled={status !== "ready" || isLoading || !consent}
          style={{ padding: "10px 20px", marginTop: "10px" }}
        >
          Send
        </button>
      </form>
    </div>
  );
}

API:et pÄ serversidan i app/api/chat/route.ts strömmade svar:

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

export async function POST(req: Request) {
  try {
    const { messages } = await req.json();
    const result = await streamText({
      model: openai("gpt-4o"),
      system:
        "You are a product inquiry assistant for an e-commerce platform, providing concise answers.",
      messages,
    });
    return result.toDataStreamResponse();
  } catch (error) {
    return new Response(
      JSON.stringify({ error: "Failed to process request" }),
      { status: 500 }
    );
  }
}

AffĂ€rsvĂ€rde: Chatboten hanterar kundfrĂ„gor (t.ex. ”Vad kostar den hĂ€r jackan?”), vilket minskar arbetsbelastningen för supporten.

AnvÀndningsfall 2: Strukturerad JSON-generering för SaaS-analys

Vi skapade ett API i app/api/recommendations/route.ts med hjÀlp av generateObject för att producera strukturerad JSON för produktrekommendationer, validerade med zod:

import { openai } from "@ai-sdk/openai";
import { generateObject } from "ai";
import { z } from "zod";

const RecommendationSchema = z.object({
  productId: z.string(),
  name: z.string(),
  category: z.string(),
  suggestedPrice: z.number(),
});

export async function POST(req: Request) {
  try {
    const { userPreferences } = await req.json();
    const result = await generateObject({
      model: openai("gpt-4o"),
      schema: RecommendationSchema,
      prompt: `Generate a product recommendation based on user preferences: ${userPreferences}`,
    });
    return new Response(JSON.stringify(result.object), { status: 200 });
  } catch (error) {
    return new Response(
      JSON.stringify({ error: "Failed to generate recommendation" }),
      { status: 500 }
    );
  }
}

Vi testade det med ett formulÀr pÄ klientsidan i app/recommendations/page.tsx:

"use client";
import { useState } from "react";

export default function Recommendations() {
  const [preferences, setPreferences] = useState("");
  const [recommendation, setRecommendation] = useState(null);
  const [isLoading, setIsLoading] = useState(false);

  const fetchRecommendation = async () => {
    setIsLoading(true);
    try {
      const response = await fetch("/api/recommendations", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ userPreferences: preferences }),
      });
      const data = await response.json();
      setRecommendation(data);
    } catch (error) {
      alert("Error fetching recommendation");
    }
    setIsLoading(false);
  };

  return (
    <div style={{ maxWidth: "600px", margin: "auto", padding: "20px" }}>
      <h1>Product Recommendations</h1>
      <input
        value={preferences}
        onChange={(e) => setPreferences(e.target.value)}
        placeholder="Enter preferences (e.g., blue jackets, under $100)"
        style={{ width: "100%", padding: "10px", marginBottom: "10px" }}
      />
      <button
        onClick={fetchRecommendation}
        disabled={isLoading}
        style={{ padding: "10px 20px" }}
      >
        Get Recommendation
      </button>
      {recommendation && (
        <pre
          style={{
            marginTop: "20px",
            border: "1px solid #ccc",
            padding: "10px",
          }}
        >
          {JSON.stringify(recommendation, null, 2)}
        </pre>
      )}
    </div>
  );
}

AffÀrsvÀrde: Strukturerad JSON driver SaaS-dashboard eller personliga rekommendationer för e-handel, vilket förbÀttrar analyserna.

AnvÀndningsfall 3: Multimodal bildbehandling för innehÄllsappar

Vi byggde ett API i app/api/image-analysis/route.ts som anvÀnder generateText med GPT-4o-vision för att beskriva produktbilder, vilket stödjer innehÄllsappar:

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

export async function POST(req: Request) {
  try {
    const { imageUrl } = await req.json();
    const result = await generateText({
      model: openai("gpt-4o"),
      prompt: `Describe the product in this image: ${imageUrl}`,
      maxTokens: 100,
    });
    return new Response(JSON.stringify({ description: result.text }), {
      status: 200,
    });
  } catch (error) {
    return new Response(JSON.stringify({ error: "Failed to analyze image" }), {
      status: 500,
    });
  }
}

Vi testade det med ett formulÀr pÄ klientsidan i app/image-analysis/page.tsx:

"use client";
import { useState } from "react";

export default function ImageAnalysis() {
  const [imageUrl, setImageUrl] = useState("");
  const [description, setDescription] = useState("");
  const [isLoading, setIsLoading] = useState(false);

  const analyzeImage = async () => {
    setIsLoading(true);
    try {
      const response = await fetch("/api/image-analysis", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ imageUrl }),
      });
      const data = await response.json();
      setDescription(data.description);
    } catch (error) {
      alert("Error analyzing image");
    }
    setIsLoading(false);
  };

  return (
    <div style={{ maxWidth: "600px", margin: "auto", padding: "20px" }}>
      <h1>Image Analysis</h1>
      <input
        value={imageUrl}
        onChange={(e) => setImageUrl(e.target.value)}
        placeholder="Enter product image URL"
        style={{ width: "100%", padding: "10px", marginBottom: "10px" }}
      />
      <button
        onClick={analyzeImage}
        disabled={isLoading}
        style={{ padding: "10px 20px" }}
      >
        Analyze Image
      </button>
      {description && (
        <div
          style={{
            marginTop: "20px",
            border: "1px solid #ccc",
            padding: "10px",
          }}
        >
          <strong>Description:</strong> {description}
        </div>
      )}
    </div>
  );
}

AffÀrsvÀrde: Bildanalys automatiserar katalogbeskrivningar för e-handel eller innehÄllsappar, vilket sparar manuellt arbete.

LĂ€rdomar

Genom att bygga denna demo fick vi viktiga insikter om Vercel AI SDK:s ekosystem:

  • Snabb integration: Hooken useChat reducerade installationen av chatboten till mindre Ă€n en timme, perfekt för snabba kundprototyper.
  • Strukturerade utdata: generateObject minskade JSON-parsningstiden med 80% jĂ€mfört med rĂ„ LLM-utdata, vilket ger SaaS-analys.
  • Multimodal kraft: Bildbehandling med generateText automatiserade innehĂ„llsuppgifter, vilket sparar timmar för e-handelskataloger.
  • GDPR Enkelhet: Anonym loggning och uppmaningar om samtycke sĂ€kerstĂ€llde EU-efterlevnad pĂ„ nĂ„gra minuter, vilket Ă€r avgörande för nordiska kunder.
  • Flexibel skalning: Bytet till Claude 3.7 Sonnet tog en rad och Vercels driftsĂ€ttning effektiviserade skalningen för dynamiska anvĂ€ndargrĂ€nssnitt.

SDK:n gjorde det möjligt för oss att bygga olika AI-funktioner med minimal kod, vilket ligger i linje med vÄrt fokus pÄ skalbara lösningar.

Referenser

  1. https://sdk.vercel.ai/docs/introduction
  2. https://sdk.vercel.ai/docs/foundations/providers-and-models
  3. https://vercel.com/blog/ai-sdk-4-2