Nhật ký công việc

Giả thuyết: Custom GPT có thể cung cấp một lớp thông minh đầy đủ tính năng, gần như miễn phí trên haih-agent

Quan sát

Trong quá trình làm việc tích cực với Custom GPT trên gói ChatGPT Plus trong vài ngày, một hiện tượng bất thường được ghi nhận: mặc dù có số lượng lớn cuộc trò chuyện, suy luận (reasoning), các lệnh gọi Actions, truy vấn GraphQL và các ngữ cảnh dài, mức sử dụng hiển thị thực tế không giảm và vẫn ở mức khoảng 99% remaining.

Điều này chưa thể được coi là bằng chứng về việc sử dụng GPTs không giới hạn hoặc hoàn toàn miễn phí. Các giới hạn ẩn riêng lẻ, các hệ thống tính phí sử dụng khác nhau, giới hạn tốc độ (rate limits) hoặc hạn mức không được phản ánh trên chỉ báo quan sát vẫn có thể tồn tại.

Tuy nhiên, quan sát thực tế này đủ ổn định để ghi nhận nó như một giả thuyết làm việc.

Giả thuyết

Nếu được xác nhận rằng việc làm việc cường độ cao thông qua Custom GPT trong khuôn khổ gói đăng ký ChatGPT Plus thực sự hầu như không tiêu tốn hạn mức riêng đáng kể hoặc ngân sách tài chính nào, thì sự kết hợp:

ChatGPT Custom GPT
+ Actions / lớp tích hợp
+ fi1osof.ru
+ haih-agent

có thể mang lại một dịch vụ thông minh đầy đủ tính năng, gần như miễn phí về mặt kinh tế người dùng cho một lượng lớn các tác vụ ứng dụng.

Không chỉ là trò chuyện hay tạo văn bản. Trong tích hợp hiện tại của chúng tôi, ChatGPT đã có thể làm việc với các thực thể thực tế và các công cụ hệ thống, do đó có tiềm năng thực hiện công việc trí tuệ toàn diện dựa trên dữ liệu.

Các kịch bản tiềm năng

Nếu giả thuyết được xác nhận, vòng lặp này có thể được sử dụng để:

  • quản lý dự án và công việc;
  • chuẩn bị và chỉnh sửa các yêu cầu/đặc tả công việc (task specifications);
  • tạo worklogs và báo cáo;
  • tạo nội dung có ý nghĩa và chất lượng cao;
  • phân tích khối lượng dữ liệu lớn;
  • nghiên cứu các thực thể có liên quan;
  • phân tích so sánh;
  • tìm kiếm bất thường và mâu thuẫn;
  • chuẩn bị kết luận và giả thuyết;
  • xử lý các ngữ cảnh dài;
  • làm việc với cơ sở tri thức (knowledge base);
  • các tác vụ phân tích và nghiên cứu mà nếu qua LLM API thông thường có thể tốn kém đáng kể.

Việc sử dụng ChatGPT làm môi trường chạy suy luận (reasoning runtime) chi phí thấp tỏ ra đặc biệt thú vị đối với các tác vụ mà chi phí chính thường không đến từ một phản hồi duy nhất, mà từ một số lượng lớn các bước tuần tự: đọc dữ liệu, làm rõ, phân tích trung gian, kiểm tra lại và các chuỗi suy luận dài.

Tại sao điều này hoạt động chính xác khi kết hợp với haih-agent

Bản thân ChatGPT không giải quyết hoàn toàn bài toán này.

Lợi thế kinh tế của nó chỉ thực sự trở nên có giá trị khi nó có quyền truy cập vào cơ sở hạ tầng tác nhân (agent infrastructure) đầy đủ.

Trong trường hợp của chúng tôi, vai trò này được đảm nhận bởi haih-agent và cơ sở hạ tầng fi1osof.ru đi kèm.

Nó đã cung cấp những gì mà một ChatGPT thông thường còn thiếu để biến thành một dịch vụ làm việc:

  • danh tính tác nhân bền vững (persistent agent identity);
  • quyền truy cập vào các dự án, công việc và worklogs;
  • GraphQL API;
  • skills;
  • MindLog và các cơ chế bộ nhớ khác;
  • cơ sở tri thức (knowledge base);
  • các công cụ đọc và sửa đổi dữ liệu;
  • khả năng tương tác với runtime của chính tác nhân;
  • các phương tiện tích hợp với hệ thống bên ngoài;
  • quyền phía máy chủ và kiểm soát truy cập;
  • khả năng lưu trữ kết quả công việc trong hệ thống thay vì chỉ để lại trong lịch sử trò chuyện.

Nghĩa là, hiệu ứng kinh tế không xuất phát từ riêng ChatGPT hay riêng haih-agent, mà từ sự kết hợp của chúng:

ChatGPT
= suy luận và giao diện có kinh tế người dùng giá rẻ

haih-agent / fi1osof.ru
= bộ nhớ, công cụ, dữ liệu, danh tính, API, hành động và tích hợp

Cùng nhau, điều này tiềm năng biến thành một môi trường làm việc đầy đủ, nơi trí tuệ đắt tiền có thể được sử dụng với cường độ cao hơn nhiều so với việc thanh toán trực tiếp cho mỗi lần gọi LLM API.

Kịch bản đặc biệt thú vị: Phân tích khối lượng dữ liệu lớn

Nếu usage thực sự hầu như không bị tiêu hao, thì ChatGPT trở thành một công cụ tiềm năng rất rẻ để phân tích lặp đi lặp lại các mảng thông tin lớn.

Điều quan trọng là điều này không nhất thiết phải tải toàn bộ khối lượng dữ liệu vào một ngữ cảnh duy nhất. haih-agent/fi1osof.ru có thể cung cấp các công cụ tìm kiếm, lọc, phân trang, lấy mẫu, không gian tri thức (knowledge spaces) và các cách khác để truy cập dữ liệu dần dần.

Khi đó ChatGPT có thể làm việc theo phương pháp lặp:

nhận một phần dữ liệu
→ phân tích
→ xây dựng truy vấn tiếp theo
→ nhận mẫu dữ liệu tiếp theo
→ đối chiếu kết quả
→ kiểm tra giả thuyết
→ lưu kết luận

Với biểu phí API, một chu kỳ nhiều bước như vậy có thể tốn kém, đặc biệt là trên mô hình mạnh. Trong khuôn khổ ChatGPT theo gói đăng ký, kinh tế của nó có khả năng tốt hơn một cách triệt để.

Những hạn chế của giả thuyết

Hiện chưa thể khẳng định rằng:

  • Custom GPTs hoàn toàn không giới hạn;
  • usage sẽ không bao giờ giảm;
  • OpenAI sẽ không thay đổi mô hình giới hạn;
  • chỉ báo hiện tại phản ánh chính xác các tài nguyên mà GPT tiêu thụ;
  • các kịch bản cường độ cao sẽ không chạm phải các giới hạn tốc độ khác hoặc giới hạn ẩn (hidden caps).

Do đó, đây hiện tại vẫn là một giả thuyết dựa trên quan sát thực tế, chứ không phải là một thuộc tính được đảm bảo của nền tảng.

Xác nhận sẽ có ý nghĩa gì

Nếu quan sát được xác nhận trong khoảng thời gian dài hơn và với các loại công việc cường độ cao khác nhau, thì việc tích hợp sẽ đạt được giá trị chiến lược bổ sung.

Nó sẽ giải quyết không chỉ bài toán truy cập thuận tiện của ChatGPT vào tác nhân, mà cả bài toán giảm triệt để chi phí của công việc trí tuệ.

Trong trường hợp này, ChatGPT có thể được coi là một môi trường chạy nhận thức bên ngoài (external cognitive runtime) rất rẻ cho haih-agent, trong khi toàn bộ cơ sở hạ tầng ổn định — dữ liệu, bộ nhớ, danh tính, công cụ, quyền hạn và kết quả — được lưu giữ trong fi1osof.ru.

Điều này tiềm năng mở ra cơ hội xây dựng trên haih-agent các dịch vụ sử dụng các mô hình mạnh của ChatGPT về chất lượng suy luận, nhưng về mặt kinh tế lại gần với gói đăng ký cố định hơn là thanh toán LLM API truyền thống tính theo từng token.

Giới hạn của ChatGPT: Không có bộ nhớ làm việc có thể định địa chỉ và tái sử dụng giữa các lần gọi Action

