מעבר מגרסה 0.5

ב-Genkit 0.9 יש כמה שינויים משמעותיים לצד שיפורים בפיצ'רים שמשפרים את הפונקציונליות הכוללת. אם פיתחתם אפליקציות באמצעות Genkit 0.5, תצטרכו לעדכן את קוד האפליקציה כשתשדרגו לגרסה האחרונה. במדריך הזה מפורטים השינויים המשמעותיים ביותר, ומוסבר איך להעביר את האפליקציות הקיימות בצורה חלקה.

מדריך למתחילים

בעזרת השלבים הבאים תוכלו לעבור במהירות מ-Genkit 0.5 ל-Genkit 0.9. מידע נוסף על השינויים האלה זמין ביומן השינויים המפורט שבהמשך.

1. התקנת ה-CLI החדש

  • הסרת ה-CLI הישן

    npm uninstall -g genkit && npm uninstall genkit
    
  • התקנת ה-CLI החדש

    npm i -D genkit-cli
    

2. עדכון יחסי התלות

  • הסרת חבילות ליבה ספציפיות של Genkit

    npm uninstall @genkit-ai/ai @genkit-ai/core @genkit-ai/dotprompt @genkit-ai/flow
    
  • התקנת החבילה המאוחדת החדשה genkit

    npm i --save genkit
    
  • משדרגים את כל הגרסאות של הפלאגין (דוגמה בהמשך)

    npm upgrade @genkit-ai/firebase
    

3. שינוי היבוא

  • הסרת ייבוא של חבילות ליבה ספציפיות של Genkit

    import { … } from '@genkit-ai/ai';
    import { … } from '@genkit-ai/core';
    import { … } from '@genkit-ai/flow';
    
  • הסרת ייבוא של zod

    import * as z from 'zod';
    
  • ייבוא של genkit ו-zod מ-genkit

    import { z, genkit } from 'genkit';
    

4. עדכון הקוד

מסירים את הבלוק configureGenkit

ההגדרה של Genkit מתבצעת עכשיו לכל מכונה בנפרד. טלמטריה ורישום ביומן מוגדרים באופן גלובלי בנפרד מהמכונה של Genkit.

  • מחליפים את configureGenkit בבלוקים של ai = genkit({...}). שומרים רק את הגדרות הפלאגין.

    import { genkit } from 'genkit';
    
    const ai = genkit({ plugins: [...]});
    
  • הגדרת טלמטריה באמצעות enableFirebaseTelemetry או enableGoogleCloudTelemetry

    ב-Firebase:

    import { enableFirebaseTelemetry } from '@genkit-ai/firebase';
    
    enableFirebaseTelemetry({...});
    

    ב-Google Cloud:

    import { enableGoogleCloudTelemetry } from '@genkit-ai/google-cloud';
    
    enableGoogleCloudTelemetry({...});
    
  • הגדרת רמת הרישום ביומן בנפרד ```js import { logger } from 'genkit/logging';

    logger.setLogLevel('debug'); ‎```

במסמכי העזרה בנושא מעקב ורישום ביומן מוסבר בהרחבה איך מגדירים טלמטריה ורישום ביומן.

במאמר תחילת העבודה מוסבר בהרחבה איך מגדירים מכונה של Genkit.

העברת פעולות של Genkit כך שיופעלו מהמכונה genkit

