Bỏ qua đến nội dung
AI Portal Docs
Trên trang này Cái gì chạy ở đâu 1/14

Portal chạy ngay trong tài khoản AWS của khách hàng. Một stack Terragrunt trong kho hạ tầng của tài khoản đó mô tả bản triển khai, và chủ tài khoản là người áp dụng nó. Portal cung cấp ứng dụng và nêu rõ bản triển khai phải có gì; bản thân portal không cấp phát hạ tầng nào.

Quy tắc chính

  1. Một lối vào công khai. CloudFront phục vụ web app và chuyển tiếp /api cùng /idp; ngoài ra không gì truy cập được từ internet.
  2. Hai host. Một host không trạng thái trong nhóm tự co giãn chạy backend và môi trường chạy agent; một host dữ liệu chạy Postgres, Keycloak và LiteLLM.
  3. Không host nào có địa chỉ công khai. Người vận hành vào qua dịch vụ phiên của AWS, có để lại nhật ký kiểm tra.
  4. Mọi giá trị khởi động đều lấy từ kho bí mật của tài khoản. Thiếu một giá trị thì khởi động thất bại, không dùng giá trị mặc định.
  5. Ứng dụng không tự tạo schema cơ sở dữ liệu. Hạ tầng của tài khoản tạo chúng trước.

Cái gì chạy ở đâu

  1. Trình duyệt gọi CloudFront, địa chỉ internet duy nhất.
  2. Mặc định CloudFront phục vụ web app đã build từ một bucket riêng tư mà không gì khác đọc được.
  3. Yêu cầu dưới /api và /idp đi tới một bộ cân bằng tải.
  4. Bộ cân bằng tải gửi /api tới host không trạng thái và /idp tới host dữ liệu.
  5. Host không trạng thái trao đổi với host dữ liệu. Cả hai đọc cấu hình từ kho bí mật.
HostChạy gìVì sao ở đó
Host không trạng thái, trong nhóm tự co giãnBackend và môi trường chạy agentCả hai không giữ trạng thái: mất host chỉ tốn một lần khởi động lại
Host dữ liệuPostgres có extension pgvector, Keycloak và LiteLLMKeycloak và LiteLLM giữ trạng thái trong chính Postgres đó, và không cái nào tự chạy được hai bản

Host dữ liệu giữ dữ liệu trên một ổ EBS gắn kèm, nên dựng lại máy vẫn còn dữ liệu. Cache phiên là một dịch vụ được quản lý, truy cập qua TLS bằng token, vì không gì trong đó tồn tại lâu hơn một phiên.

Một lối vào

Một bản triển khai có một địa chỉ internet: mạng phân phối nội dung. API của portal cần đúng một origin đó. Backend giữ access token và chỉ trao cho trình duyệt cookie phiên; dùng hai hostname nghĩa là phải nới lỏng điều đó.

CloudFront chuyển tiếp /api nguyên vẹn, và backend gắn mọi route dưới tiền tố đó. Địa chỉ trình duyệt gọi cũng là địa chỉ ứng dụng trả lời, nên cả địa chỉ chuyển hướng đăng nhập mà realm Keycloak cho phép lẫn địa chỉ cấp tài khoản bạn đưa cho thư mục của mình đều không phải thêm lại tiền tố. Gói web gọi theo đường dẫn tương đối và không được gắn hostname lúc build.

Ứng dụng đăng nhập riêng cho từng người cũng đi qua lối vào này, dưới /api/mcp. Chuyến đồng ý (consent) hai chiều đó hoạt động ra sao có ở Ứng dụng và MCP gateway.

Bộ cân bằng tải

Bộ cân bằng tải có mặt vì vòng đời chứ không vì tải. CloudFront không đổi một origin trỏ vào một máy cụ thể khi đang phục vụ, nên khi đi qua bộ cân bằng tải, thay host chỉ là đăng ký một target mới.

Nó còn cho Keycloak một tiền tố riêng, /idp, bên cạnh /auth/login và /auth/callback của portal, để yêu cầu cho bên nào cũng chỉ tới đúng bên đó.

Đường dẫnĐi tới
Mặc địnhBucket web app riêng tư (do CloudFront phục vụ)
/apiHost không trạng thái
/idpHost dữ liệu (Keycloak)

Truy cập host

