Oluwa.io
All writing
·11 min readphương pháp sản phẩm AIứng dụng llmevalskỹ thuật

Từ prompt đến sản phẩm: Biến LLM thành ứng dụng thực thụ

Phương pháp thực chiến để xây dựng ứng dụng LLM: eval, lan can bảo vệ, ngân sách độ trễ và chi phí, con người trong vòng lặp, và biết điều gì không nên tự động hóa.

By Vitor Lima

Một prompt hoạt động trong playground là một bản demo, không phải một sản phẩm. Khoảng cách giữa hai thứ đó là nơi hầu hết các dự án AI âm thầm chết đi. Xây dựng các ứng dụng LLM sống sót được qua tay người dùng thực ít liên quan đến việc viết prompt khéo léo hơn những bản demo gợi ý, và liên quan nhiều hơn đến kỷ luật phần mềm bình thường. Chúng tôi đã ship đủ nhiều sản phẩm loại này — Youp, MadaiOps, và giờ là Linea — để có quan điểm về điều gì thực sự khép lại khoảng cách đó. Không điều nào trong số đó là hào nhoáng.

Cái bẫy là phiên bản đầu tiên trông đã hoàn chỉnh. Bạn dán vào một prompt khéo léo, mô hình trả về một thứ ấn tượng, và thật hấp dẫn khi gói nó trong một giao diện và gọi đó là một lần ra mắt. Rồi người dùng thực đến với những đầu vào bạn chưa bao giờ tưởng tượng, mô hình làm một điều sai một cách tự tin, và bạn phát hiện ra mình không có cách nào để biết liệu bản sửa của mình khiến mọi thứ tốt hơn hay tệ hơn. Bài viết này nói về những giàn giáo biến bản demo ấn tượng đó thành thứ bạn có thể vận hành trong môi trường production và ngủ ngon suốt đêm.

Bắt đầu với eval, không phải prompt

Điều có đòn bẩy cao nhất bạn có thể xây dựng từ sớm là một bộ đánh giá (eval). Không phải một benchmark, không phải một bảng xếp hạng — mà là một thư mục chứa các đầu vào thực được ghép cặp với hình dung về một đầu ra tốt trông ra sao. Hai mươi ví dụ tốt hơn không có gì, và năm mươi ví dụ được tuyển chọn tốt hơn một nghìn ví dụ cào từ đâu đó.

Lý do rất đơn giản. Một khi bạn có eval, việc viết prompt không còn dựa vào cảm giác. Bạn thay đổi một dòng, bạn chạy bộ eval, bạn quan sát con số dịch chuyển. Không có nó, mỗi lần chỉnh sửa là một sự mê tín. Chúng tôi đã chứng kiến các đội dành cả tuần cải thiện một prompt chỉ để bị thoái lui ở những trường hợp họ đã giải quyết từ nhiều tháng trước, bởi vì không có gì đo lường những trường hợp họ không nhìn tới.

Một vài quan điểm chúng tôi giữ vững:

  • Chấm điểm dựa trên kết quả, không phải câu chữ. Với bất cứ thứ gì có cấu trúc — trích xuất, phân loại, định tuyến — hãy kiểm tra trên kết quả đã được phân tích cú pháp, không phải trên độ tương đồng chuỗi. Với văn bản tự do, dùng một LLM làm giám khảo với một khung chấm điểm chặt chẽ thì ổn, nhưng hãy kiểm định giám khảo đó dựa trên một nhúm nhãn do con người gán trước, nếu không bạn chỉ đang đo khẩu vị của một mô hình.
  • Giữ một tập tin ghi lại các thoái lui. Mỗi lần thất bại trong production trở thành một trường hợp kiểm thử vĩnh viễn. Đây là cách bộ eval của bạn giữ được sự trung thực — nó lớn lên đúng theo những hướng mà thực tế đẩy vào.
  • Đánh phiên bản cho eval cùng với prompt. Một prompt mà không có bộ eval của nó là một thay đổi mã chưa được kiểm thử.

Nếu bạn chỉ xây dựng một thứ từ bài viết này, hãy xây dựng thứ này. Mọi thứ phía sau đều phụ thuộc vào khả năng trả lời: điều đó có khiến nó tốt hơn không?

Lan can bảo vệ rẻ hơn lời xin lỗi

