Văn bản nhiễu trong RAG: Lỗi gõ, OCR và khoảng trống mà Spell-Check cổ điển bỏ sót

Công nghệ30 tháng 8, 2026·8 phút đọc

Bài viết phân tích ba nguồn gây nhiễu văn bản trong hệ thống RAG doanh nghiệp: lỗi gõ của người dùng, nhiễu phiên âm khi gõ nhanh và lỗi ký tự từ OCR. Tác giả chỉ ra các công cụ spell-check cổ điển chỉ xử lý được một phần ba vấn đề, đồng thời đề xuất chiến lược kết hợp embeddings, từ điển chuyên ngành và LLM để giải quyết triệt để.

Văn bản nhiễu trong RAG: Lỗi gõ, OCR và khoảng trống mà Spell-Check cổ điển bỏ sót

Văn bản nhiễu trong RAG: Lỗi gõ, OCR và khoảng trống mà Spell-Check cổ điển bỏ sót

Khi người dùng gõ "assurance décénale" trong khi tài liệu ghi "décennale", chỉ thiếu một ký tự là tìm kiếm literal không trả về kết quả nào. Vấn đề không chỉ nằm ở lỗi chính tả của người dùng mà còn ở lỗi OCR từ tài liệu scan và nhiễu do gõ nhanh trên thiết bị di động. Bài viết này phân tích sâu ba nguồn nhiễu văn bản trong hệ thống RAG doanh nghiệp, đồng thời chỉ ra giới hạn của bộ công cụ spell-check cổ điển và cách embeddings, LLM có thể xử lý hiệu quả.

Vấn đề nhiễu văn bản xuất hiện ở cả hai phía của pipeline. Ở phía câu hỏi, người dùng gõ "wat is teh covarge for fyre damge?" — ba lỗi gõ và thiếu một ký tự khiến chatbot không trả lời được cho đến khi câu hỏi được gõ lại cẩn thận. Ở phía tài liệu, đưa 50.000 ticket hỗ trợ khách hàng vào cùng một pipeline, một nửa trong số đó viết dạng fragment, viết tắt, sai hoa thường — pipeline vốn hoạt động tốt với dữ liệu sạch bắt đầu tạo ra kết quả nhiễu loạn.

Ba nguồn nhiễu văn bản, một triệu chứng chung - Ảnh tác giảBa nguồn nhiễu văn bản, một triệu chứng chung - Ảnh tác giả

Bốn mươi năm spell-correction cổ điển

Trước khi có embeddings và LLM, việc sửa lỗi chính tả là một bài toán kỹ thuật đã được giải quyết. Năm kỹ thuật chính đã chạy trong production từ 1980 đến nay, tất cả đều có thư viện Python trưởng thành: Levenshtein distance, BK-tree, Soundex/Metaphone, SymSpellcharacter n-grams.

Levenshtein distance tính số thao tác tối thiểu (chèn, xóa, thay thế) để biến từ này thành từ kia:

from rapidfuzz.distance import Levenshtein
Levenshtein.distance("coverage", "cverage")    # 1 (xóa 'o' thứ hai)
Levenshtein.distance("coverage", "covarage")   # 1 (chèn 'a')

Với một từ sai duy nhất có đáp án rõ ràng trong từ điển, bộ công cụ này giải quyết vấn đề nhanh và chính xác trong micro giây, không cần GPU. Đây là trường hợp kinh điển mà spell-check cổ điển vẫn là công cụ đúng.

Nơi kịch bản cổ điển thất bại

Lỗi gõ tạo thành từ hợp lệ khác

Khi lỗi gõ rơi vào một từ đúng chính tả khác, không spell-checker nào phát hiện được — không có gì để gắn cờ vì cả hai đều hợp lệ. Ví dụ: "coverage" và "overage" chỉ cách nhau 1 ký tự nhưng hoàn toàn khác nghĩa trong ngữ cảnh bảo hiểm. Người dùng gõ "what is the overage on my homeowner policy?" — họ muốn hỏi coverage (số tiền bồi thường), không phải overage (phần vượt hạn mức).

# Soundex cũng không phân biệt được
soundex("coverage"), soundex("overage")    # ('C162', 'O162') - khác key

Lý do cổ điển không bắt được lỗi này là cấu trúc: chúng so sánh độ tương đồng với từ điển, hoàn toàn không đọc ngữ cảnh xung quanh.

Ranh giới từ sai

Người dùng gõ nhanh trên mobile thường gộp các từ: "policy holder" thành "policyholder", "non-employee labor" thành "nonemployeelabor". OCR cũng gây lỗi tương tự từ phía tài liệu. Levenshtein distance không có điểm neo nào khi ranh giới từ không đáng tin cậy.

OCR thay chữ này bằng chữ khác

OCR hiện đại nhầm lẫn các cặp glyph gần giống nhau: O thành 0, l thành 1, rn thành m. Văn bản sau OCR đọc "có vẻ" đúng với mắt người nhưng không khớp với bất kỳ tìm kiếm literal nào.

Các cặp glyph dễ OCR nhầm - Ảnh tác giảCác cặp glyph dễ OCR nhầm - Ảnh tác giả

Khoảng cách Levenshtein tích lũy nhanh theo độ dài cụm từ: một cụm 27 ký tự bị OCR làm hỏng vài chữ có thể đạt distance 4 — vùng false-positive mà ngưỡng tìm kiếm không thể chịu đựng nổi.

Embeddings xử lý tự nhiên, nhưng vì lý do khác

So sánh thực nghiệm trên text-embedding-ada-002 cho thấy: câu hỏi có lỗi gõ (vd: "covarge" thay vì "coverage") đạt cosine > 0.95 — embeddings coi là query tương đương. Với các cặp từ nhìn giống nhau nhưng khác nghĩa (coverage vs overage), cosine chỉ giảm xuống 0.91 — ngữ cảnh xung quanh giúp phân biệt, điểm này được thảo luận kỹ trong Article 6.

Điểm mạnh nhất của embeddings nằm ở cụm từ dài bị OCR làm hỏng: dù Levenshtein distance nằm trong vùng false-positive (2-4), cosine vẫn đạt 0.86-0.97, đủ để retrieval layer coi là match. Lý do là embedding nhìn câu như một tổng thể — nhiễu ký tự trên một token làm vector dịch chuyển rất ít khi các token xung quanh vẫn giữ nghĩa.

Khoảng cách edit 2-4 là vùng false-positive với Levenshtein, nhưng cosine vẫn đủ cao - Ảnh tác giảKhoảng cách edit 2-4 là vùng false-positive với Levenshtein, nhưng cosine vẫn đủ cao - Ảnh tác giả

Chunk granularity là đòn bẩy quyết định: chia theo dòng (khoảng 100 ký tự) giữ tín hiệu tốt, chia theo trang làm loãng tín hiệu vì nhiễu từ các dòng khác. Một dòng đích bị OCR đạt cosine 0.858, nhưng cả trang chỉ còn 0.787.

Hai bài toán doanh nghiệp, không phải một

Lỗi trong câu hỏi người dùng

Vị trí xử lý đúng là ở bước question parsing, không phải retrieval. Quy trình chuẩn hóa bao gồm hạ thấp hoa thường, bỏ dấu, mở rộng từ viết tắt theo danh bạ công ty, và spell-correct theo từ vựng corpus:

def normalize_query(query, *, abbrev_dict, corpus_vocab, max_edit_distance=2):
    text = strip_accents(query.lower())
    tokens = [abbrev_dict.get(t, t) for t in text.split()]
    # ... spell-correct từng token dựa trên SymSpell xây từ corpus

Điểm mấu chốt: từ điển sửa lỗi phải là từ vựng của chính corpus, không phải từ điển generic. Lỗi sửa sẽ rơi đúng vào các thuật ngữ có trong tài liệu người dùng đang tìm kiếm.

Lỗi trong tài liệu

Hầu hết tài liệu tham chiếu doanh nghiệp (hợp đồng, chính sách, quy định) đều sạch — tỷ lệ lỗi gần bằng 0. Nhưng các corpus cần tìm kiếm nhất lại là ngoại lệ: ticket hỗ trợ khách hàng, đánh giá người dùng, chat nội bộ, tài liệu scan qua OCR.

Chọn chiến lược theo giá trị tài liệu

Tài liệu chuẩn quan trọng: làm sạch một lần

Khi corpus là nguồn sự thật chính (hợp đồng chuẩn, thông số kỹ thuật, văn bản pháp lý), hãy đầu tư làm sạch đúng một lần: quét sửa lỗi với ngưỡng tin cậy (auto-correct trên 0.92, đánh dấu cho người duyệt từ 0.70-0.92), LLM xử lý các đoạn bị đánh dấu, chuyên gia rà soát các phần rủi ro cao nhất. Chi phí chỉ xảy ra một lần mỗi phiên bản tài liệu, lợi ích tích lũy cho mọi truy vấn sau này.

Tài liệu khối lượng lớn: tối ưu tìm kiếm thay vì làm sạch

Khi corpus lớn, thay đổi liên tục và giá trị mỗi tài liệu thấp (tickets, review, chat logs), chiến lược ngược lại: giữ nguyên tài liệu, thiết kế retrieval hoạt động quanh nhiễu. Đây là cấu trúc cascade thô-tới-tinh:

  • Nhúng theo dòng, không theo trang — chunk càng ngắn, nhiễu càng ít đè lên tín hiệu
  • Embeddings là phương pháp retrieval chính, không dùng BM25 — embeddings hấp thụ hầu hết lỗi gõ, BM25 khuếch đại chúng
  • Từ điển chuyên ngành ánh xạ dạng chuẩn sang mọi biến thể đã gặp (coverage → covarge, covrage, coverag...)
  • LLM đọc top-k dòng embeddings trả về — tại mức dòng, chi phí model chỉ là phần nhỏ xu, và đây là bước duy nhất trong pipeline đọc đúng ý nghĩa

Cascade thu hẹp dần: triệu chunk → 10 trang → 10 dòng → 1 dòng LLM xác nhận - Ảnh tác giảCascade thu hẹp dần: triệu chunk → 10 trang → 10 dòng → 1 dòng LLM xác nhận - Ảnh tác giả

Một cạm bẫy cần tránh: thay vì dùng LLM, có phản xạ dùng Levenshtein (miễn phí, local). Thử nghiệm cho thấy Levenshtein xếp hạng đúng nhưng khoảng cách nằm trong vùng 60-90 phụ thuộc độ dài, không thể tách thành tín hiệu retrieval. Cách đúng là để embeddings cắt corpus từ triệu chunk xuống 10 ứng viên trước — khi đó LLM verify trên từng dòng chỉ tốn phân xu.

Kết luận

Trong RAG doanh nghiệp không có một "bài toán lỗi chính tả" duy nhất. Phân chia thực tế:

  • Sửa câu hỏi tại bước parse, dựa trên từ vựng corpus
  • Làm sạch tài liệu chuẩn một lần cho các tài liệu quan trọng
  • Dựa vào embeddings cho các corpus khối lượng lớn khó làm sạch hoàn toàn

Lớp xử lý chính tả là một hệ thống cải tiến liên tục. Mỗi query thất bại là tín hiệu thiếu từ điển hoặc mẫu OCR chưa xử lý — chuyên gia bổ sung, từ điển lớn dần, các query tháng sau tốt hơn tháng trước. Không có dự án "làm sạch một lần" nào theo kịp tốc độ thay đổi của corpus.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