• בלוג
  • איך לשלוח הודעות עדכון מ Tools ב Vercel AI SDK

איך לשלוח הודעות עדכון מ Tools ב Vercel AI SDK

22/07/2025

בדוגמה מהאתר של Vercel AI SDK הם מראים איך לקרוא לכלים מתוך הסוכן עם הקוד הבא:

import { z } from 'zod';
import { generateText, tool } from 'ai';

const result = await generateText({
  model: yourModel,
  tools: {
    weather: tool({
      description: 'Get the weather in a location',
      parameters: z.object({
        location: z.string().describe('The location to get the weather for'),
      }),
      execute: async ({ location }) => ({
        location,
        temperature: 72 + Math.floor(Math.random() * 21) - 10,
      }),
    }),
  },
  prompt: 'What is the weather in San Francisco?',
});

זה עובד יופי כשהכלי קטן וחוזר מהר, אבל אם אנחנו צריכים מתוך הפונקציה של הכלי להציג למשתמש עוד הודעות להראות התקדמות או לשאול אישור זה כבר לא יעבוד. אין בממשק של Tools גישה לאוביקט ה Stream.

וכמו כל פעם שאני מבלה יותר מדי זמן בתיעוד של ספריה בשביל למצוא מנגנון שהיה צריך להיות הרבה יותר ברור, אני מעלה את הפיתרון לכאן כדי שנוכל לחזור ולהיזכר בו בעתיד. במקרה של Tools יש כמה נקודות:

  1. צריך ליצור את ה Stream בצורה יזומה לפני שמפעילים generateText, ואז לחבר את הפלט של generateText ל Stream שיצרנו.

  2. צריך לשים לב ש Vercel AI SDK המציאה פרוטוקול כדי להעביר metadata בשיחה. בכל הודעה יש תחילית של סוג ההודעה ואחריה נקודותיים ואז ההודעה עצמה בתוך מרכאות. התחילית לטקסט היא פשוט 0. לכן היינו יכולים לכתוב משהו כמו:

writer.write('0:"hello"');

אבל יותר קל להשתמש בפונקציה מובנית שלהם שנקראת formatDataStreamPart.

התוצאה נראית כך:

import { openai } from '@ai-sdk/openai';
import { generateId, createDataStreamResponse, streamText, formatDataStreamPart } from 'ai';

import tools from '@/lib/tools';

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

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

  // immediately start streaming (solves RAG issues with status, etc.)
  return createDataStreamResponse({
    execute: dataStream => {
      dataStream.write(formatDataStreamPart('text', 'Warming up!ֿ'));
      dataStream.writeMessageAnnotation({ chunk: 'processing' });

      const result = streamText({
        model: openai('gpt-4-turbo'),
        maxSteps: 5,
        tools: tools(jwtToken, dataStream),
        messages,
        onFinish() {
          // message annotation:
          dataStream.writeMessageAnnotation({
            id: generateId(), // e.g. id from saved DB record
            other: 'information',
          });

          // call annotation:
          dataStream.writeData('call completed');
        },
      });

      result.mergeIntoDataStream(dataStream);
    },
    onError: error => {
      // Error messages are masked by default for security reasons.
      // If you want to expose the error message to the client, you can do so here:
      return error instanceof Error ? error.message : String(error);
    },
  });
}

עכשיו מתוך כל tool אפשר לקרוא ל dataStream.write כדי להוסיף הודעות לשיחה, או לבנות Workflows יותר מורכבים עם מספר סוכנים שכל אחד יוסיף הודעות לשיחה מתוך generateText שלו.