Chuyển tới nội dung chính

Kỹ thuật suy luận

Buổi 1 cho ta nền tảng: nói rõ vai trò, nhiệm vụ và định dạng, đừng bắt máy đoán ý. Nhưng có những việc dù prompt đã rõ ràng, mô hình vẫn trả lời sai hoặc hời hợt: một bài toán nhiều bước, một đoạn suy luận logic, một bài tập thuật toán cần lần theo từng bước. Lý do không phải vì mô hình kém, mà vì ta chưa hướng dẫn nó suy luận đúng cách.

Mô hình ngôn ngữ về bản chất là máy đoán chữ tiếp theo. Khi bạn hỏi thẳng "kết quả là bao nhiêu", mô hình bị ép phải đoán ngay con số cuối cùng mà chưa kịp trải các bước trung gian ra văn bản. Với bài một bước thì không sao, nhưng với bài nhiều bước, mỗi bước sai nhỏ sẽ dồn lại thành kết quả sai lớn.

Mẹo cốt lõi rất đơn giản: nếu ta cho mô hình viết ra các bước trung gian, xác suất ra đáp án đúng tăng lên rõ rệt. Viết các bước ra giấy giúp con người ít sai; với mô hình cũng vậy, vì mỗi bước được viết ra lại trở thành ngữ cảnh cho bước sau. Buổi này giới thiệu ba kỹ thuật giúp mô hình suy luận tốt hơn: Chain-of-Thought, Atom-of-Thoughts và Few-shot.

Bổ sung, không thay thế

Các kỹ thuật buổi này không thay bốn thành phần cơ bản (Instruction, Context, Input Data, Output Indicator) đã học ở buổi 1, mà bổ sung lên trên: vẫn nêu rõ vai trò, nhiệm vụ, định dạng, rồi mới thêm câu kích hoạt suy luận.

Thử ngay: tự lọc bộ thẻ kỹ thuật

Dưới đây là bộ thẻ kỹ thuật của cả khoá học. Bấm nút lọc nhóm Suy luận để xem hai kỹ thuật (Chain-of-Thought, Atom-of-Thoughts), và nhóm Cung cấp ngữ cảnh để xem Few-shot cùng phần buổi sau. Bấm từng thẻ để mở công thức và ví dụ ngắn.

Chain-of-Thought: suy nghĩ từng bước

Chain-of-Thought (viết tắt CoT, "chuỗi suy nghĩ") là kỹ thuật yêu cầu mô hình trình bày lập luận theo từng bước trước khi đưa ra đáp án cuối, thay vì trả lời ngay.

Công thức. [Câu hỏi] cộng câu kích hoạt "hãy suy nghĩ từng bước" cho ra [Bước 1] ... [Bước n] rồi mới tới [Đáp án cuối].

Ba thành phần cần nhớ: (1) câu hỏi rõ ràng; (2) câu kích hoạt "hãy suy nghĩ từng bước"; (3) tách rõ lập luận và đáp án để dễ kiểm tra.

Đừng lạm dụng

Chain-of-Thought không phải lúc nào cũng hiệu nghiệm. Câu hỏi đơn giản chỉ thành dài dòng. Chỉ dùng khi việc thật sự nhiều bước: tính toán, suy luận logic, lần theo thuật toán, gỡ lỗi.

Ví dụ kinh điển, một bài toán logic nhiều phép tính:

Một cửa hàng có 23 quả táo. Buổi sáng bán 7 quả, buổi chiều
nhập thêm 12 quả, rồi bán tiếp 5 quả. Hỏi cuối ngày còn bao
nhiêu quả?

Hãy suy nghĩ từng bước: viết rõ phép tính ở mỗi bước, sau đó
ghi "Đáp án:" ở dòng cuối.

Mô hình sẽ viết: ban đầu 23; sau bán sáng còn 16; sau nhập còn 28; sau bán chiều còn 23; rồi mới ghi Đáp án: 23. Nếu hỏi thẳng "còn bao nhiêu", mô hình dễ nhảy cóc và sai.

Gần với sinh viên hơn, hãy hỏi cách suy luận một bài quy hoạch động thay vì chỉ hỏi đáp số. Lấy bài tìm dãy con tăng dài nhất của mảng [10, 9, 2, 5, 3, 7, 101, 18]:

Giải bài tìm dãy con tăng dài nhất cho mảng:
[10, 9, 2, 5, 3, 7, 101, 18]