Không host nào truy cập được từ internet: không địa chỉ công khai, không key pair, không shell đang lắng nghe. Người vận hành vào qua dịch vụ phiên của AWS (Systems Manager Session Manager), có để lại nhật ký kiểm tra.

Danh sách kiểm tra sẵn sàng

  1. Cung cấp mạng

    Stack không tạo mạng. Tài khoản đã có sẵn mạng, với địa chỉ và định tuyến do người khác chịu trách nhiệm, và stack đọc các định danh của mạng như được cho sẵn.

  2. Tạo các schema cơ sở dữ liệu

    Ứng dụng không tạo schema nào. Datasource liệt kê các schema nó được chạm tới và sẽ lỗi nếu thiếu một schema, nên hạ tầng của tài khoản phải tạo chúng trước lần áp dụng schema đầu tiên:

    agent, application, asset, chat, directory, gateway, governance, retrieval, tool, usage, visibility — cùng pgboss, nơi hàng đợi tác vụ tự dựng bảng của nó.

  3. Đưa cấu hình vào kho bí mật

    Mọi giá trị một host cần lúc khởi động đều lấy từ kho bí mật của tài khoản, đọc khi khởi động. Bản mô tả hạ tầng chỉ cấp quyền đọc các bí mật đó và không nói gì về nội dung, nên không giá trị nào bị commit hay lọt vào trạng thái hạ tầng. Thiếu một giá trị thì khởi động thất bại.

  4. Dựng lối vào và bộ cân bằng tải

    CloudFront với bucket riêng tư làm origin mặc định, chuyển tiếp /api và /idp tới bộ cân bằng tải, nơi định tuyến chúng tới hai host như bảng trên.

  5. Cấp quyền Bedrock cho backend

    Role gắn với backend cần quyền đọc danh mục, đọc tính khả dụng và gọi mô hình. Chính sách nằm ở Danh mục mô hình.

  6. Chuẩn bị host

    Bước bootstrap chuẩn bị host, cài container runtime và dạy host cách lấy cấu hình, rồi dừng. Nó không khởi động ứng dụng.

  7. Triển khai một phiên bản

    Triển khai một phiên bản là việc riêng, tách khỏi chuẩn bị host, nên một host khoẻ mạnh không bao giờ bị triển khai dở dang. Image của agent mang sẵn các skill dựng sẵn (builtin), và mọi môi trường chạy nạp chúng khi khởi động.

Thương hiệu

Tổ chức hiển thị nhãn hiệu của chính mình thay vì của sản phẩm. Org Owner tải lên một logo, một logo cho giao diện tối và một biểu tượng vuông trong Admin console (bảng điều khiển quản trị) › Organisation — xem Tổ chức.

  • Các nhãn hiệu được lưu thành tệp của tổ chức trong kho đối tượng và phục vụ qua một route công khai.
  • Màn hình đăng nhập chỉ hiện chúng khi tổ chức bật tuỳ chọn đó.
  • Tổ chức không tải lên gì sẽ hiện nhãn hiệu của sản phẩm, được biên dịch sẵn vào gói web và theme đăng nhập của Keycloak.
  • Không gì về thương hiệu được chọn lúc build, nên nhãn hiệu mới chỉ là một lần tải lên, không phải build lại.

Hiển thị artifact

Agent tạo tài liệu Office, PDF và trang web. Image backend mang những gì cần để hiển thị chúng chính xác.

Được càiVì sao
LibreOffice Writer, Calc và ImpressChuyển tài liệu Office sang PDF
ChromiumTrình kiểm tra HTML và bộ đo bố cục
Font Liberation 2Bắt buộc cho tiếng Việt. Gói fonts-liberation cũ thiếu các glyph này và có thể đặt sai vị trí dấu khi LibreOffice đổi font giữa một dòng
DejaVuKý hiệu như dấu tích
SymbolaCác hình biểu tượng mà báo cáo dùng làm gạch đầu dòng
Carlito, Caladea, NotoThêm font chữ cho tài liệu được chuyển đổi

Không cài font emoji màu. Noto Color Emoji là font bitmap mà trình dựng PDF không dựng lại được, và fontconfig ưu tiên nó hơn các font nét viền, nên thêm nó vào sẽ làm trắng các ký hiệu đang hiển thị được. Vì vậy một hình biểu tượng lên trang dưới dạng nét viền đơn sắc — một hình tròn đỏ, một vàng hổ phách và một xanh lá sẽ ra ba vòng tròn gần như giống hệt nhau.

