Nhật ký công việc

12.10.2026. По запросу владельца создан проект newpg.ru в fi1osof.ru и поставлена задача возродить сайт веб-студии. В проект внесены исторические сведения о «Новой парадигме», ранних технических статьях, утрате прежнего сайта и профессиональной цепочке MODX.club → Prisma CMS → Freecode Academy с современными направлениями fi1osof.ru / haih.site. Подготовлена постановка с аудитом исторических URL, разработкой, тестированием и критерием фактического запуска. Разработка и публикация сайта пока не выполнялись.

Đã thiết lập hệ thống phân tích nội bộ cơ bản cho các trang web đã hoạt động: thu thập sự kiện của khách hàng thông qua JavaScript và đối chiếu chúng với nhật ký máy chủ. Điều này cho phép phân tách rõ hoạt động của người dùng thực, bot tìm kiếm, hệ thống giám sát, trình quét và lưu lượng truy cập kỹ thuật khác. Đây là nền tảng cho các bộ lọc chống gian lận trong tương lai cũng như đo lường tải/chi phí trước và sau khi lọc.

Đã xuất bản hai bài viết về dự án:

Đã lập chỉ mục hơn 1700 trang

Hiển thị tăng, lượt nhấp chuột thì không.

Kết quả tìm kiếm tạo sinh còn yếu.

Đã có hơn 7.500 trang được lập chỉ mục

Nhưng trong tháng qua vẫn không có trang mới nào xuất hiện trên kết quả tìm kiếm.

còn trong cả năm - chỉ có hai trang.

Chỉ có hai trang trong một năm, thật khó tin.

Số lượt nhấp/lượt hiển thị đang giảm mạnh.

Kết quả tìm kiếm tạo sinh - vẫn chưa rõ ràng.

Nhân tiện, hãy chú ý đến sự gia tăng bất thường về số lượt hiển thị vào tháng Năm. Lúc đó dữ liệu được nhóm theo tuần, bây giờ tôi nhóm theo ngày. Trước hết, đây là một đợt bùng nổ kết quả tìm kiếm riêng lẻ trong một ngày - gần 7.000.

Và không, điều này hoàn toàn không có sự tương quan với số lượt nhấp. Hãy cùng xem xét chỉ số lượt hiển thị:

Tuần trước đó có 220 lượt hiển thị, tuần sau đó có 157 lượt hiển thị, nhưng ở đây lại có gần 7.000. Nghĩa là sự chênh lệch lớn hơn 15 lần. Đối với số lượt nhấp thì không có sự bất thường này.

Ai có thể giải thích điều này ngoài hoạt động tự động hóa? Nói cách khác, số lượng lượt hiển thị và lượt nhấp từ lâu đã không còn phản ánh việc "Có bao nhiêu người thực sự nhìn thấy và truy cập chúng ta" nữa.

Trang web kak-prodvinut-sayt.rf đã được chuyển sang một dự án riêng: /projects/cmuymjnak0106nw0p28llboa4.

Trang web kak-prodvinut-sayt.rf thực tế đã được tạo và ra mắt trong khuôn khổ quy trình làm việc chung: /worklogs/cmuy98sq801pcnw0qakldqkfd.

Hôm nay đã hoàn thành và ra mắt 3 trang web:

Công việc được thực hiện bởi tác nhân dưới sự hướng dẫn của người dùng: tạo trang web, thêm nội dung, thiết lập cơ sở hạ tầng, cấu hình hai máy chủ mới riêng biệt, xuất bản và ra mắt trang web. Như vậy, một phần đáng kể của chu trình đầy đủ đã được thực hiện — từ việc lập kế hoạch và xây dựng trang web đến cấu hình máy chủ và đưa vào vận hành thực tế (production).

Sau vài giờ thử nghiệm với hệ thống lập kế hoạch mới, tôi đã hiểu rõ hơn đáng kể về cả những hạn chế của lần triển khai hiện tại lẫn những giới hạn của chính phương pháp phát triển thông qua AI agent. Agent đã thực hiện thành công một số giải pháp, tuy nhiên nhìn chung hệ thống vẫn chưa đáp ứng được các yêu cầu của tôi, và việc tiếp tục khắc phục cục bộ các vấn đề riêng lẻ không còn hiệu quả nữa.

