Từ Hỗn Loạn đến Tự Động Hóa: Xây Dựng Hệ Thống Gắn Thẻ Ticket Vận Hành với LLM và FastAPI

AI tutorial - IT technology blog
AI tutorial - IT technology blog

Bước chuyển mình từ Regex sang LLM

Việc mở rộng quy mô phòng IT thường gặp trở ngại khi khâu phân loại ticket thủ công trở thành một công việc toàn thời gian. Sáu tháng trước, đội ngũ của tôi ngập trong núi yêu cầu hỗ trợ, tốn hàng giờ mỗi tuần chỉ để chuyển ticket vào đúng thư mục.

Chúng tôi đã thử nghiệm nhiều phương pháp tự động hóa, và sau nửa năm vận hành hệ thống thực tế, tôi đã nhận ra chính xác những cạm bẫy nằm ở đâu. Chuyển đổi từ phân loại thủ công sang một quy trình tự động không chỉ là điều xa xỉ; đó là cách bạn lấy lại 20% thời gian của đội ngũ kỹ sư.

Đánh giá ba phương pháp chính

Trước khi quyết định sử dụng các Mô hình Ngôn ngữ Lớn (LLM), chúng tôi đã thử nghiệm ba chiến lược khác nhau. Hiểu rõ các điểm yếu của hai phương pháp đầu tiên là điều cần thiết cho bất kỳ ai đang xây dựng hệ thống hỗ trợ hiện đại.

  • Dựa trên quy tắc (Regex và khớp từ khóa): Lần thử đầu tiên của chúng tôi diễn ra nhanh chóng và gần như miễn phí, nhưng nó cực kỳ cứng nhắc. Một quy tắc tìm từ “Internet” có thể bắt được câu “Mạng internet của tôi bị hỏng”, nhưng sẽ hoàn toàn bỏ lỡ câu “Tôi đang gặp sự cố kết nối với gateway từ xa”. Việc bảo trì nhanh chóng trở thành ác mộng khi chúng tôi phải quản lý hơn 200 trường hợp ngoại lệ chồng chéo nhau.
  • Machine Learning truyền thống (Scikit-learn/NLP): Chúng tôi đã xây dựng một bộ phân loại Random Forest bằng spacy. Mặc dù nó mạnh mẽ hơn từ khóa, nhưng nó đòi hỏi một bộ dữ liệu sạch với ít nhất 5.000 ticket lịch sử đã được dán nhãn thủ công để vượt qua ngưỡng chính xác 80%. Mỗi khi ra mắt một công cụ nội bộ mới, chúng tôi lại phải dán nhãn lại dữ liệu và huấn luyện lại mô hình từ đầu.
  • Phân loại dựa trên LLM: Cuối cùng chúng tôi đã chọn các mô hình như GPT-4o-mini. Cách tiếp cận này giành chiến thắng nhờ khả năng “Zero-shot” (không cần dữ liệu mẫu). Nó hiểu được ngữ cảnh, thuật ngữ chuyên môn và thậm chí cả sự mỉa mai khi người dùng bực bội mà không cần một dòng dữ liệu huấn luyện nào.

Thực tế sử dụng LLM trong môi trường Production

Việc theo dõi nhật ký (logs) và chu kỳ thanh toán trong sáu tháng đã cho chúng tôi một bức tranh rõ ràng về những đánh đổi trong kiến trúc này.

Những ưu điểm

  • Khả năng nhận thức ngữ cảnh thực thụ: Mô hình nhận ra rằng “Tôi không thể vào được laptop” và “Đăng nhập thất bại trên portal” đều thuộc danh mục Authentication (Xác thực).
  • Hỗ trợ đa ngôn ngữ tức thì: Hệ thống của chúng tôi xử lý các ticket bằng tiếng Anh, tiếng Việt và tiếng Nhật một cách tự nhiên. Chúng tôi không phải viết bất kỳ dòng logic dịch thuật nào.
  • Dữ liệu có cấu trúc đáng tin cậy: Bằng cách kết hợp FastAPI với Pydantic, chúng tôi buộc LLM phải trả về JSON hợp lệ. Điều này cho phép chúng tôi đẩy dữ liệu trực tiếp vào cơ sở dữ liệu SQL hoặc kích hoạt các webhook của Jira mà không gặp lỗi phân tích cú pháp.

Những đánh đổi

  • Độ trễ: Các mô hình ML truyền thống phản hồi trong mili giây. LLM API thường mất từ 1,2 đến 3,5 giây. Đối với việc phân loại ticket chạy ngầm, sự chậm trễ này là không đáng kể, nhưng nó loại trừ khả năng cập nhật giao diện người dùng theo thời gian thực.
  • Chi phí dự đoán được: Sử dụng GPT-4o-mini rẻ đến mức ngạc nhiên. Chúng tôi tốn trung bình khoảng 15 USD mỗi tháng để xử lý 50.000 ticket.
  • Sự sai lệch mô hình (Model Drift): Nếu không có prompt chặt chẽ, mô hình thỉnh thoảng có thể “ảo giác” ra một thẻ mới như “Urgent-ASAP” thay vì sử dụng thẻ “Urgent” tiêu chuẩn.

