Vòng đời của một lượt
Một tin nhắn trở thành một lượt, một luồng sự kiện được lưu và một trạng thái cuối như thế nào, và trình duyệt nối lại luồng sau khi tải lại trang ra sao.
Một lượtLượtTurnMọi thứ từ lúc gửi tin nhắn đến khi nhận câu trả lời: kiểm tra, lệnh gọi mô hình, dùng công cụ, tạm dừng chờ bạn, và câu trả lời. Lượt vẫn chạy khi bạn đóng tab.Mở trong Thuật ngữ là mọi thứ diễn ra từ lúc bạn gửi tin nhắn đến lúc nhận câu trả lời: các bước kiểm tra, các lần gọi mô hình, việc dùng tool, các lần dừng chờ bạn và luồng dữ liệu trả về. Một lượt có thể gọi mô hình nhiều lần và mỗi lần gọi để lại một dòng nhật ký kiểm tra. Agent vẫn chạy dù có trình duyệt nào đang xem hay không, và một bộ đọc duy nhất phục vụ mọi trình duyệt.
Quy tắc chính
- Một tin nhắn có thể kéo theo nhiều lần gọi mô hình, mỗi lần được ghi nhật ký và tính chi phí riêng.
- Một lượt là danh sách các khối có kiểu: tóm tắt suy luận, văn bản, lệnh gọi tool và kết quả.
- Phê duyệt và câu hỏi làm rõ tạm dừng chính lượt đó; trả lời sẽ chạy tiếp.
- Agent vẫn làm việc khi bạn đóng tab.
- Tải lại trang không bao giờ nhân đôi khối hay lặp lại hành động.
Bước tiếp theo sẽ thay đổi một ứng dụng kết nối, nên lượt tạm dừng và hỏi bạn. Lượt chờ bao lâu cũng được — trả lời sẽ tiếp tục đúng lượt đó.
Bắt đầu lượt
Năm bước kiểm tra chạy theo thứ tự trước khi lượt được lưu. Bước đầu tiên thất bại sẽ chặn tin nhắn kèm lý do rõ ràng.
| Kiểm tra | Quy tắc |
|---|---|
| Phòng ban | Luôn có. Người chưa được gán nằm trong phòng ban hệ thống General. |
| Phạm vi hiển thị của agent | “Không tìm thấy” và “không được thấy” đều trả về 404. Nếu tổ chức bật công tắc agent mặc định, người không phải quản trị viên bị từ chối chứ không bị đổi sang agent khác. |
| Mô hình | Mô hình ghi đè cho tin nhắn, nếu không thì mô hình của agent, phải là mô hình chat đang phục vụ và không bị phòng ban của bạn chặn. Ghi đè chỉ có thể thu hẹp. |
| Chính sách | Đóng khi lỗi: không xác định được chính sách ngân sách thì tin nhắn bị từ chối. |
| Tệp đính kèm | Tài liệu chưa có bản đã lập chỉ mục làm yêu cầu thất bại. Tài liệu đang được đọc thì không. |
Sau đó, theo thứ tự:
- Dựng bộ nhớ ngắn hạn (xem Dựng prompt).
- Ghi dòng lượt; prompt được lưu trước khi gọi agent.
- Mã lượt được trả về trong header phản hồi trước khi thân luồng mở.
- Mô hình chỉ được lưu trên lượt khi khác với mô hình của agent.
Đặt tên cuộc trò chuyện
Cuộc trò chuyện mở ra chưa có tên và lượt đầu tiên đặt tên cho nó, qua hai lần ghi:
- Tên rút từ tin nhắn mở đầu được ghi ngay.
- Mô hình nền của tổ chức sau đó đưa ra tên tốt hơn.
Trình duyệt làm mới danh sách khi lượt kết thúc; câu trả lời ngắn có thể xong trước khi mô hình nền trả lời.
- Chỉ cuộc trò chuyện chưa có tên mới được đặt tên, nên tên bạn tự đổi luôn được giữ, kể cả khi đổi giữa lượt.
- Không có mô hình nền, gateway từ chối hoặc phòng ban hết ngân sách thì tên đầu tiên được giữ nguyên.
- Lần gọi đặt tên dùng khóa gateway của phòng ban và để lại dòng nhật ký như một lượt chat, không gắn agent nào.
Bản tóm tắt ngắn, an toàn về việc agent đang làm — không bao giờ là suy luận thô.
Mỗi công cụ agent dùng hiện thành một dòng; mở ra để xem đầu vào và kết quả.
Khi bước tiếp theo thay đổi dữ liệu trong ứng dụng kết nối, lượt dừng lại và hỏi bạn trước.
Câu trả lời cuối truyền về từng chữ, kèm trích dẫn tới tài liệu đã dùng.
Lưu từng chunk
Agent gửi công việc thành từng chunk. Mỗi chunk được ghi vào cơ sở dữ liệu trước khi đọc chunk tiếp theo, nên tải lại giữa chừng vẫn khôi phục mọi khối đã ghi.
| Chunk | Tác dụng |
|---|---|
delta | Tạm thời; khối sẽ đến nguyên vẹn sau. |
tool_start | Tạm thời; mở dòng tool khi mô hình còn đang viết tham số, có thể dài cả một tài liệu. |
tool_progress | Tạm thời; số ký tự tham số đã viết của lệnh gọi đang mở, tối đa hai lần mỗi giây. Dòng tool đếm dần tới mỗi mốc trong một giây, nên chậm hơn mô hình khoảng nửa giây. |
compaction_start | Tạm thời; đang viết bản tóm tắt, tốn một lần gọi mô hình và trong lúc đó không có gì khác đến. Nó được phát từ bên trong hook khi luồng bị chặn, nên đi qua kênh phụ được gộp vào luồng. |
guardrail | Tạm thời; kết quả một lần kiểm tra guardrail (điểm kiểm tra, loại, đối tượng, hành động), không bao giờ là nội dung. Kết quả trên tin nhắn của bạn được ghi trước khi runtime chạy; kết quả trên kết quả tool hay câu trả lời đi trước chunk kế tiếp. Bản ghi hội thoại cũng lưu các kết quả này theo lượt. |
block | Thêm khối, rồi nâng mốc đã lưu cao nhất. Kết quả tool hoàn tất bước trace của lệnh gọi không do route nào của portal phục vụ. |
usage | Thêm một bước gọi, ghi dòng nhật ký và bảng tổng hợp trong một giao dịch, rồi kiểm tra ngưỡng ngân sách. Lần gọi trên chính mô hình của lượt cũng mang đầu vào cộng đầu ra làm kích thước ngữ cảnh; lần gọi tóm tắt, đánh giá hay nén ngữ cảnh thì không. |
pause | Thêm khối, tạo yêu cầu làm rõ hoặc phê duyệt, chuyển lượt sang chờ. Chỉ phát sau khi ghi nên mang theo mã yêu cầu. |
done | Đánh dấu lượt thành công kèm tổng số. |
error, hoặc luồng kết thúc | Thất bại hoặc hết giờ, và thêm một chunk lỗi tổng hợp để bộ đọc đang chạy dừng ngay. |
Dòng trace. Mỗi lệnh gọi tool để lại đúng một dòng trace, ghi đầu vào, câu trả lời và thời gian. Route của portal phục vụ tool sẽ ghi nó. Phép tính chạy trong runtime và không qua route nào, nên luồng khối ghi lệnh đó, cùng mọi tool do một ứng dụng kết nối mang tới. Mỗi lệnh gọi có đúng một bên ghi.
Tạm dừng. Một lần tạm dừng chỉ kết thúc lần gọi agent hiện tại. Khi chạy tiếp, lượt quay về trạng thái đang chạy dưới một producer thứ hai, và các chunk của nó đến bạn qua cùng bộ đệm.
Phát lại từ con trỏ
Mỗi sự kiện được lưu trước khi gửi và mang một số thứ tự. Nếu mất kết nối, trình duyệt kết nối lại với số cuối cùng nó thấy và portal chỉ phát lại phần bạn bỏ lỡ, rồi tiếp tục trực tiếp.
last event = 4 → phát lại 5–6 → theo dõi trực tiếp từ 7 Mọi thứ trên màn hình quay lại, rồi câu trả lời tiếp tục. Không gì xuất hiện hai lần.
Agent vẫn tiếp tục làm việc. Mở lại cuộc trò chuyện sau để xem kết quả.
Lượt chờ phê duyệt hoặc câu trả lời của bạn, bao lâu cũng được.
Lượt được đánh dấu hết thời gian và bạn thấy trạng thái kết thúc rõ ràng, không phải vòng xoay chờ.
- Sự kiện của agent đi vào bộ đệm Redis Streams rồi tới trình duyệt dưới dạng server-sent events (SSE). Một bộ đọc phục vụ kết nối đầu tiên và mọi lần kết nối lại, từ bất kỳ instance backend nào.
- Mã lần chạy được tạo trước khi luồng mở và không bao giờ đổi. Mã sự kiện SSE là số thứ tự của chunk, tăng dần trong lượt; mã mục riêng của Redis chỉ dùng nội bộ.
- Chỉ chunk
blockvàpausemang số thứ tự, và do đó có mã sự kiện. - Lịch sử và các khối đã hoàn tất được lưu bền trong PostgreSQL. Redis chỉ là bộ đệm phát lại cho lần chạy đang hoạt động: giữ một số mục có giới hạn, gia hạn thời gian sống khi còn chạy và xóa khi chunk cuối đến.
- Khi tải lại, trình duyệt nạp lịch sử đã lưu rồi kết nối lại với mã sự kiện cuối đã xác nhận. Backend đọc các mục nằm sau con trỏ đó.
- Việc lưu loại trùng theo tin nhắn và số thứ tự, nên chunk phát lại không thay đổi gì và không lặp tác dụng phụ.
- Một frame chỉ được lớn tới một giới hạn. Frame vượt giới hạn bị bỏ và luồng chạy tiếp, vì mất một kết quả tool đỡ tốn hơn mất cả một lượt đã chạy nhiều phút. Bên gửi có frame không bao giờ kết thúc thì vẫn làm lượt thất bại.
| Con trỏ | Bộ đọc trả lời |
|---|---|
| Khớp một mục còn giữ, hoặc không có | Phát lại từ đó, rồi theo dõi trực tiếp tới chunk cuối. |
| Đã rơi khỏi bộ đệm, lượt đã xong | Một sự kiện trạng thái cuối tổng hợp từ bản ghi lưu bền. |
| Đã rơi khỏi bộ đệm, hoặc im lặng trọn một khung chờ, lượt vẫn đang chạy | Bên điều khiển đã chết (triển khai, sập, mất kết nối bộ đệm). Lần chạy được ghi là hết giờ và trình duyệt nhận trạng thái cuối. |
Quy tắc thứ ba chỉ kết thúc lượt đang chạy; lượt đang chờ bạn vẫn tiếp tục chờ. Con trỏ cũ không bao giờ bị đoán tiến lên.
Thời gian chờ của bộ đọc tính từ sự kiện cuối, không phải từ lúc kết nối. Bên điều khiển còn sống ghi nhịp tim vài giây một lần, nên im lặng quá khung chờ nghĩa là không còn ai để chờ. Mở lại cuộc trò chuyện sau khi khởi động lại sẽ kết thúc lượt bị bỏ rơi trong vòng một khung chờ.
| Tình huống | Bạn thấy |
|---|---|
| Bạn tải lại trang giữa câu trả lời | Mọi thứ trên màn hình quay lại, rồi câu trả lời tiếp tục. Không gì xuất hiện hai lần. |
| Bạn đóng tab | Agent vẫn làm việc. Mở lại cuộc trò chuyện sau để xem kết quả. |
| Lượt đang chờ bạn | Nó chờ phê duyệt hay câu trả lời của bạn, bao lâu cũng được. |
| Máy chủ đang chạy lượt dừng | Lượt được đánh dấu hết giờ và bạn thấy trạng thái kết thúc rõ ràng, không phải vòng xoay. |
Dọn lần chạy bị bỏ rơi
Chỉ tiến trình điều khiển lượt mới ghi kết thúc của nó. Backend dừng giữa chừng để lại dòng ở trạng thái đang chạy mà không ai hoàn tất, và không có gì trong cuộc trò chuyện hỏi lại.
Một tác vụ dọn trên hàng đợi tác vụ dùng chung sẽ kết thúc chúng. Lượt còn chạy quá trần mà chính bên điều khiển của nó sẽ dừng thì không thể còn bên điều khiển, nên tác vụ dọn không cần bản ghi sống riêng. Nó ghi cùng kiểu gián đoạn như bộ đọc, và bỏ qua lượt đang tạm dừng: lượt tạm dừng đang chờ một người và được chờ bao lâu tùy ý.
Giới hạn thời gian chạy
Hai hạn chót giới hạn một lần chạy, và chúng trả lời hai câu hỏi khác nhau.
| Hạn chót | Câu hỏi | Cách hoạt động |
|---|---|---|
| Khung chờ | Lần chạy được im lặng, không phát chunk nào, bao lâu? | Đặt lại mỗi khi có chunk. Lần chạy mất hai mươi phút qua cả chục lệnh gọi tool không bao giờ bị cắt vì chậm, chỉ bị cắt khi im lặng. |
| Trần | Cả lần chạy được kéo dài bao lâu, dù làm gì? | Cố định. Khóa gateway của lượt được cấp một lần lúc bắt đầu và hết hạn theo lịch riêng; lần chạy sống lâu hơn khóa sẽ bắt đầu lỗi các lần gọi mô hình giữa chừng. |
Bản triển khai đặt cả hai. Thời hạn của khóa phải dài hơn trần, nếu không cấu hình sẽ từ chối khởi động.
Trạng thái của lượt
| Trạng thái | Khi nào |
|---|---|
| Running (đang chạy) | Dòng lượt được ghi; hoặc khi câu trả lời/quyết định cuối cùng cho lượt tạm dừng chạy tiếp. |
| Awaiting (chờ trả lời hoặc phê duyệt) | Có chunk pause. |
| Succeeded (thành công) | Có chunk done. |
| Failed (thất bại) | Có chunk error, hoặc luồng kết thúc. |
| TimedOut (hết giờ) | Hạn chót của bộ đọc trôi qua khi bên điều khiển đã mất, hoặc tác vụ dọn kết thúc lần chạy bị bỏ rơi. |
| Cancelled (đã dừng) | Bạn bấm Stop, từ Running hoặc Awaiting. Đây là trạng thái duy nhất đạt được từ mọi trạng thái chưa kết thúc, và không mang mã lỗi. |
Bấm Stop kết thúc lượt ngay và giữ mọi thứ đã viết. Xem Tạm dừng và dừng lượt.
Bất biến
- Một lượt, N lần gọi mô hình, mỗi lần gọi một dòng nhật ký.
- Ràng buộc duy nhất trên tin nhắn và số thứ tự sự kiện, nên chunk phát lại không thể chèn hai lần.
- Không có khóa ngoại từ nhật ký kiểm tra vào chat; hai bên có thời hạn lưu giữ độc lập.
- Callback của runtime được bảo vệ bằng bí mật chung so sánh thời gian hằng, chỉ nêu mã lượt, tự suy ra tổ chức, người dùng và phòng ban từ đó, và chỉ chạm tới lượt đang chạy.
- Số thứ tự trace được cấp nguyên tử, vì cả vòng lặp mô hình lẫn callback của runtime cùng ghi vào một lượt; màn hình chat sắp xếp các bước theo số thứ tự.
Vì sao hoạt động như vậy
Vì sao lưu mọi sự kiện trước khi gửi?
Để tải lại trang, tab thứ hai hay kết nối lại đều đọc cùng một lịch sử. Trình duyệt không phải đoán phần đã lỡ, và hành động đã chạy không bao giờ chạy lại.
Vì sao hiện tóm tắt suy luận thay vì suy luận của mô hình?
Suy luận thô của mô hình không bao giờ rời runtime của agent. Mô hình nền của tổ chức viết vài câu ngay tại đó về những gì agent đã cân nhắc và quyết định: đủ để theo hướng đi và nhận ra chỗ sai, mà không lộ suy luận chưa lọc. Xem vòng lặp agent.
Vì sao tạm dừng lại kết thúc lần chạy rồi mở lần mới sau?
Bạn có thể trả lời sau một phút hoặc hôm sau, mà lần chạy có trần thời gian cố định. Vì vậy câu hỏi được lưu, lần chạy kết thúc, và câu trả lời của bạn mở một lần chạy mới từ trạng thái đã lưu. Không có gì mở chờ trong lúc đó, và câu trả lời tiếp tục đúng chỗ đã dừng.
Vì sao không đoán tiến con trỏ cũ?
Đoán có thể bỏ sót hoặc lặp khối. Khi con trỏ không khớp mục nào còn giữ, bản ghi lưu bền là câu trả lời trung thực duy nhất: lượt đã xong báo kết quả, lượt đang chạy bị bỏ rơi được kết thúc, lượt đang chờ được để yên.