Đặc biệt rõ ràng là nỗ lực thoái lùi và đơn giản hóa hệ thống. Agent đã được chỉ định rõ ràng những phần nào của việc triển khai nên được xóa hoặc đơn giản hóa, nhưng cùng với đó nó cũng ảnh hưởng đến các yếu tố khác lẽ ra phải được giữ lại. Điều này cho thấy một hạn chế quan trọng: agent có khả năng làm việc với các đoạn mã riêng lẻ và các phụ thuộc cục bộ, nhưng kém hơn trong việc duy trì ranh giới giữa việc đơn giản hóa có mục tiêu và sự phá vỡ hành vi liên kết. Khi hệ thống bao gồm nhiều hệ thống con liên kết với nhau, các thay đổi hợp lý ở cấp độ cục bộ có thể làm hỏng các liên kết chưa được mô tả rõ ràng trong ngữ cảnh hiện tại.

Từ đây rút ra một kết luận tổng quát hơn về việc phát triển phần mềm với AI. Nếu agent bắt đầu liên tục sửa chữa hậu quả của những thay đổi trước đó của chính nó, việc tiếp tục chu kỳ đó sẽ nhanh chóng dẫn đến sự tích lũy mã nguồn, các giải pháp tạm thời và các phụ thuộc ẩn. Tại một thời điểm nào đó, vấn đề không còn nằm ở một lỗi cụ thể nào nữa, mà là sự mất đi một mô hình hệ thống đơn giản và có thể kiểm chứng. Nỗ lực giao cho agent việc tái cấu trúc sâu (deep refactoring) trong trạng thái này mang theo rủi ro làm gia tăng thêm độ phức tạp: nó có thể tối ưu hóa chính xác các khu vực riêng lẻ mà không hiểu rõ những thuộc tính nào của toàn bộ hệ thống cần phải được giữ nguyên không đổi.

Do đó, cần phải suy nghĩ lại về các giai đoạn phát triển. Có lẽ đối tượng kiểm soát chính nên chuyển từ việc triển khai bên trong sang hành vi bên ngoài của hệ thống: các yêu cầu, bất biến (invariants), kịch bản, bài kiểm tra (tests) và mối liên hệ giữa các hệ thống con. Nếu việc triển khai không còn thỏa mãn các yêu cầu này và agent không thể nhanh chóng đưa nó trở lại trạng thái chính xác, việc không tiếp tục vòng lặp sửa chữa (repair-loop) vô tận, mà thay vào đó là chốt lại hành vi mong muốn, đơn giản hóa mô hình và xây dựng lại mã nguồn từ đầu có thể sẽ có lợi hơn. Nói cách khác, trong quy trình này, mã nguồn nên được xem như một hiện vật có thể thay thế hơn là một tài sản cần phải bằng mọi giá bảo tồn và sửa chữa dần dần.

Thử nghiệm này rất hữu ích ở chỗ nó vạch ra giới hạn của việc tái cấu trúc bằng AI cục bộ: agent gặp khó khăn trong việc tự xác định đâu là điểm dừng của việc đơn giản hóa được phép và bắt đầu sự phá vỡ các liên kết hệ thống. Giai đoạn công việc tiếp theo nên được xây dựng dựa trên đặc tả hành vi rõ ràng hơn và ranh giới của các hệ thống con, chứ không phải dựa trên việc tiếp tục sửa chữa phần mã đã tích tụ.

Đây là những gì ChatGPT nói:

Có, việc ngắt yêu cầu trong trình duyệt có thể dẫn đến việc hủy quá trình tạo phản hồi ở phía nhà cung cấp — nếu backend của bạn liên kết hai kết nối này và truyền tín hiệu hủy đi. Nhưng việc Chrome hiện đại thiếu hỗ trợ phản hồi truyền trực tuyến (streaming) là nguyên nhân khó xảy ra: fetch() hỗ trợ đọc phản hồi thông qua ReadableStream. MDN