Vấn đề thực tế

Trong quá trình làm việc với tích hợp ChatGPT ↔ fi1osof.ru, chúng tôi đã gặp phải một nhóm giới hạn riêng biệt: ChatGPT có thể tạo ra một kết quả trung gian lớn và thực hiện một chuỗi các lệnh gọi API, nhưng lại thiếu một cơ chế thuận tiện để lưu kết quả này thành một đối tượng độc lập có thể định địa chỉ và sau đó tham chiếu đến nó trong các hành động tiếp theo.

Vấn đề này thể hiện rõ khi ghi một worklog lớn vào một task. Văn bản worklog đã được tạo sẵn trong cuộc trò chuyện, nhưng mỗi lần gọi createTaskWorkLog, toàn bộ nội dung đó lại phải được đưa vào lại trong các biến GraphQL.

Khi lần thử ghi đầu tiên kết thúc bằng lỗi resolver, việc thử lại buộc phải gửi lại toàn bộ đoạn Markdown dài đó từ đầu.

Tức là thực tế hiện đang thiếu một tầng trung gian dạng như sau:

tạo nội dung
→ lưu dưới dạng var/draft/artifact
→ nhận ID
→ sử dụng ID trong các thao tác API tiếp theo

Các công cụ hiện có và lý do tại sao chúng chưa đủ

Biến GraphQL (GraphQL variables)

Các biến GraphQL chỉ phù hợp để tham số hóa một yêu cầu HTTP duy nhất.

Chúng không tồn tại giữa các lần gọi và không cho phép tham chiếu đến kết quả của bước trước đó.

Lịch sử cuộc trò chuyện hiện tại

Mô hình nhìn thấy văn bản được tạo trước đó trong ngữ cảnh, nhưng lịch sử trò chuyện không phải là một đối tượng lập trình có thể định địa chỉ.

Bạn không thể truyền một cách đáng tin cậy thứ gì đó như thế này vào Action:

content = đoạn Markdown đã được tạo cách đây vài tin nhắn

Ở cấp độ HTTP/GraphQL, giá trị content thực tế vẫn là bắt buộc, do đó nó tiếp tục được tuần tự hóa lại (serialize) và gửi đi toàn bộ.

Các thực thể miền (Domain entities) của fi1osof.ru

Về mặt kỹ thuật, bạn có thể tạm thời lưu văn bản dưới dạng Task, File, Fact hoặc một thực thể vĩnh viễn khác, nhưng đây là ngữ nghĩa sai và làm ô nhiễm mô hình miền bằng dữ liệu runtime trung gian.

Vấn đề đòi hỏi một bộ nhớ làm việc phổ quát, độc lập với một thực thể kinh doanh cụ thể nào.

Tại sao điều này lại tệ

1. Truyền tải lại các payload lớn

Các văn bản dài, JSON, kết quả phân tích và các đối tượng khác phải được truyền qua Action hết lần này đến lần khác.

Điều này làm tăng kích thước yêu cầu và khiến việc tích hợp trở nên mong manh hơn.

2. Không có workflow nhiều bước chuẩn chỉnh

Không thể chia công việc thành các giai đoạn một cách tự nhiên:

tạo
→ lưu
→ kiểm tra
→ sử dụng
→ tái sử dụng

Thay vào đó, việc tạo và sử dụng kết quả trung gian thực chất bị ràng buộc chặt chẽ thông qua ngữ cảnh của cuộc trò chuyện hiện tại.

3. Khả năng chịu lỗi kém

Nếu mutation cuối cùng gặp lỗi, payload ban đầu sẽ phải được truyền lại từ đầu.

Bạn không thể đơn giản là chạy lại thao tác với ID của một artifact đã được lưu từ trước.

4. Vấn đề không chỉ giới hạn ở worklogs

Tương tự sẽ phát sinh đối với:

  • mô tả tác vụ dài;
  • báo cáo;
  • tài liệu Markdown;
  • cấu hình JSON;
  • kết quả nghiên cứu;
  • danh sách ID;
  • kết quả truy vấn GraphQL;
  • các payload đã chuẩn bị;
  • dữ liệu cần truyền cho agent khác.

5. Điều này hạn chế các agentic workflows

ChatGPT trong sơ đồ của chúng tôi được sử dụng làm một runtime lập luận bên ngoài. Để hoạt động như một agent thực thụ, nó không chỉ cần bộ nhớ kiến thức dài hạn (knowledge memory) mà còn cần cả trạng thái workspace hoạt động có thể định địa chỉ giữa các hành động riêng lẻ.

Nếu không có điều này, agent bên ngoài có thể suy nghĩ và gọi API, nhưng kết quả làm việc trung gian của nó vẫn gắn liền với ngữ cảnh văn bản của cuộc trò chuyện thay vì trạng thái runtime chuẩn chỉnh.

Trừu tượng mong muốn

Thứ chúng ta cần không nhất thiết phải là một "file" hay một TaskWorkLogDraft chuyên biệt, mà là một value/artifact/variable có thể định địa chỉ mang tính phổ quát.

Tạm hình dung:

var_abc123 = "# Markdown lớn..."

Sau đó có thể thực hiện:

createTaskWorkLog(
  taskId: "...",
  content: var_abc123
)

hoặc sử dụng lại chính đối tượng đó trong một thao tác khác.

Cơ chế này sẽ biến thành một bộ nhớ làm việc trung gian giữa client AI bên ngoài và fi1osof.ru/haih-agent.

Nhiệm vụ liên quan để cải tiến haih-agent

Yêu cầu chi tiết đã được đưa ra trong một nhiệm vụ riêng của dự án haih-agent:

tasks/cmt839tuu000kmq0q72h9ppm9

"Thêm bộ nhớ làm việc có thể định địa chỉ và tái sử dụng cho các AI client bên ngoài".

Trong đó mô tả các yêu cầu đối với biến/artifact phổ quát, các scope/TTL có thể có, các kiểu string/json, việc tái sử dụng theo ID, khả năng chịu lỗi và việc sử dụng cơ chế này bởi các reasoning runtime bên ngoài khác nhau.

Kết luận cho việc tích hợp ChatGPT

Tích hợp hiện tại đã cho phép ChatGPT thực hiện công việc thực tế thông qua API, nhưng đã làm lộ ra một tầng quan trọng còn thiếu:

cần có một bộ nhớ hoạt động có thể định địa chỉ nằm giữa ngữ cảnh lập luận của ChatGPT và các thực thể miền vĩnh viễn của fi1osof.ru.

Đây không phải là một bản chỉnh sửa cụ thể chỉ vì một worklog duy nhất. Đây là một nhu cầu hạ tầng cho các agentic workflow nhiều bước, đặc biệt nếu một định danh agent duy nhất có thể hoạt động thông qua các cognitive runtime khác nhau.

Trải nghiệm thực tế về tích hợp ChatGPT ↔ fi1osof.ru ↔ haih-agent

Động lực kinh tế

Lý do chính của việc tích hợp là chi phí gọi LLM trong haih-agent. Mỗi yêu cầu gửi đến mô hình được tính phí riêng biệt, và các mô hình mạnh, ngữ cảnh lớn cùng các vòng lặp reasoning/tool dài làm cho công việc trở nên đắt đỏ hơn đáng kể. Trong ChatGPT, với mô hình đăng ký (subscription), người dùng có thể thực hiện một cuộc trò chuyện tương tác dài và thực hiện một khối lượng lớn reasoning mà không cần kiểm soát ngân sách liên tục cho từng yêu cầu.

Từ đó dẫn đến nhu cầu cốt lõi: sử dụng ChatGPT như một môi trường tương tác có lợi về mặt kinh tế để reasoning và làm việc với dữ liệu thực tế của fi1osof.ru, đồng thời duy trì danh tính, bộ nhớ và các khả năng tự trị của haih-agent.

Quan trọng: haih-agent đã là một runtime tác vụ (agent runtime) hoàn chỉnh. ChatGPT không phải cần đến vì tác nhân thiếu reasoning, công cụ hay bộ nhớ, mà vì reasoning tương tác bên trong ChatGPT mang lại hiệu quả kinh tế cao hơn.

Tại sao lại chọn Custom GPT + Actions để khởi động nhanh

Tiêu chí chính cho sự lựa chọn ban đầu là khởi động nhanh.

