Back to Explore
Wiki LLM quá cồng kềnh: Tôi đã thay thế chúng bằng một trình biên dịch Python thuần túy

Wiki LLM quá cồng kềnh: Tôi đã thay thế chúng bằng một trình biên dịch Python thuần túy

Bạn đang dùng AI để quản lý ghi chú cá nhân? Tác giả bài viết này chứng minh rằng việc sử dụng LLM để tổ chức wiki là quá mức cần thiết. Thay vào đó, một trình biên dịch Python thuần túy với các kỹ thuật xử lý văn bản, đồ thị và kiểm tra lỗi (linter) có thể mang lại kết quả nhanh hơn, ổn định và hoàn toàn có thể dự đoán được.

Website
Upvote this postSign in to upvote this article.

Wiki LLM quá cồng kềnh: Tôi đã thay thế chúng bằng một trình biên dịch Python thuần túy

LLM Wikis

Việc cấu trúc các tệp Markdown cục bộ không cần đến các tác nhân (agents) AI phức tạp. Điều nó thực sự cần là một trình biên dịch.

Tại sao tôi viết bài này?

Tôi từng cố gắng xây dựng một wiki theo phong cách "LLM wiki" của Karpathy: sử dụng các vòng lặp tác nhân (agent loops), các lệnh gọi LLM đệ quy và nhúng (embeddings) cho mọi thứ. Dữ liệu đầu vào là một thư mục chứa các tệp Markdown cục bộ mà tôi đã sở hữu trên ổ cứng của mình.

Đột nhiên, tôi nhận ra: Tôi đang phải trả tiền cho các token chỉ để sắp xếp lại văn bản mà tôi đã sở hữu. Vì vậy, tôi đã thay thế toàn bộ quy trình đó bằng một trình biên dịch Python thuần túy. Bài viết này sẽ hướng dẫn bạn cách chuyển đổi một thư mục chứa các ghi chú văn bản thô, định dạng không nhất quán thành một wiki Markdown có liên kết, được kiểm tra lỗi (linted), không cần gọi LLM, không cần API bên ngoài và không cần phụ thuộc vào thư viện bên thứ ba.

Tư duy của một trình biên dịch

Một tác nhân (agent) quyết định wiki của bạn trông như thế nào. Một trình biên dịch đảm bảo nó phải trông như thế nào.

Tôi muốn wiki này có tính dự đoán. Không giống như LLM với kết quả đầu ra thay đổi liên tục, trình biên dịch mang lại kết quả giống hệt nhau mỗi khi bạn chạy. Tôi đã cấu trúc hệ thống này sao cho các trang Markdown hoạt động giống như các tệp đối tượng (object files). Chúng được tạo ra từ nguồn và có thể xây dựng lại bất cứ lúc nào.

Quy trình gồm 4 giai đoạn:

  1. Trích xuất metadata bằng Regex: Xử lý các ghi chú lộn xộn.
  2. Xây dựng đồ thị (Graph Builder): Phát hiện các tham chiếu chéo.
  3. Viết lại nhận thức ngữ cảnh (Section-aware rewriter): Bảo toàn những gì bạn viết bằng tay.
  4. Kiểm tra lỗi (Linter): Tự kiểm tra kết quả đầu ra của chính nó.

Tại sao "không phụ thuộc" lại quan trọng?

Toàn bộ codebase này chạy trên thư viện chuẩn của Python. Không có sentence-transformers, không có vector database, không có HTTP client cho API embedding. Điều này không phải để chứng minh sự thuần khiết, mà là hệ quả trực tiếp của vấn đề. Khi loại bỏ các lệnh gọi LLM, những gì còn lại là phân tích văn bản, thao tác chuỗi và duyệt đồ thị. Đó chính là những thứ mà các module re, os và các cấu trúc dữ liệu cơ bản của Python được tạo ra để giải quyết.

Vấn đề với Wiki dựa trên Agent

