از 0.9 به 1.0 مهاجرت کنید

Genkit 1.0 بسیاری از پیشرفت‌ها را معرفی می‌کند که عملکرد کلی را بهبود می‌بخشد. همچنین دارای برخی تغییرات شکسته است. اگر برنامه‌هایی را با Genkit 0.9 توسعه می‌دهید، هنگام ارتقاء به آخرین نسخه Genkit باید کد برنامه خود را به‌روزرسانی کنید. این راهنما مهم‌ترین تغییرات را تشریح می‌کند و توضیح می‌دهد که چگونه برنامه‌های موجود خود را به آرامی منتقل کنید.

API های بتا

ما در حال معرفی یک کانال API بتای ناپایدار هستیم و APIهای سرویس گیرنده جلسه، چت و Genkit را در نسخه بتا باقی می‌گذاریم و همچنان به اصلاح آنها ادامه می‌دهیم. به طور خاص، توابع زیر در حال حاضر در فضای نام beta هستند:

  • ai.chat
  • ai.createSession
  • ai.loadSession
  • ai.currentSession
  • ai.defineFormat
  • ai.defineInterrupt

قدیمی:

import { genkit } from 'genkit';
const ai = genkit({...})
const session = ai.createSession({ ... })

جدید:

import { genkit } from 'genkit/beta';
const ai = genkit({...})
const session = ai.createSession({ ... })

قدیمی:

import { runFlow, streamFlow } from 'genkit/client';

جدید:

import { runFlow, streamFlow } from 'genkit/beta/client';

معرفی بسته جدید @genkit-ai/express

این بسته جدید شامل ابزارهایی است که ساخت سرور Express.js با Genkit را آسان‌تر می‌کند. در این صفحه می توانید جزئیات بیشتری در این مورد بیابید.

startFlowServer از بخشی از شی genkit به این بسته جدید @genkit-ai/express منتقل شده است. برای استفاده از startFlowServer، باید واردات خود را به روز کنید.

قدیمی:

const ai = genkit({ ... });
ai.startFlowServer({
  flows: [myFlow1, myFlow2],
});

جدید:

import { startFlowServer } from '@genkit-ai/express';
startFlowServer({
  flows: [myFlow1, myFlow2],
});

تغییرات در جریان

چندین تغییر در جریان ها در 1.0 وجود دارد:

  • ai.defineStreamingFlow به ai.defineFlow ادغام شده است،
  • onFlow با onCallGenkit جایگزین شده است.
  • run به ai.run منتقل شده است،
  • تغییراتی در کار با auth وجود دارد.

تابع run برای بلوک های ردیابی سفارشی به بخشی از شی genkit منتقل شده است. از ai.run برای فراخوانی آن استفاده کنید.

قدیمی:

ai.defineFlow({name: 'banana'}, async (input) => {
  const step = await run('myCode', async () => {
    return 'something'
  });
})

جدید:

ai.defineFlow({name: 'banana'}, async (input) => {
  const step = await ai.run('myCode', async () => {
    return 'something'
  });
})

ai.defineStreamingFlow حذف شده است. به جای آن از ai.defineFlow استفاده کنید. همچنین، streamingCallback به فیلدی در داخل آرگومان دوم تابع جریان منتقل شده است و اکنون sendChunk نامیده می‌شود.

قدیمی:

const flow = ai.defineStreamingFlow({name: 'banana'}, async (input, streamingCallback) => {
  streamingCallback({chunk: 1});
})

const {stream} = await flow()
for await (const chunk of stream) {
  // ...
}

جدید:

const flow = ai.defineFlow({name: 'banana'}, async (input, {context, sendChunk}) => {
  sendChunk({chunk: 1});
})

const {stream, output} = flow.stream(input);
for await (const chunk of stream) {
  // ...
}

FlowAuth auth اکنون زمینه نامیده می شود. شما می توانید به عنوان یک فیلد در داخل زمینه به auth دسترسی پیدا کنید:

قدیمی:

ai.defineFlow({name: 'banana'}, async (input) => {
  const auth = getFlowAuth();
  // ...
})

جدید:

ai.defineFlow({name: 'banana'}, async (input, { context }) => {
  const auth = context.auth;
})

onFlow به بسته firebase-functions/https منتقل شد و به onCallGenkit تغییر نام داد. قطعه زیر نمونه ای از نحوه استفاده از آن را نشان می دهد.

قدیمی

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

export const generatePoem = onFlow(
  ai,
  {
    name: "jokeTeller",
    inputSchema: z.string().nullable(),
    outputSchema: z.string(),
    streamSchema: z.string(),
  },
  async (type, streamingCallback) => {
    const { stream, response } = await ai.generateStream(
      `Tell me a longish ${type ?? "dad"} joke.`
    );
    for await (const chunk of stream) {
      streamingCallback(chunk.text);
    }
    return (await response).text;
  }
);

جدید:

import { onCallGenkit } from "firebase-functions/https";
import { defineSecret } from "firebase-functions/params";
import { genkit, z } from "genkit";