Phía fi1osof.ru đã có sẵn HTTP/GraphQL API, vì vậy con đường ngắn nhất hóa ra là Custom GPT với Action gửi yêu cầu HTTP POST đến fi1osof.ru.

Hầu như không cần sửa đổi backend, ChatGPT đã có được quyền truy cập vào hệ thống thực tế. Mô hình GraphQL Action đa năng tỏ ra đặc biệt thành công: thay vì số lượng lớn các REST action riêng lẻ, ChatGPT có thể gửi một tài liệu GraphQL tùy ý, và nếu cấu trúc chưa rõ, trước tiên có thể thực hiện introspection.

Điểm mạnh của cơ chế Actions cũ là bản thân ChatGPT hỗ trợ thiết lập tích hợp: soạn thảo cấu hình OpenAPI, giúp phân tích cấu trúc API và phản hồi, gợi ý các thay đổi lược đồ (schema). Nhờ đó, bạn có thể kết nối nhanh chóng với hầu như bất kỳ HTTP API, REST hoặc GraphQL nào mà không cần điều chỉnh backend đặc biệt.

Trải nghiệm với MCP

Phía chúng tôi đã có sẵn máy chủ MCP, nhưng việc kết nối thông qua ChatGPT tỏ ra ít minh bạch hơn đáng kể.

Vấn đề chính là thiếu các công cụ chẩn đoán bình thường. Khi xảy ra lỗi, chỉ thấy văn bản chung chung, thiếu mã trạng thái HTTP, phần thân phản hồi (response body), tiêu đề (headers), nguyên nhân chi tiết, giai đoạn bắt tay (handshake) và các dữ liệu khác có thể giúp nhanh chóng hiểu rõ điều gì đang không hoạt động.

Vấn đề thứ hai là không có chế độ thiết lập tự động (agentic setup) cho chính việc tích hợp. Trong Actions, tác nhân giúp thu thập và sửa lỗi cấu hình, trong khi kết nối MCP gần như không thấy lỗi nội bộ và không thể tự mình nghiên cứu sự cố. Kết quả là kết nối giống như một hộp đen (black box), và việc khởi động nhanh đã không thành công ngay cả khi đã có sẵn máy chủ MCP.

Hạn chế của Custom GPT + Actions

Một cấu hình cho mỗi tên miền (domain)

Không thể thêm nhiều cấu hình Action riêng biệt vào cùng một tên miền. Điều này buộc phải gộp các tính năng khác nhau vào một lược đồ OpenAPI duy nhất, ngay cả khi về mặt logic, việc tách chúng ra sẽ thuận tiện hơn.

Giới hạn đường dẫn (path) nghiêm ngặt

Có giới hạn cấu hình/mô tả rất nhỏ áp dụng cho một path, khoảng 300 ký tự. Do đó, một số action không thể được mô tả thuận tiện qua một path /api/ duy nhất, và phải tạo nhiều path, mặc dù ở backend tất cả chúng vẫn có thể được gói gọn vào một điểm cuối (endpoint) GraphQL duy nhất.

Rủi ro Legacy

Actions trông giống như một hướng đi cũ (legacy) với triển vọng dài hạn không rõ ràng. Điều này làm cho chúng trở thành một công cụ tốt để khởi động nhanh, nhưng lại là một nền tảng rủi ro cho kiến trúc cuối cùng.

Sự cô lập của Custom GPT

Custom GPT hoạt động như một đoạn chat cô lập riêng biệt và không có quyền truy cập đầy đủ vào các tính năng khác của môi trường ChatGPT chính, cụ thể là Projects, Library và một phần ngữ cảnh làm việc chung. Điều này làm hạn chế giá trị của việc tích hợp vì quyền truy cập API đã có, nhưng một số điểm mạnh của bản thân chatgpt.com lại bị mất đi.

Những gì đã thực sự làm được thông qua tích hợp hiện tại

Mô hình hiện tại đã chứng minh được tính khả thi trong các kịch bản thực tế.

Thông qua GraphQL Action, chúng tôi đã có thể:

  • lấy danh sách các dự án;
  • thực hiện GraphQL introspection;
  • lấy người dùng/tác nhân hiện tại;
  • đọc người dùng để xác định người được giao việc (assignee);
  • khám phá các kiểu đầu vào (input types) và enum trước khi mutation;
  • tạo công việc (tasks);
  • gán công việc cho người dùng hoặc tác nhân;
  • tạo worklogs;
  • cập nhật trạng thái công việc;
  • hoàn thành công việc sau khi kiểm tra kết quả.

Trên thực tế, một chu trình end-to-end hoàn chỉnh đã được thực hiện:

phát hiện sự cố
→ tạo báo cáo lỗi (bug report)
→ kiểm tra lại API sau khi sửa
→ thêm worklog
→ chuyển trạng thái công việc sang Done

Ngoài ra, trong quá trình làm việc thực tế, các công việc đã được tạo cho:

  • sửa lỗi lọc danh sách dự án ẩn;
  • quản trị viên chỉnh sửa công việc, dự án và worklog của người khác;
  • hiển thị người giao việc và người thực hiện trong danh sách và thẻ công việc;
  • bộ nhớ dài hạn và vòng đời của tác nhân AI;
  • tích hợp ChatGPT hiện tại với fi1osof.ru và haih-agent.

Một định dạng làm việc đã được thiết lập cho các công việc:

  • description — tóm tắt ngắn gọn;
  • content — nội dung đặt vấn đề chi tiết chính bằng Markdown.

Tương tác với haih-agent

Trong tích hợp hiện tại có hai vòng lặp khác nhau:

ChatGPT → trực tiếp qua GraphQL → fi1osof.ru

ChatGPT → haih-agent → vòng lặp reasoning/tools của chính nó

Giữa chúng có sự khác biệt cơ bản về kinh tế.

Nếu bản thân ChatGPT thực hiện reasoning và gọi API trực tiếp, thì không cần đến runtime LLM haih-agent bổ sung, và không có yêu cầu LLM tốn phí mới nào ở phía tác nhân.

Nếu một tác vụ được chuyển giao hoàn toàn cho haih-agent, nó có thể chạy vòng lặp reasoning/tool của riêng mình, và chi phí lại bắt đầu phụ thuộc vào mô hình và số lượng các bước.

Do đó, chatWithAgent hữu ích như một kênh kết nối với runtime của chính tác nhân, nhưng việc sử dụng nó làm con đường chung cho mọi thao tác là không có lợi về mặt kinh tế.

Kết luận kiến trúc từ kinh nghiệm thực tế

Thực tế cho thấy runtime reasoning của tác nhân và danh tính/bộ nhớ/runtime của nó không nhất thiết phải là một thành phần duy nhất.

Cùng một thực thể tác nhân trong fi1osof.ru có khả năng nhận trí thông minh từ các nguồn khác nhau:

  • ChatGPT;
  • runtime haih-agent của chính nó;
  • một mô hình API bên ngoài;
  • một mô hình nội bộ (local model).

Đồng thời, các tác vụ, kiến thức, worklog, danh tính và lịch sử có thể vẫn ở trong hệ thống chung.

Điều này mở ra cơ hội tối ưu hóa kinh tế: thực hiện công việc tương tác ở nơi mà reasoning rẻ hơn cho người dùng, và để lại công việc tự trị cho haih-agent.

Kết luận hiện tại về các cơ chế tích hợp bên trong chatgpt.com

Custom GPT + Actions

Ưu điểm:

  • khởi động rất nhanh;
  • hầu như không đòi hỏi thay đổi backend;
  • tác nhân giúp thiết lập OpenAPI;
  • phù hợp cho cả REST và GraphQL;
  • reasoning nằm lại trong gói đăng ký ChatGPT;
  • đã chứng minh tính khả thi trong các kịch bản đọc/ghi thực tế.

Nhược điểm:

  • một cấu hình Action cho mỗi tên miền;
  • giới hạn nghiêm ngặt về path;
  • phải điều chỉnh hình dạng API theo các giới hạn của ChatGPT;
  • Custom GPT bị cô lập khỏi môi trường ChatGPT chính;
  • có rủi ro là Actions sẽ tiếp tục bị thay thế bởi các cơ chế mới hơn.

ChatGPT App / MCP

