Gọi luồng Genkit từ Ứng dụng

Cloud Functions cho Firebase có một phương thức onCallGenkit cho phép bạn tạo một hàm có thể gọi bằng một thao tác Genkit (một Flow). Bạn có thể gọi các hàm này bằng genkit/beta/client hoặc SDK ứng dụng của Cloud Functions. Các hàm này sẽ tự động thêm thông tin xác thực.

Trước khi bắt đầu

  • Bạn phải quen thuộc với khái niệm luồng của Genkit và cách viết các luồng đó. Hướng dẫn trên trang này giả định rằng bạn đã xác định một số luồng mà bạn muốn triển khai.
  • Việc này rất hữu ích nhưng không bắt buộc nếu bạn đã từng sử dụng Cloud Functions cho Firebase.

Thiết lập dự án Firebase

  1. Tạo một dự án Firebase mới bằng bảng điều khiển của Firebase hoặc chọn một dự án hiện có.

  2. Nâng cấp dự án lên gói Blaze (bắt buộc để triển khai phiên bản chính thức của Hàm trên đám mây).

  3. Cài đặt Giao diện dòng lệnh (CLI) của Firebase.

  4. Đăng nhập bằng Firebase CLI:

    firebase login
    firebase login --reauth # alternative, if necessary
    firebase login --no-localhost # if running in a remote shell
  5. Tạo thư mục dự án mới:

    export PROJECT_ROOT=~/tmp/genkit-firebase-project1
    mkdir -p $PROJECT_ROOT
  6. Khởi chạy dự án Firebase trong thư mục:

    cd $PROJECT_ROOT
    firebase init functions

Phần còn lại của trang này giả định rằng bạn đã chọn viết các hàm bằng JavaScript.

Gói luồng trong onCallGenkit

Sau khi thiết lập dự án Firebase bằng Cloud Functions, bạn có thể sao chép hoặc viết định nghĩa luồng trong thư mục functions của dự án. Dưới đây là một luồng ví dụ minh hoạ điều này:

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

const jokeTeller = ai.defineFlow({
  name: "jokeTeller",
  inputSchema: z.string().nullable(),
  outputSchema: z.string(),
  streamSchema: z.string(),
}, async (jokeType = "knock-knock", {sendChunk}) => {
  const prompt = `Tell me a ${jokeType} joke.`;

  // Call the `generateStream()` method to
  // receive the `stream` async iterable.
  const {stream, response: aiResponse} = ai.generateStream(prompt);

  // Send new words of the generative AI response
  // to the client as they are generated.
  for await (const chunk of stream) {
    sendChunk(chunk.text);
  }

  // Return the full generative AI response
  // to clients that may not support streaming.
  return (await aiResponse).text;
},
);

Để triển khai một luồng như luồng này, hãy gói luồng đó bằng onCallGenkit có trong firebase-functions/https. Phương thức trợ giúp này có tất cả các tính năng của hàm có thể gọi và tự động hỗ trợ cả phản hồi truyền trực tuyến và JSON.

const {onCallGenkit} = require("firebase-functions/v2/https");
exports.tellJoke = onCallGenkit({
  // Bind the Gemini API key secret parameter to the function.
  secrets: [apiKey],
},
// Pass in the genkit flow.
jokeTeller,
);

Cung cấp thông tin xác thực API cho các flow đã triển khai

Sau khi triển khai, các luồng của bạn cần có cách thức xác thực với mọi dịch vụ từ xa mà chúng dựa vào. Ít nhất, hầu hết các luồng đều cần thông tin xác thực để truy cập vào dịch vụ API mô hình mà chúng sử dụng.

Đối với ví dụ này, hãy làm theo một trong những cách sau, tuỳ thuộc vào nhà cung cấp mô hình mà bạn chọn:

Gemini (AI của Google)

  1. Đảm bảo rằng công nghệ AI của Google có ở khu vực của bạn.

  2. Tạo khoá API cho Gemini API bằng Google AI Studio.

  3. Lưu trữ khoá API trong Trình quản lý bí mật trên đám mây:

    firebase functions:secrets:set GOOGLE_GENAI_API_KEY

    Bước này rất quan trọng để tránh vô tình rò rỉ khoá API, khoá này cấp quyền truy cập vào một dịch vụ có thể tính phí.

    Hãy xem phần Lưu trữ và truy cập thông tin cấu hình nhạy cảm để biết thêm thông tin về cách quản lý thông tin bảo mật.

  4. Chỉnh sửa src/index.js và thêm nội dung sau vào phần nhập hiện có:

    const {defineSecret} = require("firebase-functions/params");
    // Store the Gemini API key in Cloud Secret Manager.
    const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");
    

    Sau đó, trong phần khai báo hàm có thể gọi, hãy khai báo rằng hàm này cần quyền truy cập vào giá trị bí mật này:

    // Bind the Gemini API key secret parameter to the function.
    secrets: [apiKey],
    

Giờ đây, khi bạn triển khai hàm này, khoá API sẽ được lưu trữ trong Trình quản lý khoá trên đám mây và có sẵn trong môi trường của Cloud Functions.

Gemini (Vertex AI)

  1. Trong Cloud Console, hãy Bật API Vertex AI cho dự án Firebase của bạn.

  2. Trên trang IAM, hãy đảm bảo rằng Tài khoản dịch vụ điện toán mặc định được cấp vai trò Người dùng Vertex AI.

Bí mật duy nhất bạn cần thiết lập cho hướng dẫn này là dành cho nhà cung cấp mô hình, nhưng nói chung, bạn phải làm tương tự cho từng dịch vụ mà luồng của bạn sử dụng.

(Không bắt buộc) Thêm tính năng thực thi quy trình Kiểm tra ứng dụng

Kiểm tra ứng dụng Firebase sử dụng tính năng chứng thực gốc để xác minh rằng API của bạn chỉ được ứng dụng gọi. onCallGenkit hỗ trợ việc thực thi quy trình Kiểm tra ứng dụng theo cách khai báo.

export const generatePoem = onCallGenkit({
  enforceAppCheck: true,
  // Optional. Makes App Check tokens only usable once. This adds extra security
  // at the expense of slowing down your app to generate a token for every API
  // call
  consumeAppCheckToken: true,
}, generatePoemFlow);

Định cấu hình CORS (Chia sẻ tài nguyên trên nhiều nguồn gốc)

Sử dụng tuỳ chọn cors để kiểm soát những nguồn gốc nào có thể truy cập vào hàm của bạn.

Theo mặc định, các hàm có thể gọi được định cấu hình CORS để cho phép các yêu cầu từ mọi nguồn gốc. Để cho phép một số yêu cầu trên nhiều nguồn gốc nhưng không phải tất cả, hãy truyền danh sách các miền hoặc biểu thức chính quy cụ thể cần được cho phép. Ví dụ:

export const tellJoke = onCallGenkit({
  cors: 'mydomain.com',
}, jokeTeller);

Ví dụ hoàn chỉnh

Sau khi bạn thực hiện tất cả các thay đổi được mô tả ở trên, quy trình triển khai của bạn sẽ có dạng như ví dụ sau:

const {onCallGenkit} = require("firebase-functions/v2/https");
const {defineSecret} = require("firebase-functions/params");

// Dependencies for Genkit.
const {gemini15Flash, googleAI} = require("@genkit-ai/googleai");
const {genkit, z} = require("genkit");

// Store the Gemini API key in Cloud Secret Manager.
const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");

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

const jokeTeller = ai.defineFlow({
  name: "jokeTeller",
  inputSchema: z.string().nullable(),
  outputSchema: z.string(),
  streamSchema: z.string(),
}, async (jokeType = "knock-knock", {sendChunk}) => {
  const prompt = `Tell me a ${jokeType} joke.`;

  // Call the `generateStream()` method to
  // receive the `stream` async iterable.
  const {stream, response: aiResponse} = ai.generateStream(prompt);

  // Send new words of the generative AI response
  // to the client as they are generated.
  for await (const chunk of stream) {
    sendChunk(chunk.text);
  }

  // Return the full generative AI response
  // to clients that may not support streaming.
  return (await aiResponse).text;
},
);

exports.tellJoke = onCallGenkit({
  // Bind the Gemini API key secret parameter to the function.
  secrets: [apiKey],
},
// Pass in the genkit flow.
jokeTeller,
);

Triển khai flow đến Firebase

Sau khi xác định các luồng bằng onCallGenkit, bạn có thể triển khai các luồng đó như cách triển khai các hàm khác:

cd $PROJECT_ROOT
firebase deploy --only functions