Hãy suy nghĩ từng bước theo hướng quy hoạch động:
1. Định nghĩa dp[i] là gì.
2. Viết công thức truy hồi cho dp[i].
3. Lập bảng dp cho từng phần tử, giải thích mỗi ô.
4. Kết luận độ dài dãy con tăng dài nhất.

Trình bày từng bước rõ ràng, cuối cùng ghi "Đáp án:".

Với hướng dẫn này, mô hình giải thích dp[i] là độ dài dãy tăng dài nhất kết thúc tại phần tử thứ i, viết công thức truy hồi, rồi điền bảng dp từng ô. Bạn không chỉ nhận đáp số mà còn hiểu cách dựng nghiệm, đúng thứ cần khi đi thi.

Tự nhất quán: lấy nhiều lời giải rồi bỏ phiếu

Chain-of-Thought vẫn còn một điểm yếu. Mỗi lần chạy, mô hình đi theo đúng một mạch suy nghĩ, và nếu mạch đó lỡ rẽ sai ngay bước đầu thì cả lời giải hỏng theo, dù các bước sau trông vẫn mạch lạc. Tự nhất quán (self-consistency) chữa điểm này bằng một cách rất đời thường: hỏi cùng một câu nhiều lần, mỗi lần bắt mô hình suy nghĩ từng bước một cách độc lập, rồi lấy đáp án xuất hiện nhiều nhất. Giống trong lớp gặp bài khó, bạn không tin ngay lời giải của một người mà đối chiếu lời giải của năm bạn: đáp án nào nhiều người ra giống nhau thì đáng tin hơn.

Cách làm thủ công rất gọn. Bạn chạy lại cùng một prompt Chain-of-Thought ba đến năm lần, mở phiên mới mỗi lần để các lần không nhìn thấy nhau, ghi lại đáp án cuối của từng lần, rồi chọn đáp án trùng nhiều nhất. Nếu năm lần cho ra ba đáp án khác nhau, đó chính là tín hiệu rằng bài này mô hình chưa chắc, và bạn nên tự kiểm bằng tay thay vì tin bừa một lần chạy. Điểm mạnh của tự nhất quán không phải làm mô hình thông minh hơn ở mỗi lần, mà là làm lộ ra sự không chắc chắn: khi các lần chạy tản mát, bạn biết ngay là không nên tin.

Đổi lại, tự nhất quán tốn nhiều lượt chạy hơn hẳn, nên chỉ dành cho bài thật sự quan trọng và có một đáp án đúng để bỏ phiếu (một con số, một nhãn, một kết luận dứt khoát). Với câu hỏi mở, không có đáp án duy nhất để đếm phiếu, kỹ thuật này không áp được.

Suy luận trôi chảy không phải là bằng chứng

Một chuỗi suy nghĩ mạch lạc, đọc rất thuyết phục, vẫn có thể sai từ một giả định sai ở bước đầu, và mô hình sẽ tự tin đi tiếp tới kết luận sai mà giọng văn không hề nao núng. Suy luận từng bước làm lời giải dễ soát hơn, chứ không tự nó bảo đảm đúng. Nhất là với dữ kiện thực tế (một điều luật, một thông số, một mốc thời gian), suy luận nội bộ không thay được việc kiểm chứng ở nguồn ngoài: mô hình có thể lập luận rất gọn trên một dữ kiện mà nó nhớ nhầm. Chuỗi suy nghĩ giúp bạn thấy mô hình dựa vào dữ kiện gì, để còn biết đường tra lại.

Atom-of-Thoughts: chẻ thành phần độc lập rồi ghép

Với bài toán lớn, đôi khi suy nghĩ theo một chuỗi tuyến tính vẫn rối, vì nhiều phần đan vào nhau. Atom-of-Thoughts (viết tắt AoT, "nguyên tử suy nghĩ") xử lý kiểu khác: chẻ bài toán thành các phần con độc lập, giải riêng từng phần, rồi mới ghép lại thành lời giải tổng.

Công thức. [Bài toán lớn] chẻ thành {nguyên tử 1, ..., nguyên tử k} độc lập, giải riêng mỗi nguyên tử, rồi [Ghép kết quả].

Khác Chain-of-Thought (một mạch nối tiếp), Atom-of-Thoughts chia bài toán thành các viên nhỏ xử lý riêng rồi tổng hợp. Hợp với bài có nhiều phần ít liên quan nhau. Nói gọn: CoT đi thẳng một đường, AoT chẻ nhánh rồi gom về.