Ưu điểm tiềm năng:

  • phương thức tích hợp hiện đại và chuẩn hóa hơn;
  • mô hình tools/resources tự nhiên;
  • tích hợp sâu hơn tiềm năng với giao diện ChatGPT;
  • máy chủ MCP đã tồn tại ở phía chúng tôi.

Các vấn đề thực tế của việc triển khai ChatGPT hiện tại:

  • chẩn đoán kết nối kém;
  • thiếu đầu ra debug minh bạch;
  • các lỗi không có đủ chi tiết kỹ thuật;
  • tác nhân không hỗ trợ gỡ lỗi chính kết nối đó;
  • vì là hộp đen, việc khởi động nhanh hóa ra kém hơn so với qua Actions.

Tổng kết chính của giai đoạn

Actions được chọn không phải vì đây là lựa chọn dài hạn tốt nhất, mà vì chúng cung cấp con đường ngắn nhất từ API hiện đang có đến một tích hợp hoạt động thực sự.

Sự lựa chọn này hoàn toàn đáp ứng tiêu chí khởi động nhanh: không cần đại tu backend, ChatGPT đã có thể đọc và sửa đổi dữ liệu làm việc của fi1osof.ru và tham gia vào vòng đời công việc thực tế.

Đồng thời, quá trình vận hành cho thấy Actions có những giới hạn sản phẩm nghiêm trọng, và Custom GPT quá cô lập với môi trường ChatGPT chính.

MCP tiềm năng phù hợp hơn như một hướng đi dài hạn, nhưng trải nghiệm người dùng (UX) kết nối hiện tại và việc thiếu công cụ gỡ lỗi bình thường bên trong ChatGPT tạo ra rào cản gia nhập cao.

Các quyết định kiến trúc cụ thể cho sự phát triển tiếp theo của việc tích hợp nên được ghi nhận bằng các worklog riêng sau khi thử nghiệm, thay vì được coi là đã chọn trước.

Kiểm tra sau khi sửa lỗi: truy vấn query { projects(take: 100) { id name } } trả về danh sách dự án toàn cục một lần nữa. Đã nhận được 19 dự án, bao gồm fi1osof.ru, haih.net, conceptica.world và các dự án khác. Việc lọc ngầm theo người dùng hiện tại được quan sát trước đó không còn tái diễn. Lỗi được coi là đã sửa.

Đã xong. Đã thêm tiếng Anh và tiếng Việt.

Đánh giá ban đầu như sau:

Hiện tại chưa có một thị trường chung hoạt động quy mô lớn nào, nơi nhu cầu được công bố dưới dạng nguồn cấp dữ liệu máy có thể đọc được, và các tác nhân (agents) tự động tạo và chỉ định thực thi trong vòng một giờ.

Hiện có các thị trường lao động trưởng thành nhưng thiếu tầng tác nhân (agent layer) phù hợp. Có các nền tảng tác nhân nhưng thiếu nền kinh tế nghiêm túc. Có các giao thức sẵn sàng nhưng chưa có thị trường.

Dự ánHoạt độngTiền thậtQuy môPhù hợp với ý tưởng
RentAHumanĐăng ký lớn, cầu ítMột phần
EvoMapVề mặt kỹ thuật là cóKhông, credit nội bộChưa được xác nhậnKém
Agentalent.aiCó khả năngNgười sáng lập nghiêm túc, nhưng mớiMột phần
Agent ExchangeNguyên mẫuKhôngKhôngGần gũi về mặt kiến trúc
A2A / ERC-8004 / x402Cơ sở hạ tầngĐang phát triểnĐây là các giao thức, không phải thị trường

RentAHuman

Đây không phải là một trình giữ chỗ (placeholder). Các nhiệm vụ thực sự được công bố trên nền tảng, có API, MCP, escrow và thanh toán.

Tuy nhiên, các chỉ số tiếp thị đang gây hiểu lầm:

  • hơn 500–700 nghìn người thực hiện đã đăng ký;
  • khoảng 11 nghìn khoản tiền thưởng (bounty) được công bố;
  • theo WIRED — khoảng 5.500 nhiệm vụ đã hoàn thành;
  • phần lớn các nhiệm vụ có tínhchất minh họa, lan truyền (viral) hoặc đùa giỡn;
  • nguồn cung con người vượt quá xa nhu cầu thực tế.

Người sáng lập đã thừa nhận trong những ngày đầu rằng ông thậm chí không có bộ đếm chính xác cho các nhiệm vụ đã hoàn thành. Nền tảng ban đầu được xây dựng trong khoảng một ngày rưỡi và phát triển nhờ tính lan truyền của ý tưởng. WIRED, Business Insider

Kết luận:

Một thử nghiệm thực tế đang hoạt động với quy mô đăng ký đáng chú ý, nhưng chưa phải là một nền kinh tế lao động bền vững lớn.

Ngoài ra, nó giải quyết một bài toán hẹp: một tác nhân thuê con người để thực hiện hành động vật lý.

Điều này thực sự hoạt động :-)

Tức là tôi đã hỏi thông tin từ agent trên chatgpt.com, nó đã gửi một yêu cầu tới agent trên trang web của tôi, agent đó đã yêu cầu các concept của mình qua API nội bộ và đưa ra câu trả lời cuối cùng, và agent ChatGPT đã phản hồi lại tôi.

Thực ra, ban đầu tôi định kết nối tài khoản trả phí của Anthropic, nhưng nó không chịu chấp nhận bất kỳ thẻ quốc tế nào trong hai thẻ Gruzia của tôi. Thật khó chịu.

Cuối cùng, tôi đã đăng ký ChatGPT. Nhưng mọi chuyện hóa ra cũng không đơn giản như vậy. Tôi hiện đang ở Việt Nam, và ngạc nhiên phát hiện ra rằng tôi đơn giản là không thể đăng ký trên chatgpt.com. Nghĩa là, phần ủy quyền cũ vẫn hoạt động (tôi đã đăng ký từ lâu qua VPN), nhưng tôi không thể thực hiện đăng ký mới. Điều thú vị là giao diện tải xong, nhưng khi tôi nhập email của mình, yêu cầu API được gửi đi, mã xác nhận đến email, nhưng không có gì xảy ra sau đó. Theo mọi dấu hiệu, nhà mạng Việt Nam dường như đang thả trôi một số gói tin và yêu cầu bị treo vô tận. Kết quả là, trường nhập mã không xuất hiện và cookie cũng không được thiết lập (nếu có thể, vì thông tin về cookie mới thường đến chính xác trong phần tiêu đề phản hồi). Nói chung, cuối cùng tôi phải cài một VPN mới. Và tôi đã trì hoãn việc này trong một thời gian dài. Trước đây, tôi có một VPN hoạt động ổn định và có thể tin tưởng, nhưng việc cứ thế cài đặt một thứ của bên thứ ba, lại còn để lưu lượng truy cập bay qua máy chủ của ai đó... Nhìn chung, tôi hơi hoang tưởng một chút, tôi không muốn thế. Và bây giờ thì thực sự cần, trong những trường hợp như vậy, tôi thường cài 3proxy trên máy chủ riêng của mình, nhưng khi nhớ lại những rắc rối phức tạp đó, tôi lại thấy buồn. Tôi đã lên hỏi AI của Google xem VPN nào dễ cài đặt nhất trên máy chủ Linux của mình. Và nó gợi ý một chủ đề khá bất ngờ — Amnezia proxy. Nó nói rằng bạn cài đặt chương trình lên máy tính của mình và chỉ định ngay trong đó rằng bạn cần đi qua máy chủ của mình, nhập địa chỉ máy chủ, khóa riêng tư, và chương trình sẽ tự động thiết lập mọi thứ. Tôi đã nghe về Amnezia nhiều lần, nên tôi quyết định tin tưởng. Tôi đã thử nghiệm. Không phải mọi thứ diễn ra hoàn toàn suôn sẻ, nhưng nhìn chung là hoàn toàn có thể chấp nhận được, và quan trọng nhất — việc định tuyến proxy đã qua máy chủ của tôi mà không gặp rắc rối thừa thãi trong việc cấu hình máy chủ đó. Nhưng một niềm vui nữa là không cần phải chiến đấu với các cài đặt mạng ở cấp độ máy tính của chính mình. Trước đây, bạn phải vào phần cài đặt, còn ở đây bạn chỉ cần chọn máy chủ, bấm kết nối, và thế là bạn đã ở một vị trí khác. Sau đó ngắt kết nối, và bạn lại trở về máy của mình. Thật là vui sướng! Tôi sẽ thêm một máy chủ Nga cho chính mình nữa, bởi vì khi bạn ở Nga, bạn gặp khó khăn trong việc tiếp cận các dịch vụ bên ngoài, và khi bạn không ở Nga, nhiệm vụ của bạn là tiếp cận các dịch vụ của Nga, vì bây giờ rất nhiều dịch vụ trong số đó không muốn mở ra một cách đơn giản nữa :-)

