Từ monolithic 804 dòng tới pipeline 8 stage có thể test riêng —
cùng Memory 3 tầng và Event Bus phân tách phụ thuộc.
Hình dung một nhà bếp mà đầu bếp vừa nấu, vừa rửa bát, vừa nhận order, vừa mua nguyên liệu — tất cả trong 1 hàm 804 dòng. Đó là runLoop() v2. Không thể test riêng từng bước, không thể thay thế một công đoạn mà không ảnh hưởng toàn bộ.
Tất cả logic gộp chung: gọi LLM, thực thi tool, prune context, lưu message, xử lý lỗi — tất cả trong một hàm duy nhất. Bug ở bất kỳ bước nào cũng đòi hỏi debug toàn bộ hàm.
Mỗi stage là một unit riêng biệt: có input/output rõ ràng, có thể test độc lập, có thể thay thế mà không ảnh hưởng stage khác. Bug khoanh vùng chính xác trong vài giây.
Setup một lần → Lặp nhiều vòng → Kết thúc dọn dẹp.
Nhấn vào mỗi stage để xem chi tiết cách hoạt động.
Stage khởi tạo toàn bộ context cần thiết cho phiên làm việc. Chạy một lần duy nhất trước khi vòng lặp bắt đầu.
Tim đập của pipeline — stage này chịu trách nhiệm giao tiếp với LLM provider và xử lý kết quả trả về.
Quản lý context window — đảm bảo không bao giờ vượt ngưỡng token của model, với chiến lược 2 pha tốc độ khác nhau.
Stage thực thi danh sách tool calls từ ThinkStage — với chiến lược song song hoặc tuần tự tùy loại tool.
Stage quan sát — tổng hợp tất cả kết quả trong vòng lặp hiện tại và chuẩn bị cho vòng tiếp theo.
Bảo vệ dữ liệu trong long-running sessions — flush messages định kỳ để chống mất dữ liệu khi crash.
Chuyển kiến thức từ Working Memory (context window) xuống Episodic Memory (database) — kích hoạt khi PruneStage thực hiện hard compaction.
Stage cuối cùng — đảm bảo tất cả dữ liệu được lưu đúng cách và cleanup hoàn toàn, ngay cả khi context bị cancel.
4 tool mới được thêm trong v3 — mở rộng khả năng agent với memory, vault, và delegation.
Khác với subagent (clone chính mình), delegate gửi task cho một agent khác đã được liên kết qua agent_links.
| Tham số | agent_key (required), task (required), mode (async|sync), timeout (max 600s) |
| Async | Fire-and-forget — agent chính tiếp tục ngay, không chờ kết quả |
| Sync | Chờ kết quả trả về trong timeout giây, kết quả inject vào conversation |
| Permission | Phải có agent_links record giữa 2 agent, cùng tenant. Emit event delegate.completed |
File: internal/tools/delegate_tool.go
Tool tìm kiếm chính — tìm đồng thời trên vault docs, episodic memory, và knowledge graph. Kết quả xếp hạng theo relevance.
| Tham số | query (required), scope (personal|team|shared), types (context,memory,note,skill,episodic), maxResults |
| Hybrid search | FTS (BM25) + vector similarity — kết quả combine từ cả hai phương pháp |
| So với | memory_search chỉ tìm trong memory store, kg_search chỉ tìm trong graph. vault_search tìm tất cả |
File: internal/tools/vault_search.go
Giống [[wikilinks]] trong markdown — tạo liên kết hai chiều giữa 2 tài liệu. Auto-register nếu tài liệu chưa tồn tại trong vault.
| Tham số | from (required), to (required), context (optional — mô tả mối quan hệ) |
| Auto-register | Nếu source/target chưa trong vault → tự đăng ký dựa trên đường dẫn workspace-relative |
File: internal/tools/vault_link.go
Lấy toàn bộ nội dung episodic memory theo ID — dùng khi agent cần reconstruct lịch sử chi tiết từ kết quả memory_search.
| Tham số | id (required — episodic memory ID từ kết quả memory_search) |
| Output | Full summary + metadata (session key, created date, turn count) |
| Yêu cầu | V3 episodic memory phải enabled — trả lỗi nếu không có |
File: internal/tools/memory_expand.go
RunState, MessageBuffer, Flow Control và Adapter Pattern.
RunState là struct trung tâm truyền qua mọi stage — chứa tất cả thông tin về một lần thực thi agent.
7 substates phản ánh trạng thái hiện tại của agent — được emit ra ngoài qua events để UI hiển thị spinner đúng loại.
MessageBuffer không phải một mảng đơn giản — nó chia messages thành 3 vùng với semantics khác nhau.
System prompt đã render — không bao giờ bị prune. Chứa identity, workspace info, memory injection.
Messages đã được flush vào DB. PruneStage có thể trim vùng này. ReplaceHistory() khi compact.
Messages trong vòng lặp hiện tại chưa lưu. FlushPending() tại checkpoint. All() ghép cả 3 vùng.
Mỗi stage trả về một trong 3 signal để điều khiển vòng lặp pipeline.
| Signal | Ý nghĩa | Hành động Pipeline |
|---|---|---|
| Continue | Stage hoàn thành, tiếp tục vòng lặp | Chạy stage tiếp theo trong vòng lặp |
| BreakLoop | Kết thúc vòng lặp bình thường | Thoát khỏi iteration loop → chạy FinalizeStage |
| AbortRun | Dừng khẩn cấp do lỗi nghiêm trọng | Dừng ngay lập tức — ghi lỗi, không qua FinalizeStage |
Thay vì rewrite toàn bộ 804 dòng code v2, team dùng Adapter Pattern: closures wrap các callbacks của v2 Loop thành interface mà Pipeline stages có thể gọi.
Working memory = bảng trắng trên bàn làm việc — thao tác nhanh, nhưng tắt đèn là mất. Episodic memory = nhật ký ghi chép hàng ngày — đọc lại được, nhưng phải tóm lược. Semantic memory = bách khoa toàn thư cá nhân — tri thức có cấu trúc, tra cứu theo chủ đề.
Tri thức chảy từ tầng 1 lên tầng 3 — và ngược lại được inject vào tầng 1.
ContextStage tự động inject memory vào system prompt trước mỗi vòng lặp — agent "nhớ" mà không cần user nhắc lại.
Sau mỗi session kết thúc hoặc memory được compact, hệ thống tự động consolidate — tất cả bất đồng bộ, không block user.
Ba worker chạy tuần tự qua Event Bus — mỗi worker chờ kết quả của worker trước qua event, không phải direct call.
Không phải mọi tri thức đều vĩnh viễn — KG v3 thêm chiều thời gian vào mỗi entity và relation.
Entities và relations vĩnh viễn — một khi tạo ra không bao giờ tự động lỗi thời. "Việt dùng React" mãi mãi đúng dù thực tế đã thay đổi.
Mỗi entity/relation có valid_from và valid_until. Tri thức tự động lỗi thời theo thời gian — phản ánh thực tế thay đổi.
Hệ thống bưu điện nội bộ — bạn gửi thư bỏ vào hòm thư, không cần biết ai nhận, không cần chờ họ đọc xong. Người cần thì tự đến lấy. Module không biết nhau, chỉ biết sự kiện.
| Sự Kiện | Producer | Consumer | Mục Đích |
|---|---|---|---|
| session.completed | FinalizeStage | Consolidation Worker 1 | Tạo episodic summary sau khi session kết thúc |
| prune.compacted | PruneStage | MemoryFlushStage | Flush memory khi hard compaction xảy ra |
| episodic.created | Consolidation W1 | Consolidation Worker 2 | Trích xuất entities từ episodic summary mới |
| entities.extracted | Consolidation W2 | Consolidation Worker 3 | Xây dựng relations giữa các entities vừa trích xuất |
| metrics.recorded | Pipeline stages | Evolution Engine | Thu thập performance metrics sau mỗi run |
| delegate.completed | Delegate Tool | Evolution Engine | Ghi nhận kết quả uỷ quyền cho sub-agent |
Vấn đề: Memory module cần trigger Evolution, Evolution cần đọc Memory metrics, Consolidation cần notify cả hai — tạo vòng import circular không thể compile trong Go.