Gemini CLI là gì?

Google vừa chính thức cho ra mắt Gemini CLI vào ngày 25/06/2025. Về cơ bản, nó là một cái CLI cho phép mình tương tác với Gemini ngay trên terminal.

Khi đọc qua tài liệu, tôi khá ấn tượng với những tính năng của nó:

  • Tư duy kiểu ReAct: Không chỉ trả lời một cách máy móc, mà còn biết tự “suy nghĩ - hành động - quan sát” để giải quyết vấn đề.
  • Context 1 triệu token: Khả năng “nhớ” được cả một codebase khổng lồ hoặc nuốt trọn một bộ tài liệu lớn để mình hỏi đáp.
  • Sandbox Execution: Cho phép nó chạy code hay lệnh shell một cách an toàn trong sandbox, có sự giám sát của chúng ta (Human-in-the-Loop).
  • Tích hợp: Biết tự lên Google Search để tìm thông tin mới nhất và kết nối với các hệ thống khác qua Model Context Protocol (MCP).

Tài liệu chi tiết: Gemini CLI

Vibe coding với gemini - Gemini CLI là gì?

Để kiểm tra khả năng “Vibe Coding” của nó so với những công cụ khác thế nào, tôi sẽ áp dụng vào dự án thực tế luôn. Vì dạo này không có thời gian làm việc riêng nên tôi áp dụng ngay vào việc ở công ty. Kế hoạch là xây một con script để tổng hợp log lỗi.

Cụ thể, con script này sẽ:

  1. Tự động tổng hợp các file logs lỗi.
  2. Đưa nội dung logs cho Gemini CLI phân tích và đưa ra đánh giá.
  3. Gửi kết quả phân tích đó lên kênh Discord của team.

Vibe coding với gemini - Script gọi Gemini CLI tổng hợp log gửi báo cáo

Ở script này, tôi sẽ khai thác Gemini CLI để thực hiện “Vibe Coding” tạo ra code cho chính nó, và trong script cũng sẽ có đoạn yêu cầu nó tư duy để phân tích lỗi. Tất cả chỉ dừng lại ở mức cơ bản, vì hoàn toàn có thể đặt ra những kịch bản phức tạp hơn, ví dụ yêu cầu nó tự thực thi một script khác khi phát hiện ra vấn đề..

Vibe Coding với Gemini CLI

Theo tài liệu trên github của Gemini CLI, chúng ta cần có file settings.json trong thư mục .gemini của dự án. Bạn có thể xem thêm cấu hình Gemini CLI. Trong thư mục .gemini tôi có thêm file prompt.md để viết prompt vào đây rồi copy dán vào terminal, vì terminal của tôi không nhập được tiếng Việt.

.gemini/
├── prompt.md
└── settings.json

Đây là ảnh tôi yêu cầu Gemini CLI code Script. Vibe coding với gemini - Làm việc với Gemini CLI

Tôi yêu cầu Gemini CLI viết script này ở 2 phiên bản: một cho Windows (PowerShell) và một cho Linux (bash).

Có một điều bất ngờ là script PowerShell nó sinh ra chạy được ngay. Nhưng với bản bash, code lại bị lỗi và tôi phải nhờ Claude sửa lại.

Vấn đề nằm ở cơ chế fallback tự động của Gemini CLI, điều này được ghi rõ trong tài liệu. Khi model gemini-1.5-pro quá tải, nó sẽ chuyển sang gemini-1.5-flash. Và đúng là lúc tôi yêu cầu viết bản bash, tôi đã bị chuyển sang model “yếu” hơn.

Tip: Theo tài liệu, nếu muốn ép nó luôn dùng gemini-1.5-pro, bạn cần phải cấu hình GOOGLE_API_KEY của riêng mình.

Kết quả cuối cùng - Thông báo được gửi qua Discord (Tôi chụp ảnh khá xấu nên copy text):

