Thiếu một ký tự, AI viết mù cả bài mà log vẫn báo xanh

Thiếu một ký tự, AI viết mù cả bài

Bài viết do Nguyễn Nhật Ánh Dương thực hiện, biên soạn theo Chính sách nội dung của Marketing365. Cập nhật lần cuối .

Nội dung
  1. Chỗ hỏng: chuỗi phải bắt đầu bằng dấu bằng
  2. Chỗ tôi quen nhìn đều báo xanh
  3. Sửa mất một ký tự, kiểm mới là phần khó
  4. Quét lại cả máy chủ xem còn chỗ nào
  5. Cách kiểm khi nghi ngờ
  6. Ba thứ tôi mang ra khỏi vụ này

Ngày 07/08/2026, một luồng tự động của tôi có việc viết lại mấy bài cũ. Nó chạy xong, báo thành công, trả về dữ liệu đúng định dạng, bài ra đọc trôi chảy. Chỉ có một chuyện: bài mới không dính gì tới bài cũ mà nó phải viết lại.

Không có dòng lỗi nào. Không có cảnh báo nào. Nguyên nhân là một ký tự bị thiếu ở đầu một chuỗi dài 13.924 ký tự.

Chỗ hỏng: chuỗi phải bắt đầu bằng dấu bằng

Công cụ tự động tôi dùng có một quy ước: trong ô nhập của một bước, phần {{ ... }} chỉ được thay bằng dữ liệu thật khi cả chuỗi bắt đầu bằng dấu bằng. Thiếu dấu đó, chuỗi được coi là chữ thường, và {{ ... }} đi thẳng sang bên nhận dưới dạng đúng mấy ký tự đó.

Ô nhập ở đây là prompt gửi cho model. Nó có bốn chỗ cắm dữ liệu: bài cũ, danh sách tít vừa dùng, góc viết, và mấy ví dụ tít. Thiếu dấu bằng, model nhận được bốn dòng chữ như dưới đây thay vì nhận bốn khối dữ liệu.

{{ $json.body.taskBrief }}
{{ $json.body.recentBan }}
{{ $json.body.angleHint }}
{{ $json.body.titleExamples }}

Model không có bài cũ trong tay, nhưng phần luật viết bài thì vẫn nhận đủ. Nên nó làm đúng thứ nó có: viết chay theo luật.

So sánh chuỗi thiếu dấu bằng với chuỗi có dấu bằng, bảng tín hiệu kiểm tra và kết quả quét 211 luồng
Sự cố ngày 07/08/2026 trên luồng viết lại bài, và bản quét lại toàn bộ 211 luồng tự động ngày 14/08/2026.

Chỗ tôi quen nhìn đều báo xanh

Đây là loại hỏng khó thấy nhất tôi từng gặp, vì mọi thứ tôi có thói quen kiểm đều nói là ổn:

  • Lần chạy báo thành công.
  • Dữ liệu trả về hợp lệ, đủ trường.
  • Nhật ký lỗi trống trơn.
  • Bài ra có tít, có bố cục, đọc trôi.

Bốn tín hiệu đó đều đúng theo nghĩa hẹp: lệnh đã gửi đi, bên kia đã trả lời, câu trả lời hợp lệ. Không tín hiệu nào trả lời được câu “model có nhận đúng thứ tôi định gửi không”.

Thứ duy nhất tố cáo là nội dung: ba bài khác hẳn chủ đề lại ra cùng một bộ tiêu đề phụ. Và có một lần model trả thẳng ra dòng “[Cần dữ liệu taskBrief]” — nó đang nói rằng chỗ đó trống, nhưng nói bằng cách trông giống một câu trong bài.

Sửa mất một ký tự, kiểm mới là phần khó

Bản vá là thêm một dấu bằng vào đầu chuỗi: 13.924 ký tự thành 13.925. Phần đáng nói không phải bản vá, mà là hai chốt tôi gắn quanh nó.

Chốt thứ nhất chặn trước khi ghi: nếu chuỗi sau khi sửa không bắt đầu bằng dấu bằng thì dừng luôn, không ghi gì cả. Có thêm một chốt nữa đếm đủ bốn chỗ cắm dữ liệu — thiếu một chỗ nghĩa là tôi vừa sửa nhầm chuỗi.

if not t.startswith("="):
    raise SystemExit("prompt mất dấu bằng — DỪNG")
if found != EXPECT:
    raise SystemExit("biến trong prompt lệch — DỪNG, không ghi")

Chốt thứ hai là bước kiểm sau khi ghi: đọc lại từ máy chủ rồi kiểm đúng cái điều kiện đó, chứ không kiểm kiểu “chuỗi mới có nằm trong đó không”. Hai câu hỏi nghe giống nhau nhưng chỉ một câu trả lời được thứ tôi cần biết.

Hôm đó tôi viết 12 đoạn vá cho nhiều luồng khác nhau; 6 đoạn có chốt này, vì chỉ 6 đoạn đụng vào chuỗi có {{ ... }}.

Quét lại cả máy chủ xem còn chỗ nào

Ngày 14/08/2026 tôi lấy về toàn bộ 211 luồng đang có trên máy chủ và đếm: chuỗi nào chứa {{ ... }} mà không bắt đầu bằng dấu bằng thì tính là thiếu. Tôi bỏ qua các bước viết mã, vì ở đó {{ ... }} không có nghĩa gì đặc biệt, và bỏ qua ghi chú dán trên sơ đồ.

  • 6.733 chỗ viết đúng, có dấu bằng ở đầu.
  • 36 chỗ thiếu dấu — 0,53%, nằm rải ở 16 luồng.
  • 0 luồng đang bật bị dính. Cả 16 luồng đó đều đang tắt.

Nói cho đúng thì hiện không có gì đang hỏng vì lý do này. Nhưng con số 16 luồng không phải 16 lỗi riêng biệt: 7 trong số đó là bản sao của nhau, sai ở đúng một bước cùng tên. Một luồng mẫu bị sai, mỗi lần nhân bản cho một trang là lỗi đi theo. Đó là kiểu lỗi nhân ra chứ không phải kiểu lỗi ngẫu nhiên.

Tôi cũng quét cả bảng bài viết của trang xem có bài nào lọt chuỗi {{ ... }} ra ngoài không. Chỉ có hai bài chứa nó, và cả hai là bài hướng dẫn dùng chính công cụ đó — tức là cố ý. Không bài đăng nào dính chuỗi literal do lỗi này.

Cách kiểm khi nghi ngờ

Khi một bước có AI ra kết quả lạ, phản xạ cũ của tôi là mở phần trả về ra đọc. Phản xạ đó sai chỗ. Thứ cần mở là đầu vào thật đã gửi đi, ghi trong dữ liệu của lần chạy đó. Nhìn đúng chỗ thì lỗi lộ ra ngay: dòng chữ {{ $json.body.taskBrief }} nằm chình ình trong prompt.

Nhìn vào phần trả về thì không bao giờ thấy, vì phần trả về luôn hợp lệ. Model được giao một việc thiếu dữ liệu và nó vẫn làm hết sức — đó chính là chỗ khiến lỗi này sống lâu.

Thiếu một ký tự, AI viết mù cả bài, log vẫn báo xanh
Prompt 13.925 ký tự sau khi vá; trước đó thiếu đúng ký tự đầu tiên nên bốn chỗ cắm dữ liệu đi ra dưới dạng chữ.

Ba thứ tôi mang ra khỏi vụ này

  • “Chạy thành công” chỉ nói lệnh đi tới nơi và có trả lời. Nó không nói nội dung gửi đi là đúng. Muốn biết điều đó thì phải đọc đầu vào thật.
  • Khi một công cụ có quy ước kiểu “chuỗi phải bắt đầu bằng ký tự này thì mới có tác dụng kia”, ký tự đó phải nằm trong danh sách kiểm tự động. Mắt người đọc lướt qua 13.924 ký tự sẽ không thấy thiếu một dấu ở đầu.
  • Bước kiểm sau khi sửa phải hỏi đúng câu đã hỏng, không hỏi câu na ná. “Chuỗi mới có mặt chưa” và “chuỗi có đang ở chế độ biểu thức không” là hai câu khác nhau.

Cùng một họ với chuyện tôi kể trong bài sửa xong nhưng máy vẫn chạy bản cũ: công cụ báo xong việc, mà việc thì chưa tới nơi. Và cũng là lý do tôi giữ thói quen đo lại thay vì tin số cũ, như lần ba cách đếm bài đăng trễ đều cho ra số sai.

36 chỗ còn lại tôi chưa vá. Chúng nằm trong luồng đang tắt, vá bây giờ là sửa thứ không ai dùng, và mỗi lần đụng vào một luồng đang tắt là một lần có thể làm hỏng thứ đang yên. Tôi ghi lại danh sách; luồng nào được bật lại thì vá trước khi bật.

Có thể bạn thích

Để lại bình luận