Menu

Cải tiến prompt: cách kiểm thử và tối ưu prompt

Cải tiến một prompt hiệu quả nhất khi làm như một thí nghiệm nhỏ: xác định một câu trả lời tốt trông như thế nào, giữ cố định vài đầu vào thử nghiệm, mỗi lần chỉ thay đổi một điều và đặt các đầu ra cạnh nhau để so sánh.

Mọi prompt bên dưới đều có thể chỉnh sửa: thay đổi nó, rồi mở trong ChatGPT, Claude hoặc ứng dụng AI khác.

Phiên bản đầu tiên của một prompt là bản nháp. Nó thường cho bạn thứ gì đó gần với điều bạn muốn, và khoảng cách giữa gần đúng và đúng được thu hẹp bằng cách cải tiến qua từng vòng: chủ động thay đổi prompt, chạy lại trên cùng đầu vào, và kiểm tra xem thay đổi có giúp ích không. Nếu làm cẩu thả, việc cải tiến biến thành đổi câu chữ ngẫu nhiên cho đến khi một đầu ra may mắn trông ổn. Nếu làm như một thí nghiệm nhỏ, nó cho bạn một prompt chạy tốt trên một trăm đầu vào tiếp theo, chứ không chỉ trên đầu vào bạn đã thử.

Phương pháp gồm năm bước: xác định thế nào là tốt, giữ cố định các đầu vào thử nghiệm, mỗi lần thay đổi một điều, so sánh đầu ra, và biết khi nào dừng.

Xác định một câu trả lời tốt trông như thế nào

Trước khi sửa bất cứ điều gì, hãy viết ra những gì đầu ra phải làm được, dưới dạng các câu kiểm tra trả lời được bằng có hoặc không. "Một commit message tốt" thì không kiểm tra được. Những điều sau thì được:

  1. Dòng tiêu đề (subject) dưới 50 ký tự.
  2. Theo định dạng Conventional Commits (fix:, feat: và tương tự).
  3. Phần thân nói vì sao cần thay đổi, chứ không lặp lại điều diff đã cho thấy.
  4. Có nhắc số issue khi có issue.

Tiêu chí làm hai việc. Chúng cho bạn biết cần thêm gì vào prompt, vì mỗi tiêu chí thường là một chỉ dẫn còn thiếu. Và chúng ngăn bạn đánh giá đầu ra theo cảm giác nghe có xuôi tai không, vốn là cách dễ nhất để chấp nhận một câu trả lời tự tin nhưng sai.

Giữ một bộ nhỏ đầu vào thử nghiệm

Chọn từ ba đến mười đầu vào và giữ chúng cố định trong lúc làm. Bao gồm các trường hợp điển hình, vài trường hợp khó (một trường bị trống, một đầu vào rất dài, một ngôn ngữ mà prompt không lường trước), và mọi đầu vào từng thất bại. Một prompt được tinh chỉnh trên một ví dụ duy nhất thường khớp với ví dụ đó và thất bại ở ví dụ tiếp theo.

Hãy viết prompt dưới dạng template có một chỗ trống cho đầu vào, để mọi phiên bản đều chạy trên đúng cùng một nội dung.

Mỗi lần thay đổi một điều

Khi bạn thay đổi cùng lúc vai trò, định dạng và ví dụ mà đầu ra tốt lên, bạn không biết thay đổi nào đã tạo ra kết quả, và có thể đang giữ lại hai chỉnh sửa vô ích. Hãy thay đổi một điều, chạy, so sánh. Các tab bên dưới là ba phiên bản của một prompt, mỗi phiên bản chỉ khác phiên bản trước một điểm.

Viết commit message cho diff này.- if len(password) > 8: + if len(password) >= 8: return True
Try it
Example replyReplies vary between models and runs.

Cập nhật kiểm tra độ dài mật khẩu

Commit này cập nhật logic kiểm tra mật khẩu bằng cách đổi toán tử so sánh từ > sang >=. Nhờ vậy, những mật khẩu dài đúng 8 ký tự giờ sẽ được coi là hợp lệ. Thay đổi này giúp việc kiểm tra chính xác hơn và mang lại trải nghiệm tốt hơn cho người dùng khi tạo tài khoản.

Phiên bản 1 không đạt tiêu chí 2 và 3: tiêu đề không có tiền tố loại commit, và phần thân kể lại diff bằng nhiều chữ hơn. Phiên bản 2 thêm yêu cầu về định dạng và đạt tiêu chí 1 và 2, nhưng phần thân vẫn mô tả diff. Chỉnh sửa tiếp theo dễ nghĩ đến nhất là thêm một chỉ dẫn ("giải thích lý do"), nhưng mô hình không thể giải thích một lý do mà nó chưa bao giờ được cho biết. Phiên bản 3 thay vào đó bổ sung bối cảnh còn thiếu, và phần thân cùng tham chiếu issue tự xuất hiện mà không cần yêu cầu. Đó là bài học phổ biến nhất của việc cải tiến: khi một chỉ dẫn không sửa được đầu ra, prompt thường đang thiếu thông tin, chứ không phải thiếu sự nhấn mạnh.