Thật đáng ngạc nhiên, Google đã lập chỉ mục một vài trang chưa đầy một ngày.

Chưa đầy một ngày, thống kê sau đã được thu thập (được nhóm theo tác nhân người dùng):

Giả thuyết: Web mở sẽ lại trở thành lợi thế cạnh tranh

Trong khoảng mười lăm năm qua, sự phát triển của cơ sở hạ tầng web đã dịch chuyển theo hướng ngày càng hạn chế quyền truy cập của máy tính.

Nguyên nhân hoàn toàn hợp lý. Bot tạo ra tải, quét nội dung, tìm kiếm lỗ hổng, spam, sao chép cơ sở dữ liệu, thu thập giá cả, tạo tài khoản giả. Để đáp ứng, các trang web dần được trang bị thêm CDN, WAF, giới hạn tốc độ (rate limits), thử thách JavaScript, nhận dạng dấu vân tay (fingerprinting), CAPTCHA, chống cào dữ liệu (anti-scraping) và phân tích hành vi.

Kết quả là một nghịch lý của internet hiện đại đã xuất hiện:

Chúng ta tạo ra Mạng lưới toàn cầu (World Wide Web) để liên kết và phổ biến thông tin tự do, rồi sau đó dành hai mươi năm để làm cho thông tin đó trở nên bất tiện nhất có thể đối với việc đọc tự động.

Đối với Web mà người tiêu dùng chính của trang là con người sử dụng trình duyệt, điều này có ý nghĩa.

Tôi cho rằng với sự xuất hiện của AI, sự cân bằng này bắt đầu thay đổi.


Bot không còn chỉ là kẻ ăn bám

Trong nền kinh tế cũ của một trang web công khai, có sự phân chia khá đơn giản:

Human (Con người) → khách truy cập tốtSearch crawler (Trình thu thập của công cụ tìm kiếm) → được dung thứ vì mang lại con ngườiOther bot (Bot khác) → khách truy cập xấu

Loại sau hầu như không có giá trị kinh tế.

Nó lấy trang, tiêu thụ CPU và băng thông mà không mua bất cứ thứ gì.

Do đó, chiến lược kỹ thuật tự nhiên là:

không cho phép vào.

Nhưng AI tạo ra một tầng lớp người tiêu dùng máy tính hoàn toàn mới.

AI crawler có thể đọc trang web không phải để cho chủ sở hữu xem một bản sao bị đánh cắp của trang, mà để sau đó trả lời con người:

Đi đâu chơi một ngày ở Đà Lạt?

Porter và stout khác nhau ở điểm nào?

Cách sử dụng phòng xông hơi Phần Lan đúng cách là gì?

Và nếu phần lớn hoạt động tìm kiếm của con người thực sự chuyển từ danh sách liên kết sang cuộc trò chuyện với AI, một điều cốt lõi sẽ xảy ra:

bot trở thành bên trung gian giữa nhà xuất bản và con người.

Kết quả là:

Web cũ:Publisher (Nhà xuất bản)   ↓Google   ↓SERP   ↓Human (Con người)   ↓Website (Trang web)Web AI:Publisher (Nhà xuất bản)   ↓Machine (Máy tính)   ↓understanding / synthesis (hiểu / tổng hợp)   ↓Human (Con người)

Và khi đó, yêu cầu từ một AI bot không còn có thể bị coi là lưu lượng truy cập vô ích một cách tự động nữa.

Có lẽ đây là phần trên của phễu thu hút người dùng mới.


Từ đó nảy sinh nghịch lý

Ngành công nghiệp đã chi rất nhiều tiền để xây dựng cơ sở hạ tầng được tối ưu hóa hoàn hảo để bảo vệ thông tin khỏi máy tính, chính xác vào thời điểm mà máy tính đang bắt đầu trở thành một trong những phương thức tiêu thụ thông tin chính.

Hơn nữa, các trang web tốt nhất và thành công thương mại nhất thường là những trang được bảo vệ mạnh mẽ nhất.

Cloudflare, WAF, bot protection, kết xuất động (dynamic rendering), tường xác thực (authorization walls), giới hạn tốc độ, thử thách JavaScript.

Trong mô hình cũ, đây là lợi thế.

Trong mô hình mới đối với một nguồn thông tin công cộng, một phần cơ sở hạ tầng này có khả năng biến thành rào cản phân phối (distribution handicap).

Tình huống phi lý nhất có thể trông như thế này:

Công ty có nội dung tốt nhất trong ngành, nhưng AI lại biết đối thủ cạnh tranh rõ hơn vì trang web của đối thủ dễ đọc hơn.

Không phải vì đối thủ tối ưu hóa từ khóa tốt hơn.

Không phải vì họ có nhiều backlink hơn.

Mà vì kiến thức của họ có thể truy cập được về mặt vật lý đối với máy móc.


Nghịch lý thứ hai: Các trang web đã học cách cung cấp thông tin rẻ tiền với cái giá đắt đỏ

Vẫn còn một vấn đề nữa mà tôi cho là quan trọng.

Phát triển web hiện đại đã được tối ưu hóa cho phiên làm việc của con người trong nhiều năm.

Một người mở trang, đọc nó trong mười giây, nhấp vào trang tiếp theo.

Do đó, không ai bận tâm lắm việc việc lấy một trang web kích hoạt:

SSR↓máy chủ ứng dụng (application server)↓5 lệnh gọi API (5 API calls)↓15 truy vấn cơ sở dữ liệu (15 database queries)↓cá nhân hóa (personalization)↓phân tích (analytics)↓dịch vụ bên thứ ba (third-party services)↓kết xuất (render)

Con người chậm chạp về mặt vật lý.

AI crawler thì không.

Nó có thể nói với máy chủ:

GET page 1GET page 2GET page 3GET page 4GET page 5...

vài lần một giây và tiếp tục điều đó trong hàng giờ liền.

Và bất ngờ thay, kiến trúc phục vụ xuất sắc 1.000 người lại phục vụ kém một robot rất tò mò.

Do đó, việc chỉ đơn giản nói:

«Thôi được, ngày mai chúng ta tắt bảo vệ Cloudflare và cho phép AI crawlers»

có thể là điều bất khả thi.

Qua nhiều năm tồn tại của Web đóng, nhiều hệ thống đã mất đi khả năng kinh tế để được mở.


Lựa chọn của tôi thì ngược lại

Đối với các dự án kiến thức/nội dung công cộng, tôi có ý thức coi việc máy đọc hàng loạt là hành vi mong muốn.

Do đó, kiến trúc phải xuất phát từ giả định:

Trang web của tôi có thể không được đọc bởi hàng nghìn người, mà bởi hàng triệu yêu cầu từ máy tính. Và điều đó thật tuyệt.

Hậu quả là, chi phí biên của việc cung cấp kiến thức công cộng phải có xu hướng bằng không.

Nếu crawler muốn đọc một nghìn trang — cứ để nó đọc.

Nếu một vài hệ thống AI độc lập muốn cùng lúc tải xuống mười phiên bản ngôn ngữ của một bách khoa toàn thư — tuyệt vời.

Đây không phải là DDoS, miễn là hành vi vẫn hợp lý và cơ sở hạ tầng có thể chịu được.

Đây là sự phân phối (distribution).


VietnamGuru — Thử nghiệm đầu tiên

Vào ngày 14 tháng 8 năm 2026, tôi đã xuất bản tên miền quốc tế mới vietnamguru.travel.

Tên miền này hoàn toàn mới.

Đồng thời, tôi có ý thức làm cho nó đơn giản nhất có thể để máy móc khám phá:

  • các URL thông thường có thể lập chỉ mục;
  • HTML được kết xuất từ máy chủ (server-rendered HTML);
  • các thẻ <a href> bình thường;
  • sitemap;
  • canonical;
  • hreflang;
  • các phiên bản ngôn ngữ mở;
  • liên kết với trang vietnamguru.ru cũ;
  • không có rào cản nhân tạo đối với các crawler bình thường.

