Di chuyển từ phiên bản 0.9 lên phiên bản 1.0

Genkit 1.0 giới thiệu nhiều tính năng nâng cao giúp cải thiện chức năng tổng thể; phiên bản này cũng có một số thay đổi có thể gây lỗi. Nếu đang phát triển ứng dụng bằng Genkit 0.9, bạn cần cập nhật mã ứng dụng khi nâng cấp lên phiên bản Genkit mới nhất. Hướng dẫn này trình bày những thay đổi đáng kể nhất và giải thích cách di chuyển các ứng dụng hiện có một cách suôn sẻ.

API thử nghiệm

Chúng tôi sẽ ra mắt một kênh API Beta không ổn định và để các API ứng dụng phiên, trò chuyện và Genkit ở giai đoạn thử nghiệm trong khi tiếp tục tinh chỉnh các API đó. Cụ thể hơn, các hàm sau đây hiện đang nằm trong không gian tên beta:

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

Cũ:

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

Mới:

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

Cũ:

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

Mới:

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

Giới thiệu gói @genkit-ai/express mới

Gói mới này chứa các tiện ích giúp bạn dễ dàng tạo máy chủ Express.js bằng Genkit. Bạn có thể xem thêm thông tin chi tiết về vấn đề này trên trang này.

startFlowServer đã chuyển từ một phần của đối tượng genkit sang gói @genkit-ai/express mới này; để sử dụng startFlowServer, bạn phải cập nhật các lệnh nhập.

Cũ:

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

Mới:

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

Thay đổi đối với Flow

Có một số thay đổi đối với flow trong phiên bản 1.0:

  • ai.defineStreamingFlow đã được hợp nhất vào ai.defineFlow,
  • onFlow đã được thay thế bằng onCallGenkit,
  • run đã chuyển sang ai.run,
  • Có thay đổi đối với việc làm việc với auth.

Hàm run cho các khối theo dõi tuỳ chỉnh đã chuyển sang một phần của đối tượng genkit; hãy sử dụng ai.run để gọi hàm này.

Cũ:

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

Mới:

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

Xoá ai.defineStreamingFlow; hãy sử dụng ai.defineFlow. Ngoài ra, streamingCallback đã chuyển sang một trường bên trong đối số thứ hai của hàm flow và hiện được gọi là sendChunk.

Cũ:

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

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

Mới:

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) {
  // ...
}

Lượt xác thực FlowAuth hiện được gọi là ngữ cảnh. Bạn có thể truy cập thông tin xác thực dưới dạng một trường bên trong ngữ cảnh:

Cũ:

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

Mới:

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

onFlow đã chuyển sang gói firebase-functions/https và được đổi tên thành onCallGenkit. Đoạn mã sau đây cho thấy ví dụ về cách sử dụng.

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

Mới:

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

Các chính sách xác thực đã bị xoá khỏi defineFlow. Việc xử lý chính sách xác thực hiện phụ thuộc vào máy chủ.

Cũ:

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

Đoạn mã sau đây cho thấy ví dụ về cách xử lý thông tin xác thực trong Express.

Mới:

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

Để biết thêm thông tin, hãy tham khảo tài liệu về xác thực.

Đoạn mã sau đây cho thấy ví dụ về cách xử lý việc xác thực trong Cloud Functions cho 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);

Lời nhắc

Chúng tôi đã thực hiện một số thay đổi và cải tiến đối với lời nhắc.

Bạn có thể xác định các mẫu riêng biệt cho lời nhắc và thông báo hệ thống:

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

Ngoài ra, bạn có thể xác định lời nhắc nhiều thông báo trong trường thông báo:

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

Thay vì mẫu lời nhắc, bạn có thể sử dụng một hàm:

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

Bạn có thể truy cập vào ngữ cảnh (bao gồm cả thông tin xác thực) từ trong lời nhắc:

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

Các hàm truyền trực tuyến không yêu cầu await

Cũ:

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

Mới:

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

Trình nhúng có loại dữ liệu trả về mới

Chúng tôi đã thêm tính năng hỗ trợ cho các nội dung nhúng đa phương thức. Thay vì chỉ trả về một vectơ nhúng, tính năng Nhúng sẽ trả về một mảng các đối tượng nhúng, mỗi đối tượng chứa một vectơ nhúng và siêu dữ liệu.

Cũ:

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

Mới:

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