Open WebUI, AnythingLLM hay LibreChat: câu hỏi về giao diện thật ra là câu hỏi về truy xuất

Quyết định người ta hỏi sau cùng lại chính là thứ người dùng của họ chạm vào đầu tiên. Bạn đã có GPU, đã chọn máy chủ suy luận, truy xuất chạy tốt trong notebook — và giờ phải có ai đó thật sự dùng cái hệ thống này. Vậy thì: Open WebUI, AnythingLLM hay LibreChat?

Gần như mọi câu trả lời cho câu hỏi đó đều là một danh sách tính năng, và đó đúng là cách người ta chọn sai. Cả ba đều sẽ cho bạn một cửa sổ chat gọn gàng trên mô hình của chính bạn trong một buổi chiều. Điều sẽ quan trọng sau một năm thì hoàn toàn không nằm trong danh sách tính năng.

Chúng giống nhau nhiều hơn là khác nhau

Cả ba đều tự vận hành, ưu tiên Docker, chat nhiều người dùng trên một endpoint tương thích OpenAI. Cả ba đều có lịch sử hội thoại, đổi mô hình, tài khoản riêng từng người, streaming, kết xuất markdown, tải tệp lên. Trỏ bất kỳ cái nào trong ba vào máy chủ suy luận bạn đã chọn và bạn sẽ có thứ để demo trước giờ ăn trưa.

Đó là lý do các bài so sánh đều bất đồng với nhau. Người viết chúng đánh giá đúng cái mà họ cài đầu tiên, thấy nó tốt — vì nó tốt thật — rồi dừng lại ở đó.

“Ai giữ dữ liệu của bạn” là câu hỏi sai

Cách đặt vấn đề bạn thường thấy là Open WebUI và AnythingLLM giữ tài liệu của bạn, còn LibreChat thì không. Nghe có lý. Nhưng không đúng.

Cả ba đều nhận một vector store bên ngoài. Open WebUI hỗ trợ pgvector, Qdrant và Milvus — và bắt buộc phải dùng loại bên ngoài ngay khi bạn chạy nhiều hơn một worker. AnythingLLM đi kèm LanceDB nhúng sẵn nhưng cũng nói được pgvector, Chroma, Milvus, Qdrant, Weaviate và Pinecone. RAG API của LibreChat là một dịch vụ LangChain/FastAPI riêng, chạy trên pgvector. Vector nằm ở đâu chỉ là một dòng cấu hình, ở cả ba.

Câu hỏi thật sự là ai sở hữu pipeline: cách chia chunk, mô hình embedding nào chạy, ở số chiều bao nhiêu, câu truy vấn có được thêm tiền tố chỉ dẫn hay không, kết quả dense và kết quả từ khóa được hợp nhất ra sao, cái gì rerank chúng — và, phần đau nhất, liệu bạn còn đổi được thứ nào trong số đó sau mười tám tháng nữa hay không.

Đây là phép thử tôi sẽ dùng. Giả sử bạn quyết định tìm kiếm hybrid của mình nên hợp nhất kết quả dense và từ khóa bằng reciprocal rank fusion thay vì trộn có trọng số, bởi vì RRF so sánh thứ hạng chứ không so sánh điểm nên không cần tinh chỉnh một trọng số riêng cho từng kho tài liệu. Việc đó là một núm cấu hình, một plugin, hay là code của chính bạn?

Chỉ một câu hỏi đó thôi đã phân loại cả ba rất gọn.

Mỗi cái nằm ở đâu

AnythingLLM sở hữu pipeline theo thiết kế. Bạn tạo một workspace, bỏ tài liệu vào, và nó tự chia chunk, tự embedding, tự truy xuất. Đây là con đường ngắn nhất trong lĩnh vực này từ số không đến một hệ thống chat tài liệu riêng tư, và với nhiều doanh nghiệp thì đó là lựa chọn đúng. Cái giá phải trả là truy xuất của nó là truy xuất của nó — bạn đang chọn một bộ embedding và một vector store, không phải chọn một chiến lược truy xuất.

Xin nói rõ về đoạn vừa rồi: AnythingLLM là cái duy nhất trong ba mà tôi đã đọc kiến trúc chứ chưa vận hành thật trong môi trường sản xuất. Hãy cân nhắc trọng lượng của đoạn đó đúng mức. Tôi đang mô tả thiết kế theo tài liệu, không phải vết thương thực chiến.

Open WebUI sở hữu pipeline theo mặc định, nhưng cho thuê lại. Truy xuất gốc của nó nghiêm túc hơn người ta tưởng: BM25 song song với tìm kiếm dense, một bước rerank, và những núm điều chỉnh thật — RAG_HYBRID_BM25_WEIGHT, RAG_TOP_K, RAG_TOP_K_RERANKER, RAG_RELEVANCE_THRESHOLD, RAG_RERANKING_MODEL. Bạn có thể trỏ bộ embedding của nó về máy chủ vLLM của mình. Và khi hết núm để vặn, Pipelines, Functions và OpenAPI tool server cho phép bạn đặt truy xuất của riêng bạn phía sau giao diện mà vẫn giữ lại mọi thứ khác nó cho bạn.