Đặt các đầu ra cạnh nhau để so sánh

Chạy mọi phiên bản trên mọi đầu vào thử nghiệm, và chạy mỗi phiên bản nhiều hơn một lần, vì mô hình chat lấy mẫu từ ngữ và hai lần chạy cùng một prompt sẽ khác nhau. Đặt các đầu ra cạnh nhau và đối chiếu chúng với tiêu chí của bạn, chứ không phải với trí nhớ về lần chạy trước.

Với những tiêu chí chính xác, một lần gọi mô hình thứ hai có thể chấm vòng đầu. Dán các đầu ra vào một prompt chấm điểm có ghi rõ các tiêu chí:

Chấm đầu ra theo tiêu chí cố định
Fill in
Kiểm tra từng đầu ra bên dưới theo các tiêu chí. Với mỗi tiêu chí, trả lời đạt hoặc không đạt kèm lý do ngắn có trích dẫn từ đầu ra. Chỉ đánh giá các tiêu chí được liệt kê. Không cộng điểm cho độ dài hay văn phong. Tiêu chí: 1. Dòng tiêu đề dưới 50 ký tự. 2. Theo Conventional Commits. 3. Phần thân nói vì sao cần thay đổi, chứ không phải điều diff cho thấy. 4. Có nhắc số issue. Đầu ra A: """ fix: chấp nhận mật khẩu dài đúng 8 ký tự Đổi điều kiện kiểm tra độ dài từ > sang >= để mật khẩu dài đúng 8 ký tự vượt qua bước kiểm tra. """ Đầu ra B: """ fix: chấp nhận mật khẩu dài đúng 8 ký tự Trang đăng ký yêu cầu ít nhất 8 ký tự, nhưng bước kiểm tra lại từ chối mật khẩu dài đúng bằng đó, nên người dùng làm đúng hướng dẫn vẫn không đăng ký được. Fixes #412 """ Trả lời bằng một bảng, mỗi tiêu chí một hàng.
Try it
Example replyReplies vary between models and runs.
Tiêu chíĐầu ra AĐầu ra B
1. Tiêu đề dưới 50 ký tựĐạt: tiêu đề dài 40 ký tựĐạt: cùng tiêu đề, 40 ký tự
2. Conventional CommitsĐạt: bắt đầu bằng "fix:"Đạt: bắt đầu bằng "fix:"
3. Phần thân giải thích lý doKhông đạt: "Đổi điều kiện kiểm tra độ dài từ > sang >=" lặp lại diffĐạt: "người dùng làm đúng hướng dẫn vẫn không đăng ký được"
4. Có nhắc issueKhông đạt: không có số issueĐạt: "Fixes #412"

Hãy coi mô hình chấm điểm là trợ lý, không phải trọng tài. Zheng và cộng sự năm 2023, trong "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena", đã ghi nhận các thiên lệch của mô hình chấm điểm, như thiên về câu trả lời dài hơn và thiên về câu trả lời ở một vị trí nhất định. Giữ tiêu chí kiểm tra được, yêu cầu trích dẫn làm bằng chứng, đổi thứ tự A và B khi so sánh hai đầu ra, và tự đọc một phần đầu ra. Những phép kiểm tra như đếm ký tự đáng tin cậy hơn khi viết thành một dòng code so với để mô hình phán đoán.

Sửa prompt, đừng sửa cuộc trò chuyện

Trong một cuộc chat, rất dễ muốn sửa câu trả lời bằng các tin nhắn tiếp theo: "ngắn hơn", "không, nhắc đến issue đi", "dùng định dạng kia". Cách đó cho bạn một đầu ra tốt và để nguyên prompt tệ như cũ. Khi một lời sửa có hiệu quả, hãy đưa nó vào prompt và chạy lại prompt từ đầu. Lần sau cần kết quả, bạn chỉ dán một tin nhắn thay vì lặp lại năm tin nhắn.

Giữ lại các phiên bản cũ kèm một dòng ghi chú về điều đã thay đổi và điều nó sửa được. Một tệp văn bản thuần là đủ. Khi một chỉnh sửa sau đó làm mọi thứ tệ đi, bạn có thể quay lại thay vì cố nhớ prompt từng viết gì.

Chạy so sánh bằng code

Khi prompt đã chạy qua API, một script ngắn có thể tạo bảng so sánh cạnh nhau cho mọi phiên bản và mọi đầu vào thử nghiệm. Script này dùng OpenAI Python SDK và ghi ra một tệp markdown để bạn đọc từ trên xuống dưới.

from openai import OpenAI