Các mô hình thất bại theo những cách mà phần mềm thông thường không có. Chúng sẽ bịa ra một API không tồn tại, đồng tình với một tiền đề sai của người dùng, hoặc phát ra một JSON trông hợp lệ với một trường bị ảo giác. Lan can bảo vệ là lớp bắt được điều này trước khi nó đến tay người dùng hoặc, tệ hơn, một bước thực thi.

Hãy nghĩ theo ba vị trí.

  • Lan can đầu vào từ chối hoặc làm sạch trước khi mô hình chạy: sàng lọc prompt-injection, che thông tin định danh cá nhân (PII), lọc nội dung lạc đề.
  • Lan can đầu ra kiểm định những gì được trả về: kiểm tra schema, kiểm tra tính có căn cứ của trích dẫn, lọc theo chính sách.
  • Lan can hành động nằm giữa mô hình và bất cứ thứ gì có tác dụng phụ.

Cái thứ ba đó là nơi rủi ro thực sự cư trú. Trong Linea, các agent tự động hóa quy trình của chúng tôi, mô hình có thể đề xuất hành động — gọi một API, di chuyển một bản ghi, gửi một tin nhắn. Đề xuất và việc thực thi là hai bước được tách rời một cách có chủ ý. Mọi hành động có hệ quả đều đi qua một hợp đồng có kiểu (typed contract) và một lần kiểm tra chính sách trước khi bất cứ điều gì chạy, và các hành động phá hủy hoặc không thể đảo ngược đòi hỏi một cổng xác nhận tường minh. Một agent gợi ý sai điều gì đó là một vấn đề trải nghiệm người dùng mà bạn có thể lặp lại để cải thiện. Một agent làm sai điều gì đó là một sự cố. Hãy giữ hai chế độ hỏng hóc đó ở hai phía đối lập của một ranh giới cứng.

Phiên bản có quan điểm rõ ràng: hãy kiểm định đầu ra có cấu trúc dựa trên một schema và thử lại khi thất bại, thay vì tin rằng mô hình sẽ nhất quán. Và đừng bao giờ để đầu ra thô của một mô hình là thứ kích hoạt một hành động không thể đảo ngược. Hãy đặt một lần kiểm tra tất định vào giữa, luôn luôn.

Lập ngân sách cho độ trễ và chi phí như những tính năng

Độ trễ và chi phí không phải là những thứ bạn đo ở cuối cùng. Chúng là những ràng buộc mà bạn thiết kế để đối phó ngay từ đầu, bởi vì chúng thay đổi kiến trúc, không chỉ hóa đơn.

Hãy đặt các ngân sách tường minh cho mỗi hành động hướng tới người dùng: một mục tiêu độ trễ p95 và một trần chi phí cho mỗi lời gọi. Một khi những thứ đó được ghi ra, các quyết định thiết kế trở nên dễ dàng hơn. Một vài mẫu hình chúng tôi thường xuyên dùng đến:

  • Chọn đúng kích cỡ mô hình cho từng bước. Hầu hết các pipeline có một hoặc hai bước thực sự cần mô hình tuyến đầu (frontier) và vài bước mà một mô hình nhỏ hơn, nhanh hơn xử lý tốt. Định tuyến việc phân loại đơn giản sang một mô hình rẻ và để dành mô hình đắt cho bước suy luận khó là tối ưu hóa có lợi tức cao nhất hiện có, và nó thường cải thiện cả độ trễ.
  • Stream token đầu tiên. Với bất cứ thứ gì mang tính hội thoại, độ trễ cảm nhận được bị chi phối bởi thời gian tới token đầu tiên. Một phản hồi được stream mất bốn giây cảm giác tốt hơn một phản hồi chặn (blocking) mất hai giây.
  • Cache mạnh tay. Cache prompt trên phần ngữ cảnh hệ thống ổn định, cache kết quả thông thường trên các đầu vào lặp lại. Một phần đáng kể lưu lượng production là gần-trùng-lặp.

Sự đánh đổi cần giữ trong đầu: những mô hình lớn hơn giảm công sức kỹ thuật của bạn nhưng nâng chi phí biên và độ trễ mãi mãi. Những mô hình rẻ hơn đẩy công việc về phía bạn — chăm chút prompt nhiều hơn, nhiều lan can hơn, nhiều eval hơn — nhưng công việc đó là một chi phí một lần đổi lấy một khoản tiết kiệm vĩnh viễn. Với bất cứ thứ gì có khối lượng lớn, hãy bỏ công sức kỹ thuật.

