Back to Explore
Xây dựng luồng dữ liệu AI thời gian thực với Firebase Genkit và Angular Signals

Xây dựng luồng dữ liệu AI thời gian thực với Firebase Genkit và Angular Signals

Khám phá cách tối ưu hóa trải nghiệm người dùng trong các ứng dụng AI bằng cách sử dụng Firebase Genkit để truyền tải dữ liệu telemetry theo thời gian thực và Angular Signals để cập nhật giao diện một cách khai báo, thay thế cho các vòng lặp chờ đợi chậm chạp.

Website
Upvote this postSign in to upvote this article.

Bài viết được dịch và tổng hợp từ tin tức gốc. Bạn có thể đọc bài viết gốc bằng tiếng Anh tại đây.

Điểm tin nhanh:

  • Giải quyết vấn đề "loading spinner" nhàm chán bằng cách truyền tải trạng thái xử lý AI theo thời gian thực từ server xuống client.
  • Sử dụng Firebase Genkit kết hợp với Gemini 3.5 Flash để tạo pipeline AI phân tầng, giúp tăng độ chính xác và khả năng theo dõi tiến trình.
  • Ứng dụng Angular Signals để quản lý trạng thái UI một cách khai báo, loại bỏ sự phức tạp của RxJS trong các luồng dữ liệu đơn giản.

Ảnh minh họa

Trong phát triển ứng dụng web hiện đại, việc bắt người dùng chờ đợi một "loading spinner" trong 10-15 giây khi chạy các pipeline AI phức tạp là một trải nghiệm tồi tệ. Thay vì bắt người dùng "mù quáng" chờ đợi, chúng ta có thể xây dựng một pipeline tương tác trực tiếp. Bài viết này sẽ hướng dẫn cách sử dụng Firebase Genkit và Angular Signals để truyền tải dữ liệu telemetry (dữ liệu đo lường tiến trình) thời gian thực.

So sánh kiến trúc xử lý AI

Đặc điểm Cách tiếp cận truyền thống Kiến trúc Telemetry thời gian thực
Trải nghiệm người dùng Chờ đợi toàn bộ quy trình hoàn tất Cập nhật tiến độ từng bước
Lưu trữ trạng thái Ghi vào Database (Firestore) Truyền trực tiếp qua HTTP Stream
Độ trễ phản hồi Cao (chờ xử lý xong mới hiển thị) Thấp (phản hồi ngay khi có chunk)
Hiệu năng hệ thống Tốn chi phí đọc/ghi DB trung gian Tối ưu hóa tài nguyên, không ghi DB

1. Thiết lập Backend với Firebase Genkit

Chúng ta sẽ sử dụng onCallGenkit để tạo một Callable Cloud Function. Thay vì gọi một prompt duy nhất, chúng ta chia nhỏ thành các bước để gửi trạng thái về client.

// functions/src/index.ts
import { ai } from '@genkit-ai/firebase';
import { onCallGenkit } from '@genkit-ai/firebase/functions';
import { z } from 'zod';

const ResumeAnalysisSchema = z.object({
    atsScore: z.number().min(0).max(100),
    formattingReview: z.string(),
    actionableTips: z.array(z.string()),
});

export const analyzeResumeFlow = onCallGenkit(
    { authPolicy: (auth) => auth?.token.email_verified === true },
    async (input, streamingCallback) => {
        const { resumeText } = input;

        // Milestone 1: Structural Scan
        if (streamingCallback) streamingCallback({ status: 'parsing_structure' });
        const structureResponse = await ai.models.generate({ model: 'gemini-3.5-flash', prompt: `...` });

        // Milestone 2: Content Impact Analysis
        if (streamingCallback) streamingCallback({ status: 'analyzing_impact' });
        const impactResponse = await ai.models.generate({ model: 'gemini-3.5-flash', prompt: `...` });

        // Milestone 3: Final Schema
        if (streamingCallback) streamingCallback({ status: 'generating_tips' });
        // ... logic gọi model cuối cùng
        return JSON.parse(finalResponse.text);
    }
);

2. Xử lý Stream trong Angular

Sử dụng httpsCallable để nhận luồng dữ liệu (stream) và cập nhật Angular Signals.

// src/app/services/resume-analyzer.service.ts
@Injectable({ providedIn: 'root' })
export class ResumeAnalyzerService {
    private readonly _currentStep = signal<ResumeStep>('idle');
    readonly currentStep = this._currentStep.asReadonly();

    async runAnalysis(rawText: string) {
        const runFlow = httpsCallable<{ resumeText: string }, any>(this.functions, 'analyzeResumeFlow');
        const streamResult = await runFlow({ resumeText: rawText });

        for await (const chunk of streamResult.stream) {
            if (chunk.status) this._currentStep.set(chunk.status as ResumeStep);
        }
    }
}

3. Xây dựng giao diện khai báo (Declarative UI)

Sử dụng các khối điều khiển luồng mới của Angular (@switch, @case) để hiển thị trạng thái dựa trên Signal:

@switch (service.currentStep()) {
  @case ('parsing_structure') { <div>🔎 Bước 1: Đang phân tích cấu trúc...</div> }
  @case ('analyzing_impact') { <div>⚡ Bước 2: Đang đo lường tác động...</div> }
  @case ('complete') { <div>✓ Hoàn tất!</div> }
}

Lưu ý khi triển khai thực tế

  • Cold Starts: Serverless có thể bị trễ khi khởi động, hãy thông báo "Đang khởi động AI..." cho người dùng.
  • Debug: Sử dụng Firebase Emulator Suite và Genkit Developer UI (npx genkit start) để theo dõi trace mà không tốn chi phí API.
  • Tối ưu chi phí: Việc truyền trạng thái qua HTTP stream giúp giảm đáng kể số lần đọc/ghi Firestore, tiết kiệm chi phí vận hành đáng kể.

Discussion (0)

You need to log in to post comments. Log In

No comments yet. Start the discussion!

Do you like this post?

Upvote to push this post higher on the community feed

Details

Posted by: @admin
Categories: Libraries & Frameworks
Date posted: 8 tháng 7, 2026