client = OpenAI()
MODEL = "your-model-id"  # e.g. from your provider's model list

# each prompt file contains {input} where the test diff goes
PROMPTS = {
    "v2": open("prompts/commit_v2.txt").read(),
    "v3": open("prompts/commit_v3.txt").read(),
}
TESTS = [open(f"tests/diff_{i}.txt").read() for i in range(1, 6)]

with open("results.md", "w") as out:
    for i, test in enumerate(TESTS, 1):
        out.write(f"## Test {i}\n\n")
        for name, template in PROMPTS.items():
            for run in (1, 2):
                response = client.chat.completions.create(
                    model=MODEL,
                    messages=[{"role": "user", "content": template.replace("{input}", test)}],
                )
                out.write(f"### {name}, run {run}\n\n{response.choices[0].message.content}\n\n")

Khi nào nên dừng

Dừng khi mọi tiêu chí đều đạt trên mọi đầu vào thử nghiệm qua vài lần chạy. Thêm nữa sau thời điểm đó chủ yếu chỉ làm prompt dài ra, và mỗi chỉ dẫn thêm vào là thêm một thứ có thể mâu thuẫn với các chỉ dẫn khác.

Cũng nên dừng khi các thay đổi bắt đầu đổi lỗi này lấy lỗi khác: một chỉnh sửa sửa được test 2 nhưng làm hỏng test 4, chỉnh sửa tiếp theo lại đảo ngược. Hiện tượng đó nghĩa là prompt đang bị yêu cầu làm điều mà một chỉ dẫn đơn lẻ không thể chốt được. Các lối ra thường gặp là cho xem định dạng bằng vài ví dụ (few-shot prompting), chia công việc thành các bước với prompt chaining, hoặc chuyển các phần xác định được, như đếm ký tự hay kiểm tra định dạng, sang code kiểm tra đầu ra. Nếu bạn bí ý tưởng, meta prompting có thể giúp: đưa cho mô hình prompt, đầu vào và đầu ra tệ, rồi hỏi phần nào của prompt nhiều khả năng đã gây ra lỗi.

Câu hỏi thường gặp

Làm sao cải thiện một prompt cho câu trả lời tệ?

Xem câu trả lời tệ và gọi tên điều sai trong đó: sai định dạng, thiếu một sự thật, sai đối tượng người đọc, quá dài. Sau đó tìm điều prompt đã không nói mà lẽ ra có thể ngăn lỗi đó, thêm đúng một điều ấy, rồi chạy phiên bản mới trên cùng đầu vào. Câu trả lời tệ thường đến từ việc thiếu bối cảnh hoặc thiếu chỉ dẫn về định dạng hơn là từ câu chữ.

Cần bao nhiêu đầu vào để kiểm thử một prompt?

Với một prompt bạn sẽ dùng lại, từ ba đến mười đầu vào thường là đủ: vài trường hợp điển hình, một hoặc hai trường hợp biên (rất ngắn, rất dài, khác thường) và một đầu vào từng bị làm sai. Giữ chúng cố định trong khi cải tiến, để thay đổi ở đầu ra đến từ prompt chứ không phải từ một đầu vào khác.

Vì sao chạy lại cùng một prompt lại cho câu trả lời khác?

Mô hình chat lấy mẫu từng từ từ một phân phối xác suất, nên đầu ra khác nhau giữa các lần chạy. Khi so sánh hai phiên bản prompt, hãy chạy mỗi phiên bản nhiều hơn một lần trên cùng đầu vào. Một khác biệt xuất hiện ở mọi lần chạy có lẽ là thật; một khác biệt chỉ xuất hiện ở một lần chạy có thể là ngẫu nhiên. Qua API, bạn cũng có thể giảm temperature để giảm độ dao động.

Có thể dùng AI để chấm đầu ra của prompt không?

Có, với những tiêu chí bạn nêu được chính xác, như "phần thân nói vì sao cần thay đổi" hoặc "có nhắc số issue". Đưa cho mô hình chấm đúng các tiêu chí của bạn và yêu cầu kết quả đạt hoặc không đạt cho từng tiêu chí, kèm một câu trích làm bằng chứng. Mô hình chấm điểm có những thiên lệch đã được biết đến, như ưu ái câu trả lời dài hơn và ưu ái một vị trí hơn vị trí kia, nên hãy tự đọc một số đầu ra và đổi thứ tự khi so sánh hai đầu ra.

Khi nào nên dừng cải tiến một prompt?

Dừng khi mọi tiêu chí đều đạt trên mọi đầu vào thử nghiệm qua vài lần chạy, hoặc khi mỗi thay đổi mới sửa được một trường hợp nhưng làm hỏng trường hợp khác. Lúc đó vấn đề thường không nằm ở prompt: tác vụ có thể cần ví dụ, cần được chia thành các bước, hoặc cần một bước kiểm tra bằng code.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu