Heim > Artikel > Web-Frontend > Mehrere parallele KI-Streams mit dem Vercel AI SDK
Das Vercel AI SDK erleichtert die Interaktion mit LLM-APIs wie OpenAI, Anthropic usw. und das Streamen der Daten, sodass sie beim Laden schnell in Ihrer Web-App angezeigt werden. In diesem Artikel erfahren Sie, wie Sie mehrere Eingabeaufforderungen gleichzeitig ausführen und ihre Ergebnisse parallel sehen.
TL;DR: GitHub Repo ist da.
Es ist nicht ungewöhnlich, dass in einer Web-App mehrere Datenabrufanforderungen gleichzeitig ausgeführt werden sollen. Wenn beispielsweise in einem hypothetischen Blogging-System die Dashboard-Oberfläche geladen wird, möchten wir möglicherweise gleichzeitig die Profildaten des Benutzers, die von ihm erstellten Beiträge und die Beiträge anderer Benutzer, die er als Favorit markiert hat, abrufen.
Wenn dasselbe Dashboard gleichzeitig Anfragen an OpenAI sendet, möchten wir OpenAI möglicherweise gleichzeitig um Tipps zur Verbesserung des Benutzerprofils und um eine Analyse seines neuesten Beitrags bitten. Theoretisch könnten wir, wenn wir wollten, Dutzende von KI-Anfragen parallel nutzen (sogar von völlig unterschiedlichen Plattformen und Modellen) und gleichzeitig Informationen analysieren, Inhalte generieren und alle möglichen anderen Aufgaben erledigen.
Sie können das GitHub-Repo mit dem Endergebnis hier klonen.
So richten Sie es von Grund auf ein:
Die Hauptkomponente, die die ganze Arbeit erledigt, enthält ein Formular und einige Container für die Ausgabe. Unter Verwendung einiger grundlegender Shadcn-UI-Komponenten sieht das Formular folgendermaßen aus:
export function GenerationForm() { // State and other info will be defined here... return ( <form onSubmit={onSubmit} className="flex flex-col gap-3 w-full"> <div className="inline-block mb-4 w-full flex flex-row gap-1"> <Button type="submit">Generate News & Weather</Button> </div> {isGenerating ? ( <div className="flex flex-row w-full justify-center items-center p-4 transition-all"> <Spinner className="h-6 w-6 text-slate-900" /> </div> ) : null} <h3 className="font-bold">Historical Weather</h3> <div className="mt-4 mb-8 p-4 rounded-md shadow-md bg-blue-100"> {weather ? weather : null} </div> <h4 className="font-bold">Historical News</h4> <div className="mt-4 p-4 rounded-md shadow-md bg-green-100">{news ? news : null}</div> </form> ) }
Sie können sehen, dass wir hier ein paar Dinge haben:
Im Moment können Sie diese Werte fest codieren; Sie werden alle aus unseren Streams entnommen.
Die StreamAnswer-Serveraktion übernimmt die Aufgabe, unsere Streams zu erstellen und zu aktualisieren.
Die Struktur der Aktion ist folgende:
export async function streamAnswer(question: string) { // Booleans for indicating whether each stream is currently streaming const isGeneratingStream1 = createStreamableValue(true); const isGeneratingStream2 = createStreamableValue(true); // The current stream values const weatherStream = createStreamableValue(""); const newsStream = createStreamableValue(""); // Create the first stream. Notice that we don't use await here, so that we // don't block the rest of this function from running. streamText({ // ... params, including the LLM prompt }).then(async (result) => { // Read from the async iterator. Set the stream value to each new word // received. for await (const value of result.textStream) { weatherStream.update(value || ""); } } finally { // Set isGenerating to false, and close that stream. isGeneratingStream1.update(false); isGeneratingStream1.done(); // Close the given stream so the request doesn't hang. weatherStream.done(); } }); // Same thing for the second stream. streamText({ // ... params }).then(async (result) => { // ... }) // Return any streams we want to read on the client. return { isGeneratingStream1: isGeneratingStream1.value, isGeneratingStream2: isGeneratingStream2.value, weatherStream: weatherStream.value, newsStream: newsStream.value, }; }
Der onSubmit-Handler des Formulars erledigt hier die ganze Arbeit. Hier ist die Aufschlüsselung, wie es funktioniert:
"use client"; import { SyntheticEvent, useState } from "react"; import { Button } from "./ui/button"; import { readStreamableValue, useUIState } from "ai/rsc"; import { streamAnswer } from "@/app/actions"; import { Spinner } from "./svgs/Spinner"; export function GenerationForm() { // State for loading flags const [isGeneratingStream1, setIsGeneratingStream1] = useState<boolean>(false); const [isGeneratingStream2, setIsGeneratingStream2] = useState<boolean>(false); // State for the LLM output streams const [weather, setWeather] = useState<string>(""); const [news, setNews] = useState<string>(""); // We'll hide the loader when both streams are done. const isGenerating = isGeneratingStream1 || isGeneratingStream2; async function onSubmit(e: SyntheticEvent) { e.preventDefault(); // Clear previous results. setNews(""); setWeather(""); // Call the server action. The returned object will have all the streams in it. const result = await streamAnswer(question); // Translate each stream into an async iterator so we can loop through // the values as they are generated. const isGeneratingStream1 = readStreamableValue(result.isGeneratingStream1); const isGeneratingStream2 = readStreamableValue(result.isGeneratingStream2); const weatherStream = readStreamableValue(result.weatherStream); const newsStream = readStreamableValue(result.newsStream); // Iterate through each stream, putting its values into state one by one. // Notice the IIFEs again! As on the server, these allow us to prevent blocking // the function, so that we can run these iterators in parallel. (async () => { for await (const value of isGeneratingStream1) { if (value != null) { setIsGeneratingStream1(value); } } })(); (async () => { for await (const value of isGeneratingStream2) { if (value != null) { setIsGeneratingStream2(value); } } })(); (async () => { for await (const value of weatherStream) { setWeather((existing) => (existing + value) as string); } })(); (async () => { for await (const value of newsStream) { setNews((existing) => (existing + value) as string); } })(); } return ( // ... The form code from before. ); }
Das obige ist der detaillierte Inhalt vonMehrere parallele KI-Streams mit dem Vercel AI SDK. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!