Ở đây cần phân tách hai phần: trình duyệt → máy chủ của bạn và máy chủ của bạn → nhà cung cấp. Nếu trình duyệt ngắt yêu cầu, máy chủ có thể hủy yêu cầu đến nhà cung cấp thông qua AbortController. Khi đó, trình xử lý lỗi thực sự có thể nhầm lẫn việc hủy này với việc «nhà cung cấp gián đoạn quá trình tạo». Bản thân thông báo lỗi chưa chứng minh được bên nào đã ngắt kết nối trước. Việc hủy thông qua AbortSignal có thể kết thúc yêu cầu HTTP với lỗi AbortError. Tài liệu Node.js v26.10.0

Bạn có thể kiểm tra tính có sẵn của API trực tiếp trong bảng điều khiển (console) của trình duyệt:

const supportsResponseStreaming =
  typeof fetch === 'function' &&
  typeof ReadableStream === 'function' &&
  typeof Response === 'function' &&
  'body' in Response.prototype &&
  typeof ReadableStream.prototype.getReader === 'function';

console.log({ supportsResponseStreaming });

Thao tác này kiểm tra tính hỗ trợ đọc phản hồi dạng stream. Không có hàm riêng biệt nào trong trình duyệt mang tên «hỗ trợ HTTP Streamable»; nếu chúng ta đang nói về yêu cầu JSON thông thường và phản hồi stream từ trợ lý ảo (agent), thì chính tính năng này là cần thiết. Việc gửi phần thân (body) yêu cầu theo dạng stream là một tính năng khác, với các giới hạn riêng của nó. MDN

Nhưng giá trị true không đảm bảo rằng stream hoạt động bình thường qua toàn bộ chuỗi. Để làm điều này, bạn cần một endpoint kiểm thử trên máy chủ của mình, ví dụ gửi năm thông điệp với khoảng cách một giây mỗi thông điệp, và kiểm tra trong trình duyệt:

async function testStream(url) {
  const started = performance.now();
  const response = await fetch(url, { cache: 'no-store' });

  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  if (!response.body) throw new Error('Không có phần thân phản hồi');

  const reader = response.body.getReader();

  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;

      console.log({
        elapsedMs: Math.round(performance.now() - started),
        bytes: value.byteLength,
      });
    }
    console.log('Stream đã hoàn tất');
  } catch (error) {
    console.error('Lỗi khi đọc stream:', error);
  } finally {
    reader.releaseLock();
  }
}

testStream('/api/stream-test');

Địa chỉ ở đây chỉ mang tính ước lệ — bạn cần triển khai endpoint đó. Việc đọc qua getReader() cho phép theo dõi quá trình tiếp nhận các phần phản hồi. Ranh giới của các phần mạng không nhất thiết phải trùng khớp với ranh giới thông điệp của máy chủ. MDN

Diễn giải:

  • Các phần đến dần dần — stream đang hoạt động.
  • Mọi thứ đến trong một cục ở cuối — đâu đó đang có bộ đệm (buffering).
  • Việc đọc gặp lỗi và dừng lại — kết nối hoặc quá trình xử lý stream bị gián đoạn; nguyên nhân cần được đối chiếu với nhật ký (log) của máy chủ.

Đối với trường hợp của bạn, bài kiểm tra quyết định chính là thứ tự sự kiện trong log của một yêu cầu duy nhất: ngắt kết nối từ phía client, gọi lệnh hủy yêu cầu tới nhà cung cấp, lỗi đọc phản hồi từ nhà cung cấp. Nếu client ngắt kết nối trước, sau đó mã của bạn mới hủy quá trình tạo, thì giả thuyết này được xác nhận. Nếu stream từ nhà cung cấp bị hỏng trước — nguyên nhân nằm ở một bộ phận khác.

Sự khác biệt giữa «máy tính xách tay / thiết bị di động» bản thân nó chỉ cho thấy sự khác biệt về điều kiện: mạng, VPN, tiện ích mở rộng (extension), phiên bản frontend hoặc logic hủy yêu cầu của nó. Không thể chọn ra một nguyên nhân cụ thể chỉ dựa vào dấu hiệu này.

Mô hình sự kiện tối thiểu của agent và LLM

Đã triển khai lớp phản ứng cơ bản của agent, phù hợp làm khối xây dựng cho runtime trong tương lai:

  • lớp Agent và endpoint POST /api/agent;
  • chuỗi cơ bản message.received → Agent.react → message.publish;
  • liên kết hành động với sự kiện nguồn thông qua stimulusId và actionId riêng;
  • JSON/NDJSON và cơ chế hủy chung;
  • Agent.react hiện gọi runChat/LLM thực tế thay vì bản giả lập (mock);
  • đã vượt qua lại 2/2 bài kiểm tra agent về các đoạn/tính danh tính của action, việc hủy và lỗi nhà cung cấp.

Việc triển khai hiện tại xử lý một loại sự kiện đến và kênh chat; mô hình chỉ nhận tin nhắn hiện tại. Hiện tại chưa có bộ nhớ hội thoại, tích lũy nhiều sự kiện, khử trùng lặp (deduplication), hệ thống ra quyết định chung và máy chuyển đổi trạng thái theo kịch bản.

Nền tảng runtime: thực thi dạng stream và hủy bỏ

Đối với runtime hội thoại tùy chỉnh trong tương lai, cơ chế thực thi cấp độ thấp đã được triển khai:

  • ExecutionContext chung với định danh chạy, tín hiệu hủy (abort signal) và phân phối sự kiện;
  • Hợp đồng NDJSON dạng stream POST /api/chat;
  • Các trạng thái chính xác started/delta/done/error/cancelled;
  • Hủy bỏ thực thi rõ ràng và hủy bỏ khi ngắt kết nối/quá thời gian/tắt hệ thống (disconnect/timeout/shutdown);
  • Tính độc lập của các tiến trình chạy song song;
  • Giới hạn đầu vào và kích thước phản hồi.

Lớp HTTP đã được kiểm tra lại bằng 8/8 bài kiểm tra.

Điều này không có nghĩa là công cụ kịch bản đã sẵn sàng: mô hình kịch bản khai báo, các nút/nhánh, phiên bản kịch bản, trạng thái hội thoại bền vững (persistent), tính bất biến (idempotency) của tin nhắn và các chuyển đổi nguyên tử vẫn chưa được triển khai.

Tích hợp trang web hiện có với trung tâm tác nhân mới

Đã triển khai khả năng tương thích với giao diện chat cũ của dự án lân cận agent:

  • thông qua CHAT_AGENT_URL, chat có thể được định tuyến đến tác nhân mới và nếu không được cấu hình, đường dẫn trước đó tới n8n sẽ được giữ nguyên;
  • bộ điều hợp chuyển đổi các tin nhắn của client cũ thành các sự kiện của tác nhân mới;
  • các phản hồi started/delta/done được chuyển đổi ngược lại thành định dạng cũ begin/item/end;
  • đã xử lý các phân mảnh UTF-8/JSON bị cắt đứt, lỗi, luồng chưa hoàn thành, client phản hồi chậm và ngắt kết nối người tiêu dùng;
  • các thay đổi liên quan: be06299, 4fe6d85, c2a8ded.

Đã chạy lại thành công 3/3 bài kiểm tra cục bộ của bộ điều hợp.

Hạn chế ở trạng thái hiện tại: đây là tích hợp thử nghiệm thông qua giao diện cũ chứ không phải tiện ích nhúng mới độc lập. sessionId, token người dùng và địa chỉ trang chưa được truyền cho tác nhân mới; chưa có bộ nhớ/bức tranh ngữ cảnh của khách truy cập. Trang web cũ trên cổng 3000 chưa được chạy trong lần kiểm tra gần đây nhất, do đó việc kiểm tra end-to-end trực tiếp qua trang web đó chưa được thực hiện lại.

HTTP-chat và phản ứng sự kiện tối thiểu của agent

Đã triển khai các hợp đồng máy chủ (server contract) làm nền tảng cho dịch vụ hội thoại trung tâm:

  • POST /api/chat hỗ trợ JSON thông thường và NDJSON dạng stream;
  • ExecutionContext thống nhất chứa execution id, chế độ phản hồi, tín hiệu hủy (abort signal) và việc gửi sự kiện;
  • Hỗ trợ khởi động, các delta tuần tự, hoàn thành thành công, lỗi và hủy bỏ;
  • Có cơ chế hủy tường minh qua DELETE, hủy khi ngắt kết nối/quá thời gian/tắt hệ thống và tính độc lập của các tiến trình chạy song song;
  • Đã triển khai lớp Agent và POST /api/agent với chuỗi message.received → Agent.react → message.publish;
  • Các hành động được liên kết với kích thích (stimulus) thông qua stimulusId, các phân đoạn của cùng một phản hồi có chung actionId;
  • Phản hồi giả lập (mock) đã được thay thế bằng lệnh gọi thực tế tới runChat/LLM hiện có.

Kiểm tra lại từ đợt kiểm toán: HTTP-chat đạt 8/8 bài kiểm tra, phản ứng của agent đạt 2/2 bài kiểm tra.

Đây là nền tảng cho phần hội thoại, nhưng hiện tại vẫn chưa có bộ nhớ trò chuyện cố định, tính năng khử trùng lặp sự kiện và mô hình chung về trang web/khách truy cập/hội thoại.

Nền tảng máy chủ và LLM/API

Theo trạng thái thực tế của dự án, lớp máy chủ cơ bản của trung tâm tác nhân (agents center) đã được triển khai:

  • đã thêm các thao tác GraphQL llmChatCompletion, llmCompletion, llmImageGeneration, llmSpeechGeneration;
  • client LLM chung hỗ trợ Local và OpenRouter, các khóa (keys) được giữ lại trên máy chủ;
  • đã thêm ngữ cảnh thực thi chung và transport WebSocket của GraphQL;
  • các thao tác GraphQL LLM hiện được bảo vệ bằng ủy quyền (authorization) của người dùng đang hoạt động;
  • đã triển khai PostgreSQL/Prisma và lớp tài khoản phía máy chủ (User, Token, đăng ký, đăng nhập, hồ sơ, phiên làm việc, JWT + kiểm tra phiên đã lưu, bcrypt, thu hồi phiên);
  • đã thêm bootstrap cơ sở dữ liệu và khắc phục quá trình khởi chạy/build trên production.

Các commit liên quan đã được ghi nhận trong quá trình kiểm toán: d3bea97, ea2c78e, b8ce41b, bc95738.

Đã xác nhận lại cục bộ (locally): Các kiểm tra TypeScript thành công, sự tương ứng của cơ sở dữ liệu với hợp đồng Prisma thành công, kết nối với agents-center từ host và từ container thành công, máy chủ mới trên cổng 3001 phản hồi HTTP 200, qua proxy ở cổng 8080 cũng trả về HTTP 200.

Quan trọng: Lưu trữ cuộc trò chuyện liên tục và các thực thể đầy đủ của trang web/tác nhân/hội thoại/tin nhắn dưới dạng lớp sản phẩm vẫn chưa hoàn thành.

Tiến độ đến ngày 30/09/2026

Baseline về hiệu suất và chất lượng của trang web cũ đã được đo đạc và lưu lại.

Các chỉ số đo lường trong phòng thí nghiệm (lab metrics) cho trang chủ đã được ghi nhận:

  • Mobile Performance: 54 (giá trị trung vị của 3 lần chạy)
  • Desktop Performance: 67
  • Accessibility: 58 / 58
  • Best Practices: 73 / 77
  • SEO: 100 / 100
  • Mobile LCP: 26,17 giây (trung vị)
  • Desktop LCP: 4,56 giây
  • Dung lượng tài nguyên: khoảng 4,83–4,87 MB

Bốn báo cáo Lighthouse cũng đã được lưu lại. Đây là các phép đo trong phòng thí nghiệm, không phải số liệu thực tế từ người dùng (Core Web Vitals).

Trên hệ thống HAIH mới, tính năng prerender cũ từng làm chặn bản dựng production (production build) đã được khắc phục, đồng thời cơ chế request-time SSR fallback đã được triển khai. Tuy nhiên, việc tối ưu hóa hình ảnh, JS/CSS, bộ nhớ đệm (caching), khả năng tiếp cận (accessibility) và luồng production Traefik → Varnish → Node vẫn chưa được thực hiện, do đó các phép đo Lighthouse lại cho phiên bản mới vẫn chưa được ghi nhận.

Mốc kiểm tra tiếp theo là đo lường trang chủ mới và các trang thương mại quan trọng trong cùng điều kiện, sau đó tiến hành nâng cấp liên tục các chỉ số Performance/Accessibility/Best Practices đạt mức mục tiêu mà không làm ảnh hưởng xấu đến SEO.

Tiến độ tính đến 30/09/2026

Máy tính hiện tại đã được nghiên cứu và vấn đề đã được xác nhận bằng một kịch bản có thể tái tạo.

Trong phiên bản cơ sở (baseline), máy tính được thực hiện cho đến bước yêu cầu liên hệ cuối cùng: người dùng trả lời tám câu hỏi, nhưng giá cả hoặc kết quả hữu ích khác lại không được hiển thị trước khi nhập số điện thoại và email. Tức là, cơ chế khiến người dùng phải mất thời gian trước, và chỉ nhận được kết quả đã hứa để đổi lại thông tin liên hệ đã thực sự được xác nhận.

Đã lưu lại các tài liệu giao diện gốc trên desktop/mobile và kịch bản người dùng, do đó đã có cơ sở để so sánh phiên bản mới.

Việc làm lại chưa được triển khai. Giai đoạn tiếp theo là xác định tập hợp tối thiểu các thông số thực sự ảnh hưởng đến chi phí, rút ngắn kịch bản và hiển thị kết quả ước tính trước khi bắt buộc yêu cầu liên hệ, sau đó không chỉ đo lường số lượng khách hàng tiềm năng gửi đi (lead submitted), mà còn cả quá trình đi đến kết quả và tỷ lệ chuyển đổi tiếp theo.

Tiến độ đến ngày 30/09/2026

Phần chuẩn bị cho phân tích và kiểm soát chất lượng đã được bắt đầu.

Trong cơ sở đường cơ sở (baseline) của trang web cũ, các kịch bản trình duyệt, kiểm tra HTTP, robots/sitemap, bốn báo cáo Lighthouse, ảnh chụp tài nguyên vùng chứa (container) và tổng kiểm tra (checksums) của tài liệu đã được lưu trữ. Các vấn đề hiện tại cần được theo dõi như các lỗi hồi quy (regression) đã được ghi nhận.

Trên hệ thống cũ (legacy), phát hiện thấy hai kết nối Google Analytics cũ — đây là nguồn tiềm ẩn gây ra các sự kiện trùng lặp. Một phần của giao diện cũng phụ thuộc vào sự hiện diện của Yandex.Metrika.

Việc triển khai mới đã được bao phủ bởi các bài kiểm tra kỹ thuật: npm run types, npm run lint, npm run build, đọc tích hợp MySQL, 17 bài kiểm tra SSR/khả năng truy cập/ định tuyến, chuyển hướng trình duyệt qua URI cũ mà không gặp lỗi hydration.

Công việc còn lại: kiểm kê và chuyển đổi các mục tiêu/sự kiện phân tích thực tế, loại bỏ việc trùng lặp bộ đếm, xác định các sự kiện tạo khách hàng tiềm năng (lead generation), kiểm tra UTM/referrer, kiểm tra việc gửi biểu mẫu và khách hàng tiềm năng, và sau khi ra mắt, tiếp tục giám sát tỷ lệ chuyển đổi thực tế, lỗi 404/5xx và khả năng truy cập tìm kiếm.

Page 1 of 14