Tech Stack khuyến nghị

Để có một hệ thống vận hành bền bỉ, tôi khuyên dùng sự kết hợp các công cụ sau:

  1. FastAPI: Tiêu chuẩn vàng cho các dịch vụ AI dựa trên Python. Hỗ trợ async gốc của nó rất quan trọng để xử lý nhiều lệnh gọi API đồng thời đến OpenAI hoặc Anthropic.
  2. Pydantic: Xử lý các công việc nặng nhọc về xác thực dữ liệu và thực thi schema.
  3. OpenAI SDK: Giao diện đơn giản để tương tác với mô hình.
  4. Python-dotenv: Cần thiết để giữ API key của bạn không bị lộ trong lịch sử git.

Xây dựng bộ phân loại

Chúng ta sẽ xây dựng một microservice chuyển đổi một ticket thô thành một đối tượng JSON đã được phân loại, ưu tiên và tóm tắt.

1. Thiết lập môi trường

Cài đặt các thư viện cốt lõi. Tôi khuyên bạn nên sử dụng môi trường ảo hoặc tệp requirements.txt.

pip install fastapi uvicorn openai pydantic python-dotenv

2. Thiết kế Schema dữ liệu

Một schema chặt chẽ giúp ngăn ngừa lỗi hệ thống ở các bước sau. Chúng ta định nghĩa chính xác những gì mong đợi LLM tạo ra.

from pydantic import BaseModel, Field
from typing import List

class TicketRequest(BaseModel):
    content: str

class TicketAnalysis(BaseModel):
    category: str = Field(description="Phần cứng, Phần mềm, Mạng, Quyền truy cập, hoặc Thanh toán")
    priority: str = Field(description="Thấp, Trung bình, Cao, hoặc Khẩn cấp")
    tags: List[str] = Field(description="3-5 từ khóa kỹ thuật")
    summary: str = Field(description="Một câu tóm tắt ngắn gọn")

3. Logic FastAPI

Bí mật của thành công nằm ở SYSTEM_PROMPT. Bằng cách xác định “Các danh mục cho phép”, chúng ta ngăn mô hình tự tạo ra hệ thống phân loại của riêng nó.

import os
import json
from fastapi import FastAPI
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
app = FastAPI()

SYSTEM_PROMPT = """
Bạn là một chuyên viên phân loại hỗ trợ IT. Hãy phân tích ticket và trả về một đối tượng JSON.
Các danh mục cho phép: Hardware, Software, Network, Access, Billing, General.
Các mức độ ưu tiên cho phép: Low, Medium, High, Urgent.
"""

@app.post("/analyze-ticket", response_model=TicketAnalysis)
async def analyze_ticket(ticket: TicketRequest):
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": ticket.content}
        ],
        response_format={ "type": "json_object" }
    )
    
    # Trả về kết quả phân tích ticket sau khi load từ JSON
    return TicketAnalysis(**json.loads(response.choices[0].message.content))

Những bài học xương máu từ thực tế

Xây dựng API chỉ là một nửa trận chiến. Vận hành nó ở quy mô lớn đã dạy cho chúng tôi ba bài học cụ thể mà bạn sẽ không tìm thấy trong các tài liệu cơ bản.

Xử lý ticket chứa nhiều vấn đề

Người dùng hiếm khi chỉ báo cáo một vấn đề duy nhất. Một ticket có thể viết: “Màn hình của tôi bị nhấp nháy và tôi không thể đăng nhập vào VPN.” Chúng tôi thấy rằng việc hướng dẫn LLM “Phân loại dựa trên rào cản quan trọng nhất” là cách hiệu quả nhất để đảm bảo ticket đến đúng chuyên gia.

Ràng buộc định dạng JSON

Trong tháng đầu tiên, hệ thống đã bị sập vài lần vì LLM thêm dòng chữ “Đây là phân tích của bạn:” vào trước JSON. Luôn sử dụng tham số response_format={ "type": "json_object" }. Đây là thiết lập quan trọng nhất để đảm bảo sự ổn định của hệ thống.

Quản lý phiên bản Prompt

Tránh việc viết cứng (hardcoding) các prompt bên trong tệp Python. Khi đội ngũ hỗ trợ tinh chỉnh các danh mục, bạn sẽ cần cập nhật prompt mà không muốn phải triển khai lại toàn bộ ứng dụng. Cuối cùng, chúng tôi đã chuyển các prompt sang các tệp YAML bên ngoài. Điều này cho phép chúng tôi chia danh mục “Phần mềm” rộng lớn thành “SaaS” và “Ứng dụng nội bộ” chỉ trong vài giây, đơn giản bằng cách cập nhật tệp cấu hình và làm mới.

Kiến trúc này tạo ra một hệ thống vừa thông minh vừa dễ bảo trì. Bạn không chỉ đơn thuần thêm một tính năng AI; bạn đang xây dựng một đường ống dữ liệu bền bỉ và có thể phát triển theo nhu cầu của bộ phận mình.

Share: