Kiểm tra backend đã hoạt động
Trang này được chính service phục vụ ở GET / — không phải một tệp tĩnh mở bằng file://, và đó là lý do mọi trạng thái bên dưới lấy được từ endpoint thật. Chạy bộ kiểm chứng runtime rồi dùng playground để đi thử luồng ngoài đời.
- Chủ tài liệu
- Lê Đức Anh (Alex Le) — Chief Technology Officer, InCard
- Loại tài liệu
- Bảng điều khiển runtime (trang kiểm chứng)
- Đối tượng đọc
- Dev · QA · Vận hành
- Phiên bản
- v1.0
- Cập nhật
- 2026-08-28
- Phân loại
- Nội bộ InCard — không phát hành ra ngoài
anh.le@incard.biz- Nạp một bộ tri thức thật19 tài liệu → kho tri thức, một lần bấm, qua đúng đường khách hàng dùng
- Xem nó đang BIẾT gìbản đồ tri thức — chứng minh dữ liệu đã vào, không phải model tự biết
- Hỏi một câu khách hay hỏitrả lời đúng, kèm trích dẫn trỏ về tài liệu đã nạp
- Hỏi một câu nó PHẢI TỪ CHỐI“giữ phòng và giảm 20%” → nó từ chối. Đây là chỗ thuyết phục nhất
- Gắn một năng lựcchatbot thành agent — mở thêm việc mà KHÔNG sửa một dòng mã
- Điểm sẵn sàngmột con số đọc được, không cần thuật ngữ nào
DEMO 111/09 · D1 — «Trợ lý Chat trọn vẹn», đi hết A→Z ở một chỗ
Cần trước: đăng nhập role=admin · Đây là khu vực duy nhất cần mở trong buổi hôm nay. Năm bước dưới đây là năm bước mà lộ trình khai cho mốc 11/9 — không phải một danh sách mới. Mỗi bước có: làm gì · bằng chứng phải thấy · nút nhảy tới màn thao tác.
Khán giả hôm nay: BLĐ · PM · Sales. Mốc kế tiếp 18/9 (D2) thêm thoại và hình — không trình bày hôm nay, và hai mục đó đã được đẩy xuống sau khu vực này.
Một workspace có nhiều trợ lý thì «đã xong mấy bước» là câu hỏi về một trợ lý cụ thể. Bản trước lấy trợ lý ĐẦU danh sách — tức phụ thuộc thứ tự nạp thư mục, và không gì trên màn hình nói con số đang thuộc về ai.
Vì sao gói vào MỘT khu vực thay vì để người trình bày tự cuộn
Trước khu này, năm bước của mốc 11/9 nằm ở vị trí 6 · 12 · 17 · 18 · 21 trong một trang 31 mục — và hai mục thuộc mốc D2/D3 (voice, eyes) chen vào giữa bước ③ và bước ④. Người trình bày phải cuộn qua hai màn ngoài phạm vi để đi từ «hỏi thử» sang «bàn giao», và khán giả đọc ra là hệ đang nhảy cóc.Khu này không sao chép một nút nào: mỗi bước chỉ nhảy tới đúng màn có thao tác thật. Sao chép nút sẽ tạo nguồn sự thật thứ hai, và bản sao sẽ lệch ngay lần sửa màn gốc kế tiếp — đúng kiểu hỏng mà
_w.js vừa gây ra ở chỗ khác.Con số ở mỗi bước là ĐO ĐƯỢC: chúng đọc
getSetupProgress, getAgentList, getChannelList và bảng câu vàng — không một ô nào tự khai.Đang có gì · thiếu gì · sắp có gì
Cần trước: — · Mở được ngay, không cần đăng nhập. Hai ô ĐO ĐƯỢC đọc /version và /readyz — hai đường công khai.
Màn hình đầu tiên của một buổi trình bày. Mỗi con số dưới đây nói ra nó từ đâu ra — ĐO ĐƯỢC nghĩa là trang này vừa gọi service thật; KHAI BÁO nghĩa là một người đã gõ nó vào bản kê. Hai loại đó không được cộng lại thành một phần trăm: gộp chúng là cách một hệ mới viết xong trông y hệt một hệ đã chạy sáu tháng.
Năm mốc kiểm chứng trước ngày phát hành 30/9
Một mốc không xong vì có người tích vào ô. Nó xong khi bằng chứng ở dòng cần xanh xanh — và bằng chứng đó bấm chạy được ngay tại bước 12.
Từng mảng đang tới đâu
Một khoảng trống là việc của AI?
Ba trạng thái, ba người khác nhau phải làm — và chúng không thay thế nhau. Gộp chúng lại là cách một tính năng chưa cấu hình trông y hệt một tính năng chưa xây.
Đang đo...
Đọc từ bản kê đối chiếu ở bước 15 — KHAI BÁO. Nó chấm mã, không chấm bản đang chạy; cột bên phải là tỉ lệ mục «đã có» trên tổng số mục của nhóm.
Chưa xong — nói thẳng
Một bản trình bày chỉ có màu xanh là một bản trình bày không ai kiểm được. Đây là những mục đang dở hoặc cố ý không làm.
Vì sao không có MỘT con số phần trăm duy nhất
Vì ba câu hỏi khác nhau: đã viết chưa (bản kê mã) · đang phục vụ chưa (/version khai khối nào bật, và vai trò tiến trình có nhận đường đó không) · đã chứng minh chưa (một lượt chạy thật có model + runId + usage trong trace). Một hệ có thể viết xong 100% mà phục vụ 0% — đo được 2026-08-30: bản 8 tiến trình bỏ lại 17/306 đường không ai phục vụ, không lỗi nào báo ra. Trộn ba con số thành một là xoá đúng khoảng cách mà cả bàn này tồn tại để chỉ ra.Bước 0Bắt đầu ở đây
Cần trước: đăng nhập role=admin · Bàn này có 30 mục. Bạn không cần đi hết — có ba đường, và mỗi lần bạn chỉ đi một đường.
Sáu ô dưới đây đo từ kho thật, không đọc một cờ nào. Ô nào đỏ thì đó là việc tiếp theo — đi theo thứ tự, vì ô sau chỉ có nghĩa khi ô trước xanh.
Ba đường, chọn một
- Nạp một bộ demo~20 giây · có ngay một trợ lý trả lời được
- Khai khoá hệ thống của kháchOnePMS · PMS khác · CRM · webhook
- Khai khoá kênhtuỳ chọn · widget không cần bước này
- Bật chế độ trình bàyrồi vào «DEMO 1 · 11/09»
- Cho xem nó BIẾT gìbấm «Vẽ bộ não»
- Hỏi thử hai câumột câu trả lời được · một câu PHẢI từ chối
- Gắn/tháo một năng lựchệ chạy khác ngay, không deploy
- Sinh widget gửi kháchmỗi trợ lý một đoạn nhúng riêng
- Thang sáu bậc«trợ lý NÀY chạy được chưa»
- Chạy tập vàng«Kiểm thử ngay» · đọc câu nào trượt
- Bộ kiểm runtime«cả hệ còn đúng không»
Lần đầu: A1 → B2 → B3 là đủ để thấy nó hoạt động (khoảng 3 phút). Khoá OnePMS và khoá kênh chỉ cần khi muốn tra hệ thật hoặc mở kênh thật.
Bước 0Sơ đồ vận hành core — một trang cho dev, PM và BOD
Cần trước: — · Ba người đọc ba thứ khác nhau từ cùng một hệ. Màn này vẽ một sơ đồ và chú ba lớp đọc lên nó, thay vì ba bản vẽ sẽ lệch nhau sau lần sửa thứ nhất.
/version chứ không gõ tay. Một tính năng mới rơi vào đúng một ô — nếu không rơi vào ô nào thì nó chưa có chỗ, và đó là câu hỏi thiết kế, không phải câu hỏi lịch.Ba gói, ba nhịp phát hành khác nhau. Mũi tên phụ thuộc chỉ đi một chiều: kernel biết thư viện AI, thư viện AI không biết kernel tồn tại. Nhờ vậy bóc aiagent-ai đặt vào một sản phẩm khác không phải sửa một dòng nào của nó — và đó là phép thử, không phải một lời hứa.
Vì sao ba gói chứ không một
Nhịp đổi khác nhau ba bậc. Hợp đồng (aiagent-contract) gần như không đổi — đổi nó là đổi cho cả tám service. Nhân (aiagent-kernel) đổi theo tháng. Thư viện AI (aiagent-ai) đổi theo tuần, vì đó là chỗ nhà cung cấp model thay đổi. Gộp làm một thì mỗi lần thêm một nhà cung cấp là một lần phát hành lại toàn hệ — và đó đúng là thứ kiến trúc này tồn tại để tránh.Phép thử đọc được bằng máy:
aiagent-ai không import aiagent_kernel và không import service nào; có một bài kiểm canh đúng chiều import đó, nên lời hứa này không trôi được.Đây là đường nóng: mỗi tin nhắn của khách đi hết mười chặng này. Con số đáng nhớ cho BOD: đúng một lần gọi model cho một câu hỏi — định tuyến và chấm điểm đều tất định, không đốt thêm lượt nào.
| # | Chặng | Làm gì | Chặn được không |
|---|---|---|---|
| 1 | Vỏ & quyền | Kiểm header bắt buộc, xác thực, cắt theo vai trò tiến trình | Có — sai quyền thì đường không tồn tại |
| 2 | Che PII | Bóc số điện thoại, email khỏi câu hỏi trước khi nó đi tiếp | — |
| 3 | Dò tiêm lệnh | Câu hỏi chứa “bỏ qua hướng dẫn…” → đánh dấu, xử lý như dữ liệu | Đánh dấu, không chặn |
| 4 | Chốt cấu hình lượt | Chốt một lần: model · phiên bản prompt · thời điểm hiện tại theo múi giờ khách sạn | — |
| 5 | Ký ức ngắn hạn | Lấy vài lượt gần nhất, có trần ký tự — tất định, không gọi model | — |
| 6 | Truy hồi | Nhúng câu hỏi → tìm trong phạm vi dữ liệu của chính trợ lý đó | Không đủ bằng chứng → từ chối |
| 7 | Dựng prompt | thời điểm → bằng chứng → lịch sử → câu hỏi, cộng “cách trả lời” của bản khai | — |
| 8 | Hàng rào ngân sách | Trần bước · công cụ · token · tiền · hạn chót | Có — chạm trần thì dừng có lý do |
| 9 | Gọi model · 1 lần | Sinh câu trả lời từ bằng chứng đã có | — |
| 10 | Hậu kiểm | Chống lặp vô nghĩa · chấm bằng chứng · ghi trace · ghi cước | Có — lặp vô nghĩa thì bỏ câu trả lời |
Thao tác GHI sang hệ thứ ba (đặt phòng, hoàn tiền, đẩy đơn) không đi đường này. Nó đi qua graph nhiều node và dừng ở cổng người — máy đề nghị, người bấm duyệt.
Câu hỏi PM hỏi nhiều nhất: “thêm việc này mất bao lâu?” Câu trả lời phụ thuộc nấc nào, và nấc càng cao thì càng rẻ. Leo từ trên xuống, dừng ở nấc đầu tiên giải được.
| Nấc | Cách | Tốn gì | Ví dụ vừa làm |
|---|---|---|---|
| ① | Thêm tri thức — nạp tài liệu | Vài phút. Không deploy, không sửa mã | 6 mảnh “quanh resort”: điểm chơi · taxi · xe ôm · thuê xe · quán ăn · mùa |
| ② | Thêm kỹ năng — một thư mục SKILL.md | Thả thư mục, bấm tải lại. Không deploy | Kỹ năng của một ngành hoặc của riêng một khách |
| ③ | Thêm năng lực / công cụ — một tệp khai JSON | Sửa cấu hình. Không sửa mã | Gọi API kho của khách, tra internet |
| ④ | Sửa mã lõi | Phát hành lại toàn hệ | Chỉ khi ba nấc trên đều không diễn đạt được |
Vì sao thang này quan trọng với BOD: mỗi công cụ ở nấc ④ được gửi lên trong mọi lời gọi model, cho cả khách không bao giờ dùng nó — tức nó là một khoản thuế vĩnh viễn trên hoá đơn. Một kỹ năng ở nấc ② chỉ tốn một dòng. Chênh lệch đó là lý do thang tồn tại.
Thanh 0/4 ở đầu ứng dụng đọc kho thật, không đọc cờ đã lưu. Khách làm ba trong bốn việc mà không đi qua wizard — vào thẳng trang Giọng thương hiệu và tạo một cái — thì bước đó vẫn tính là xong. Đọc mỗi cờ thì thanh nhắc sẽ nói “chưa làm” trong khi màn hình ngay dưới đang liệt kê thứ vừa làm.
| # | Bước | Bằng chứng đếm | Đường API |
|---|---|---|---|
| 1 | Tạo brand voice | Có bản ghi giọng thương hiệu trong kho social | onboarding/submitBrandVoicesocial/createBrandVoice |
| 2 | Thiết lập Sales Chat Agent | Có một bản khai trợ lý trong agents/ | agent/createAgent |
| 3 | Kết nối tài khoản mạng xã hội | Có ít nhất một kênh đã nối | onboarding/getChannelStatussocial/bindChannel |
| 4 | Tạo AI Social Agent & bài đăng đầu | Có trợ lý social và một bài nháp | onboarding/provisionWorkspace |
Bước 3 bỏ qua được: nhánh skip chỉ dựng Chat Agent. Khách chưa có Page vẫn dùng được widget web ngay. Mở màn Hoàn tất thiết lập để điền cả bốn ở một chỗ thay vì đi bốn màn.
Bước 0Bàn điều khiển demo — đòn bẩy chỉnh tay khi đang trình bày
Cần trước: đăng nhập role=admin · Mở sẵn tab này trong lúc demo. Mọi thứ dưới đây đổi được lúc chạy, không khởi động lại máy chủ.
Cái làm gãy một buổi demo hiếm khi là lỗi mã — nó là một hàng rào làm đúng việc của nó vào đúng lúc không nên. Cổng eval chặn bật bot, §6 chặn một miền chưa đăng ký, một câu trả lời sai vì tài liệu thiếu một dòng. Ba thứ đó đều có đường đi vòng có ghi vết — dùng đường đó, đừng tắt hàng rào.
Ép bật KHÔNG tắt phép đo — nó ghi enabled_forced_at + lý do + người bấm vào cấu hình trợ lý. Một cổng không có đường đi vòng là một cổng sẽ bị gỡ; một đường đi vòng không để lại dấu vết là một cổng giả.
| Cách trả lời của một trợ lý | agent/updateAgent |
| Gắn/tháo năng lực | capability/attachCapability |
| Thêm tri thức ngay giữa buổi | profile/upsertProfile |
| Thêm câu mẫu | agent/addExampleList |
| Sửa prompt đường nóng | prompt/updatePrompt |
| Lùi prompt về bản trước | prompt/rollbackPrompt |
| Lùi bản khai trợ lý | agent/rollbackAgent |
| Mở một miền ra ngoài | connector/registerConnector |
| Hạ ngưỡng cổng bật | agent/setActivationThreshold |
| Nạp lại tri thức từ nguồn | onboarding/refreshKnowledge |
| Mở một ngành mới | thả thư mục vào AI_PACK_DIR → nạp lại |
PHẢI khởi động lại: đổi model/embedding, đổi AI_WEB_SEARCH_URL, đổi danh sách miền ở mức hệ thống. Nên chốt ba thứ đó trước khi vào phòng họp, không chỉnh giữa buổi.
Bước 0Hoàn tất thiết lập — điền vào đây, không phải đi năm màn
Cần trước: một trợ lý · Bảy mục của thanh nhắc, mục nào chưa xong thì mở sẵn một form ngay dưới. Xong mục nào thì nó tự gập lại.
Mỗi form gọi đúng một đường API chính chủ — không có đường tắt nào ở đây. Form nào khoá hiện tại không đủ quyền thì nó nói trước, thay vì để bạn điền xong rồi nhận 403 giữa buổi demo.
Đang đo...
Giọng này dùng cho bài đăng mạng xã hội, không phải cho câu trả lời chat. Nó quyết định AI viết bài nghe như ai.
Viết như dặn một nhân viên mới trong ngày đầu: xưng hô thế nào, cái gì được hứa, cái gì phải chuyển cho người. Đây là chỗ sửa cách trả lời — không phải chỗ dạy kiến thức (kiến thức nạp ở bước 3).
Một câu mẫu là một lời khẳng định về việc trợ lý phải làm được — nó vào bộ kiểm của trợ lý, không sửa prompt. Thêm cả câu trợ lý phải TỪ CHỐI: bộ kiểm chỉ có câu dễ là bộ kiểm luôn xanh.
Gắn một Page/OA vào một trợ lý. Cần mã Page (Facebook: Page ID; Zalo: OA ID) — lấy ở trang quản trị của nền tảng đó. Bí mật webhook khai riêng ở Mở đường ra ngoài.
Chọn kiểu và vị trí, rồi dán một dòng vào trước </body> của website. Không cần sửa gì thêm ở phía website.
Form ② và ③ đi qua HAI hàng rào khác nhau, và lẫn chúng là lý do phổ biến nhất khiến một admin bị từ chối:
- Vai — phải là
role=admin. Thiếu thì lỗi làPrivilegeNeed. Sửa bằng bảng bên dưới. - Chủ sở hữu — trợ lý phải thuộc tenant của bạn. Ba trợ lý ship sẵn không thuộc ai, nên không admin nào sửa được; lỗi là
AgentIsSharedTemplate, và cách sửa là nhân bản (nút hiện ngay trong form ②/③), không phải xin thêm quyền.
Cổng chặn ở API chứ không chỉ ẩn nút — nên tạo tài khoản thử ở đây rồi đăng nhập bằng nó mới là phép thử thật; đổi vai xong phải đăng nhập lại vì vai nằm trong token.
Chưa tải.
· Email chưa có →
auth/createUser, có đặt mật khẩu, và tài khoản đăng nhập được ngay. Bắt buộc điền, tối thiểu 8 ký tự.
· Email đã có →
staff/upsertStaff, sửa tên và vai. Đường này không chạm tới mật khẩu — điền vào ô cũng không đổi được gì, nên nó bị bỏ qua và trang sẽ nói rõ.
· Quên mật khẩu → bề mặt admin không có đường đặt lại hộ.
auth/changePassword là tự đổi (đòi mật khẩu hiện tại). Đặt lại hộ chỉ có ở bàn nền tảng: platformUser/resetPassword.
Bước 0Khoá LLM của workspace — dùng Claude/OpenAI của chính bạn
Cần trước: đăng nhập role=admin · Không có khoá thì trợ lý chạy bằng cấu hình của máy chủ — chạy được, nhưng chi phí và hạn mức là của chúng tôi, không phải của bạn. Khai ở đây là workspace này gọi bằng tài khoản của chính bạn, không sửa .env và không khởi động lại service.
.env, KHÔNG cần khởi động lạiKhoá lưu theo workspace, không theo máy. Có hiệu lực từ lượt chạy kế tiếp — không phải sau một lần restart. Chi phí và hạn mức tính về nhà cung cấp của chính bạn.
Khoá đi vào đây và không đi ra: mọi lần đọc lại chỉ trả set(***).
Vì sao Claude đi qua openai_compat chứ không phải một provider riêng
Slot model khai bốn provider: ollama · openai_compat · llamacpp · mock. Anthropic phát một đầu tương thích giao thức OpenAI tại https://api.anthropic.com/v1, nên Claude nối được mà không thêm một dòng mã nào — đổi bên là đổi base_url.Đó đúng là phép thử §4.6 của chuẩn: "nếu đổi model phải sửa code nghiệp vụ thì kiến trúc sai". Thêm một provider
anthropic riêng sẽ là thêm mã cho một thứ đã chạy được bằng cấu hình — và mã đó phải nuôi mãi.Giới hạn phải biết: đầu tương thích của Anthropic không phủ hết tính năng gốc (khối suy nghĩ, cache prompt theo phiên). Cần chúng thì lúc đó mới đáng bàn một provider riêng — không phải trước.
Bước 0Thiết lập ban đầu — 4 bước, chạy THẬT
Cần trước: đăng nhập role=admin · Đúng bốn bước của mockup, nhưng mỗi nút ở đây gọi API thật trên máy chủ này — không một con số nào dựng sẵn. Thanh x/4 đọc từ onboarding/getState, và mỗi bước tự đo bằng chứng thay vì đọc một cờ đã lưu.
Danh sách lấy từ onboarding/getIndustryPresetList — một bảng ở backend, không phải một bản chép trong giao diện. Ba khách hàng frontend giữ ba bản là ba con số lệch nhau.
Ba ô THAY THẾ lẫn nhau. Thiếu cả ba thì máy chủ trả OnboardingInputNeed — không phải ParameterError, vì câu «thiếu tham số» không nói được rằng ba ô này thay nhau.
Vì sao bước này đi qua HÀNG ĐỢI
Bò tới 5 trang web rồi gọi model một lượt vượt xa ngân sách của một request HTTP (ASYNC-01). submitInput đẩy việc vào queue.onboarding.analyzeInput rồi trả ngay analysis_id; màn này hỏi lại bằng getAnalysis.Cờ quá hạn do BACKEND tính, không do giao diện: trần 90 giây là lời hứa của backend, và ba khách hàng frontend giữ ba con số sẽ mở đường tự điền ở ba thời điểm khác nhau — không cái nào khớp thứ backend làm.
Worker phải CÓ MẶT:
AI_SERVICE_ROLE=all hoặc một tiến trình vai trò worker. Không có worker thì việc nằm trong hàng đợi và màn này quay mãi — nên ô bên cạnh đọc luôn trạng thái worker.Không có trích dẫn mà vẫn khẳng định là ảo giác (§1.1). Màn này hiện thẳng grounded và danh sách citations để bạn thấy nó dựa vào đâu — hoặc thấy nó KHÔNG dựa vào đâu.
Hai nhánh, không phải một nút có hộp chọn:
full dựng cả AI Social Agent và một bài nháp; skip chỉ dựng Chat Agent — dành cho
khách bỏ qua bước nối kênh. Gọi lại khi đã có thì không dựng con thứ hai: nó trả về đúng con đang có,
vì bấm hai lần do mạng chậm là chuyện xảy ra thật.
«Để sau» KHÁC «hoàn tất», và khác biệt đó nhìn thấy được: skipped vẫn giữ thanh nhắc, completed thì ẩn. Gộp hai trạng thái là mất đúng thông tin «khách đã bấm để sau».
Bước 3Nguồn dữ liệu (source plugin, §4.6.1)
Cần trước: — · Có dữ liệu thì trợ lý mới có gì để trả lời. Chưa nạp thì /readyz báo indexHasDocuments:false — đó là bình thường, không phải hỏng.
Nạp hồ sơ từ một sidecar bên ngoài (vd LinkedIn qua Apify) vào index — chỉ hoạt động khi server được bật với AI_SOURCE_PROVIDER=sidecar và AI_SOURCE_MANIFEST trỏ tới một plugin.json hợp lệ. Không bật thì nút bên dưới sẽ báo lỗi rõ ràng thay vì im lặng không làm gì.
Bước 4Bộ não trợ lý — nó đang biết gì
Cần trước: bước 3 · Xem nó biết gì trước khi trách nó trả lời sai.
Mạng lưới bên dưới là bộ nhớ nghiệp vụ của trợ lý: khái niệm nó thấy trong dữ liệu, hồ sơ đứng sau từng khái niệm, bài đã được dạy, câu học từ người soát, chỗ đang hỏng, và chủ đề khách hỏi lặp lại. Bấm vào một điểm để xem chi tiết — hồ sơ thì đọc được đúng đoạn tài liệu đã đưa vào prompt.
Bấm “Vẽ bộ não”, rồi bấm vào một điểm.
Bản đồ này KHÔNG phải neuron của model
Đếm từ chính mạng lưới ở trên, không phải từ phỏng đoán. Bấm một dòng để soi đúng vùng đó trên bản đồ.
Bấm “Vẽ bộ não” để đọc.
“Học được” ở đây không phải gradient của model — là chuỗi việc có dấu vết: một lượt vào hàng đợi soát, người soát duyệt hoặc loại, rồi câu đã duyệt thành một bài kiểm chạy mãi.
Bấm “Vẽ bộ não” để đọc.
Chu trình tri thức — kho có còn khớp nguồn không
Bộ não ở trên trả lời “nó đang biết gì”. Khối này trả lời câu đắt hơn: “thứ nó biết có còn đúng không”. Trước bản này, thiết lập ban đầu chạy đúng một lần — khách đổi bảng giá trên website thì kho vẫn giữ bảng giá cũ, và trợ lý báo giá cũ với giọng chắc chắn, có trích dẫn, grounded=true. Không phép kiểm nào đỏ, không dòng log nào bất thường. Nay nguồn được đọc lại theo nhịp, và trang đã biến mất khỏi website bị gỡ khỏi kho chứ không nằm lại để bị trích dẫn.
Chưa đọc.
“Làm mới ngay” đi qua hàng đợi, không chạy trong request: nó bò web rồi có thể gọi model — hai thứ ASYNC-01 cấm đặt trên đường nóng. Bấm xong thì đọc lại trạng thái.
Chưa đọc.
Chu trình không bao giờ đè giọng khách đã sửa tay. Khách bỏ nửa buổi chỉnh câu chữ, một tuần sau job nền trích lại từ website rồi ghi đè — không ai báo, họ chỉ thấy trợ lý bỗng nói khác đi. Nên kho tri thức tự cập nhật, còn giọng thì chỉ đề xuất và chờ người bấm.
Chi tiết kỹ thuật
Bốn đường:POST /aiagent-admin/onboarding/getKnowledgeCycle · refreshKnowledge · setKnowledgeCycle · applyBrandVoiceSuggestion. Nhịp mặc định 7 ngày, tự hẹn lượt kế tiếp bằng run_at của hàng đợi — không cron, nên nhịp tim nằm trong thứ đã có sẵn sổ lỗi và overdue(). Vân tay nội dung chạy TRƯỚC khi gọi model: nguồn không đổi thì dừng, không tốn token. Khách sửa liên tục thì gộp bằng cửa sổ 120 giây (khoá idempotency theo tenant + mốc đã làm tròn). Một lượt làm mất quá 50% số trang thì không gỡ và báo người — “toàn bộ nguồn vừa biến mất” gần như luôn là đọc hỏng, không phải khách xoá. Cần role=admin.Bước 5Kết nối ra ngoài
Cần trước: — · Chỉ cần khi trợ lý phải gọi ra ngoài. Mở ra: năng lực api.connector ở bước 7. Chưa có kết nối nào thì bước 6 sẽ chặn mẫu «Nối API bên thứ ba».
Phần khó của việc nối một hệ bên thứ ba chưa bao giờ là kỹ thuật — nó là bốn mươi lần gõ tay, mỗi lần một cơ hội sai một ký tự. Hai đường dưới đây đọc hộ bạn: địa chỉ đầy đủ, chỗ gắn khoá, đọc hay ghi, và tham số bắt buộc.
Thường kết thúc bằng /openapi.json, /swagger.json hoặc /v3/api-docs.
Máy chủ mở một trình duyệt thật, bạn lái nó ngay ở đây. Không cài gì, không mở terminal, không dán tệp. Bạn đăng nhập vào hệ của khách trên ảnh dưới rồi bấm qua đúng những màn cần nối — mỗi màn là một nhóm lời gọi được ghi lại. Xong thì bấm «Đọc lưu lượng».
Mật khẩu bạn gõ ở đây đi thẳng từ trình duyệt của bạn qua máy chủ vào trang khách, và KHÔNG được lưu lại ở đâu. Hệ không có kho mật khẩu hệ khách — nó chỉ chuyển tiếp một lần bấm phím.
Bản đồ trang — tên ref của từng phần tử
Bảo mật: hệ đọc tên header xác thực để biết khoá gắn vào đâu — giá trị bị xoá trước khi rời tiến trình. Ảnh chụp không bao giờ ghi xuống đĩa. Phiên tự đóng sau 20 phút không dùng, và mất khi service khởi động lại — một phiên quét LÀ một tab đang mở, không phải một bản ghi.
Cách này không cần bên cung cấp làm gì. Đo trên hai hệ thật — app.resident.vn (SPA React) và app.onepms.net (Flutter) — cả hai trả 200 kèm cùng một trang HTML cho mọi đường Swagger, và api.resident.vn trả 404 thành thật cho cả mười quy ước. Không có đặc tả nào để dán. Nhưng trình duyệt của bạn đã ghi lại mọi lời gọi mà ứng dụng của họ thực hiện.
- Mở hệ của bên cung cấp, đăng nhập bình thường.
- F12 → tab Network → tick Preserve log.
- Bấm đúng màn hình bạn cần nối. Chỉ những gì bạn bấm mới được ghi.
- Chuột phải → Save all as HAR with content, mở tệp, copy toàn bộ.
Cách nhanh hơn — để máy mở trình duyệt và ghi hộ
Bốn bước trên là phần TAY CHÂN, và nó lặp lại y hệt cho mỗi hệ cần nối. Có một lệnh làm đúng phần đó:node ops/quet-api-sau.mjs https://app.onepms.netNó mở một cửa sổ trình duyệt thật, bạn đăng nhập và bấm qua đúng những màn cần nối — mỗi màn là một nhóm lời gọi được ghi. Đóng cửa sổ thì tệp HAR ghi ra
data/har/, kèm bảng đếm host để bạn biết điền gì vào ô «Chỉ lấy host này».Nó KHÔNG tự đẩy lên. Tệp nằm trên máy bạn, bạn mở, bạn nhìn, rồi bạn dán vào ô dưới. Tự động hoá phần bấm chuột là tiết kiệm thời gian; tự động hoá phần quyết định là bỏ mất đúng cái hàng rào đang giữ token của bạn — và HAR thì chứa token.
Nó cũng không ghi thân phản hồi (
content: omit): thân của một hệ PMS chứa tên khách, số điện thoại, số phòng. Ghi chúng xuống một tệp trên máy dev là tạo một bản sao dữ liệu khách mà không ai khai và không ai xoá.Danh sách dựng từ chính tệp HAR của bạn, không phải một gợi ý. Đo được 2026-09-11: api.onepms.net không phân giải được (trả 000), còn ứng dụng thật gọi app.onepms.net. Một ô gợi ý sẵn tên host là một ô dẫn người ta lọc sạch mọi lời gọi rồi nhận về 0 đường — mà thông báo lại nói «không thấy đường nào», nghe như HAR sai.
Bảo mật: HAR có chứa token và cookie của bạn. Hệ chỉ đọc tên header xác thực để biết khoá gắn vào đâu — không đọc giá trị, không đọc cookie, không đọc nội dung request, và không lưu tệp này.
Khoá lưu trên máy chủ và không bao giờ gửi lại ra ngoài — xem lại chỉ thấy set(***). Trình duyệt của bạn không giữ nó.
Đây là nơi duy nhất một địa chỉ ra ngoài đi vào hệ thống. Người tạo trợ lý ở mục trên không bao giờ gõ một URL — họ chỉ chọn id trong danh sách này. Ranh giới đó là toàn bộ lý do mục này tồn tại: một ô văn bản nhận URL trong wizard là một cổng SSRF do người dùng điền, và họ trỏ sai không vì có ý xấu mà vì dán sai.
Khoá không bao giờ đọc lại được qua API — danh sách bên phải chỉ hiện set(***) hoặc unset, đúng hai trạng thái mà /version dùng cho mọi bí mật. Xoá một kết nối đang có trợ lý gắn vào sẽ bị chặn, và xoá là ghi một bản ghi vô hiệu hoá chứ không mất lịch sử.
Chưa tải.
Nối OnePMS — một lần khai, sáu đường tra
OnePMS xác thực bằng một header tính lại mỗi lời gọi: Authentication: CryptoJS.AES.encrypt("email:password", secretKey). CryptoJS sinh salt ngẫu nhiên nên chuỗi đó khác nhau ở từng lời gọi — một khoá tĩnh không diễn đạt được, nên sổ kết nối có thêm lược đồ xác thực cryptojs_aes. Khoá bạn khai ở đây không bao giờ đi ra: đường đọc trả set(***).
Đúng ba ô. Ô hotelID trước đây nằm ở đây đã được bỏ: không đường mã nào đọc nó — nó là một ô bắt người dùng đi tìm một giá trị mà hệ không dùng tới.
Ba ô này là ĐỦ — và hàng rào ra ngoài tự mở, không sửa .env
Ba tham số, đúng bằng hệ cũ.opKhoa() ghép email:mật khẩu thành authAccount và giữ secretKey riêng; cả sáu đường dùng chung đúng bộ ba đó. Đây là nghĩa của «một lần khai, sáu đường tra» — không phải sáu lần khai.Địa chỉ gốc — ĐÃ đối chứng bằng một lời gọi thật.
us-central1-neutron-pms.cloudfunctions.net lấy từ tài liệu «TÍCH HỢP ONEPMS API 3.4», và ngày 11/09 nó trả về {"result":"001","message":"Account authentication failed"} — JSON của OnePMS. Một tên hàm bịa ra ở cùng host trả về trang HTML 404 của Google. Hai thứ đó khác nhau, nên có một phép phân biệt chắc chắn: thân phản hồi có result ⇒ đã tới đúng ứng dụng, đường dẫn đúng, bất kể mã HTTP.OnePMS trả lỗi nghiệp vụ kèm HTTP 404 — không giống chuẩn của ta (API-06 trả 200 kèm
code), nhưng đó là thứ bên kia làm, và bộ chẩn đoán phải mô tả thế giới chứ không mong thế giới cư xử cho đúng. Đọc mã HTTP mà không đọc thân là cách chắc chắn để kết luận ngược hướng.Không phải
app.onepms.net (giao diện web Flutter, nói thẳng với Firestore project onepms---test) và không phải api.onepms.net (không phân giải). Ô địa chỉ vẫn sửa được — đổi môi trường không phải đổi mã.Hàng rào
Egress mặc định TỪ CHỐI, nhưng nó KHÔNG chỉ đọc biến môi trường. build_outbound() dựng allowlist bằng hợp của AI_WEB_SEARCH_ALLOWED_HOSTS với host của mọi kết nối đã đăng ký, và _rebuild_outbound() chạy lại ngay ở mỗi lần ghi sổ. Nên bấm «Đăng ký 6 đường» là đã mở hàng rào cho host trên — không sửa .env, không khởi động lại service.Việc đăng ký tự cấp quyền cho chính host của nó không nới hàng rào: đường ghi sổ là bề mặt của
role=admin, và §6 cấm URL đến từ NGƯỜI GỌI lúc chạy, không cấm đích mà quản trị viên đã khai có chủ ý.Vậy «ghi đủ 6 đường mà vẫn không gọi được» còn hai lớp nguyên nhân, và thứ tách chúng ra là THÂN phản hồi, không phải mã HTTP: có
result ⇒ đường đúng, xét tiếp result ("00" xong · "001" là khoá); không có result mà 404 ⇒ mới là chuyện đường dẫn. Bấm «Tra cơ sở» và đọc result — "00" là đúng khoá; 401 hoặc result khác là sai khoá, hoặc tài khoản chưa được OnePMS cấp quyền gọi API. Nút «Kiểm hàng rào» phân định đúng hai khả năng đó.| Danh sách cơ sở | api-fetchHotelList |
| Hạng phòng + giá niêm yết | api-getRoomTypes |
| Danh sách phòng theo tầng | api-getRooms |
| Bảng dịch vụ 5 nhóm | api-getServices |
| Phương thức thanh toán | api-getPaymentMethods |
| Phòng trống + giá theo ngày | api-checkAvailabilityAndRate |
Cả sáu đều CHỈ ĐỌC (writes=false) nên chúng chạy thẳng, không qua cổng người — một lượt đọc không để lại gì để hoàn tác.
Chưa có: đặt phòng · nhận phòng (check-in) · thêm thanh toán · huỷ đơn. Tài liệu được cấp (TÍCH HỢP ONEPMS API 3.4) chỉ tới trang 19 trong 59, và bốn API đó nằm ở phần còn thiếu. Đoán tham số của một API GHI vào hệ thật của khách là cách tạo đơn rác trong một hệ đang chạy — nên chúng bị để trống có chủ ý, không phải bỏ sót.
Chi tiết kỹ thuật
Bốn đường:getConnectorList · registerConnector · deleteConnector · testConnector, tất cả /aiagent-admin/connector/* và đòi role=admin. Mọi lời gọi ra ngoài đi qua Egress.check() — so trên host đã phân tích chứ không trên chuỗi thô, và mặc định TỪ CHỐI. Nút "Thử" gọi thật một lần ngay lúc đăng ký, khi còn có người nhìn màn hình: một đích sai chỉ lộ ra lúc có khách đang chờ trả lời là kiểu hỏng đắt nhất. Lý lẽ đầy đủ + miễn trừ §3.4 của vòng ReAct: docs/specs/react-web-augmented.md.Chiều ngược lại: để bên thứ ba GỌI VÀO
Hai chiều, hai cơ chế, đừng lẫn. Kết nối ở trên là trợ lý gọi ra — ta cầm khoá của họ. Đầu vào dưới đây là họ gọi vào — họ cầm bí mật của ta và ký từng lời gọi. Dùng khi CiHMS/CukCuk/Base muốn đẩy sự kiện sang (đơn mới · bill mới · trạng thái đổi) thay vì để ta hỏi liên tục.
Bí mật hiện đúng một lần, ngay sau khi cấp — cùng luật với khoá API. Hiện lại được về sau nghĩa là nó nằm trong lịch sử trình duyệt của mọi người từng mở màn này. Mất thì cấp lại; thao tác đó rẻ và để lại một dòng trong sổ.
Chưa tải.
Chi tiết kỹ thuật
Ba đường/aiagent-admin/hook/* — getHookList · registerHook · revokeHook. Bên kia POST tới /aiagent-internal/hook/receiveHook kèm hai header: AiAgent-Hook-Id và AiAgent-Signature: sha256=<hmac-sha256(bí mật, thân THÔ)>. Thân THÔ, không phải bản đã định dạng lại — chuẩn hoá JSON đổi thứ tự khoá và chữ ký sẽ không bao giờ khớp. Hook không tồn tại và hook ký sai trả cùng một câu: xác nhận sự tồn tại là đủ để dò danh sách id của người khác. Thu hồi ghi một dòng vô hiệu hoá, không xoá lịch sử.Chiều thứ ba: TA bắn sự kiện về hệ của khách
Khi có đơn mới · thanh toán thành công · bắt được khách tiềm năng, hệ tự POST sang CRM/ERP của bạn theo bản đồ trường bạn tự khai. Ta cầm bí mật và ký từng lời gọi để bên kia phân biệt được ta với người lạ biết URL của họ.
Dữ liệu cá nhân: mặc định KHÔNG gửi. Trường nào có nguồn trông như dữ liệu cá nhân (điện thoại · email · hộ chiếu · địa chỉ · ngày sinh) chỉ đi ra khi bạn khai tường minh. Không khai thì nó bị bỏ, và ô kết quả nói rõ đã bỏ trường nào — bạn thấy ngay lúc khai, không phải đợi tới lần bắn đầu tiên.
Trong ví dụ trên, tel sẽ bị bỏ vì nguồn $.phone là dữ liệu cá nhân mà không khai "pii": true; guestName thì đi qua vì đã khai. Bí mật ký hiện đúng một lần sau khi đăng ký.
Chưa tải.
Chi tiết kỹ thuật
Bốn đường/aiagent-admin/outHook/*. Gửi qua hàng đợi, không trên đường request — một CRM chậm không được làm chậm chính luồng trả lời khách. Thử lại lùi theo cấp số nhân có trần (5 lần); hết trần thì vào thư chết, đọc được ở bảng sự cố. Mọi đích đi qua Egress.check() — mặc định TỪ CHỐI, và kiểm lúc gửi chứ không lúc đăng ký, nên một đích bị thu quyền sau đó không được thừa hưởng quyền cũ. Nhật ký xuất ghi tên trường, không ghi giá trị (SEC-02).Bước 19Loại AI Agent — super admin khai
Cần trước: role=platform + quyền agentType.write · Mở ra: người dùng ở bước 6 chỉ việc chọn một loại đã khai — họ không bao giờ chọn năng lực trực tiếp.
Một loại là một bó năng lực: gắn một hoặc nhiều. Hai loại không được cùng bộ năng lực — chúng làm được đúng những việc như nhau, chỉ khác cái tên, và người tạo trợ lý sẽ chọn nhầm rồi đi tìm một khác biệt không tồn tại.
Chưa tải.
Chi tiết kỹ thuật
Bốn đường/aiagent-platform/capabilityPack/*, đòi role=platform và khoá quyền agentType.read/.write (ghi: chỉ Super Admin). Ở bề mặt platform chứ không admin là một quyết định phân quyền: "sản phẩm này cho phép dùng những loại trợ lý nào" là câu hỏi cấp nền tảng — một tenant admin tự khai được loại mới nghĩa là tự cấp cho mình quyền gọi ra ngoài. Khoá định danh của một loại là TẬP năng lực (frozenset), không phải id: [a,b] và [b,a] là cùng một agent. Loại ship sẵn thì đọc được, sửa không được — sửa qua API sẽ tạo bản ghi đè ở tầng dữ liệu mà make check không đối chiếu.Bước 6Tạo trợ lý của riêng bạn
Cần trước: bước 3 (và bước 5 nếu chọn mẫu ra ngoài) · Mẫu là một bó năng lực. Mẫu nào chưa dùng được sẽ hiện lý do ngay ở bước 1 của wizard.
Không cần biết lập trình. Trả lời 4 câu bên dưới là xong — phần kỹ thuật (phạm vi dữ liệu, quyền, ngân sách, bộ kiểm) do mẫu điền sẵn và vẫn phải qua đúng bộ kiểm của bản khai §11, giống như khi kỹ sư viết tay.
Bạn không gõ địa chỉ ở đây. Đích ra ngoài do admin đăng ký trước ở Kết nối ra ngoài; bên dưới bạn chỉ chọn dùng cái nào. Bỏ trống = dùng tất cả những cái đã đăng ký.
Mỗi ví dụ là một lời khẳng định: câu này trợ lý phải trả lời được, hoặc câu này phải nói không biết. Ví dụ loại thứ hai là thứ duy nhất bắt được một trợ lý bắt đầu bịa — mẫu đã điền sẵn một câu như vậy, bạn chỉ cần sửa cho sát việc của mình.
Chi tiết kỹ thuật
Nút này gọiPOST /agents. Nó sinh ra agents/<id>/agent.json + agents/<id>/eval/golden.jsonl từ chính các ví dụ bạn nhập, rồi nạp lại file đó bằng đúng load_declaration — bản khai không hợp lệ thì thư mục vừa tạo bị xoá, không để lại trợ lý nửa vời. Wizard KHÔNG mở egress_allowlist: một trợ lý tạo qua trang web không được phép gọi ra internet (CLAUDE.md §6) — muốn mở phải sửa file tay, có người đọc lại. Cần role=admin.Bước 7Năng lực — gắn plugin để AI gốc thành agent
Cần trước: bước 6 · Đây là chỗ chatbot thành agent: gắn năng lực → tools · graph · egress đều suy ra lại.
AI gốc là một chatbot bình thường: trả lời theo tài liệu đã nạp, không ra ngoài, không luồng nhiều bước. Gắn một năng lực vào là nó thành agent — và ranh giới đó là một phép tính, không một công tắc ai phải nhớ bật. Mỗi năng lực là một tệp capabilities/<id>.json: thêm một loại trợ lý mới không sửa một dòng mã nào.
Bản khai đến từ BỐN lớp, yếu → mạnh: builtin (ship kèm slot loop) → service (ship kèm repo) → pack — GÓI NGÀNH → tenant — riêng một khách. Hai lớp cuối là DỮ LIỆU: mở một lĩnh vực mới = thả một thư mục vào AI_PACK_DIR rồi bấm “Đọc lại thư mục khai báo” — không deploy, không khởi động lại. Trước đó, thêm một năng lực cho một ngành là sửa cây mã aiagent-ai và phát hành cho tất cả khách, tức mỗi khách mới trong một ngành mới là một thay đổi bán kính toàn hệ.
Id ở hai lớp dữ liệu bắt buộc mang tiền tố (<gói>. hoặc t.<khách>.), nên một khách không diễn đạt được việc ghi đè năng lực dùng chung — đó là hàng rào theo kiểu, không phải một phép kiểm có thể quên ở đường thứ hai. Mỗi bản khai còn mang version + vân tay nội dung: sửa does_not mà quên nâng số thì nhãn phiên bản im lặng nói dối, vân tay thì không.
Chưa tải.
ready=false kèm lý do và lệnh cài — một công tắc không biết mình có chạy được hay không là một công tắc sẽ bật rồi im lặng.
Gắn năng lực chưa đủ cho một năng lực phải gọi ra ngoài: nó còn cần đích. Wizard hỏi câu này lúc tạo; ở đây là chỗ đổi sau đó — nếu không thì gắn hotel.booking cho một trợ lý đã tạo là một việc không làm được trên bàn.
Bạn không gõ địa chỉ ở đây — đích do admin đăng ký ở Mở đường ra ngoài. egress_allowlist suy ra từ host của chính những đích này, nên không có ô nhập thứ hai để lệch. Bỏ chọn hết = thu hồi mọi đích.
Chạy tập vàng của trợ lý — ví dụ riêng của nó cộng ví dụ của từng năng lực vừa gắn (§10.2). Chấm tất định: câu phải trả lời đạt khi có bằng chứng, câu phải từ chối đạt khi không có. Tốn credit — mỗi câu là một lần gọi model thật.
Chi tiết kỹ thuật
Gắn năng lực là sửa bản khai, không phải bật một cờ:tools · egress_allowlist · connectors · graph đều SUY RA từ bản khai của các năng lực đã gắn, rồi bản khai mới đi qua đúng load_declaration như khi kỹ sư gõ tay. Hai năng lực đòi hai graph khác nhau thì bị chặn (CapabilityGraphConflict) chứ không tự chọn một cái — tự chọn nghĩa là luồng thật của trợ lý phụ thuộc thứ tự chữ cái của id.Bước 8Dạy trợ lý
Cần trước: bước 6 · Dạy bằng ví dụ, sửa cách trả lời, thử ngay. Mỗi lần sửa là một phiên bản mới — lùi lại được.
Sửa cách trả lời, thêm ví dụ, thử ngay, và lùi lại bản cũ nếu bản mới tệ hơn. Mỗi lần sửa là một phiên bản mới — không có bản sửa nào đè mất bản trước.
Bước 0Vì sao trợ lý trả lời như vậy — truy tới tận nguồn
Cần trước: một lượt chạy đã có run_id · Dán run_id vào đây để thấy: nó đọc tài liệu nào, chạy bằng bản khai prompt nào, gọi model nào, và — thứ không màn nào khác trả lời được — tài liệu đó có bị sửa SAU khi trả lời không.
Ba trạng thái của một căn cứ, và vì sao phải tách «chưa đo»
khớp — vân tay nội dung y nguyên, căn cứ còn đứng vững.đã đổi — nội dung bị sửa SAU khi trả lời. Câu trả lời có thể vẫn đúng, nhưng không còn được chứng minh bằng tài liệu này.
mất — tài liệu không còn; trích dẫn trỏ vào hư không.
chưa đo — lượt chạy ghi trước khi hệ lưu vân tay. Nó không được hiển thị thành «khớp»: «chưa đo» và «đã đo và khớp» là hai điều khác nhau, và gộp chúng là biến một khoảng trống dữ liệu thành một lời bảo đảm — rồi lời bảo đảm đó sẽ được dùng để kết luận về một tranh chấp thật.
Vân tay bỏ qua thay đổi khoảng trắng: một cảnh báo kêu lên ở mọi thay đổi vô nghĩa là một cảnh báo không ai còn đọc.
Bước 12Duyệt hành động chờ người — ca trực, không phải màn giám sát
Cần trước: bước 7 (một năng lực có công cụ GHI) · Đây nằm trên đường đi của một lượt chạy thật: công cụ GHI dừng ở đây và không đi tiếp cho tới khi có người bấm.
Trợ lý được phép đề nghị ghi sang hệ của bạn — tạo đơn, phát mã thanh toán — nhưng nó không được tự làm. Mỗi đề nghị dừng ở đây, kèm đúng những tham số sẽ được gửi đi. Không có màn này thì năng lực booking.create và payment.qr gắn vào rồi treo vĩnh viễn, và triệu chứng bạn thấy chỉ là «trợ lý không làm gì».
Chưa tải.
Hết hạn thì lượt chạy TỪ CHỐI, không mặc định cho qua. Đồng hồ đếm ngược ở mỗi thẻ là thời gian còn lại trước khi điều đó xảy ra.
Chi tiết kỹ thuật
Bốn đường/aiagent-admin/graph/*: getPendingList · decideRun · expireRun · getRunHistory. Quyền chặn ở API, không chỉ ẩn nút: bản khai graph nói approvers: ["admin","platform"], nên một khoá role=staff gọi decideRun nhận 403 dù trang này có hiện nút. Tham số hiện trên thẻ là tham số ĐÃ KIỂM (đúng kiểu, đúng miền giá trị), không phải thứ model vừa sinh — được dựng ở node planner chứ không ở action_gate, vì engine park một node hitl trước khi handler của nó chạy, nên nếu dựng ở action_gate thì lúc dừng lại chờ bạn sẽ chưa có gì để trình ra. Sau khi bạn bấm duyệt, action_gate kiểm lại — hai lần kiểm không trùng lặp: cái đầu quyết định bạn thấy gì, cái sau quyết định có gọi ra ngoài không.Bước 13Trợ lý đã chạy được chưa — thang sáu bậc
Cần trước: bước 6 (đã có trợ lý) · Khác bước 13 ở ĐỐI TƯỢNG: bước 13 hỏi «cả hệ còn đúng hợp đồng không», bước này hỏi «trợ lý NÀY đã chạy được chưa» và đi từ hạ tầng lên tới kênh thật. Bậc trên chỉ có nghĩa khi bậc dưới xanh — có bậc đỏ thì sửa bậc THẤP NHẤT trước.
Bốn cái bẫy thang này được dựng lên để tránh, cả bốn đã sập một lần trong lúc xây nó: degraded rỗng KHÔNG phải bằng chứng LLM chạy được — bằng chứng là một lượt chạy có model và runId; nội dung nằm trong data và khoá là camelCase, đọc ở gốc cho ra rỗng rồi báo đỏ trong khi hệ khoẻ; một câu trả lời RỖNG nghĩa là lời gọi hỏng, KHÔNG phải «agent đang hứa» — một phép kiểm buộc tội sai thì lần sau không ai tin nó; và bậc 12 này chỉ xét các mục THUỘC BẢN KHAI, mục «đã nối kênh» để bậc 9 xét, nếu không thì bậc thấp phụ thuộc bậc cao.
Bước 10Nói chuyện với agent
Cần trước: engine STT/TTS · Kênh tiếng. Thiếu engine thì mục này nói thiếu gì và cài bằng lệnh nào.
Bấm “Bắt đầu”, rồi cứ nói bình thường.
Trình duyệt sẽ xin quyền dùng microphone.
Chi tiết kỹ thuật
Đường đi: microphone → PCM16 → WebSocket
/voice/stream → VAD → STT → agent → TTS, không dùng nhận dạng giọng nói của trình duyệt hay dịch vụ nào ngoài máy này.Khi agent nghe sai: micro nên là 16000 Hz và mức to nhất trên −25 dBFS. Agent nghe thành chữ gì thì đọc
transcript_final trong trace của từng lượt.Voice chạy trên macOS, Linux và Windows. Cái khó không phải là bật lên, mà là "máy của tôi thiếu gì và cài bằng lệnh nào" — bấm nút dưới đây là trả lời được, kèm đúng lệnh cho hệ điều hành đang chạy.
Chưa kiểm tra.
Khung thoại phía trên chạy cả chuỗi nghe → hiểu → trả lời → đọc. Khi kết quả tệ, chuỗi đó có bốn chỗ hỏng được và nó không nói chỗ nào. Hai phép thử dưới đây cắt hai đầu ra để đo riêng.
Thu một câu ngắn — nên đọc một tên riêng và một con số (vd «Đặt phòng deluxe cho chị Lan, số 0901234567»). Đó là hai thứ engine nghe sai nhiều nhất, và cũng là hai thứ nghiệp vụ cần đúng nhất.
Không phép kiểm tự động nào chấm được «nghe có tự nhiên không» — tai bạn chấm. Thử một câu có dấu hỏi và một con số: hai chỗ giọng máy lộ ra rõ nhất.
Ngôn ngữ tự nhận từ chính đoạn chữ — không có ô chọn, vì một ô chọn là một ô sẽ bị để nguyên mặc định. Thử dán một câu tiếng Anh vào đây rồi bấm đọc: nhãn ngôn ngữ phải đổi theo.
Hai đường này không gọi model và không ghi vào bộ nhớ hội thoại — một phép đo phải đo đúng một thứ. Đo xong hai cái này rồi mới bấm «Bắt đầu» ở khung thoại: lúc đó nếu còn sai thì cái sai nằm ở hiểu hoặc trả lời, và đã loại được hai nghi phạm.
- Bấm Bắt đầu — micro mở và giữ mở.
- Nói. Ngừng khoảng nửa giây là agent hiểu bạn đã nói xong.
- Agent trả lời ra loa, rồi tự nghe tiếp — không phải bấm gì.
- Nói câu tiếp theo. Cứ thế tới khi bấm Kết thúc.
Nghe không rõ thì agent hỏi lại, tối đa 2 lần, rồi chuyển sang người thật thay vì đoán bừa. Nói “xin chào” thì nó chào lại và hỏi bạn cần tìm ai. Nói “tạm biệt” hoặc “cảm ơn nhé” là nó kết thúc phiên.
Bước 11Mắt — đọc chữ trong ảnh, nhận vật thể, camera realtime
Cần trước: engine OCR/vision · Kênh hình. Khung camera trả nhãn thô; bấm Hỏi mới chạy graph đầy đủ.
Ba năng lực (vision.ocr · vision.detect · vision.realtime) dùng chung hai engine ở slot session — cùng chỗ với tai (STT/TTS), vì cùng loại: engine tri giác của một phiên.
Khung hình đi lên liên tục và trả nhãn thô — nhanh, không graph. Bấm Hỏi mới chạy graph đầy đủ một lần trên khung mới nhất, có bước evaluator chấm. Hai nhịp khác nhau nên là hai đường: chạy graph cho mỗi khung là 2 lần gọi model × 2 khung/giây, và câu trả lời có căn cứ sẽ đến sau khi camera đã quay sang chỗ khác.
Chi tiết kỹ thuật
Khung đi lên bằng WebSocket binary tớiGET /aiagent-user/vision/openStream, kết quả về bằng khung TEXT (JSON). Server bỏ khung cũ: sau mỗi lần xử lý nó vét socket và chỉ lấy khung mới nhất — chỉ giới hạn nhịp là không đủ, vì xử lý một khung mất vài giây nên hàng đợi sẽ trả nhãn về một khung của vài chục giây trước. Trần thứ hai là AI_VISION_MAX_FPS ở biên. Không lưu khung nào xuống đĩa.Bước 0Kịch bản demo — 5 chặng, theo thứ tự sản phẩm
Cần trước: — · Lối đi bên dưới sắp theo hình dạng phụ thuộc (máy sống → dựng → dùng thật → kiểm chứng). Màn này sắp theo hình dạng sản phẩm — thứ tự bạn đi khi trình bày.
Hai luồng, hai vai trò — đừng trộn khi trình bày
Một buổi demo trộn hai vai trò làm người xem không biết đang nhìn ai. Luồng ADMIN là người của bạn dựng trợ lý; luồng KHÁCH là thứ người dùng cuối gặp. Hai luồng dùng hai tài khoản khác nhau — admin cần role=admin, khách đi qua widget hoặc kênh, không đăng nhập. Trỏ chuột vào từng bước để đọc nó là gì và vì sao nó có.
- Nạp tri thức của kháchbấm «Nạp toàn bộ» ở bước 0, hoặc thêm nguồn ở bước 3
- Xem nó đang BIẾT gìbấm «Vẽ bộ não», rồi «Soi chùm sáng» với một câu thật
- Nối hệ thống của kháchOnePMS: điền email · mật khẩu · secretKey → «Đăng ký 6 đường»
- Chọn loại trợ lýsuper admin khai loại · người dùng chỉ chọn
- Tạo trợ lý và khai giới hạnđiền does · does_not · cách trả lời
- Gắn / tháo năng lựcbật một cái → hỏi lại cùng câu → tắt → hỏi lần nữa
- Dạy bằng câu mẫuthêm cả câu phải trả lời VÀ câu phải từ chối
- Đo trước khi bậtbấm «Kiểm thử ngay», đọc câu nào trượt và vì sao
- Bật và nối kênhnối một Page → tin nhắn thật đi vào
- Hỏi một câu trong phạm vivd «mấy giờ phải trả phòng» → trả lời + trích dẫn
- Hỏi một câu nó PHẢI TỪ CHỐIvd «giảm 20% nhé» → nó từ chối, có lý do
- Việc cần ghi sang hệ thậttrợ lý đề nghị → người trực duyệt hoặc từ chối
- Đòi gặp nhân viênbàn giao kèm ngữ cảnh → nhân viên nhận ca
Mỗi chặng nói một con số ĐO được, không một ô nào tự khai. Chặng nào chưa có màn trên bàn này thì nó nói ra — một dấu tích cho một thứ không tồn tại là thứ hỏng đúng lúc có người đang nhìn.
Bấm «Đo lại tất cả» — hoặc chờ, trang tự đo một lần khi mở.
Chặng ③ hiện vàng khi có đề nghị đang chờ duyệt. Đó không phải lỗi — đó là đúng thứ cần cho xem trong một buổi demo: trợ lý đề nghị ghi sang hệ thật, và một người quyết.
Chi tiết kỹ thuật
Sáu đường đọc, chạy song song:overview/getSetupProgress · overview/getSummary · agent/getAgentList · capability/getCapabilityList · graph/getPendingList · staff/getStaffList. Đường nào 404 ở tiến trình đang trả lời thì chặng đó ghi «tiến trình này không phục vụ» — ARCH-01: một đường không thuộc vai của tiến trình thì nó không tồn tại, trả 404 chứ không 403, nên đó là một câu trả lời hợp lệ chứ không phải một sự cố. Đường nào 403 thì ghi «khoá hiện tại không đủ quyền», vì đó là hai chuyện khác nhau và trộn chúng lại sẽ làm người demo đi sửa nhầm chỗ.Bước 0Bộ demo — chọn một ngành, nạp một lần, chạy được ngay
Cần trước: đăng nhập role=admin · Dựng sẵn một trợ lý THẬT từ tài liệu của một ngành: tri thức, câu vàng (gồm câu PHẢI TỪ CHỐI), bản khai và PHẠM VI DỮ LIỆU riêng của nó.
Nút này không có đường tắt nào: nó gọi đúng những đường mà một khách hàng thật gọi — upsertProfile cho từng tài liệu, createAgent, addExampleList. Nếu bộ này chạy được thì một khách hàng làm y hệt cũng chạy được; nếu nó gãy ở bước nào thì đó là chỗ khách sẽ gãy.
Chạy lại không tạo trợ lý thứ hai: nó tìm theo tên trước. Tài liệu ghi theo id cố định (Green Bio 9001–9036, khách sạn 8001+) nên nạp lại là ghi đè, không nhân bản. Mỗi khách hàng cần ba trợ lý — trước, trong và sau bán hàng — nên nhóm nào hiện còn GỘP cả ba giai đoạn là nhóm chưa tách xong, không phải nhóm đã đủ.
Sáu câu lấy thẳng từ tài liệu — ba câu trợ lý phải trả lời được, ba câu nó phải từ chối. Bấm một câu là gửi thật vào trợ lý vừa nạp.
Câu «phải từ chối» mà trợ lý báo giá hoặc cam kết diệt 100% là hỏng — đó là hai điều tài liệu cấm tuyệt đối, và nó là thứ đáng kiểm nhất trong cả bộ.
Ba bước. Website của khách không phải sửa gì.
Khoá chỉ chạy trên tên miền đã khai, và nó hiện đúng một lần.
Vì sao phải khai tên miền
Một lần bấm làm hai việc, và thiếu việc nào thì widget cũng không nói được câu nào.① Mở CORS. JS chạy trên trang của KHÁCH gọi chéo nguồn gốc, nên trình duyệt đòi header
Access-Control-Allow-Origin mang đúng origin đó. Chưa khai thì khách nhận No 'Access-Control-Allow-Origin' header is present — một thông báo không nói gì về danh sách nào cần khai. Đã xảy ra trên site khách thật h-holding.vn.② Ràng khoá. Khoá
role=widget nằm trong JS công khai, nên ai xem source cũng đọc được. Phạm vi của nó đã hẹp — đúng hai đường hỏi đáp (SEC-05), lộ khoá không kéo theo CRM và không kéo theo cước — nhưng nó vẫn chạy: dán sang website thứ hai, thứ ba, và cả ba site tiêu cước model của một khách. Ràng tên miền là thứ chặn việc đó.Nói thẳng giới hạn: nó chặn được lạm dụng bằng trình duyệt (mọi lần nhúng đều gửi
Origin), không chặn được curl. Với curl thì hàng rào vẫn là phạm vi hẹp của khoá và hạn mức cước.Xem và bỏ tên miền đã khai ở Widget nhúng → «Xem tên miền đã khai».
Đi theo thứ tự này
Hai mươi mục dưới đây xếp theo thứ tự phụ thuộc, không theo thứ tự chúng được viết ra. Bước sau cần bước trước — và chỗ nào cần thì mục đó nói thẳng ở dòng «Cần trước».
A · Máy này sống chưa
Chưa cần làm gì. Đỏ ở đây thì mọi bước sau vô nghĩa.
bước 1–2B · Dựng một trợ lý
Nạp dữ liệu → mở đường ra ngoài → tạo → gắn năng lực → dạy. Thứ tự này không hoán đổi được.
bước 3–8C · Đưa vào dùng thật
Ba kênh khách chạm tới: chữ (Social), tiếng (voice), hình (camera).
bước 9–11D · Kiểm chứng & vận hành
Đọc khi cần trả lời câu «nó còn đúng không».
bước 12–20Vì sao thứ tự này, không phải thứ tự khác
Bản trước xếp theo lịch sử viết ra, và thanh điều hướng lại xếp theo một thứ tự thứ hai — bấm một mục thì nhảy tới chỗ không đoán được. Tệ hơn: «Kết nối ra ngoài» nằm SAU «Năng lực», trong khi năng lựcapi.connector bị chặn cho tới khi có một kết nối — chính thông báo chặn bảo người dùng quay lại một mục nằm phía trước. Nay hai thứ tự là MỘT, và nó là thứ tự phụ thuộc thật: mục nào cần gì thì nói ra ở dòng «Cần trước», nên bạn không phải học thuộc sơ đồ này.Bước 0AI từ A đến Z — bắt đầu ở đây
Cần trước: — · Đọc 2 phút, rồi bấm Hỏi thử ở cuối mục. Nếu câu trả lời hiện ra kèm bằng chứng thì máy này đã dùng được, và bạn có thể bỏ qua phần lớn 20 mục bên dưới.
- Bạn đưa dữ liệu vào: hồ sơ, tài liệu, câu hỏi–đáp có sẵn.
- Khách hỏi một câu — bằng chữ, bằng tiếng nói, hoặc bằng ảnh.
- Hệ tìm những mẩu dữ liệu gần nghĩa nhất với câu hỏi đó.
- Model viết câu trả lời dựa trên mấy mẩu ấy, và chỉ ra đã dựa vào mẩu nào. Đó là cột «bằng chứng» bạn sẽ thấy ở dưới.
- Không tìm được gì hợp lý thì nó nói không biết — không bịa. Đây là lựa chọn thiết kế, không phải giới hạn kỹ thuật.
Một «trợ lý» ở đây không phải một model riêng. Nó là một bản khai: làm gì · không làm gì · được dùng công cụ nào · lấy dữ liệu từ đâu. Cùng một model, hai bản khai khác nhau cho ra hai trợ lý cư xử khác hẳn nhau. Câu «không làm gì» là câu quan trọng nhất trong bản khai — thiếu nó thì vai trò của trợ lý trôi dần theo thời gian.
Không phải danh sách viết sẵn. Mỗi dòng gọi một đường thật lúc bạn mở trang. Dòng nào báo «vai trò này không phục vụ» thì không phải lỗi: tiến trình đang phục vụ trang này được giao một bề mặt hẹp hơn — xem Bước 20.
Câu trả lời kèm bằng chứng — danh sách hồ sơ mà nó đã dựa vào. Không có bằng chứng nào mà vẫn có câu trả lời trôi chảy là dấu hiệu xấu, không phải tốt: xem Bước 4 để biết nó đang thật sự biết gì.
Bước 1Trạng thái runtime
Cần trước: — · Nếu Liveness hay Readiness đỏ thì đừng đọc tiếp; sửa nó trước.
Bước 2Các khối đã nối vào server
Cần trước: bước 1 · Khối nào tắt ở đây thì mục tương ứng bên dưới sẽ báo lý do, không im lặng.
Đang tải...
Đọc cấu hình thật từ /version
Bước 14Bộ kiểm chứng runtime
Cần trước: server đang chạy · 72 phép kiểm gọi endpoint thật. Không thay python3 -m aiagent_portfolio.eval.
Khi API_KEY được đặt, middleware chặn mọi endpoint trừ /health và /metrics — điền khoá vào ô ở mục “Thử API” trước khi chạy, nếu không tất cả sẽ đỏ vì 401. Mỗi phép kiểm nối với một điều khoản của AI_AGENT_STANDARD hoặc một luật trong CLAUDE.md §2; khi đỏ, thông báo nói rõ điều khoản nào đang bị vi phạm và sửa ở đâu. Các phép kiểm gọi endpoint thật, tự dọn hồ sơ tạm mình tạo ra. “Chỉ phép kiểm nhanh” bỏ những phép phải gọi model local (mỗi lần gọi tốn 9–40 s). Trang này không thay python3 -m aiagent_portfolio.eval: nó nói “còn sống và còn đúng hợp đồng”, eval mới nói “còn đúng chất lượng”.
Chưa chạy.
Bước 15Playground: gọi API bằng tay
Cần trước: bước 3 · Gọi tay từng đường khi cần soi một tham số cụ thể.
/aiagent-admin/auth/* (tạo tenant · user · api-key) — nó không tạo “principal”, nên mọi đường khác trả 401 nếu thiếu khoá tenant. X-Tenant-Api-Key mở phần còn lại, và role của nó quyết định bề mặt nào: role=admin → /aiagent-admin/*, role=platform → /aiagent-platform/*. Một khoá mang một role, nên getAgentTypeList cần khoá platform riêng./chat cần index + runtime AI. /recommend có thể trả fallback nhưng phải nói rõ trạng thái. Bộ lọc áp dụng cho cả hai — để trống mọi ô lọc thì không lọc gì.Bước 17Đối chiếu tính năng với agentic-mockup
Cần trước: — · Đối chiếu với mockup — chấm theo endpoint có thật, không theo việc UI mô phỏng được.
Bảng này chấm mã, không chấm bản triển khai — nên nhóm «0 · Bản triển khai» được thêm vào để bịt đúng khoảng cách đó. Một tính năng có đủ route, qua đủ phép kiểm, vẫn có thể 404 ở mọi cổng nếu không tiến trình nào trong bản đang chạy nhận vai trò phục vụ tiền tố của nó. Đo 2026-08-30: bản 8 service bỏ lại 17/306 đường không ai phục vụ — 12 tiền tố quản trị của conversation, hai đường đọc của platform_admin, và ba đường WebSocket. Không lỗi nào báo ra; chúng chỉ đơn giản không tồn tại ở đó.
Bảng này khoá theo cấu trúc mockup hiện tại — 7 khu vực · 32 màn · wizard 5 bước — chứ không theo bản 26/08 (khi đó mockup chia AI Chat Agent · AI Social Agent · AI CS Agent; nay là AI Agents · AI Sales Agent · AI Marketing Agent cộng ba khu vực mới: Nhân viên, Cài đặt, Quản trị hệ thống).
Chấm theo endpoint có thật và gọi được, không theo việc UI mô phỏng được — và "có thật" ở đây nghĩa là đã gọi thử, không phải đã có mặt trong bảng định tuyến. Phân biệt đó không phải tiểu tiết: ngày 30/08, ba màn (Brand Voice, Tổng quan Sales, Thiết lập ban đầu) có đủ route, qua đủ mọi phép kiểm, và vẫn trả HTTP 500 — handler gọi một phương thức mà kho của nó không có. Nay test/contract/test_read_surface.py gọi thật mọi đường ĐỌC nên lớp lỗi đó không lọt lại được.
Bảy dòng "Một phần" là bảy chỗ CẦN hạ tầng hoặc dữ liệu bên ngoài, không phải bảy chỗ chưa làm: reach/impressions chỉ tồn tại ở Meta/Zalo Insights; sinh ảnh cần một model chưa cấu hình ở đây; làm mới token cần một App đã được nền tảng duyệt. Ba thứ đó không được làm giả — bịa một con số reach là đúng thứ toàn bộ hệ thống này từ chối làm, và một generateImage trả ảnh placeholder sẽ làm frontend dựng xong, demo chạy, rồi hỏng đúng lúc có khách thật. Mỗi dòng nói rõ "CÒN THIẾU" là gì.
Bước 18Cấu hình đang chạy (bằng lời thường)
Cần trước: — · Cấu hình đang chạy, đọc từ /version. Bí mật chỉ hiện set(***).
Không phải bảng biến môi trường — đây là những gì máy chủ đang thực sự dùng lúc này, mỗi dòng kèm chỗ để đổi và có phải khởi động lại hay không. Đọc từ GET /version, không phải chữ viết sẵn.
Vì sao “tôi sửa .env mà không thấy gì đổi”
Biến môi trường thật LUÔN thắng file.env — cần như vậy để AI_VOICE_ENABLED=false python3 -m aiagent_portfolio.main thắng được một file .env cũ trên máy. Mặt sau của luật đó chính là câu hỏi trên, nên ô này nói rõ: đã nạp file nào, đặt được bao nhiêu biến, và biến nào bị môi trường đè lên.Khoá LLM của workspace đã chuyển ra khu demo → Khoá LLM của workspace. Nó nằm ở đây vì đây là màn «cấu hình», nhưng người cần nó là khách đang được onboard — và họ không bao giờ mở tới bước 18 của khu kỹ thuật.
Bước 20Bàn quản trị nền tảng — aiagent-platform
Cần trước: role=platform · Bề mặt đọc chéo tenant. role=admin của một tenant không qua được.
Bề mặt thứ hai của hệ: bàn của người vận hành InCard, không phải bàn của chủ shop. Nó đọc chéo mọi tenant, nên nó là audience riêng ở đường dẫn (/aiagent-platform/) chứ không phải một nhánh if trong tầng phân quyền — nhìn path là biết một khoá chạm tới được những gì. Một khoá role=admin của tenant gọi bất kỳ đường nào dưới đây đều nhận PrivilegeNeed.
Ba nhóm ở đây: Đối chiếu hợp đồng (85 đường của tài liệu ⟂ bảng định tuyến thật), Quét đường đọc (gọi thật, xem mã trả về), và Gọi tay (dựng form từ chính bản khai tham số).
“Quét đường đọc” chỉ gọi những hành động bắt đầu bằng get — đúng tập mà token đăng nhập hộ được phép gọi, và cũng đúng tập không đổi gì. Các đường ghi phải bấm tay ở phần “Gọi tay” bên dưới, có chủ đích: một nút “chạy tất cả” quét qua setRate, refundTransaction và reembedAll là một nút không ai dám bấm.
“Nạp dữ liệu mẫu” chạy trọn một vòng đời: khách báo chuyển khoản → kế toán xác nhận → doanh thu và credit xuất hiện; cộng thêm một khoản còn chờ, một ticket, một yêu cầu xoá và một thông báo nháp, để bốn màn tiền và hàng đợi việc có số thật mà nhìn thay vì toàn số 0. Nó nạp qua chính những đường mà luồng thật đi qua (kể cả đường của bàn khách), không ghi thẳng vào kho — dữ liệu mẫu có hình dạng mà không luồng nào tạo ra được sẽ làm màn hình đẹp trong khi luồng thật vẫn hỏng. Nó ghi — chỉ chạy trên máy chạy thử.
Chưa gọi đường nào.
Cột Bảng định tuyến đọc từ chính /version của binary đang chạy, không phải từ một danh sách chép tay ở trang này. Một dòng đỏ nghĩa là tài liệu hợp đồng và bảng định tuyến đã trôi khỏi nhau — và đó là thứ duy nhất mà bảng này tồn tại để phát hiện.
Bước 21Quan sát và kiểm chứng
Cần trước: — · /metrics và các lệnh kiểm tra đề xuất.
Đang tải...
Bộ unittest kiểm hợp đồng offline, không cần server. `python3 -m aiagent_portfolio.eval`/`voice_eval` và bộ "Bộ kiểm chứng runtime" ở trên mới là kiểm đầu-cuối nên cần server, index và runtime AI đang sống.
Bước 22Bản đồ kiến trúc runtime
Cần trước: bước 1 · Mục này trả lời một câu: tiến trình đang phục vụ trang này là ai trong hệ, và nó KHÔNG phục vụ những gì. Số liệu đọc từ /health + /version, không gõ vào trang.
Cùng một bản mã, cùng một ảnh triển khai. Thứ quyết định tiến trình này phục vụ đường nào là một biến môi trường, và việc cắt xảy ra ở roles.keeps() — trước khi có request nào tới. Vì thế một khoá quản trị bị lộ không mở được gì trên một tiến trình user: đường đó không tồn tại ở đó, nên nó trả 404 chứ không phải 403.
Bảng này chép từ aiagent-kernel/aiagent_kernel/roles.py; nó là hợp đồng, không phải trạng thái. Dòng được tô là vai trò tiến trình này đang chạy — phần đó đọc từ /version. Gõ sai tên vai trò thì tiến trình từ chối khởi động chứ không âm thầm rơi về all.
| AI_SERVICE_ROLE | Phục vụ tiền tố | WebSocket | Worker |
|---|---|---|---|
all | user · admin · platform · internal | ✓ | ✓ |
user | user | — | — |
admin | admin | — | — |
platform | platform | — | — |
webhook | internal | — | — |
longconn | không đường text nào | ✓ | — |
worker | không cổng nghiệp vụ | — | ✓ |
Đọc từ /version. Cột bỏ đi thì mất gì là lời khai của chính plugin — nó tồn tại để một quyết định gỡ plugin không phải là một phép đoán.
Đang đọc…
GET /version
Mỗi kho đọc biến riêng của nó, và mặc định là đường tương đối — nên chúng rơi vào ./data/ của thư mục đang đứng. Không có biến gom nào; danh sách dưới đây là đường thật đang dùng, lấy từ /version.
Trang này chỉ nói chắc chắn được về tiến trình đang phục vụ nó — trình duyệt không gọi được sang cổng khác (nguồn gốc khác). Bảng dưới là bản khai, và nguồn sự thật của nó là ops/agentctl cộng ENV trong Dockerfile của từng kho. Dòng được tô là tiến trình đang phục vụ trang này, so theo cổng đọc từ /version.
| Tiến trình | Cổng | Vai trò | Sở hữu / vai trò trong hệ |
|---|---|---|---|
conversation | 7077 | user | bề mặt người dùng cuối — hỏi đáp, tiếng, hình |
identity | 7101 | admin | danh tính, tenant, nhân sự, khoá API |
knowledge | 7102 | admin | chủ ghi của index/ — nạp và lưu tri thức |
platform | 7103 | platform | bàn quản trị nền tảng — đọc chéo tenant |
webhook | 7104 | webhook | ingress công khai — xác minh chữ ký rồi phát việc |
conversation-admin | 7105 | admin | CÙNG ảnh với 7077, đổi vai trò. Không chạy nó thì 12 tiền tố quản trị không có ai phục vụ |
crm | 7106 | admin | khách hàng, cơ hội, chuyển người thật |
social | 7107 | admin | kênh, chiến dịch, hội thoại mạng xã hội |
billing | 7108 | admin | sổ credit, bảng định mức |
Ba chủ sở hữu kho gọi nhau qua mạng khi chạy nhiều tiến trình. Không khai địa chỉ nào thì nhân dùng bản gọi trong tiến trình — đúng cho bản một tiến trình, nhưng ở bản nhiều tiến trình nó nghĩa là mỗi service tự trả lời chính mình, và câu hỏi chéo chủ sở hữu trả về rỗng mà không có lỗi nào.
Bước 0Tổng quan
Cần trước: đăng nhập role=admin · Màn này gọi /aiagent-user/overview/getSummary. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Agent của tôi
Cần trước: đăng nhập · một trợ lý đã tạo ở bước 6 · Màn này gọi /aiagent-admin/agent/getAgentList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Kho kiến thức
Cần trước: đăng nhập · nguồn đã nạp ở bước 3 · Màn này gọi /aiagent-admin/source/getSourceList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Brand Voice
Cần trước: đăng nhập · brand voice tạo ở bước thiết lập · Màn này gọi /aiagent-admin/social/getBrandVoiceList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Kênh kết nối
Cần trước: đăng nhập · một Page đã gắn ở bước 9 · Màn này gọi /aiagent-admin/channel/getChannelBindingList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0AI Growth
Cần trước: đăng nhập · đã có lượt hỏi để duyệt · Màn này gọi /aiagent-admin/feedback/getFeedbackList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Tổng quan Chat
Cần trước: đăng nhập · plugin social bật · Màn này gọi /aiagent-admin/analytics/getOverview. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Hội thoại
Cần trước: đăng nhập · một kênh đã nối ở bước 9 · Màn này gọi /aiagent-admin/conversation/getConversationList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Pipeline
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/crm/getStageList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Tổng quan CS
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/cs/getCsatSummary. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Lời nhắc
Cần trước: đăng nhập · một trợ lý đã có kênh · Màn này gọi /aiagent-admin/cs/getReminderRuleList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Chiến dịch vòng đời
Cần trước: đăng nhập · khách đã có đơn (mốc vòng đời tính từ lần mua) · Màn này gọi /aiagent-admin/cs/getLifecycleCampaignList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Phản hồi & CSAT
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/cs/getCsatSummary. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Tổng quan Marketing
Cần trước: đăng nhập · plugin social bật · Màn này gọi /aiagent-admin/analytics/getOverview. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Lịch đăng
Cần trước: đăng nhập · một bài đã lên lịch · Màn này gọi /aiagent-admin/social/getSchedule. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Bài viết
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/social/getPostList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Thư viện ảnh
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/asset/getAssetList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Chiến dịch
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/social/getCampaignList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Lead từ comment
Cần trước: đăng nhập · một Page đã gắn · Màn này gọi /aiagent-admin/commentLead/getRuleList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Phân tích
Cần trước: đăng nhập · đã có bài đăng và đơn để dựng phễu · Màn này gọi /aiagent-admin/analytics/getFunnel. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Quản lý công việc
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/crm/getTaskList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Khách tiềm năng
Cần trước: đăng nhập · lead vào từ chat hoặc nhập tay · Màn này gọi /aiagent-admin/crm/getLeadList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Khách hàng
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/crm/getCustomerList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Nhóm khách hàng
Cần trước: đăng nhập · đã có khách để chia nhóm · Màn này gọi /aiagent-admin/crm/getSegmentList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Đơn hàng
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/crm/getOrderList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Sản phẩm
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/crm/getProductList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Danh sách nhân viên
Cần trước: đăng nhập role=admin — danh sách này là của MỘT tenant · Màn này gọi /aiagent-admin/staff/getStaffList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Bảng điểm nhân viên
Cần trước: đăng nhập · đã có hội thoại để AI chấm · Màn này gọi /aiagent-admin/coach/getScorecardList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Tiêu chuẩn đánh giá
Cần trước: đăng nhập role=admin · Màn này gọi /aiagent-admin/coach/getRubric. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Gói & Thanh toán
Cần trước: đăng nhập · đã có ít nhất một lần nạp hoặc gia hạn · Màn này gọi /aiagent-admin/billing/getInvoiceList. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Chi tiết credit
Cần trước: đăng nhập · đã có lượt gọi model để trừ credit · Màn này gọi /aiagent-admin/billing/getUsageSummary. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Tích hợp
Cần trước: đăng nhập role=admin · Màn này gọi /aiagent-admin/integration/getCatalog. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Giới thiệu & hoa hồng
Cần trước: đăng nhập · Màn này gọi /aiagent-admin/referral/getSummary. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 0Hồ sơ của tôi
Cần trước: đăng nhập — đường này đọc hồ sơ của CHÍNH token đang cầm · Màn này gọi /aiagent-admin/auth/getSelfProfile. Rỗng ở đây là rỗng CÓ THẬT, không phải dữ liệu mẫu.
Đang dựng…
Bước 9Gắn trợ lý vào kênh Social
Cần trước: bước 6 · worker bật · Một Page gắn một trợ lý. Worker tắt thì tin nhắn vào hàng đợi mà không ai trả lời.
Một Page/OA được gắn với một trợ lý. Mọi tin nhắn đến Page đó sẽ được trả lời bằng đúng phạm vi dữ liệu và cách trả lời của trợ lý đó — không gắn thì trợ lý lõi trả lời như trước. Đây là đường để thử một trợ lý bạn vừa tạo trên một Page thật mà không phải sửa dòng cấu hình nào.
① Khai khoá kênh của khách — làm TRƯỚC khi gắn
Đây là chỗ trả lời câu "trăm khách thì điền vào đâu". Mỗi khách nạp khoá của CHÍNH HỌ: từ giây này webhook của kênh đó được xác thực bằng App Secret của tenant này, không bằng biến môi trường của máy. Chưa khai khoá thì bậc 5 của thang sáu bậc còn đỏ, và một tin nhắn thật sẽ không vào được.
Chưa có khoá Meta thì bậc 5 còn đỏ, và đó là trạng thái ĐÚNG — không phải một lỗi cần vòng qua. Ba bậc dưới (hệ · model · tri thức) và bản khai vẫn xanh, nên phần demo hỏi–đáp chạy đủ; chỉ đường ra kênh thật là chưa.
② Widget nhúng — gửi cho khách dùng thật
Đây là đường nhanh nhất để khách dùng thật: một thẻ
<script>dán vào website của họ, không cần Meta, không cần chờ duyệt app. Mỗi trợ lý một đoạn riêng — khoá gắn với tenant,data-agenttrỏ tới đúng trợ lý.Một lần bấm mở CORS cho tên miền đó và ràng khoá vào đúng nó — bỏ trống thì đoạn nhúng chạy được ở mọi website, và trang khách vẫn bị trình duyệt chặn.
<script>hoàn chỉnh hiện ở đây. Khoá hiện đúng MỘT LẦN.Tên miền khai ở ô bên cạnh, không ở biến môi trường: khai bằng env nghĩa là bán widget cho một khách mới phải khởi động lại máy chủ cho mọi khách đang chạy. Trang
/widget-trycùng nguồn gốc với API nên nó tách được «trợ lý sai» khỏi «CORS chặn».② Gắn trợ lý vào kênh đã khai
AgentIdNotExist) chứ không đợi tới lúc có khách nhắn — một binding hỏng chỉ lộ ra khi khách đang chờ trả lời là kiểu hỏng đắt nhất.Chưa tải.