Bỏ qua điều hướng
chuanweb.com
Quay lại tất cả bài viết

Nâng cấp website tĩnh bằng AI nội bộ: tìm kiếm ngữ nghĩa và trợ lý hội thoại

chuanweb.com 3 phút đọc

Website tĩnh giỏi việc phục vụ nhanh, nhưng tìm kiếm theo từ khóa thường tệ với câu hỏi tự nhiên kiểu “cách tăng tốc blog Astro”. Đưa một model AI nội bộ vào giúp trang trả lời theo nghĩa, dữ liệu không rời máy chủ của bạn. Bài này đi qua hai mức: tìm kiếm ngữ nghĩa và trợ lý hội thoại.

Kiến trúc tổng thể

  • Nội dung bài viết được chuyển thành vector (embedding) lưu trong file hoặc database nhỏ.
  • Khi người dùng hỏi, câu hỏi được embed rồi tìm các đoạn văn gần nhất.
  • Model sinh câu trả lời dựa trên những đoạn đã tìm — kỹ thuật retrieval-augmented generation (RAG).

Bước 1: tạo index nội dung

Dùng API nội bộ của Ollama để embed từng bài viết:

import json, urllib.request

def embed(text: str) -> list:
    data = json.dumps({
        "model": "bge-m3",
        "prompt": text,
        "options": {"num_predict": 0},
    }).encode()
    req = urllib.request.Request(
        "http://127.0.0.1:11434/api/embeddings",
        data=data, headers={"Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req) as resp:
        return json.loads(resp.read())["embedding"]

Build đã sinh file nội dung có cấu trúc, chỉ cần duyệt qua và lưu vector kèm đoạn nguồn.

Bước 2: tìm kiếm ngữ nghĩa ở phía server

Server nhỏ (Express chẳng hạn) nhận câu hỏi, embed lần nữa và tính độ tương đồng cosine:

function cosine(a, b) {
  let dot = 0, na = 0, nb = 0;
  for (let i = 0; i < a.length; i++) {
    dot += a[i] * b[i];
    na += a[i] * a[i];
    nb += b[i] * b[i];
  }
  return dot / (Math.sqrt(na) * Math.sqrt(nb) + 1e-9);
}

Chỉ cần duyệt vài trăm đoạn văn, chọn top 5 có điểm cao nhất là đủ cho blog cỡ vừa.

Bước 3: trợ lý hội thoại

Gộp các đoạn tìm được vào context và để model viết câu trả lời tự nhiên:

Bạn là trợ lý cho blog kỹ thuật tiếng Việt. Chỉ trả lời dựa trên thông tin dưới đây, nếu không có thì nói không tìm thấy.

Thông tin:
- Kiến trúc Islands giúp cắt giảm JavaScript xuống mức tối thiểu.
- client:load thủy hóa ngay lập tức, client:visible chỉ khi vào viewport.

Câu hỏi của người dùng: cải thiện tốc độ blog Astro thế nào?

Model tổng hợp thành câu trả lời mạch lạc có dẫn nguồn, người đọc có thể bấm vào bài gốc.

Điều cần lưu ý

  • Chọn model embedding nhỏ như bge-m3 để index nhanh, RAM phải chăng.
  • Lọc câu hỏi nhạy cảm: dựng danh sách chặn đơn giản nếu cần thiết.
  • Đo lường latency: model 4B trên CPU trả lời trong vài giây — chấp nhận được với blog, nhưng nhớ cache các câu hỏi lặp lại.

Kết luận

  • RAG biến website tĩnh từ “thư viện im lặng” thành người bạn đọc — trả lời đúng nhu cầu người dùng.
  • AI nội bộ giữ dữ liệu kín, không tốn phí API theo lượt hỏi.
  • Bắt đầu từ tìm kiếm ngữ nghĩa đơn giản, mở rộng dần sang trợ lý hội thoại toàn trang khi nội dung nhiều lên.