Việc sử dụng LLM để xây dựng wiki cá nhân có 3 chi phí lớn:

  1. Chi phí token: Mỗi khi thêm tài liệu, agent phải đọc lại nội dung, quyết định thay đổi gì và viết lại trang. Điều này tốn kém khi bạn có hàng trăm tệp.
  2. Độ trễ: Mỗi chu kỳ đọc-quyết định-viết đều tốn thời gian tính toán hoặc gọi API.
  3. Tính không xác định: Tôi đã chạy cùng một thư mục qua một bản mẫu dựa trên agent hai lần và nhận được hai cấu trúc liên kết khác nhau. Đối với mã nguồn, điều này có thể thú vị, nhưng đối với "nguồn sự thật" (source of truth), đó là một vấn đề.

Chi tiết kỹ thuật các giai đoạn

1. Trích xuất Metadata (Regex)

Các ghi chú thực tế rất lộn xộn. Trình trích xuất của tôi quét các tiêu đề # trước. Nếu thất bại, nó tìm dòng chữ in hoa, hoặc mặc định là tên tệp. Nó quét các trường metadata ở bất cứ đâu chúng tồn tại.

2. Xây dựng đồ thị (Graph Builder)

Tôi đã gặp một "bức tường hiệu năng". Phiên bản đầu tiên chạy regex riêng biệt cho mỗi thực thể so với mỗi tệp khác (độ phức tạp O(n^2)). Với 5.000 tệp, nó mất 107 giây. Tôi đã thay thế bằng bộ khớp cụm từ dựa trên chỉ mục từ (word-indexed phrase matcher). Thay vì kiểm tra mọi thực thể, tôi chỉ kiểm tra các ứng viên có thể khớp. Kết quả: thời gian giảm từ 107 giây xuống dưới 1 giây.

3. Viết lại nhận thức ngữ cảnh

Tôi không muốn trình biên dịch xóa sạch mọi tệp. Tôi cần giữ lại phần ghi chú thủ công. Logic rất đơn giản: trước khi ghi trang, nó kiểm tra xem tệp đã tồn tại trên đĩa chưa. Nếu có, nó lấy nội dung dưới tiêu đề ## Notes, sau đó xóa các phần do trình biên dịch sở hữu (Metadata, Related, Referenced By, Body) và tạo lại từ nguồn, rồi ghi đè nội dung Notes cũ vào.

4. Linter (và lỗi thứ hai)

Linter đi bộ qua kết quả đầu ra, gắn cờ các liên kết bị hỏng. Lỗi tôi gặp phải là linter đếm nhầm các liên kết trong phần Referenced By là liên kết đi ra (outgoing). Tôi đã sửa bằng cách chỉ giới hạn việc đếm trong phần Related.

Kiểm thử và Benchmark

Tôi có 17 bài kiểm tra (unittest) bao phủ mọi giai đoạn.

Kết quả Benchmark (5.000 tệp):

  • Tổng thời gian: 12.44s
  • Trích xuất: 1.40s
  • Đồ thị: 0.63s
  • Viết lại: 3.45s
  • Linter: 6.97s

Linter là giai đoạn tốn kém nhất do I/O đĩa. Tuy nhiên, với 5.000 tệp, 12 giây là một cái giá rất rẻ để đổi lấy một hệ thống hoàn toàn deterministic (xác định) và không tốn phí token.

Kết luận

Nếu đầu vào của bạn là xác định, quy trình của bạn cũng nên như vậy. Không phải mọi vấn đề quản lý tri thức đều cần một vòng lặp tác nhân. Đôi khi, bạn chỉ cần một trình phân tích, một đồ thị và một linter.

Mã nguồn đầy đủ: https://github.com/Emmimal/wiki-compiler/

Discussion (0)

You need to log in to post comments. Log In

No comments yet. Start the discussion!

Do you like this post?

Upvote to push this post higher on the community feed

Details

Posted by: @admin
Categories: Developer Tools
Date posted: 8 tháng 7, 2026