Ví dụ tính tổng chi phí một chuyến đi, chẻ thành ba phần độc lập:

Tính tổng chi phí chuyến đi 3 ngày của 4 người. Hãy CHẺ bài
toán thành các phần độc lập rồi tính riêng từng phần:
- Phần A: tiền xe (2 triệu/lượt, đi và về).
- Phần B: tiền khách sạn (600 nghìn/phòng/đêm, 2 phòng, 2 đêm).
- Phần C: tiền ăn (150 nghìn/người/ngày).
Tính riêng A, B, C rồi cộng lại thành tổng. Chia cho 4 để ra
chi phí mỗi người.

Mỗi phần A, B, C độc lập, tính riêng không sợ nhầm. Cuối cùng ghép tổng bằng A cộng B cộng C, rồi chia 4. Cách chia nguyên tử này giảm nhầm lẫn so với cộng dồn một mạch.

Gần với sinh viên hơn, hãy nhờ mô hình chẻ một đồ án nhỏ khi bạn thấy "to quá, không biết bắt đầu từ đâu":

Tôi cần viết chương trình quản lý sinh viên bằng Java
(thêm/xoá/sửa/tìm/sắp xếp theo điểm).

Hãy chia bài toán thành các phần ĐỘC LẬP có thể làm riêng,
mỗi phần nêu rõ: dữ liệu cần, hàm cần viết, cách kiểm thử.
Sau đó nói thứ tự nên làm trước sau và cách ghép các phần lại
thành chương trình hoàn chỉnh.

Mô hình tách thành các nguyên tử: lớp SinhVien, danh sách lưu trữ, hàm thêm, hàm xoá, hàm tìm, hàm sắp xếp, phần menu. Bạn làm xong từng phần (kiểm thử riêng) rồi ghép. Đây chính là tư duy chia để trị mà môn cấu trúc dữ liệu đã dạy, nay áp vào cách hỏi AI.

Few-shot: cho ví dụ mẫu để định khuôn

Đôi khi điều bạn muốn không phải lập luận mà là đúng kiểu đầu ra: đúng định dạng, đúng văn phong, đúng cách phân loại. Cách nhanh nhất là cho mô hình vài ví dụ mẫu. Few-shot là kỹ thuật đặt một vài cặp ví dụ "đầu vào rồi đầu ra" ngay trong prompt, để mô hình bắt chước khuôn đó cho ca mới.

Công thức. [Mô tả việc] cộng [Ví dụ 1: vào rồi ra] cộng thêm vài ví dụ nữa, rồi tới [Đầu vào thật: vào rồi ?].

Có ba mức: zero-shot không ví dụ; one-shot một ví dụ; few-shot vài ví dụ (thường 2 đến 5). Nhiều ví dụ thì khuôn rõ hơn nhưng prompt dài hơn, nên cho vừa đủ. Ví dụ phải đa dạng (phủ nhiều trường hợp), nhất quán (cùng một khuôn đầu ra), và đúng (ví dụ sai dạy mô hình làm sai theo).

Tránh ví dụ thiên lệch

Nếu cả ba ví dụ đều nhãn TÍCH CỰC, mô hình sẽ nghiêng về nhãn đó. Hãy cân bằng các nhãn, và đưa ca khó (dễ nhầm) vào ví dụ để mô hình học được ranh giới.

Ví dụ phân loại cảm xúc bình luận, ba ví dụ mẫu phủ ba nhãn:

Phân loại cảm xúc của bình luận thành: TÍCH CỰC, TIÊU CỰC,
hoặc TRUNG TÍNH. Theo đúng mẫu sau:

Bình luận: "Sản phẩm tuyệt vời, giao nhanh!" -> TÍCH CỰC
Bình luận: "Hàng kém, không như mô tả." -> TIÊU CỰC
Bình luận: "Đóng gói bình thường, tạm ổn." -> TRUNG TÍNH

Bình luận: "Giá hơi cao nhưng chất lượng xứng đáng." ->

Ba ví dụ mẫu dạy rõ ba nhãn và khuôn "Bình luận rồi NHÃN". Mô hình điền nốt nhãn cho ca cuối theo đúng khuôn, không lan man.

Gần với sinh viên hơn, hãy cho một ví dụ mẫu để mọi hàm trong đồ án có chú thích cùng một kiểu:

Viết chú thích (docstring) cho hàm Python theo ĐÚNG khuôn ví dụ:

# Ví dụ:
def cong(a, b):
"""Return the sum of two integers.
Args: a (int), b (int).
Returns: int, the sum a + b.
"""
return a + b

# Hãy viết docstring theo khuôn trên cho hàm sau:
def tim_max(arr):
return max(arr)

Mô hình sinh docstring tiếng Anh đúng khuôn ("Return ...", "Args", "Returns"), khớp quy ước chú thích bằng tiếng Anh. Một ví dụ mẫu đáng giá hơn một đoạn mô tả dài.

Tự kiểm tra lại kết quả

Ba kỹ thuật trên giúp mô hình nghĩ kỹ hơn. Còn một bước nữa hay bị bỏ quên: bắt mô hình kiểm lại cái nó vừa viết. Mô hình trả lời trôi chảy và tự tin ngay cả khi sai, nên nếu bạn không yêu cầu, nó sẽ không tự soát.

Cách đơn giản nhất là tách thành hai lượt: lượt một để mô hình giải, lượt hai yêu cầu nó đóng vai người phản biện, thay giá trị vừa tìm được ngược lại vào đề bài, rồi kết luận đúng hay sai.

Hãy KIỂM TRA LẠI lời giải ở trên, đóng vai người chấm bài
khó tính:
1. Thay đáp án vừa tìm được ngược lại vào đề, kiểm tra xem
có thoả mọi điều kiện của đề không.
2. Chỉ ra bước nào (nếu có) tính sai hoặc suy luận vội.
3. Kết luận: ĐÚNG, hoặc SAI kèm lời giải đã sửa.

Với lập trình, hiệu quả nhất là bắt mô hình chạy thử bằng tay trên các ca cụ thể, thay vì hỏi chung chung "đoạn này đúng chưa".

Đây là hàm tìm nhị phân bạn vừa viết. Hãy tự kiểm tra bằng
cách chạy tay ba ca sau, in low, high, mid sau MỖI vòng lặp:
- Ca 1: mảng [1, 3, 5, 7], tìm 7.
- Ca 2: mảng rỗng, tìm 5.
- Ca 3: phần tử cần tìm không có trong mảng.
Mỗi ca ghi rõ hàm trả về gì. Nếu sai, sửa lại code.

Yêu cầu in trạng thái sau mỗi vòng lặp buộc mô hình trải quá trình ra văn bản, đúng tinh thần Chain-of-Thought nhưng áp cho khâu kiểm tra. Ba ca kia cũng là ba ca hay lỗi nhất: biên cuối, đầu vào rỗng, và trường hợp không tìm thấy.

Tự kiểm tra không phải bảo chứng

Mô hình hoàn toàn có thể kiểm tra xong rồi khẳng định chắc nịch rằng một đáp án sai là đúng. Tự kiểm tra làm tăng khả năng bắt lỗi, chứ không bảo đảm gì. Với những thứ xác minh được một cách khách quan (code chạy được, phép tính tính lại được), hãy tự chạy và tự đối chiếu.

Chọn kỹ thuật nào cho việc gì

Bốn kỹ thuật không loại trừ nhau, nhưng mỗi kỹ thuật giải một loại khó riêng.

Việc bạn cầnKỹ thuật hợpVì sao
Bài nhiều bước tính toán, suy luận logicChain-of-ThoughtBắt trải các bước trung gian ra, giảm nhảy cóc.
Đề bài to, nhiều phần ít dính nhauAtom-of-ThoughtsChẻ thành phần độc lập, giải riêng rồi ghép.
Cần đúng định dạng, đúng văn phong, đúng nhãnFew-shotVí dụ mẫu định khuôn nhanh hơn mọi lời mô tả.
Kết quả quan trọng, sai thì tốn kémTự kiểm traThêm một lượt phản biện để bắt lỗi sớm.
Câu hỏi tra cứu một bướcKhông cần kỹ thuật nàoHỏi thẳng, thêm kỹ thuật chỉ làm dài dòng.

Một prompt cho bài tập lớn thường ghép cả bốn: chẻ đề bằng Atom-of-Thoughts, cho ví dụ mẫu về định dạng bằng Few-shot, yêu cầu suy nghĩ từng bước bằng Chain-of-Thought, rồi chốt bằng một lượt tự kiểm tra.

Ba lỗi hay gặp