Một điểm tinh tế trước khi bạn dựa vào phương án vector store bên ngoài: Open WebUI vẫn embedding câu truy vấn bằng đúng mô hình embedding mà nó được cấu hình. Trỏ nó vào một collection do thứ khác ghi ra thì phía truy vấn phải trùng khớp chính xác với phía tài liệu. Sai chỗ này thì recall xuống cấp mà không hề báo lỗi — bạn sẽ nhận được câu trả lời nghe hợp lý cho những câu hỏi dễ và không có gì dùng được cho những câu hỏi khó, tức là kiểu thất bại tệ nhất của truy xuất.

LibreChat gần nhất với một lớp giao diện thuần túy. RAG vẫn có — một dịch vụ riêng bạn chạy kèm — nhưng trọng tâm của nó nằm ở nơi khác: nhiều nhà cung cấp, agent, MCP, một bề mặt chat thật sự được đánh bóng. Nếu truy xuất đã nằm trong một dịch vụ do bạn sở hữu, LibreChat là cái ít chống lại bạn nhất, vì ngay từ đầu nó không cố làm lớp truy xuất của bạn.

Tôi đã xây cùng một hệ thống theo cả hai cách

Không phải để thí nghiệm. Cái thứ hai vốn được kỳ vọng sẽ giúp tôi đỡ việc.

Tôi có một hệ thống tìm kiếm tài liệu mà tôi thích: truy xuất hybrid dense + BM25, hợp nhất theo thứ hạng, một cross-encoder rerank, một agent nhiều bước có thể truy xuất lại khi lượt đầu trả về mỏng, và một bước kiểm tra tính neo nội dung trước khi bất cứ gì đến tay người dùng. Rồi tôi xây lại đúng ý tưởng đó bằng chính cơ chế gốc bên trong một giao diện chat, để xem mình lấy lại được bao nhiêu phần miễn phí.

Câu trả lời là khoảng 90%, với gần như không có dòng code tùy biến nào. Đó là con số trung thực, và nó là một lý lẽ ủng hộ hướng dùng cơ chế gốc. Cùng mô hình embedding. Cùng mô hình rerank. Tìm kiếm hybrid và rerank đã có sẵn, kèm núm điều chỉnh.

10% còn thiếu không phải chuyện hình thức. Vòng lặp agent không có gì tương đương — truy xuất gốc là một lượt duy nhất, nên truy xuất, chấm điểm, rồi truy xuất lại đơn giản là mất. Mở rộng sang chunk liền kề, mất. Bước kiểm tra neo nội dung, mất. Đó lại đúng là những phần khiến hệ thống đáng tin ở các câu hỏi khó, tức là những phần quan trọng.

Có những thứ khác thì lệch đi theo cách tôi không có quyền quyết định. Hợp nhất theo thứ hạng của tôi trở thành một ensemble có trọng số — một chiến lược hợp lệ, chỉ là không phải của tôi, và giờ lại thêm một trọng số phải tinh chỉnh cho từng kho tài liệu. Tôi vốn cắt embedding xuống 1536 chiều; điều đó hóa ra là không thể, vì máy chủ suy luận bỏ qua tham số dimensions và phía host thì không tự cắt ở client, nên nó lưu đủ 4096 chiều. Chất lượng không tệ hơn. Chỉ là tốn thêm lưu trữ và thêm độ trễ, và quyết định đó không do tôi đưa ra.

Chi tiết dạy tôi nhiều nhất lại nhỏ hơn tất cả những điều trên. Mô hình của tôi phát ra phần suy luận bên trong thẻ <think>, nhưng chat template lại nhét thẻ mở vào prompt, nên mô hình chỉ phát ra thẻ đóng — để lại cho giao diện một khối không cân, và nó kết xuất khối đó ngay giữa câu trả lời. Cách sửa là một filter toàn cục chèn thẻ mở còn thiếu vào token đầu tiên của luồng, sau đó hộp suy luận thu gọn sẵn có của host hoạt động hoàn hảo.

Cái filter đó khoảng mười lăm dòng và tôi khá thích nó. Nhưng hãy nhìn xem nó là gì: để đổi cách hiển thị đầu ra của mô hình của tôi, tôi phải diễn đạt bản sửa lỗi bằng ngôn ngữ plugin của người khác, ngược lại giả định của bộ kết xuất của họ. Nhân điều đó với mọi cải tiến bạn sẽ muốn làm trong hai năm tới. Rồi cộng thêm sự phụ thuộc phiên bản — việc tôi có đặt được tiền tố chỉ dẫn cho embedding hay không phụ thuộc vào bản phát hành tôi tình cờ đang chạy có mở ra thiết lập đó hay không.