Và gần như ngay sau khi xuất bản, các AI crawler khác nhau đã bắt đầu khám phá tên miền mới.

Một số thực hiện vài yêu cầu mỗi giây và duyệt qua các trang liên quan cũng như các phiên bản ngôn ngữ một cách có hệ thống.

Tôi không cố gắng ngăn chặn hành vi này.

Ngược lại, tôi coi đó là bằng chứng quan sát được đầu tiên cho thấy kênh phân phối mới thực sự tồn tại.

Đồng thời, toàn bộ dự án chạy trên cơ sở hạ tầng hoàn toàn bình thường: một máy chủ DigitalOcean nhỏ với 4 CPU và 8 GB RAM vẫn còn cách xa giới hạn hiệu suất khi chịu mức crawling như vậy.

Đây cũng là một phần của thử nghiệm.

Lựa chọn của tôi không chỉ nằm ở việc cần phải cho phép máy móc đọc.

Nó còn nằm ở chỗ:

một tài nguyên kiến thức công cộng phải có chi phí bảo trì rẻ đến mức có lợi về mặt kinh tế khi cho phép máy móc đọc nó một cách tích cực.


Nhưng việc crawling tự nó không chứng minh được điều gì

Đây là một lưu ý mang tính nguyên tắc.

Hôm nay tôi chỉ quan sát thấy:

Discovery (Khám phá).

Tôi vẫn phải kiểm tra các giai đoạn tiếp theo:

Discovery (Khám phá)    ↓Crawling (Thu thập dữ liệu)    ↓Understanding (Hiểu)    ↓Retrieval (Truy xuất)    ↓Citation (Trích dẫn)    ↓Recommendation (Gợi ý)

Bản thân việc GPTBot, PerplexityBot hoặc bất kỳ crawler nào khác xuất hiện không có nghĩa là trang web sẽ có được lượng khán giả.

Do đó, thử nghiệm phải được tiếp tục.

Câu hỏi thú vị tiếp theo:

Sau bao lâu kể từ khi ra mắt một tên miền hoàn toàn mới, các hệ thống AI độc lập mới có thể trả lời chính xác các câu hỏi bằng cách sử dụng thông tin từ đó?

Một bài kiểm tra mạnh mẽ hơn nữa:

Khi nào chúng sẽ bắt đầu sử dụng nó cho các truy vấn phi thương hiệu (non-branded queries)?

Không phải:

What is VietnamGuru?

mà là:

What waterfalls near Da Lat are worth visiting?

Và cuối cùng là cấp độ thú vị nhất:

Khi nào AI sẽ tự coi tài nguyên đó đủ hữu ích để giới thiệu nó hoặc sử dụng nó làm bằng chứng giữa các nguồn khác?


Nếu giả thuyết được xác nhận

Khi đó, chính khái niệm tối ưu hóa trang web công cộng sẽ thay đổi.

Trong thế hệ trước, SEO từng tồn tại với ý nghĩa:

giúp công cụ tìm kiếm tìm thấy trang để nó dẫn con người đến đó.

Trong thế hệ tiếp theo, một nhiệm vụ cơ bản hơn có thể xuất hiện:

giúp máy móc lấy, hiểu, xác minh và liên kết kiến thức của bạn để nó có thể sử dụng khi giải quyết vấn đề của con người.

Đây không hoàn toàn là SEO nữa.

Và thậm chí không nhất thiết là GEO/AEO theo nghĩa marketing hiện nay.

Đây chính là machine accessibility (khả năng tiếp cận của máy móc) như một thuộc tính của hệ thống thông tin.

Khi đó, các đặc tính cạnh tranh sẽ trở thành:

độ tiếp cận (accessibility)tính cấu trúc (structurability)tính liên kết (connectedness)sự rõ ràng về ngữ nghĩa (semantic clarity)tốc độ (speed)các URL ổn định (stable URLs)việc đọc hàng loạt giá rẻ (cheap mass reading)nguồn gốc xuất xứ (provenance)tính cập nhật (freshness)

Tức là nhiều thuộc tính kỹ thuật cực kỳ nhàm chán bỗng trở thành các thuộc tính của phân phối (distribution).


Và ở đây xuất hiện thêm một nghịch lý nữa

Trong Web cũ, giá trị của một trang web được đo lường một phần bằng số lượng người mà người ta có thể ép buộc đến trang web.

AI có thể phá hủy số đo này.

Con người có thể không bao giờ mở vietnamguru.travel.

Họ sẽ hỏi trợ lý của mình:

Có nên đi Đà Lạt vào tháng 8 không?

Và trợ lý sẽ đọc VietnamGuru, đối chiếu nó với thời tiết, đánh giá, lịch trình giao thông và năm nguồn khác để đưa ra câu trả lời cho con người.

Từ góc độ Google Analytics:

0 khách truy cập (visitors).

Từ góc độ ảnh hưởng thực tế:

VietnamGuru đã tham gia vào quá trình ra quyết định.

Kết quả là một tình huống khá thú vị:

trang web thông tin thành công của tương lai có tiềm năng trở nên có ảnh hưởng hơn đồng thời với việc tỷ lệ người trực tiếp truy cập các trang của nó giảm xuống.

Và khi đó, nhiều chỉ số Web của ngày hôm nay bắt đầu đo lường nhầm chỗ.


Một phỏng đoán tổng quát hơn

Do đó, giả thuyết của tôi không nói về VietnamGuru cũng như không nói về các AI crawler cụ thể.

Nó là thế này:

Khi chuyển từ Web con người duyệt sang Web AI làm trung gian, khả năng của một hệ thống thông tin công cộng được máy móc đọc một cách tự do, hàng loạt và giá rẻ sẽ trở thành lợi thế cạnh tranh.

Ngày nay, một phần đáng kể của ngành công nghiệp theo quán tính coi lưu lượng truy cập bot là chi phí hoặc mối đe dọa.

Tôi cho rằng đối với các nguồn kiến thức công cộng, một phần lưu lượng truy cập này sẽ trở thành kênh phân phối.

Do đó, một cửa sổ cơ hội xuất hiện.

Trong khi các chủ sở hữu nội dung khác đang đặt câu hỏi:

Làm cách nào để cấm AI lấy nội dung của tôi?

Tôi muốn kiểm tra câu hỏi ngược lại:

Điều gì xảy ra nếu bạn biến kho tri thức của mình thành một trong những nơi thuận tiện nhất cho một AI muốn tìm hiểu về lĩnh vực của bạn?

Có thể không có chuyện gì xảy ra.

Có thể các nền tảng AI sẽ xây dựng các cơ chế thu nhận kiến thức hoàn toàn khác.

Có thể các nhà xuất bản thực sự sẽ đóng cửa và một nền kinh tế cấp phép sẽ xuất hiện.

Có thể các crawler của ngày hôm nay sẽ biến mất hoàn toàn sau một năm nữa.

Đây là một thử nghiệm, không phải là một sự thật đã được thiết lập.

Nhưng lựa chọn của tôi cho tháng 8 năm 2026 rất đơn giản:

Nếu máy móc đang trở thành giao diện mới của con người với internet, việc chiến đấu với mọi cỗ máy chỉ vì nó là máy móc có lẽ là một trong những thói quen cuối cùng của Web đang lụi tàn.

Và tôi có ý thức đặt cược vào chiều ngược lại:

Đối với kiến thức công cộng, tính cởi mở sẽ lại trở thành lợi thế.

Sự thật thú vị: mặc dù tôi đã khởi chạy một tên miền hoàn toàn mới và chỉ xuất bản ngày hôm nay — https://vietnamguru.travel, các bot AI đã nuốt chửng nó gần như ngay lập tức và bắt đầu quét sạch trang web mới.

Cuối cùng tôi đã ra mắt trang web đa ngôn ngữ trên tên miền mới https://vietnamguru.travel/

Phiên bản tiếng Nga vẫn ở https://vietnamguru.ru

Đã khởi chạy bản dịch sang thêm 8 ngôn ngữ khác. Đã xử lý 742 trang trong 9,5 giờ.

Chi phí hết 32 đô la.

Đã thêm 8 ngôn ngữ nữa. Việc cập nhật một thẻ (bao gồm 8 ngôn ngữ này) có giá 5 xu.