const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");

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

export const jokeTeller = ai.defineFlow(
  {
    name: "jokeTeller",
    inputSchema: z.string().nullable(),
    outputSchema: z.string(),
    streamSchema: z.string(),
  },
  async (type, { sendChunk }) => {
    const { stream, response } = ai.generateStream(
      `Tell me a longish ${type ?? "dad"} joke.`
    );
    for await (const chunk of stream) {
      sendChunk(chunk.text);
    }
    return (await response).text;
  }
);

export const tellJoke = onCallGenkit({ secrets: [apiKey] }, jokeTeller);

خط‌مشی‌های احراز هویت از defineFlow حذف شده‌اند. مدیریت خط‌مشی‌های احراز هویت اکنون به سرور وابسته است.

قدیمی:

export const simpleFlow = ai.defineFlow(
  {
    name: 'simpleFlow',
    authPolicy: (auth, input) => {
      // auth policy
    },
  },
  async (input) => {
    // Flow logic here...
  }
);

قطعه زیر نمونه ای از مدیریت auth در Express را نشان می دهد.

جدید:

import { UserFacingError } from 'genkit';
import { ContextProvider, RequestData } from 'genkit/context';
import { expressHandler, startFlowServer } from '@genkit-ai/express';

const context: ContextProvider<Context> = (req: RequestData) => {
  return {
    auth: parseAuthToken(req.headers['authorization']),
  };
};

export const simpleFlow = ai.defineFlow(
  {
    name: 'simpleFlow',
  },
  async (input, { context }) => {
    if (!context.auth) {
      throw new UserFacingError("UNAUTHORIZED", "Authorization required.");
    }
    if (input.uid !== context.auth.uid) {
      throw new UserFacingError("UNAUTHORIZED", "You may only summarize your own profile data.");
    }
    // Flow logic here...
  }
);

const app = express();
app.use(express.json());
app.post(
  '/simpleFlow',
  expressHandler(simpleFlow, { context })
);
app.listen(8080);

// or

startFlowServer(
  flows: [withContextProvider(simpleFlow, context)],
  port: 8080
);

برای جزئیات بیشتر، به مستندات auth مراجعه کنید.

قطعه زیر نمونه ای از مدیریت auth در Cloud Functions برای Firebase را نشان می دهد:

import { genkit } from 'genkit';
import { onCallGenkit } from 'firebase-functions/https';

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

const simpleFlow = ai.defineFlow({
  name: 'simpleFlow',
}, async (input) => {
  // Flow logic here...
});

export const selfSummary = onCallGenkit({
  authPolicy: (auth, data) => auth?.token?.['email_verified'] && auth?.token?.['admin'],
}, simpleFlow);

درخواست می کند

ما چندین تغییر و بهبود در درخواست‌ها ایجاد کرده‌ایم.

می توانید الگوهای جداگانه ای برای پیام های اعلان و سیستم تعریف کنید:

const hello = ai.definePrompt({
  name: 'hello',
  system: 'talk like a pirate.',
  prompt: 'hello {{ name }}',
  input: {
    schema: z.object({
      name: z.string()
    })
  }
});
const { text } = await hello({name: 'Genkit'});

از طرف دیگر، می‌توانید اعلان‌های چند پیام را در قسمت پیام‌ها تعریف کنید:

const hello = ai.definePrompt({
  name: 'hello',
  messages: '{{ role "system" }} talk like a pirate. {{ role "user" }} hello {{ name }}',
  input: {
    schema: z.object({
      name: z.string()
    })
  }
});

به جای الگوهای سریع می توانید از یک تابع استفاده کنید:

ai.definePrompt({
  name: 'hello',
  prompt: async (input, { context }) => {
    return `hello ${input.name}`
  },
  input: {
    schema: z.object({
      name: z.string()
    })
  }
});

می‌توانید از داخل فرمان به متن (از جمله اطلاعات تأیید اعتبار) دسترسی داشته باشید:

const hello = ai.definePrompt({
  name: 'hello',
  messages: 'hello {{ @auth.email }}',
});

عملکردهای پخش جریانی نیازی به await ندارند

قدیمی:

const { stream, response } = await ai.generateStream(`hi`);
const { stream, output } = await myflow.stream(`hi`);

جدید:

const { stream, response } = ai.generateStream(`hi`);
const { stream, output } = myflow.stream(`hi`);

Embed یک نوع بازگشت جدید دارد

ما پشتیبانی از تعبیه‌های چندوجهی را اضافه کرده‌ایم. به جای برگرداندن تنها یک بردار جاسازی، Embed آرایه ای از اشیاء جاسازی شده را برمی گرداند که هر کدام حاوی یک بردار جاسازی و ابرداده است.

قدیمی:

const response = await ai.embed({embedder, content, options});  // returns number[]

جدید:

const response = await ai.embed({embedder, content, options}); // returns Embedding[]
const firstEmbeddingVector = response[0].embedding;  // is number[]