Viết content SEO theo template thì dễ quên ô này, bỏ sót ô kia. Dân kỹ thuật có một cách quen thuộc để xử lý chuyện đó: biến template thành dữ liệu có cấu trúc, rồi viết một script nhỏ để kiểm tra. Bài này hướng dẫn từng bước làm việc đó với YAML và Python, khoảng 60 dòng code.
Lưu ý: script chỉ kiểm tra "đủ ô" và vài lỗi hình thức. Nó không chấm được nội dung có hữu ích hay không. Phần đó vẫn cần người biên tập.
Bước 1: Định nghĩa brief bằng YAML
Tạo file brief.yaml cho mỗi bài:
keyword: "mẫu bài viết chuẩn seo"
secondary: ["template bài viết seo"]
intent: informational # informational | commercial | transactional | navigational
reader: "người viết content mới, đã biết SEO cơ bản"
task: "tự lập brief và dàn bài mà không bỏ sót onpage"
role: cluster # pillar | cluster | landing | tool
must_answer:
- "Mẫu gồm những phần nào?"
- "Điền brief thế nào?"
- "Kiểm tra gì trước khi đăng?"
title: "Mẫu bài viết chuẩn SEO: template có ví dụ"
meta: "Brief, dàn ý heading và checklist Onpage điền sẵn, kèm ví dụ thật."
internal_links:
- "/blog/search-intent-la-gi"
sources:
- "Google Search Central - helpful content"
Điểm quan trọng: task và must_answer là bắt buộc. Một brief chỉ có keyword và số từ là brief chưa xong.
Bước 2: Viết bản nháp bằng Markdown
Bản nháp draft.md dùng # cho H1, ## cho H2. Mỗi H2 nên ứng với một câu hỏi trong must_answer.
Bước 3: Viết script kiểm tra
# check_brief.py
import re, sys, yaml
REQUIRED = ["keyword", "intent", "reader", "task", "role",
"must_answer", "title", "meta"]
def check(brief_path, draft_path):
b = yaml.safe_load(open(brief_path, encoding="utf-8"))
md = open(draft_path, encoding="utf-8").read()
issues = []
# 1. Brief đủ ô
for k in REQUIRED:
if not b.get(k):
issues.append(f"brief thiếu: {k}")
# 2. Độ dài title/meta theo quy ước biên tập (không phải quy định của Google)
if len(b.get("title", "")) > 60:
issues.append("title > 60 ký tự")
if len(b.get("meta", "")) > 160:
issues.append("meta > 160 ký tự")
# 3. Đúng một H1
h1 = re.findall(r"^# (.+)$", md, re.M)
if len(h1) != 1:
issues.append(f"cần đúng 1 H1, đang có {len(h1)}")
# 4. Keyword bị nhồi vào heading?
h2 = re.findall(r"^## (.+)$", md, re.M)
kw = b["keyword"].lower()
stuffed = [h for h in h2 if kw in h.lower()]
if h2 and len(stuffed) / len(h2) > 0.5:
issues.append("hơn nửa số H2 lặp keyword chính")
# 5. Mỗi câu hỏi bắt buộc có H2 tương ứng (so khớp thô theo từ)
for q in b.get("must_answer", []):
words = {w for w in re.findall(r"\w+", q.lower()) if len(w) > 3}
if not any(words & set(re.findall(r"\w+", h.lower())) for h in h2):
issues.append(f"chưa thấy H2 trả lời: {q}")
# 6. Số liệu không có nguồn (heuristic: có % mà không có link)
for line in md.splitlines():
if "%" in line and "http" not in line:
issues.append(f"số liệu chưa dẫn nguồn: {line[:60]}")
return issues
if __name__ == "__main__":
problems = check(sys.argv[1], sys.argv[2])
print("\n".join(problems) or "OK: không phát hiện lỗi hình thức")
sys.exit(1 if problems else 0)
Chạy thử:
pip install pyyaml
python check_brief.py brief.yaml draft.md
Bước 4: Đưa vào quy trình
Vài cách dùng thực tế:
- Pre-commit hook: nếu nội dung nằm trong repo (Hugo, Astro, Next.js), chặn commit khi script trả mã lỗi.
-
CI: chạy trong GitHub Actions cho mỗi pull request chứa file
.mdmới, để reviewer thấy danh sách lỗi trước khi đọc. - Biên tập thủ công: ngay cả khi không có repo, chạy script trên bản export Markdown từ Google Docs hoặc Notion cũng đủ bắt được lỗi quên ô.
Bước 5: Biết giới hạn của script
Script này không biết:
- Bài có thật sự trả lời đúng ý định tìm kiếm không.
- Ví dụ và số liệu có chính xác không (nó chỉ phát hiện thiếu link nguồn).
- Mở bài có đi thẳng vào vấn đề không.
Hướng dẫn về nội dung hữu ích của Google Search Central cũng không đặt ra số từ hay mật độ từ khóa cố định. Vì vậy hãy coi script như lan can chống bỏ sót, không phải công thức xếp hạng.
Lấy phần template ở đâu?
Các ô trong brief.yaml ở trên được rút gọn từ bộ template bài viết chuẩn SEO của Mạnh Digital, trong đó có bảng giải thích từng ô brief, khung heading và checklist Onpage đầy đủ. Bạn có thể map thêm các mục checklist thành rule mới cho script, ví dụ kiểm tra alt ảnh hoặc canonical.
Nếu bạn đã tự động hóa phần kiểm tra content theo cách khác, chia sẻ ở phần bình luận nhé.
Top comments (0)