Hiển thị tài liệu cho người đọc

  1. Tệp Office được LibreOffice chuyển sang PDF — một lần, với profile tạm mới, macro bị tắt và môi trường tiến trình con sạch.
  2. PDF được gửi nguyên vẹn.
  3. Trình duyệt tự vẽ các trang bằng pdf.js, nên máy chủ không raster hoá gì cho người đang đọc.

Bản build frontend sao chép font, bảng ký tự, profile màu và dữ liệu wasm của pdf.js cạnh ứng dụng; trình duyệt chỉ tải chúng cho trang cần đến.

Hiển thị trang cho agent

Điểm ảnh chỉ dành cho một người đọc thực sự cần: agent nhìn một trang trước khi lưu tệp. Trang đó bị giới hạn theo cạnh dài nhất — kích thước mà mô hình tính phí — và khai báo định dạng mã hoá của nó: trang của tài liệu đã chuyển đổi ra từ poppler dưới dạng JPEG, khung trình duyệt dưới dạng PNG.

Trình duyệt được gia cố

Chromium phục vụ trình kiểm tra HTML và bộ đo bố cục qua một lần khởi chạy đã gia cố:

  • không có phiên portal, không có mạng bên ngoài;
  • không service worker, không WebSocket, không tải xuống;
  • khung được sandbox.

Trình duyệt mở sẵn giữa các lần gọi, vì khởi động nó tốn hơn dựng trang trong nó, và tự đóng sau một phút không có gì để vẽ. Cô lập theo từng lần gọi: mỗi lần kiểm tra mở context riêng, và hai độ rộng dùng để duyệt một ứng dụng được tải cùng lúc trong context đó. Lỗi runtime và lỗi console của trang được thu trong context, vì một listener gắn sau khi nội dung tải xong đã bỏ lỡ script lỗi ngay lúc phân tích.

Giới hạn an toàn

  • Bước kiểm tra đọc hợp các bộ ký tự của font đã cài một lần cho mỗi tiến trình và báo mọi ký tự nằm ngoài, vì ký tự đó sẽ lên trang thành một ô trống.
  • Cache chỉ giữ byte bất biến; mỗi yêu cầu kiểm tra lại quyền truy cập tệp trước khi dùng kết quả đã cache.
  • Hàng đợi chuyển đổi, số worker dựng trang và thời gian chờ của tiến trình giới hạn phần việc native.
  • Trang dài hơn chiều cao ảnh chụp sẽ báo rõ phần chưa được chụp.

Vì sao hoạt động như vậy

Vì sao Keycloak và LiteLLM không nằm trong nhóm tự co giãn?

Không cái nào tự chạy được hai bản. Keycloak cần một cụm cache giữa các bản sao, còn LiteLLM là nơi duy nhất áp dụng ngân sách. Vì vậy chúng ở host dữ liệu, cạnh Postgres nơi chúng giữ trạng thái.

Vì sao Postgres chạy trên host thay vì dịch vụ được quản lý?

Để extension vector nằm cạnh mọi bảng khác. Tri thức, bộ nhớ và dữ liệu riêng của portal nằm chung một cơ sở dữ liệu.

Bên dưới

Vì sao nạp pdf.js từ bản build legacy

Bản build hiện tại của pdf.js lấy dấu vân tay tài liệu bằng Uint8Array.prototype.toHex, có từ Chrome 140, Firefox 133 và Safari 18.2. Trình duyệt cũ hơn trả lời mọi tài liệu bằng n.toHex is not a function và không vẽ gì. Không có gì bảo đảm máy của khách hàng mới hơn mức đó, nên portal nạp bản legacy có kèm polyfill. Bản này nặng hơn khoảng 60KB, trong một chunk chỉ tải khi ai đó mở tài liệu.

Skill dựng sẵn trong image agent

Các skill dựng sẵn được đóng vào image của agent và mọi môi trường chạy nạp chúng khi khởi động. Việc build và cập nhật chúng là việc kỹ thuật, làm bằng CLI harness của portal.

Liên quan

AI Portal Docs
EN VI