Skip to content

AI Engine & Prompt Engineering

Phần này giải thích cách module src/analyzer.py sử dụng AI để biến ảnh chụp màn hình thành hướng dẫn chi tiết.

1. Multimodal AI Models

Hệ thống hỗ trợ 2 provider chính với cơ chế auto-detectionfallback thông minh:

ProviderModels mặc địnhThư viện PythonĐặc điểm
Googlegemma-3-27b, gemini-2.5-flash, gemini-1.5-flashgoogle-generativeaiRPD cao (14.4K), Free tier tốt
OpenAIgpt-4o-mini, gpt-4o, gpt-4-turboopenaiChi phí thấp, hiệu năng ổn định

1.1. Cơ chế Auto-Detection Model

Thay vì hardcode model, hệ thống tự động:

  1. Lấy danh sách models khả dụng từ API (get_available_gemini_models)
  2. Lọc models hỗ trợ vision (loại bỏ TTS, embedding, audio...)
  3. Chọn model tốt nhất theo thứ tự ưu tiên đã định nghĩa
python
# Thứ tự ưu tiên trong code thực tế
GEMINI_DEFAULT_MODELS = [
    "gemma-3-27b",           # RPD cao (14.4K)
    "gemma-3-12b",           # Backup
    "gemini-2.5-flash",      # RPD=20
    "gemini-1.5-flash",      # Ổn định
]

1.2. Cơ chế Fallback khi hết Quota

Khi gặp lỗi 429 (quota exceeded), hệ thống tự động:

  1. Đánh dấu model hiện tại vào _failed_gemini_models
  2. Tìm model thay thế từ danh sách còn lại
  3. Retry tối đa 2 lần mỗi request
  4. Nếu tất cả models đều fail → fallback về code-based description
python
# Logic trong _analyze_with_gemini()
if "429" in error_str or "quota" in error_str.lower():
    _failed_gemini_models.append(current_model)
    new_model = select_best_model(None, remaining, GEMINI_DEFAULT_MODELS, _failed_gemini_models)
    if new_model:
        _switch_gemini_model(api_key, new_model)
        return _analyze_with_gemini(..., retry_count + 1)

Ưu điểm của cơ chế này

  • Tự động thích ứng: Không cần sửa code khi Google thay đổi models
  • Resilient: Hệ thống không bị gián đoạn khi 1 model hết quota
  • Transparent: User thấy rõ model nào đang được sử dụng

Nhược điểm

  • Latency: Mất thời gian gọi API lấy danh sách models
  • Inconsistent output: Các models khác nhau có thể cho kết quả khác nhau

2. Quy trình xử lý ảnh

Trước khi gửi cho AI, ảnh được xử lý trong hàm _encode_image_base64:

  1. Read: Đọc file ảnh từ đĩa (rb mode).
  2. Encode: Chuyển đổi sang chuỗi Base64 (base64.standard_b64encode).
  3. Context: Nếu có ảnh của bước trước đó (previous_screenshot), hệ thống sẽ gửi cả 2 ảnh (Trước/Sau) để AI so sánh sự thay đổi.

3. Prompt Engineering (Thực tế)

Dưới đây là Prompt thực tế được sử dụng trong code (src/analyzer.py), được tối ưu qua nhiều lần iteration.

3.1. System Prompt (Code thực tế)

python
prompt = f"""Bạn là chuyên gia viết tài liệu hướng dẫn sử dụng phần mềm.

NHIỆM VỤ: Viết MỘT câu tiếng Việt mô tả hành động người dùng cần làm.

GỢI Ý HÀNH ĐỘNG: {action_hint if action_hint else 'Không có'}

YÊU CẦU:
- Viết câu HOÀN CHỈNH bằng tiếng Việt (có chủ ngữ, vị ngữ)
- Mô tả hành động cụ thể (nhấn, nhập, chọn, điền...)
- Độ dài: 8-20 từ
- Kết thúc bằng dấu chấm (.)

VÍ DỤ TỐT:
- "Nhấn nút Đăng nhập để vào hệ thống."
- "Nhập địa chỉ email vào ô Email đăng nhập."
- "Chọn menu Cloud Server từ thanh điều hướng bên trái."

CHỈ TRẢ VỀ MỘT CÂU MÔ TẢ, KHÔNG GIẢI THÍCH THÊM."""

3.2. Generation Config

python
generation_config={
    "temperature": 0.2,        # Giảm để output ổn định
    "max_output_tokens": 256,  # Đủ cho câu hoàn chỉnh
    "top_p": 0.8,
    "top_k": 40,
}

3.3. Validation Output

Sau khi nhận response từ AI, hệ thống validate:

python
# Đảm bảo câu hoàn chỉnh (ít nhất 3 từ)
if result and len(result.split()) >= 3:
    if not result.endswith(('.', '!', '?')):
        result += '.'
    return result
# Nếu câu quá ngắn, dùng action_hint
return action_hint

Ưu điểm của Prompt này

  • Structured: Yêu cầu rõ ràng, có ví dụ cụ thể
  • Constrained: Giới hạn độ dài (8-20 từ) tránh output quá dài/ngắn
  • Vietnamese-first: Tối ưu cho tiếng Việt

Nhược điểm

  • Rigid: Khó customize cho các ngôn ngữ khác
  • Context-limited: Không có thông tin về các bước trước đó

4. Fallback Mechanism (3 tầng)

Hệ thống có 3 tầng fallback để đảm bảo không bao giờ gián đoạn:

Tầng 1: Model Fallback

Khi model hiện tại hết quota → tự động chuyển sang model khác.

Tầng 2: Provider Fallback

Khi tất cả Gemini models đều fail → có thể chuyển sang OpenAI (nếu có key).

Tầng 3: Code-based Fallback

Khi AI hoàn toàn không khả dụng → dùng get_action_hint() từ Parser.

python
def analyze_screenshot(screenshot, provider, previous_screenshot=None):
    global _all_models_exhausted
    action_hint = get_action_hint(screenshot.action)
    
    # Skip AI nếu đã biết tất cả models đều fail
    if provider == "gemini" and _all_models_exhausted:
        return action_hint
    
    try:
        if provider == "gemini":
            return _analyze_with_gemini(...)
        elif provider == "openai":
            return _analyze_with_openai(...)
    except Exception as e:
        print(f"⚠️ AI analysis failed: {e}")
        print(f"↪️  Falling back to code-based description")
        return action_hint

5. So sánh AI vs Code-based Description

Tiêu chíAI DescriptionCode-based
Chất lượngTự nhiên, dễ đọcKỹ thuật, khô khan
Tốc độ1-3s/stepInstant
Chi phí~$0.001/stepFree
Độ tin cậyPhụ thuộc API100%

Ví dụ output:

  • AI: "Nhấn nút Đăng nhập để vào hệ thống."
  • Code-based: "Nhấn nút 'Đăng nhập'"

6. Tham khảo

Internal documentation for iNET Portal