פעולות (תהליכים, כלים, שירותי אחזור, שירותי הוספה לאינדקס וכו') מוגדרות לכל מכונה בנפרד. מומלץ לקרוא את רשימת השינויים כדי לקבל מידע על כל התכונות שצריך לשנות, אבל הנה כמה דוגמאות לתכונות נפוצות.

import { genkit } from 'genkit';
import { onFlow } from '@genkit-ai/firebase/functions';

const ai = genkit({ plugins: [...]});

// Flows and tools are defined on the specific genkit instance
// and are directly callable.
const sampleFlow = ai.defineFlow(...);
const sampleTool = ai.defineTool(...);

async function callMyFlow() {
  // Previously, text output could accessed via .text()
  // Now it is either .output() or .text
  return await sampleFlow().output();
}

// onFlow now takes the Genkit instance as first argument
// This registers the flow as a callable firebase function
onFlow(ai, ...);
const flows = [ sampleFlow, ... ];
// Start the flow server to make the registered flows callable over HTTP
ai.startFlowServer({flows});

5. מריצים אותו

# run the DevUI and your js code
genkit start -- <command to run node>
# run a defined flow
genkit flow:run <flowName>

יומן שינויים

1. שינויים ב-CLI

ממשק שורת הפקודה (CLI) עבר עדכונים משמעותיים ב-Genkit 0.9. הפקודה להפעלת Genkit השתנתה, וה-CLI הופרד לחבילה עצמאית שצריך להתקין בנפרד.

כדי להתקין את ה-CLI:

npm i -g genkit-cli

בוצעו כמה שינויים בפקודה genkit start:

הפעלה של קוד האפליקציה של Genkit + ממשק המשתמש של הפיתוח ביחד:

genkit start -- [start command]
genkit start -- tsx src/index.ts
genkit start -- go run main.go

יש גם תמיכה במצב צפייה:

genkit start -- tsx --watch src/index.ts

מפעילה רק את קוד האפליקציה במצב הפיתוח של Genkit:

genkit start --noui -- <start command>
genkit start --noui -- tsx src/index.ts

מפעיל את ממשק המשתמש למפתחים בלבד:

genkit start

בעבר, הפקודה genkit start הייתה מפעילה את ממשק המשתמש של הפיתוח ואת קוד האפליקציה יחד. אם יש לכם צינורות עיבוד נתונים של CI/CD שמסתמכים על הפקודה הזו, יכול להיות שתצטרכו לעדכן את צינור עיבוד הנתונים.

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

2. חבילות וייבוא פשוטים יותר

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

הקודם:

npm i @genkit-ai/core @genkit-ai/ai @genkit-ai/flow @genkit-ai/dotprompt

חדש:

npm i genkit

הקודם:

import { … } from '@genkit-ai/ai';
import { … } from '@genkit-ai/core';
import { … } from '@genkit-ai/flow';
import * as z from 'zod';

חדש:

import { genkit, z } from 'genkit';

עדיין צריך להתקין ולייבא את הפלאגינים של Genkit בנפרד.

3. הגדרת Genkit

בעבר, כדי לאתחל את Genkit, היינו צריכים לבצע קריאה לפונקציה configureGenkit פעם אחת ברמת האפליקציה. כל המשאבים של Genkit (תהליכים, כלים, הנחיות וכו') יהיו מחוברים באופן אוטומטי לתצורה הגלובלית הזו.

ב-Genkit 0.9 נוספו מכונות Genkit, שכל אחת מהן מכילה הגדרה. דוגמאות:

הקודם:

import { configureGenkit } from '@genkit-ai/core';

configureGenkit({
  telemetry: {
    instrumentation: ...,
    logger: ...
  }
});

חדש:

import { genkit } from 'genkit';
import { logger } from 'genkit/logging';
import { enableFirebaseTelemetry } from '@genkit-ai/firebase';

logger.setLogLevel('debug');
enableFirebaseTelemetry({...});

const ai = genkit({ ... });

ננסה להסביר:

  • configureGenkit() הוחלף ב-genkit(), והוא מחזיר מופע Genkit מוגדר במקום להגדיר הגדרות באופן גלובלי.
  • פונקציית האיפוס של Genkit נמצאת עכשיו בחבילה genkit.
  • רישום ביומן וטלמטריה עדיין מוגדרים באופן גלובלי באמצעות שיטות מפורשות משלהם. ההגדרות האלה חלות באופן אחיד על כל המופעים של Genkit.

4. הגדרת תהליכים והפעלה מפורשת של שרת התהליכים

עכשיו, אחרי שיצרתם מכונה מוגדרת של Genkit, תצטרכו להגדיר את התהליכים. כל שיטות ה-API המרכזיות למפתחים, כמו defineFlow,‏ defineTool ו-onFlow, מופעלות עכשיו דרך המופע הזה.

זה שונה מהדרך הקודמת, שבה תהליכים וכלים נרשמו באופן גלובלי.

הקודם:

import { defineFlow, defineTool, onFlow } from '@genkit-ai/core';

defineFlow(...);
defineTool(...);

onFlow(...);

חדש:

// Define tools and flows
const sampleFlow = ai.defineFlow(...);
const sampleTool = ai.defineTool(...);

// onFlow now takes the Genkit instance as first argument
// This registers the flow as a callable firebase function
onFlow(ai, ...);  

const flows = [ sampleFlow, ... ];
// Start the flow server to make the registered flows callable over HTTP
ai.startFlowServer({flows});

נכון לעכשיו, כל הפלואואים שרוצים להפוך לזמינים צריכים להיות רשומים במפורש במערך flows שלמעלה.

5. צריך להגדיר כלים והנחיות באופן סטטי

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

בגרסה 0.9 של Genkit, התנהגות כזו כבר לא מותרת. במקום זאת, צריך להגדיר את כל הפעולות והתהליכים מחוץ לביצוע התהליך (כלומר באופן סטטי).

השינוי הזה אוכף הפרדה מחמירה יותר בין הגדרות הפעולות לבין הביצוע שלהן.

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

❌ אסור:

const flow = defineFlow({...}, async (input) => {
  const tool = defineTool({...});
  await tool(...);
});

✅ צריך:

const tool = ai.defineTool({...});

const flow = ai.defineFlow({...}, async (input) => {
  await tool(...);
});

6. ממשק API חדש לזרימות סטרימינג

בגרסה 0.9 של Genkit, הפשטנו את התחביר להגדרת תהליך סטרימינג ולהפעלה שלו.

קודם כל, defineFlow ו-defineStreamingFlow הופרדו. אם יש לכם תהליך שמיועד לשידור, תצטרכו לעדכן את הקוד כדי להגדיר אותו באמצעות defineStreamingFlow.

שנית, במקום להפעיל פונקציות נפרדות של stream() ו-response(), עכשיו גם הסטרימינג וגם התגובה הם ערכים שמוחזרים ישירות מהזרימה. השינוי הזה מפשט את הסטרימינג של הנתונים.

הקודם:

import { defineFlow, streamFlow } from '@genkit-ai/flow';

const myStreamingFlow = defineFlow(...);
const { stream, output } = await streamFlow(myStreamingFlow, ...);

for await (const chunk of stream()) {
  console.log(chunk);
}

console.log(await output());

חדש:

const myStreamingFlow = ai.defineStreamingFlow(...);
const { stream, response } = await myStreamingFlow(...);

for await (const chunk of stream) {
  console.log(chunk);
}

console.log(await response);

7. שיטות הכיתה GenerateResponse הוחלפו במאפייני getter

בעבר, הגישה לתגובה המובנית או לטקסט שלה התבצעה באמצעות שיטות מחלקה, כמו output() או text().

ב-Genkit 0.9, השיטות האלה הוחלפו במאפייני getter. כך קל יותר לעבוד עם התשובות.

הקודם:

const response = await generate({ prompt: 'hi' });
console.log(response.text());

חדש:

const response = await ai.generate('hi');
console.log(response.text);

אותו הדבר חל על output:

הקודם:

console.log(response.output());

חדש:

console.log(response.output);

8. יצירת מועמדים בוטלה

ב-Genkit 0.9, הטיפול בתשובות פשוט יותר כי המאפיין candidates הוסר. בעבר, התשובות יכלו להכיל כמה מועמדים, והייתם צריכים לטפל בהם באופן מפורש. עכשיו רק המועמד הראשון מוחזר ישירות בתגובה פשוטה.

כל קוד שמקבל גישה ישירות לנתוני המועמדים לא יפעל יותר.

הקודם:

const response = await generate({
 messages: [ { role: 'user', content: ...} ]
});
console.log(response.candidates); // previously you could access candidates directly

חדש:

const response = await ai.generate({
 messages: [ { role: 'user', content: ...} ]
});
console.log(response.message); // single candidate is returned directly in a flat response

9. Generate API – שיפורים של שיחות בכמה שלבים

בשיחות עם כמה תשובות, השיטה הישנה toHistory() הוחלפה ב-messages, וכך הפכנו את הטיפול בהיסטוריית השיחות לפשוט יותר.

הקודם:

const history = response.toHistory();

חדש:

const response = await ai.generate({
 messages: [ { role: 'user', content: ...} ]
});
const history = response.messages;

10. Chat API משופר

ב-Genkit 0.9, Chat API עוצב מחדש כדי להקל על ניהול הסשנים ועל האינטראקציה. כך תוכלו להשתמש בו גם בחוויית צ'אט סינכרונית וגם בחוויית צ'אט בסטרימינג:

import { genkit } from 'genkit';
import { gemini15Flash, googleAI } from '@genkit-ai/googleai';

const ai = genkit({
 plugins: [googleAI()],
 model: gemini15Flash,
});

const session = ai.createSession({ store: firestoreSessionStore() });
const chat = await session.chat({ system: 'talk like a pirate' });

let response = await chat.send('hi, my name is Pavel');
console.log(response.text()); // "hi Pavel, I'm llm"

// continue the conversation
response = await chat.send("what's my name");
console.log(response.text()); // "Pavel"

// can stream
const { response, stream } = await chat.sendStream('bye');
for await (const chunk of stream) {
 console.log(chunk.text());
}
console.log((await response).text());

// can load session from the store
const prevSession = await ai.loadSession(session.id, { store });
const prevChat = await prevSession.chat();
await prevChat.send('bye');