Giữ con người trong vòng lặp, một cách có chủ đích

Cụm từ "con người trong vòng lặp" (human in the loop) được nói ra nhiều đến mức nó không còn mang ý nghĩa gì nữa. Làm tốt, nó không phải là một phương án dự phòng cho khi AI thất bại — nó là một sự phân công lao động được thiết kế. Câu hỏi không phải là nên bao gồm một con người hay không mà là nơi nào phán đoán của con người đáng giá hơn độ trễ mà nó thêm vào.

Mẫu hình phục vụ chúng tôi tốt nhất là leo thang được kiểm soát bởi độ tin cậy (confidence-gated escalation). Hệ thống tự động xử lý phần đa số tự tin và định tuyến phần thiểu số bất định tới một con người, kèm theo lập luận của mô hình để con người quyết định trong vài giây, không phải vài phút. Trong MadaiOps, các thao tác lệnh nằm trong tham số bình thường thì chảy qua; bất cứ điều gì bất thường đều nổi lên cho một người vận hành kèm ngữ cảnh thay vì thực thi âm thầm. Người kiểm duyệt không phải đang trông chừng cỗ máy. Họ chỉ đang dùng sự chú ý của mình ở nơi nó khan hiếm và giá trị.

Thêm một quy tắc nữa: hãy đo lường các chỉnh sửa của con người và đưa chúng ngược trở lại bộ eval và các prompt của bạn. Một hệ thống có con người trong vòng lặp mà không học từ những con người của nó thì chỉ đang trả tiền hai lần cho cùng một công việc.

Biết điều gì không nên tự động hóa

Phán đoán khó nhất trong lĩnh vực này là sự tiết chế. Không phải mọi tác vụ đều nên giao cho một mô hình, và sự trưởng thành là biết những tác vụ nào nên để yên.

Bài kiểm tra sơ bộ của chúng tôi: hãy tự động hóa nơi chi phí của một sai lầm là thấp, hoặc sai lầm dễ phát hiện và đảo ngược. Soạn thảo nháp, tóm tắt, trích xuất, phân loại, định tuyến — những ứng viên tốt. Một bản nháp sai thì được chỉnh sửa; một bản tóm tắt sai thì bị bắt lỗi khi đọc. Hãy thận trọng hơn nhiều ở nơi các sai lầm tốn kém, khó phát hiện, hoặc không thể đảo ngược: bất cứ điều gì di chuyển tiền, gửi một liên lạc không thể thu hồi, hoặc đưa ra một phán quyết pháp lý hay y tế. Ở đó, mô hình thuộc về một vai trò hỗ trợ — nêu ra các phương án, soạn nháp để duyệt — chứ không phải ngồi ở ghế lái.

Lằn ranh chúng tôi giữ: nếu bạn không thể mô tả cách bạn sẽ bắt được mô hình khi nó sai, thì bạn chưa sẵn sàng tự động hóa bước đó. Khả năng phát hiện thất bại mới là điều kiện tiên quyết thực sự, hơn cả độ chính xác. Một bước chính xác 95% mà bạn có thể kiểm chứng hoàn toàn thì an toàn để ship hơn một bước chính xác 99% mà bạn không thể.

Hình dạng của công việc

Biến một prompt thành một sản phẩm chủ yếu là phần không hào nhoáng: eval để bạn có thể đo lường, lan can để các thất bại được kiềm chế, ngân sách để nó nhanh và phải chăng, con người được đặt ở nơi phán đoán quan trọng, và kỷ luật để chừa một số thứ không được tự động hóa. Mô hình có lẽ chỉ là hai mươi phần trăm của hệ thống. Tám mươi phần trăm còn lại là phần kỹ thuật khiến sự xuất sắc thi thoảng của nó trở nên an toàn để dựa vào.

Tin tốt là đây là công việc quen thuộc. Nó tưởng thưởng cho cùng những bản năng làm nên phần mềm tốt thuộc bất kỳ loại nào: đo lường trước khi bạn thay đổi, kiềm chế bán kính vụ nổ của bạn, tôn trọng thời gian của người dùng. Mô hình thì mới. Nghề thì không.