✨ Tình trạng Hệ thống IoT & API
❌ Critical - Lỗi truy cập cấp độ nghiêm trọng ảnh hưởng đến nhiều dịch vụ cốt lõi.
---
🚨 Vấn đề trong giờ qua
Phát hiện lỗi "Fatal error: Access level to Mita\UranusIoT\Tasks\" lặp lại trên các log: `rule-chain-system`, `mqtt-collector`, `websocket-publisher`, `socket-server`. Lỗi liên quan đến PHP-DI trong `embedding-job.log`.
---
📊 Chuẩn đoán & Phân tích
Lỗi "Access level" là phổ biến, cho thấy vấn đề cấu hình hoặc quyền truy cập lớp PHP trong namespace `Mita\UranusIoT\Tasks`. Sự xuất hiện của lỗi PHP-DI trong `embedding-job` củng cố giả thuyết về sự cố với container Dependency Injection hoặc định nghĩa lớp. Mặc dù có lỗi, các tác vụ vẫn báo cáo "Đang chạy", có thể là lỗi không chặn hoặc tác vụ tự phục hồi.
---
🚀 Hiệu suất & Thống kê
Tần suất lỗi "Fatal error: Access level" cao trên hầu hết các dịch vụ IoT. Các dịch vụ bị ảnh hưởng: `rule-chain-system`, `mqtt-collector`, `websocket-publisher`, `socket-server`, `embedding-job`.
---
🛠️ Khuyến nghị hành động
1.  Kiểm tra chi tiết log PHP để có stack trace đầy đủ của lỗi "Access level".
2.  Rà soát lại các định nghĩa lớp PHP trong `Mita\UranusIoT\Tasks\` về các bộ sửa đổi truy cập (public/protected/private).
3.  Kiểm tra cấu hình PHP-DI cho namespace `Mita\UranusIoT\Tasks\`.
4.  Xác minh quyền truy cập tệp/thư mục cho `Mita\UranusIoT\Tasks\`.
5.  Khởi động lại các dịch vụ bị ảnh hưởng.

Kết luận

So với những công cụ AI coding khác mà tôi đã dùng như Claude hay Cursor, Gemini CLI có những điểm mạnh riêng:

  • Tích hợp sâu với terminal: Không cần chuyển đổi context giữa editor và browser
  • ReAct reasoning: Có thể “suy nghĩ” và đưa ra kế hoạch trước khi code
  • Sandbox execution: An toàn hơn khi test code

Tuy nhiên vẫn còn một số hạn chế:

  • UI/UX: Diff view trên terminal khó sử dụng
  • Model switching: Fallback tự động có thể làm giảm chất lượng output
  • Context management: Chưa có cách quản lý conversation history hiệu quả

Nhìn chung, Gemini CLI là một công cụ đầy tiềm năng cho DevOps và automation workflows. Với những cải tiến về UX, nó có thể trở thành một alternative mạnh mẽ cho các AI coding assistant hiện tại.

Dưới đây là nội dung script, script này có thể tùy chỉnh để phù hợp với từng dự án cụ thể. Quan trọng là nó minh hoạ được khả năng của Gemini CLI trong việc tự động phân tích và tạo báo cáo thông minh.

#!/bin/bash
# ==============================================================================
# This script automates the process of monitoring log files from a project.
# It performs the following steps:
#   1. Aggregates and filters recent log entries, focusing on warnings/errors.
#   2. Uses the Gemini CLI to analyze the aggregated logs and generate a
#      concise, structured report in Vietnamese.
#   3. Sends the generated report to a specified Discord webhook.
#
# Author:  MiTaDev.Blog Shared for the community
# Version:  1.0.0
#
# Prerequisites:
#   - bash
#   - gemini-cli (https://github.com/google-gemini/gemini-cli)
#   - jq (A lightweight command-line JSON processor)
#     On Debian/Ubuntu: sudo apt-get install jq
#
# ==============================================================================

# --- 🔧 CONFIGURATION - BẠN PHẢI THAY ĐỔI CÁC THÔNG SỐ DƯỚI ĐÂY 🔧 ---

# 1. Đường dẫn đến thư mục gốc của dự án bạn muốn theo dõi.
#    Ví dụ: "/var/www/my-project"
PROJECT_DIR="\/PATH\/TO\/YOUR\/PROJECT"

# 2. URL của Discord Webhook để nhận báo cáo.
#    Lấy từ: Server Settings -> Integrations -> Webhooks -> New Webhook
DISCORD_WEBHOOK_URL="YOUR_DISCORD_WEBHOOK_URL_HERE"

# 3. Cấu hình các loại log (Tùy chọn nâng cao)
#    Thay đổi các giá trị này nếu cấu trúc log của bạn khác với mô tả.

#    Logs được định dạng (ví dụ: Monolog/LineFormatter)
#    Script sẽ lọc các dòng có chứa "WARNING" hoặc "ERROR".
STRUCTURED_LOG_DIR="${PROJECT_DIR}/storage/logs/app"
STRUCTURED_LOG_PATTERN="*$(date +"%Y-%m-%d").log" # Mẫu file log của ngày hôm nay

#    Logs không có định dạng (ví dụ: stdout/stderr từ supervisord)
#    Script sẽ lấy các dòng cuối cùng của file.
UNSTRUCTURED_LOG_DIR="${PROJECT_DIR}/storage/logs"

# --- END OF CONFIGURATION ---


# Exit immediately if a command exits with a non-zero status.
set -e
# Treat unset variables as an error.
set -u
# Pipes return the exit code of the last command to exit with a non-zero status.
set -o pipefail


main() {
    # --- 1. VALIDATE CONFIGURATION & PREREQUISITES ---
    echo "🔎 Validating configuration and prerequisites..."

    if [[ "$PROJECT_DIR" == *"\/PATH\/TO\/YOUR\/PROJECT"* || "$DISCORD_WEBHOOK_URL" == *"YOUR_DISCORD_WEBHOOK_URL"* ]]; then
        echo "❌ Lỗi Cấu Hình: Vui lòng chỉnh sửa script này và cập nhật các biến 'PROJECT_DIR' và 'DISCORD_WEBHOOK_URL'." >&2
        exit 1
    fi

    if ! command -v gemini &> /dev/null || ! command -v jq &> /dev/null; then
        echo "❌ Lỗi Thiếu Công Cụ: 'gemini' và 'jq' là bắt buộc." >&2
        echo "Vui lòng cài đặt chúng để tiếp tục. Trên Ubuntu: sudo apt-get install jq" >&2
        exit 1
    fi

    # --- 2. SETUP & CLEANUP ---
    # Create temporary files for processing
    local temp_log_file
    temp_log_file=$(mktemp)
    
    # Setup a trap to automatically clean up temporary files on exit
    trap 'rm -f "$temp_log_file"' EXIT

    # --- 3. AGGREGATE LOGS ---
    echo "🔄 Aggregating log files..."
    
    local all_log_entries=""
    
    # Process structured logs (e.g., Monolog)
    if [ -d "$STRUCTURED_LOG_DIR" ]; then
        while read -r file; do
            # Filter for WARNING/ERROR, get last 20 lines, truncate each line to 150 chars
            local filtered_content
            filtered_content=$(grep -E "WARNING|ERROR" "$file" 2>/dev/null | tail -n 20 | cut -c 1-150 || true)
            
            if [ -n "$filtered_content" ]; then
                all_log_entries+="==== $(basename "$file") ====\n${filtered_content}\n\n"
            fi
        done < <(find "$STRUCTURED_LOG_DIR" -type f -name "$STRUCTURED_LOG_PATTERN" 2>/dev/null || true)
    fi

    # Process unstructured logs (e.g., supervisord stdout)
    if [ -d "$UNSTRUCTURED_LOG_DIR" ]; then
        while read -r file; do
            # Get last 10 lines, truncate each line to 80 chars
            local content
            content=$(tail -n 10 "$file" 2>/dev/null | cut -c 1-80 || true)
            
            if [ -n "$content" ]; then
                all_log_entries+="==== $(basename "$file") ====\n${content}\n\n"
            fi
        done < <(find "$UNSTRUCTURED_LOG_DIR" -maxdepth 1 -type f -name "*.log" 2>/dev/null || true)
    fi

    local log_data
    if [ -z "$all_log_entries" ]; then
        echo "✅ No relevant log entries found. System appears healthy." >&2
        log_data="Không tìm thấy log WARNING hoặc ERROR mới trong lần kiểm tra này."
    else
        log_data="$all_log_entries"
    fi
    
    # --- 4. GENERATE REPORT WITH GEMINI ---
    echo "🤖 Building prompt and calling Gemini API..."

    # The prompt guides the AI to create a high-quality, structured report.
    read -r -d '' GEMINI_PROMPT <<EOF
Bạn là một kỹ sư DevOps chuyên nghiệp, nhiệm vụ của bạn là phân tích dữ liệu log từ một hệ thống và tạo ra một báo cáo tình trạng ngắn gọn, súc tích bằng tiếng Việt cho đội ngũ giám sát.

**Dữ liệu Log Thô:**
\`\`\`
${log_data}
\`\`\`

**Yêu Cầu Định Dạng Báo Cáo (Sử dụng Markdown cho Discord):**

✨ **Tình Trạng Hệ Thống**
_Cập nhật lúc: $(date +"%H:%M:%S %d-%m-%Y")_
[Điền 1 trong 3 trạng thái: ✅ **Ổn định**, ⚠️ **Cảnh báo**, hoặc ❌ **Nghiêm trọng**] Kèm theo một câu tóm tắt tổng quan.

---
🚨 **Vấn Đề Nổi Bật**
- [Liệt kê các lỗi hoặc cảnh báo cụ thể, đáng chú ý nhất. Nếu không có, ghi: "Không phát hiện vấn đề mới."]

---
📊 **Chẩn Đoán & Phân Tích**
- [Đây là phần quan trọng nhất. Phân tích của AI: nhóm các lỗi tương tự, xác định các mẫu lặp lại, và đưa ra giả thuyết về nguyên nhân gốc rễ. Cung cấp cái nhìn sâu sắc mà con người có thể bỏ lỡ.]

---
🛠️ **Hành Động Đề Xuất**
- [Đưa ra các khuyến nghị cụ thể, có thể thực hiện ngay. Nếu không cần, ghi: "Hiện tại không cần hành động khẩn cấp."]
EOF

    # Call Gemini and save the raw output
    local gemini_raw_output
    if ! gemini_raw_output=$(gemini <<<"$GEMINI_PROMPT"); then
        echo "❌ Lỗi khi gọi Gemini CLI. Tạo báo cáo thủ công." >&2
        gemini_raw_output="⚠️ **Lỗi Hệ Thống Báo Cáo**: Không thể kết nối hoặc thực thi Gemini CLI. Vui lòng kiểm tra lại cấu hình và kết nối mạng của máy chủ."
    fi

    # Clean the report from any potential CLI artifacts
    local final_report
    final_report=$(echo "$gemini_raw_output" | sed 's/\\n/\n/g') # Ensure newlines are rendered correctly

    if [ -z "$final_report" ]; then
        final_report="⚠️ **Cảnh báo**: Gemini CLI đã chạy nhưng không tạo ra nội dung báo cáo. Điều này có thể xảy ra khi không có lỗi mới hoặc log không đủ thông tin."
    fi

    # --- 5. SEND REPORT TO DISCORD ---
    echo "🚀 Sending report to Discord..."

    # Discord has a 2000 character limit per message. Truncate if necessary.
    if [ ${#final_report} -gt 1900 ]; then
        echo "⚠️ Report is too long (${#final_report} chars), truncating..." >&2
        final_report="${final_report:0:1850}...\n\n**(Báo cáo đã được rút gọn do vượt quá giới hạn độ dài)**"
    fi

    # Create a valid JSON payload for the Discord webhook
    local json_payload
    json_payload=$(jq -n --arg content "$final_report" '{"content": $content, "username": "Giám Sát Hệ Thống", "avatar_url": "https://i.imgur.com/g8vB3v6.png"}')

    # Send the report via curl
    if curl -s -S -H "Content-Type: application/json" -X POST -d "$json_payload" "$DISCORD_WEBHOOK_URL"; then
        echo "✅ Report sent successfully!"
    else
        echo "❌ Thất bại khi gửi báo cáo đến Discord. Vui lòng kiểm tra URL Webhook và kết nối mạng." >&2
        exit 1
    fi
}

# Run the main function with all script arguments
main "$@"

Bình luận

Đang tải bình luận...