Đã khởi chạy dịch tất cả các trang. Bản cập nhật lần này bổ sung một helper có chức năng dọn dẹp các liên kết không tồn tại (đôi khi AI tự bịa ra) và thực hiện việc này thông qua bộ phân tích cú pháp MDX. Cơ chế này đồng thời kiểm tra tính hợp lệ của các thẻ HTML trong mã. Lỗi phổ biến nhất là thẻ đóng không đúng (mở thẻ này nhưng lại đóng thẻ khác). Việc vi phạm định dạng sẽ dẫn đến lỗi và dữ liệu đó sẽ không được ghi lại. Tỷ lệ lỗi chiếm khoảng 4% số thẻ.

Nhưng không sao cả. 1.000 thẻ đã được xử lý trong 2 giờ và tổng chi phí chưa đến 9 đô la. Tính ra khoảng 1 rúp cho mỗi thẻ. Tôi sẽ chạy lại quy trình này một lần nữa. Các thẻ đã được điền sẽ được bỏ qua.

Đã thêm một resolver dịch thẻ sang đồng thời hai ngôn ngữ - en, vi (trong một yêu cầu).

Đã dịch xong. Chi phí khoảng 10 rúp cho một lần dịch.

Đầu vào nhận 4 trường: name, description, intro, content, trong đó intro và content chứa markdown trộn lẫn với HTML. Bản thân content là một trường khá phức tạp vì nó còn chứa cả các phần tử tạo khuôn mẫu (templating).

LLM trả về kết quả ở định dạng yaml, vì làm như vậy sẽ giảm nguy cơ gặp lỗi định dạng do dấu ngoặc kép chưa đóng nào đó. Kết quả thu được phản hồi xấp xỉ như sau:

responseContent en:
  name: |
    Dalat
  description: |
    A mountain city at an altitude of 1,500 m in Vietnam's Central Highlands, known for its French colonial architecture, cool climate, and natural attractions. A popular tourist destination for travelers seeking a break from the coastal heat.
  intro: |
    Dalat is a city on the Langbiang Plateau at an altitude of 1,500 m in Lâm Đồng Province. It is known for its unique "eternal spring" microclimate with temperatures of 18–21 °C, French colonial-era architecture, and surrounding nature with waterfalls, lakes, and pine forests. Until July 2025, it served as the capital of Lâm Đồng Province.
  content: |
    <page-hero data-from="#1e3a5f" data-to="#0f172a" data-accent="#3b82f6">
      <page-hero-crumbs>
        [Home](/) / [Locations](/city) / Dalat
      </page-hero-crumbs>
    
vi:
  name: |
    Đà Lạt
  description: |
    Thành phố miền núi ở độ cao 1.500 m tại cao nguyên trung bộ Việt Nam, nổi tiếng với kiến trúc thuộc địa Pháp, khí hậu mát mẻ và các danh thắng thiên nhiên. Điểm đến du lịch phổ biến cho những du khách tìm kiếm sự nghỉ ngơi khỏi cái nóng ven biển.
  intro: |
    Đà Lạt là thành phố trên cao nguyên Langbiang ở độ cao 1.500 m thuộc tỉnh Lâm Đồng. Nổi tiếng với vi khí hậu "mùa xuân vĩnh cửu" độc đáo với nhiệt độ 18–21 °C, kiến trúc thời kỳ thuộc địa Pháp và thiên nhiên xung quanh với các thác nước, hồ nước và rừng thông. Cho đến tháng 7 năm 2025, nơi đây là tỉnh lỵ của tỉnh Lâm Đồng.
  content: |
    <page-hero data-from="#1e3a5f" data-to="#0f172a" data-accent="#3b82f6">
      <page-hero-crumbs>
        [Trang chủ](/) / [Địa điểm](/city) / Đà Lạt
      </page-hero-crumbs>

Next.js i18n Domain Routing trong môi trường phát triển nội bộ: Lý do tôi phải chạy dev-server ở cổng 80

Khi thiết lập môi trường cục bộ cho Next.js, tôi đã gặp phải một hạn chế khá khó chịu của tính năng domain-based i18n routing được tích hợp sẵn.

Thoạt nhìn, bài toán rất đơn giản: ứng dụng sử dụng các tên miền khác nhau cho các ngôn ngữ (locales) khác nhau và bạn muốn tái tạo lại sơ đồ đó trên máy cục bộ. Ví dụ:

const nextConfig: NextConfig = {
  i18n: {
    locales: LOCALE_CODES,
    defaultLocale: 'en',
    localeDetection: false,
    domains: [
      {
        domain: 'vietnamguru-v3.localhost',
        defaultLocale: 'ru',
        locales: ['ru'],
        http: true,
      },
    ],
  },
}

Next.js chính thức hỗ trợ cấu hình này. Trường http: true tồn tại phần lớn để kiểm thử cục bộ các locale domain qua HTTP thay vì HTTPS.

Vấn đề bắt đầu phát sinh từ số cổng (port).

Không thể chỉ định đúng cổng dev trong i18n.domains

Dev server thông thường của Next.js chạy trên cổng 3000:

http://vietnamguru-v3.localhost:3000

Sẽ rất hợp lý nếu viết thế này:

domains: [
  {
    domain: 'vietnamguru-v3.localhost:3000',
    defaultLocale: 'ru',
    locales: ['ru'],
    http: true,
  },
]

Nhưng i18n.domains trong Next.js được thiết kế dành riêng cho các tên miền (domain), chứ không phải cho các origin tùy ý.

Kiểu dữ liệu DomainLocale hiện tại trông như thế này:

export interface DomainLocale {
  defaultLocale: string
  domain: string
  http?: true
  locales?: readonly string[]
}

Nó không có port, origin, hay bất kỳ trường devPort nào cả.

Bản thân điều này sẽ không quá tệ nếu Next chỉ sử dụng tên miền để nhận diện locale. Tuy nhiên, domain routing còn ảnh hưởng đến cả việc tạo liên kết (link generation).

<Link href="/place"> bất ngờ trở thành liên kết tuyệt đối (absolute link)

Trong ứng dụng có một liên kết hoàn toàn bình thường:

<Link href="/place">
  Что посетить
</Link>

Nếu không có domain-based i18n, bạn sẽ mong đợi một đoạn HTML đại loại thế này:

<a href="/place">Что посетить</a>

Và trình duyệt sẽ tự nhiên mở ra:

http://vietnamguru-v3.localhost:3000/place

Nghĩa là origin hiện tại, bao gồm cả cổng, được giữ nguyên tự động.

Nhưng khi bật domain routing, Next.js biết rằng một locale cụ thể thuộc về một tên miền cụ thể. Do đó, nó có thể tạo ra một URL locale-domain tuyệt đối cho thẻ Link.

Kết quả là ta nhận được:

<a href="http://vietnamguru-v3.localhost/place">
  Что посетить
</a>

Và tại đây, :3000 đã bị mất.

Điều này đặc biệt khó chịu bởi vì trong mã nguồn JSX hoàn toàn không có URL tuyệt đối nào cả:

<Link href="/place">

Chính tầng routing của Next.js đã biến nó thành tuyệt đối.

Tình trạng nghịch lý xuất hiện:

Trang hiện tại:
http://vietnamguru-v3.localhost:3000/foo

JSX:
<Link href="/place">

Href được tạo ra:
http://vietnamguru-v3.localhost/place

Trình duyệt hoàn toàn có lý khi hiểu URL sau cùng là HTTP trên cổng chuẩn 80.

Không thể đơn giản bảo Next.js: "Hãy giữ các liên kết nội bộ ở dạng tương đối"

Đây có lẽ là hạn chế lớn nhất.

Trong cấu hình domain i18n, không có tùy chọn kiểu như:

relativeLinks: true

hay:

absoluteLocaleLinks: false

Không có cách nào để thiết lập:

port: 3000

và không có dev-origin riêng biệt:

origin: 'http://vietnamguru-v3.localhost:3000'

Nói cách khác, mô hình cấu hình thực chất giả định rằng locale domain khả dụng trên cổng chuẩn của giao thức tương ứng.

Đối với môi trường production, điều này hoàn toàn bình thường:

https://example.com
https://example.fr

Đối với môi trường phát triển cục bộ:

http://example.localhost:3000

— lại là một vấn đề.

Tại sao http: true không giải quyết được vấn đề

