Bạn có thể chạy tập lệnh phía máy chủ tuỳ chỉnh của riêng mình trước và sau mỗi yêu cầu mà ứng dụng của bạn gửi đến Gemini API thông qua Firebase AI Logic — mà không cần thay đổi mã ứng dụng. Bạn triển khai các tập lệnh này dưới dạng hàm kiểu lệnh gọi lại được triển khai cho Cloud Functions for Firebase.
Với tính năng này, bạn có thể làm những việc như kiểm duyệt câu lệnh, giới hạn mức sử dụng mã thông báo, ghi nhật ký các thế hệ để phân tích hoặc biên tập nội dung phản hồi.
Có hai loại sự kiện:
beforeGenerateContent: Chạy trước khi yêu cầu đến được Gemini API. Hàm này có thể kiểm tra hoặc sửa đổi yêu cầu, hoặc chặn hoàn toàn yêu cầu bằng cách gửi lỗi.afterGenerateContent: Chạy sau khi phản hồi được gửi lại từ Gemini API và trước khi phản hồi được trả về ứng dụng khách. Hàm này có thể kiểm tra hoặc sửa đổi phản hồi, chặn hoàn toàn phản hồi hoặc chỉ quan sát phản hồi (như để ghi nhật ký hoặc kiểm tra).
Sau khi được triển khai dưới dạng hàm cho Cloud Functions for Firebase, các tập lệnh của bạn sẽ được đăng ký dưới dạng Firebase AI Logic trình kích hoạt, tức là các tập lệnh này sẽ chạy cho mọi yêu cầu generateContent trong dự án của bạn đến Gemini API thông qua Firebase AI Logic (bao gồm cả các yêu cầu được thực hiện bằng mẫu câu lệnh của máy chủ).
Các hàm này không được kích hoạt bằng các yêu cầu gửi đến Gemini API mà không thông qua Firebase AI Logic.
Điều kiện tiên quyết
Thiết lập Firebase AI Logic: Nếu bạn chưa thực hiện, hãy hoàn tất Firebase AI Logic hướng dẫn bắt đầu sử dụng. Hướng dẫn này mô tả cách thiết lập dự án Firebase, kết nối ứng dụng với Firebase, thêm SDK, khởi chạy dịch vụ phụ trợ cho nhà cung cấp Gemini API mà bạn chọn và tạo một thực thể
GenerativeModel.Quyền cần thiết: Đảm bảo rằng bạn có quyền IAM cần thiết để triển khai cho Cloud Functions for Firebase.
Bước 1: Thiết lập dự án cho Cloud Functions for Firebase
Nếu bạn chưa từng sử dụng Cloud Functions for Firebase trong dự án Firebase, hãy hoàn tất quy trình thiết lập sau đây.
Đảm bảo dự án Firebase của bạn đang sử dụng gói giá Blaze (trả tiền theo mức dùng) (bắt buộc để sử dụng Cloud Functions for Firebase).
Cài đặt giao diện dòng lệnh (CLI): gcloud CLI và Firebase CLI
Cấp cho tài khoản dịch vụ mặc định của Compute Engine vai trò Tài khoản dịch vụ Cloud Build (
roles/cloudbuild.builds.builder) cần thiết để tạo hàm. Chạy lệnh gcloud CLI sau:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/cloudbuild.builds.builder"Khởi chạy Cloud Functions for Firebase trong dự án Firebase:
Chạy lệnh CLI Firebase sau:
firebase init functionsKhi được nhắc, hãy chọn TypeScript.
Đảm bảo rằng
firebase-functionstrongfunctions/package.jsoncủa bạn là phiên bản 6.3.0 trở lên. Sau đây là cách kiểm tra phiên bản:npm --prefix functions list firebase-functions
Bước 2: Viết hàm
Viết hàm trước yêu cầu (beforeGenerateContent)
Viết hàm sau yêu cầu (afterGenerateContent)
Viết hàm trước yêu cầu (beforeGenerateContent)
Với loại sự kiện beforeGenerateContent, hàm sẽ được kích hoạt khi proxy Firebase AI Logic nhận được yêu cầu generateContent. Hàm này
chạy dựa trên yêu cầu trước khi yêu cầu được gửi đến Gemini API.
Hàm này có thể sửa đổi yêu cầu hoặc chặn hoàn toàn yêu cầu.
Hãy nhớ xem thông tin sau trước khi viết hàm:
- Dữ liệu sự kiện mà bạn có thể sử dụng trong hàm của mình
- Những điểm chính cần xem xét đối với hàm trước khi gửi yêu cầu
- Các giới hạn và hành vi của hàm
Ví dụ
Dưới đây là hàm yêu cầu trước mẫu thực hiện những việc sau:
Chỉ định rằng hàm chỉ nên chạy khi yêu cầu là dành cho một nhà cung cấp Gemini API cụ thể.
Kiểm tra câu lệnh để tìm các chủ đề bị chặn và từ chối yêu cầu bằng cách gửi một lỗi.
Giới hạn số lượng mã thông báo đầu ra tối đa cho các mô hình tạo văn bản.
import { logger } from "firebase-functions";
import {
beforeGenerateContent,
HttpsError,
vertexV1Beta1,
type VertexV1Beta1GenerateContentRequest,
} from "firebase-functions/v2/ai";
const BLOCKED_TOPICS = ["weapon", "explosive", "self-harm"];
const MAX_OUTPUT_TOKENS = 4000;
export const guardPrompts = beforeGenerateContent((event) => {
// 1. Optional: If you want the function to only run for a specific Gemini API provider, specify it here.
if (event.data.api !== vertexV1Beta1) return;
const request = event.data.request as VertexV1Beta1GenerateContentRequest;
// 2. Read the prompt: contents[] -> parts[] -> text
const prompt = (request.contents ?? [])
.flatMap((c) => c.parts ?? [])
.map((p) => ("text" in p ? p.text : "") ?? "")
.join(" ")
.toLowerCase();
// 3. Throwing rejects the request. The request is never sent to the Gemini API.
const blocked = BLOCKED_TOPICS.find((t) => prompt.includes(t));
if (blocked) {
logger.warn("Blocked a prompt", { topic: blocked });
throw new HttpsError("invalid-argument", `We don't return content about ${blocked}.`);
}
logger.info("Allowing generation", {
model: event.data.model,
authType: event.authType,
authId: event.authId,
appId: event.appId,
});
// 4. The next step truncates the response, but that will break images.
if (event.data.model.includes("image")) return;
// 5. Return the WHOLE request, edited. Returning nothing leaves it untouched.
return {
...request,
generationConfig: {
...request.generationConfig,
maxOutputTokens: Math.min(
request.generationConfig?.maxOutputTokens ?? MAX_OUTPUT_TOKENS,
MAX_OUTPUT_TOKENS,
),
},
};
});
Những điểm chính cần xem xét đối với hàm trước yêu cầu
Chỉ định nhà cung cấp Gemini API:
event.data.requestcó thể dành cho Gemini Developer API hoặc Agent Platform Gemini API (formerly Vertex AI). Đối tượng yêu cầu cho các API này có hình dạng khác nhau. Để làm việc an toàn với đối tượng yêu cầu, bạn phải kiểm traevent.data.api(ví dụ: so sánh vớigeminiV1BetahoặcvertexV1Beta1, tương ứng).Throwing chặn yêu cầu: Nếu bạn gửi
HttpsError, yêu cầu sẽ bị từ chối.Trả về toàn bộ yêu cầu: Nếu hàm của bạn sửa đổi yêu cầu, thì bạn phải trả về đối tượng yêu cầu hoàn chỉnh, đã sửa đổi. Nếu không trả về giá trị nào (hoặc trả về
undefined), yêu cầu sẽ không thay đổi.Kiểm tra độ trễ: Tuỳ thuộc vào chức năng của hàm, hàm có thể làm tăng độ trễ và ảnh hưởng đến trải nghiệm người dùng.
Viết hàm sau yêu cầu (afterGenerateContent)
Với loại sự kiện afterGenerateContent, hàm sẽ được kích hoạt khi proxy Firebase AI Logic nhận được phản hồi từ yêu cầu generateContent. Hàm này chạy dựa trên phản hồi trước khi phản hồi được trả về ứng dụng khách. Hàm này có thể ghi lại mức sử dụng, sửa đổi phản hồi hoặc chặn hoàn toàn phản hồi.
Hãy nhớ xem thông tin sau trước khi viết hàm:
- Dữ liệu sự kiện mà bạn có thể sử dụng trong hàm của mình
- Những điểm chính cần xem xét đối với các hàm sau yêu cầu
- Các giới hạn và hành vi của hàm
Ví dụ
Dưới đây là một ví dụ về hàm sau yêu cầu ghi lại mức sử dụng mã thông báo và lý do hoàn tất:
import { logger } from "firebase-functions";
import {
afterGenerateContent,
vertexV1Beta1,
type VertexV1Beta1GenerateContentResponse,
} from "firebase-functions/v2/ai";
export const recordGenerationUsage = afterGenerateContent((event) => {
// Optional: If you want the function to only run for a specific Gemini API provider, specify it here.
if (event.data.api !== vertexV1Beta1) return;
const response = event.data.response as VertexV1Beta1GenerateContentResponse;
logger.info("Generation finished", {
model: event.data.model,
promptTokens: response.usageMetadata?.promptTokenCount,
totalTokens: response.usageMetadata?.totalTokenCount,
finishReason: response.candidates?.[0]?.finishReason,
});
// To leave the response untouched, return nothing.
// To modify the response, return a modified response object here.
});
Những điểm chính cần xem xét đối với các hàm sau yêu cầu
Chỉ định nhà cung cấp Gemini API:
event.data.responsecó thể dành cho Gemini Developer API hoặc Agent Platform Gemini API (formerly Vertex AI). Để truyền và làm việc một cách an toàn với đối tượng yêu cầu, bạn phải kiểm traevent.data.api(ví dụ: so sánh vớigeminiV1BetahoặcvertexV1Beta1, tương ứng).Kiểm tra độ trễ: Tuỳ thuộc vào chức năng của hàm, hàm có thể làm tăng độ trễ và ảnh hưởng đến trải nghiệm người dùng.
Bước 3: Triển khai các hàm
Khi bạn triển khai các hàm cho Firebase, tác nhân dịch vụ Firebase AI Logic sẽ được cấp quyền gọi các hàm này và đăng ký từng hàm dưới dạng một trình kích hoạt Firebase AI Logic.
Triển khai các hàm bằng CLI Firebase:
firebase deploy --only functionsSau khi triển khai, hãy xác nhận rằng các hàm của bạn đã được triển khai cho Firebase:
firebase functions:listNếu bạn cần lặp lại hàm:
Cập nhật hàm trong thư mục dự án, sau đó chạy lại
firebase deploy --only functions.
Dừng chạy hàm
Để dừng chạy một trong các hàm này, bạn phải xoá hàm đó khỏi máy chủ của chúng tôi và huỷ đăng ký hàm đó dưới dạng một trình kích hoạt Firebase AI Logic. Bạn có thể thực hiện việc này bằng cách sử dụng Firebase CLI với một trong các lựa chọn sau:
Cách 1: Xoá hàm một cách ngầm ẩn
Xoá hàm khỏi toàn bộ mã nguồn của thư mục dự án.
Chạy lệnh CLI Firebase sau:
firebase deploy --only functions
Cách 2: Xoá hàm một cách rõ ràng
Xoá hàm khỏi toàn bộ mã nguồn của thư mục dự án.
Chạy lệnh CLI Firebase sau:
firebase functions:delete FUNCTION_NAME
Tài liệu tham khảo về dữ liệu sự kiện
Cả beforeGenerateContent và afterGenerateContent đều nhận được một đối tượng AIBlockingEvent chứa bối cảnh và siêu dữ liệu về yêu cầu.
Siêu dữ liệu yêu cầu cấp cao nhất (AIBlockingEvent)
Đối tượng AIBlockingEvent cấp cao nhất cung cấp thông tin về phương thức gọi và môi trường kích hoạt:
event.authType: Trạng thái xác thực của người gọi:"app_user","unauthenticated"hoặc"unknown".event.authId: UID xác thực Firebase của phương thức gọi, nếu đã đăng nhập.event.authClaims: Thông tin xác nhận quyền sở hữu tuỳ chỉnh của người gọi (nếu có).event.appId: Mã ứng dụng Firebase đã gửi yêu cầu.event.androidPackageName/event.iosBundleId: Tên gói hoặc mã nhận dạng gói của ứng dụng gọi điện (áp dụng tương ứng cho nền tảng Android hoặc Apple).event.data: Trọng tải sự kiện, khác nhau giữa các hàm trước yêu cầu và sau yêu cầu:- Đối với
beforeGenerateContent, đây là một đối tượngBeforeGenerateContentData. - Đối với
afterGenerateContent, đây là đối tượngAfterGenerateContentData.
- Đối với
Dữ liệu sự kiện trước khi yêu cầu (beforeGenerateContent)
Trong hàm beforeGenerateContent, event.data được điền sẵn đối tượng BeforeGenerateContentData:
event.data.api: Nhà cung cấp Gemini API:geminiV1Beta(Gemini Developer API) hoặcvertexV1Beta1(Agent Platform Gemini API (formerly Vertex AI)).event.data.model: Đường dẫn tài nguyên đầy đủ của mô hình (ví dụ:projects/{PROJECT_ID}/locations/global/publishers/google/models/gemini-3.8-flash).event.data.template: Siêu dữ liệu về mẫu câu lệnh của máy chủ được sử dụng (PromptTemplateInfo), nếu có.event.data.request: Trọng tải yêu cầu gửi đi. Loại đối tượng và thuộc tính phụ thuộc vào nhà cung cấp Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentRequest - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentRequest
- Gemini Developer API (
Dữ liệu sự kiện sau khi yêu cầu (afterGenerateContent)
Trong hàm afterGenerateContent, event.data được điền sẵn một đối tượng AfterGenerateContentData. Đối tượng này mở rộng BeforeGenerateContentData (cung cấp api, model, template và request) và thêm phản hồi của mô hình:
event.data.response: Trọng tải phản hồi của mô hình. Loại đối tượng và thuộc tính phụ thuộc vào nhà cung cấp Gemini API:- Gemini Developer API (
geminiV1Beta):GeminiV1BetaGenerateContentResponse - Agent Platform Gemini API (formerly Vertex AI) (
vertexV1Beta1):VertexV1Beta1GenerateContentResponse
- Gemini Developer API (
Các giới hạn và hành vi
Khi triển khai các hàm này, hãy lưu ý những hành vi và hạn chế sau:
Chỉ các yêu cầu
generateContent: Những hàm này chỉ có thể được kích hoạt bằng các yêu cầugenerateContentđến Gemini API thông qua Firebase AI Logic.Những trường hợp sau đây sẽ không kích hoạt các hàm này và các hàm sẽ được bỏ qua một cách thầm lặng đối với yêu cầu đó:
Yêu cầu gửi đến
generateContentStreamsẽ không kích hoạt các hàm này.Yêu cầu gửi đến Gemini Live API sẽ không kích hoạt các hàm này.
Không có thay đổi nào về mã phía máy khách: Ngoài việc đảm bảo rằng bạn sử dụng các yêu cầu
generateContentkhi muốn chạy các hàm này, bạn không cần thay đổi gì trong toàn bộ mã nguồn phía máy khách.Các hàm này được triển khai cho máy chủ của chúng tôi và được đăng ký dưới dạng trình kích hoạt Firebase AI Logic để proxy Firebase AI Logic có thể chặn các yêu cầu và phản hồi phía máy chủ.
Phạm vi cấp dự án: Bạn có thể triển khai tối đa một hàm
beforeGenerateContentvà một hàmafterGenerateContentcho mỗi dự án Firebase.Vị trí mặc định: Theo mặc định, các hàm này sẽ được triển khai cho
us-central1(tìm hiểu về vị trí cho các hàm). Tuy nhiên, hàm này sẽ được đăng ký dưới dạng một trình kích hoạt Firebase AI Logic trong khu vựcglobalbất kể bạn triển khai hàm ở đâu.