0.9 sürümünden 1.0 sürümüne taşıma

Genkit 1.0, genel işlevselliği iyileştiren birçok özellik geliştirmesinin yanı sıra bazı önemli değişiklikler de içerir. Genkit 0.9 ile uygulama geliştiriyorsanız Genkit'in en son sürümüne geçtiğinizde uygulama kodunuzu güncellemeniz gerekir. Bu kılavuzda en önemli değişiklikler özetlenmiş ve mevcut uygulamalarınızın sorunsuz bir şekilde nasıl taşınacağı açıklanmaktadır.

Beta API'leri

Kararsız bir Beta API kanalı kullanıma sunuyoruz. Oturum, sohbet ve Genkit istemci API'lerini iyileştirmeye devam ettiğimiz için bu API'leri beta sürümünde bırakıyoruz. Daha ayrıntılı açıklamak gerekirse şu işlevler şu anda beta ad alanındadır:

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

Eski:

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

Yeni:

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

Eski:

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

Yeni:

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

Yeni @genkit-ai/express paketi kullanıma sunuldu

Bu yeni paket, Genkit ile Express.js sunucusu oluşturmayı kolaylaştıran yardımcı programlar içerir. Bu konuyla ilgili daha fazla bilgiyi bu sayfada bulabilirsiniz.

startFlowServer, genkit nesnesinin bir parçasından bu yeni @genkit-ai/express paketine taşındı. startFlowServer'ı kullanmak için içe aktarma işlemlerinizi güncellemeniz gerekir.

Eski:

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

Yeni:

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

Akışlarda yapılan değişiklikler

1.0 sürümünde akışlarda birkaç değişiklik yapılmıştır:

  • ai.defineStreamingFlow, ai.defineFlow ile birleştirildi.
  • onFlow, onCallGenkit ile değiştirildi.
  • run, ai.run adlı kuruluş birimine taşındı.
  • Kimlik doğrulamayla ilgili çalışmalarda değişiklikler yapıldı.

Özel izleme blokları için run işlevi, genkit nesnesinin bir parçasına taşındı. Bunun yerine ai.run işlevini kullanarak işlevi çağırın.

Eski:

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

Yeni:

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

ai.defineStreamingFlow kaldırıldı; bunun yerine ai.defineFlow kullanın. Ayrıca streamingCallback, akış işlevinin ikinci bağımsız değişkenindeki bir alana taşındı ve artık sendChunk olarak adlandırılıyor.

Eski:

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

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

Yeni:

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 kimlik doğrulaması artık context olarak adlandırılıyor. Bağlam içinde bir alan olarak kimlik doğrulamasına erişebilirsiniz:

Eski:

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

Yeni:

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

onFlow, firebase-functions/https paketine taşındı ve onCallGenkit olarak yeniden adlandırıldı. Aşağıdaki snippet'te bu işlevin nasıl kullanılacağına dair bir örnek gösterilmektedir.

Eski

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;
  }
);

Yeni:

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);

Kimlik doğrulama politikaları defineFlow'ten kaldırıldı. Kimlik doğrulama politikalarının işlenmesi artık sunucuya bağlıdır.

Eski:

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

Aşağıdaki snippet'te, Express'te kimlik doğrulamayı ele almanın bir örneği gösterilmektedir.

Yeni:

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
);

Daha fazla bilgi için autentikasyon belgelerine bakın.

Aşağıdaki snippet'te, Firebase için Cloud Functions'da kimlik doğrulamayı işleme örneği gösterilmektedir:

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);

İstemler

İstemlerde çeşitli değişiklikler ve iyileştirmeler yaptık.

İstem ve sistem mesajları için ayrı şablonlar tanımlayabilirsiniz:

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'});

Alternatif olarak, mesajlar alanında birden fazla mesaj istemi tanımlayabilirsiniz:

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

İstem şablonları yerine bir işlev kullanabilirsiniz:

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

İstemden bağlama (doğrulama bilgileri dahil) erişebilirsiniz:

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

Akış işlevleri için await gerekmez

Eski:

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

Yeni:

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

Yerleştirmenin yeni bir döndürme türü var

Çoklu biçimli yerleştirmeler için destek ekledik. Yerleştirme işlevi, yalnızca tek bir yerleştirme vektörü döndürmek yerine her biri bir yerleştirme vektörü ve meta veri içeren bir yerleştirme nesnesi dizisi döndürür.

Eski:

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

Yeni:

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