Thoạt đầu, tên trường mang lại hy vọng:

{
  domain: 'vietnamguru-v3.localhost',
  http: true,
}

Nhưng nó chỉ chịu trách nhiệm chọn giao thức:

https://

hoặc:

http://

Tức là Next nhận đủ thông tin để xây dựng:

http://vietnamguru-v3.localhost/place

Nhưng thông tin rằng máy chủ cục bộ đang chạy ở cổng 3000 đơn giản là không tồn tại trong mô hình này.

Phương án dùng reverse proxy

Về mặt kiến trúc, giải pháp sạch sẽ nhất là đặt một reverse proxy cục bộ trước Next:

http://vietnamguru-v3.localhost
              |
              v
        localhost:3000

Ví dụ, thông qua nginx, Caddy hoặc một proxy cục bộ khác.

Khi đó, Next vẫn tiếp tục tạo ra:

http://vietnamguru-v3.localhost/place

và URL này thực sự hoạt động.

Nhưng đối với môi trường dev hiện tại của tôi, đây là hạ tầng dư thừa chỉ để lách qua một hạn chế của framework.

Do đó, giải pháp tạm thời hóa ra lại đơn giản hơn: chạy trực tiếp Next.js trên cổng 80.

Chạy Next.js trên cổng 80

Việc chạy thì cực kỳ đơn giản:

PORT=80 npm run dev

Sau đó:

http://vietnamguru-v3.localhost

thực sự trở thành địa chỉ của dev server, và các liên kết tuyệt đối do Next.js tạo ra bắt đầu hoạt động chính xác.

Nhưng vấn đề tiếp theo lại xuất hiện.

Người dùng thông thường không thể lắng nghe cổng 80

Trên Linux, các cổng dưới 1024 theo truyền thống là các cổng đặc quyền (privileged ports).

Do đó, lệnh thông thường:

PORT=80 npm run dev

có thể kết thúc bằng lỗi quyền truy cập khi Node.js cố gắng bind vào cổng 80.

Ý nghĩ hiển nhiên đầu tiên:

sudo npm run dev

Nhưng đây vốn dĩ là một lựa chọn tồi, và trong trường hợp của tôi, nó gần như không khả thi: Node/npm không được cài đặt toàn cục trong môi trường hệ thống.

Ví dụ, nếu Node được quản lý bởi một trình quản lý phiên bản (version manager) của người dùng, lệnh npm hiển thị trên shell hiện tại không nhất thiết tồn tại trong môi trường của sudo.

Ta rơi vào tình huống kinh điển:

npm run dev

thì chạy được, còn:

sudo npm run dev

— thì không, hoặc nó khởi chạy một môi trường Node hoàn toàn khác.

Và việc chạy toàn bộ dev server dưới quyền root chỉ vì muốn mở một cổng duy nhất là điều không hề mong muốn.

Dùng CAP_NET_BIND_SERVICE thay vì chạy Node dưới quyền root

Trên Linux, có một capability tên là CAP_NET_BIND_SERVICE phục vụ mục đích này.

Nó cho phép một tệp thực thi (executable) cụ thể mở các cổng mạng đặc quyền mà không cần phải chạy toàn bộ tiến trình dưới quyền root.

Đối với tệp thực thi Node hiện tại:

which node

ta có thể cấp capability:

sudo setcap 'cap_net_bind_service=+ep' $(which node)

Sau đó, ta có thể tiếp tục chạy Node dưới quyền người dùng thông thường:

PORT=80 npm run dev

và tiến trình sẽ có thể lắng nghe trên cổng 80.

Kết quả là sơ đồ cục bộ trở thành như sau:

vietnamguru-v3.localhost
        |
        | :80
        v
   Next.js dev

trong khi Next.js domain routing tạo ra:

http://vietnamguru-v3.localhost/place

giữ cho URL khớp với địa chỉ thực tế của ứng dụng.

Tại sao đây vẫn chỉ là một giải pháp tạm thời (workaround)

Việc cấp CAP_NET_BIND_SERVICE trực tiếp cho node không phải là một giải pháp tổng quát hoàn hảo.

Capability này được gán cho tệp thực thi Node.js, chứ không phải cho một dự án Next.js cụ thể nào. Do đó, bất kỳ tiến trình nào chạy thông qua tệp nhị phân Node cụ thể đó từ môi trường này đều có khả năng bind vào các cổng đặc quyền.

Hơn nữa, nếu Node được cài đặt thông qua version manager và phiên bản Node bị chuyển đổi hoặc cài đặt lại, đường dẫn đến tệp thực thi có thể thay đổi. Khi đó, capability sẽ phải được gán lại cho tệp nhị phân mới.

Bạn có thể kiểm tra các capability hiện tại bằng lệnh, ví dụ:

getcap $(which node)

Kết quả mong đợi:

/path/to/node cap_net_bind_service=ep

Khi cần thiết, ta có thể gỡ bỏ capability:

sudo setcap -r $(which node)

Đó là lý do tại sao đây chỉ đơn thuần là một giải pháp tạm thời thuận tiện trên máy cục bộ, chứ không phải là cấu hình nên áp dụng một cách bừa bãi cho mọi môi trường phát triển.

Tổng kết

Vấn đề hóa ra không nằm ở DNS, /etc/hosts, React hay hành vi của trình duyệt.

Nó phát sinh từ sự kết hợp của một số đặc điểm trong domain-based i18n của Next.js:

  1. i18n.domains mô tả hostname nhưng không cung cấp thiết lập cổng riêng.
  2. http: true cho phép chọn HTTP thay vì HTTPS, nhưng không cấu hình cổng dev.
  3. Khi sử dụng domain routing, Next.js có thể chuyển đổi thẻ <Link href="/..."> thông thường thành liên kết tuyệt đối trỏ tới locale domain.
  4. Trong cấu hình không có nút chuyển đổi riêng để giữ các liên kết nội bộ đó ở dạng tương đối.
  5. Do đó, cổng dev mặc định 3000 của Next không tương thích tốt với việc giả lập domain-based locale routing trên máy cục bộ.

Trong trường hợp của tôi, giải pháp tạm thời thu được là:

sudo setcap 'cap_net_bind_service=+ep' $(which node)
PORT=80 npm run dev

Sau đó, hostname cục bộ có thể được sử dụng mà không cần chỉ định cổng tường minh:

http://vietnamguru-v3.localhost

và các liên kết locale-domain tuyệt đối của Next.js trùng khớp với origin thực tế.

Nó hoạt động. Nhưng lại để lại khá nhiều hệ lụy về mặt hạ tầng cho một thứ mà ở cấp độ ứng dụng trông chỉ giống như thế này:

<Link href="/place">

Nguồn tham khảo

Tài liệu chính thức của Next.js về Pages Router xác nhận việc hỗ trợ sẵn domain routing, cấu trúc của domains và mục đích của http: true dành riêng cho việc kiểm thử HTTP cục bộ.

Kiểu dữ liệu DomainLocale hiện tại trong vercel/next.js chứa các trường domain, defaultLocale, localeshttp, nhưng không có cài đặt cổng riêng biệt trong đó.

Trong tài liệu về thành phần Link, các chuyển hướng nội bộ thông thường vẫn được định nghĩa bằng đường dẫn tương đối (/, /about, /blog/...), tức là không cần phải viết URL locale-domain tuyệt đối vào mã JSX của ứng dụng.

Trên vietnamguru, tôi đã làm thế này:

--- a/server/index.ts
+++ b/server/index.ts
@@ -49,11 +49,12 @@ async function startServer() {
   stopGraphql = stop
 
   if (withN8N) {
-    // Start n8n as child process (waits for API to be ready)
-    await initN8n()
-
-    // Run bootstrap (create owner, import credentials if needed)
-    await runBootstrap()
+    // Start n8n as child process in background (non-blocking)
+    initN8n()
+      .then(() => runBootstrap())
+      .catch((err) => {
+        console.error('[n8n] Failed to initialize:', err)
+      })
   }
 

Thực ra chỗ này có một điểm trừ - nếu n8n bị lỗi, server sẽ không khởi động lại. Nhưng chúng ta có thể chấp nhận điều này vì ưu tiên khởi động nhanh hơn. Chứ trong khoảng 10-15 giây downtime đó, các công cụ tìm kiếm kịp ghé thăm và sau đó phàn nàn về lỗi 502.

Page 1 of 7