Dùng Chain-of-Thought cho câu hỏi một bước. Hỏi "Java có bao nhiêu kiểu nguyên thuỷ" mà bắt suy nghĩ từng bước thì chỉ được câu trả lời dài hơn, không đúng hơn.

Cho ví dụ Few-shot mâu thuẫn nhau. Hai ví dụ cùng một tình huống mà gán hai nhãn khác nhau sẽ dạy mô hình đoán bừa. Ví dụ phải nhất quán và phải đúng.

Tin lời tự kiểm tra thay vì tự chạy thử. Code phải chạy mới biết đúng, phép tính phải tính lại mới biết khớp.

Bài tập thực hành

Bài tập 1: viết prompt Chain-of-Thought cho một bài thuật toán

Viết prompt yêu cầu mô hình giải bài "kiểm tra một chuỗi có phải chuỗi đối xứng không" theo từng bước, có tách phần lập luận khỏi phần đáp án.

Gợi ý lời giải

Prompt cần đủ ba thành phần: câu hỏi rõ, câu kích hoạt suy nghĩ từng bước, và yêu cầu tách đáp án ra cuối để dễ soát.

Kiểm tra chuỗi "hacminh" có phải chuỗi đối xứng không.

Hãy suy nghĩ từng bước:
1. Nhắc lại định nghĩa chuỗi đối xứng.
2. So sánh từng cặp ký tự đối xứng nhau, ghi rõ kết quả
từng cặp và dừng ngay khi gặp cặp không khớp.

Cuối cùng ghi "Đáp án:" trên một dòng riêng.

Ý chính: câu kích hoạt cộng yêu cầu tách đáp án giúp bạn soát được lập luận, chứ không chỉ nhận về một chữ "có" hay "không".

Bài tập 2: chọn kỹ thuật cho ba tình huống

Chọn kỹ thuật hợp nhất cho mỗi tình huống và giải thích ngắn gọn. (a) Phân loại 200 phản hồi sinh viên thành ba nhãn theo đúng một định dạng cố định. (b) Giải một bài quy hoạch động và muốn hiểu cách dựng nghiệm. (c) Hỏi cú pháp khai báo mảng trong Java.

Gợi ý lời giải

(a) Few-shot. Cái khó là đúng nhãn và đúng định dạng, không phải suy luận nhiều bước. Cho ba đến năm ví dụ mẫu phủ đủ ba nhãn, cân bằng, có cả ca khó.

(b) Chain-of-Thought. Bài nhiều bước và bạn muốn thấy đường đi, không chỉ đáp số. Yêu cầu định nghĩa dp[i], viết công thức truy hồi, lập bảng, rồi mới kết luận.

(c) Không cần kỹ thuật nào. Câu hỏi tra cứu một bước, hỏi thẳng là xong.

Ý chính: chọn kỹ thuật theo loại khó của việc, đừng dùng cùng một khuôn cho mọi câu hỏi.

Câu hỏi tự kiểm

Kiểm tra nhanh: kỹ thuật suy luận0/4 đúngchưa trả lời
  1. 1Vì sao Chain-of-Thought giúp mô hình ra đáp án đúng thường xuyên hơn ở bài nhiều bước?
  2. 2Điểm mạnh thật sự của tự nhất quán (self-consistency) là gì?
  3. 3Một chuỗi suy nghĩ mạch lạc, đọc rất thuyết phục thì...
  4. 4Atom-of-Thoughts khác Chain-of-Thought ở chỗ nào?

Ghi nhớ

  • Bắt mô hình viết ra các bước trung gian thì đáp án đúng thường xuyên hơn: đó là ý cốt lõi của Chain-of-Thought.
  • Với bài quan trọng có một đáp án đúng, chạy lại vài lần rồi lấy đáp án trùng nhiều nhất (tự nhất quán); các lần tản mát là dấu hiệu mô hình chưa chắc.
  • Atom-of-Thoughts chẻ đề thành phần độc lập, giải riêng rồi ghép, hợp với đề to.
  • Few-shot định khuôn đầu ra bằng vài ví dụ mẫu; ví dụ phải đa dạng, nhất quán và đúng.
  • Tự kiểm tra là một lượt riêng, không phải một câu thêm vào cuối prompt.
  • Việc một bước thì hỏi thẳng, đừng khoác thêm kỹ thuật cho dài.

Buổi sau ta sang nửa còn lại của tiêu đề buổi học: cung cấp ngữ cảnh và dữ liệu, để câu trả lời bám một nguồn cho trước thay vì bịa.