Hướng còn lại cũng gửi hóa đơn, và tôi sẽ nói thẳng chuyện đó. Tự chạy backend của mình với một client chat phía trước nghĩa là tôi sở hữu xác thực, lịch sử hội thoại, chia sẻ, phân quyền, xử lý tệp, và từng chi tiết đánh bóng của trải nghiệm chat mà người dùng mặc định cho là miễn phí bởi mọi sản phẩm thương mại đều có. Đó là một khối lượng công việc không tạo ra khác biệt rất lớn, và nó không bao giờ kết thúc.

Vậy đây là sự đánh đổi, không che giấu gì: hoặc bạn thừa hưởng truy xuất của người khác cùng nhịp phát hành của họ, hoặc bạn thừa hưởng chi phí tự xây phần chat. Không có phương án thứ ba nơi bạn được cả hai. Hãy chọn cái bạn muốn sở hữu trong hai năm tới.

Tôi sẽ khuyên bạn chạy cái gì

Hoàn cảnh Chạy Vì sao
Chưa có backend truy xuất, không có nguồn lực kỹ thuật, muốn chat tài liệu riêng tư trong tháng này AnythingLLM Workspace lo phần nạp tài liệu cho bạn. Khoảng cách đến “chạy được” là ngắn nhất.
Bạn sẽ còn tinh chỉnh truy xuất, nhưng không muốn sở hữu phần chat Open WebUI Có núm điều chỉnh thật, và có cửa thoát bằng tool server khi hết núm.
Truy xuất đã nằm trong một dịch vụ bạn tin LibreChat Nó không cố làm lớp truy xuất của bạn.
Định tuyến nhiều nhà cung cấp, agent hay MCP quan trọng ngang với tài liệu LibreChat Đó là trọng tâm thiết kế, không phải phần gắn thêm.
Một đội ngũ, một GPU, và chất lượng câu trả lời là toàn bộ vấn đề Open WebUI trên truy xuất của riêng bạn Giữ pipeline là của bạn mà bề mặt chat vẫn miễn phí.

Và phần ngược lại, vì một bài so sánh không có nó thì chỉ là quảng cáo: nếu bạn là năm người với 200 tệp PDF, truy xuất có sẵn của bất kỳ cái nào trong ba cũng đủ tốt thật, và việc tự xây pipeline chỉ để kiểm soát chiến lược hợp nhất sẽ là một sai lầm nghề nghiệp. Câu hỏi về pipeline chỉ bắt đầu sinh lời khi chất lượng truy xuất chính là thứ chắn giữa bạn và việc người ta tin vào hệ thống.

Quyết định duy nhất đắt tiền khi muốn làm lại

Không phải chọn giao diện nào. Không phải vector nằm ở đâu. Mà là pipeline của ai đã tính ra chúng.

Embedding chỉ tái sử dụng được nếu bạn tái tạo được phía truy vấn một cách chính xác — cùng mô hình, cùng số chiều, cùng quy ước tiền tố, cùng cách chuẩn hóa. Tài liệu được nạp qua pipeline của chính một giao diện thì tìm kiếm bên trong giao diện đó rất rẻ, và mang đi nơi khác thì đắt một cách đáng ngạc nhiên, vì chuyển đi nghĩa là hoặc embedding lại toàn bộ kho tài liệu, hoặc dịch ngược xem người ta đã làm gì với nó.

Nên nếu bạn thật sự chưa chắc, mà ở giai đoạn này thì phần lớn là chưa chắc, hãy giữ pipeline là của bạn ngay cả khi giao diện có thể chạy nó. Nạp tài liệu bằng script của bạn vào store của bạn, rồi để giao diện truy vấn nó. Việc đó tốn một ngày bây giờ và giữ cho quyết định đắt tiền vẫn còn mở.

Tóm lại

Câu hỏi về máy chủ là bao nhiêu người dùng cùng lúc. Câu hỏi về giao diện là ai sở hữu truy xuất. Không câu nào được giải quyết bằng một danh sách tính năng, và đó là lý do các danh sách tính năng cứ liên tục cho ra những người thắng khác nhau.

Hãy trả lời phép thử về hợp nhất một cách trung thực cho đội của bạn — núm, plugin, hay code của chính bạn — và lựa chọn gần như tự hiện ra.

Demo trên trang này đi theo mô hình thứ hai: một bề mặt chat mỏng trên một dịch vụ truy xuất do tôi sở hữu, và đó là lý do nó có thể cho bạn thấy một trích dẫn cho mỗi khẳng định thay vì một đoạn văn đầy tự tin. Nếu bạn đang cân nhắc đặt cái nào trong ba thứ này trước kho tài liệu của mình, đó là cuộc trò chuyện đáng có trước khi bạn nạp 10.000 tài liệu vào một hệ thống, chứ không phải sau.

Bài viết khác