Mở đầu — vì sao bài này quan trọng
Nếu bạn đã đi qua các bài trước về Pools, Lanes và Events, bạn sẽ nhận ra một điều: tất cả những thứ đó chỉ là khung. Chúng cho biết ai tham gia và khi nào quy trình bắt đầu hay kết thúc. Nhưng phần "thịt" thực sự của một quy trình — phần mô tả công việc gì đang được làm — nằm ở Activities. Đây là nơi nhân viên điền form, nơi hệ thống gọi API, nơi một con người ra quyết định, nơi một email được gửi đi. Không có Activity, sơ đồ BPMN của bạn chỉ là một cái khung rỗng.
Trong thực tế triển khai, tôi thấy đây là phần mà người mới mắc lỗi nhiều nhất. Nhiều bạn vẽ tất cả mọi thứ thành một hình chữ nhật chung chung gắn nhãn "Xử lý đơn hàng", rồi tự hỏi tại sao engine BPMN không chạy được, tại sao đội developer không hiểu phải làm gì. Lý do là vì BPMN 2.0 phân biệt rất rõ 8 loại Task chuẩn — mỗi loại có một biểu tượng riêng góc trên bên trái, và mỗi loại nói cho người đọc biết bản chất công việc đó là gì: do người làm, do máy làm, hay gửi/nhận thông điệp.
Bài này sẽ giúp bạn nắm vững hai cấp độ của Activity: Task (nguyên tử, không chia nhỏ được nữa) và Sub-process (gói gọn nhiều bước thành một khối). Khi bạn dùng đúng, sơ đồ của bạn vừa đọc được bằng mắt người, vừa chạy được bằng engine. Đó chính là sức mạnh của BPMN.
Khái niệm cốt lõi
Activity là gì
Trong BPMN, Activity là thuật ngữ chung chỉ bất kỳ "công việc nào được thực hiện" trong quy trình. Activity có hai dạng chính: Task và Sub-process. Cả hai đều được vẽ bằng hình chữ nhật bo tròn góc (rounded rectangle) — đây là cách bạn phân biệt Activity với Event (hình tròn) và Gateway (hình thoi) ngay từ cái nhìn đầu tiên.
Task — đơn vị công việc nguyên tử
Task là Activity nhỏ nhất, không thể chia nhỏ thêm nữa trong phạm vi của mô hình (atomic). Nghĩa là khi bạn vẽ một Task, bạn ngầm khẳng định: "Ở mức chi tiết này, đây là một bước trọn vẹn, không cần tách ra thêm." Một Task được biểu diễn bằng hình chữ nhật bo tròn với một dòng nhãn động từ + danh từ ở giữa, ví dụ "Phê duyệt yêu cầu", "Gửi email xác nhận".
Điểm mấu chốt mà nhiều người bỏ qua: BPMN 2.0 định nghĩa 8 loại Task chuẩn (task types), mỗi loại có một marker (biểu tượng nhỏ) ở góc trên bên trái:
- User Task (biểu tượng người): Công việc do con người thực hiện với sự trợ giúp của phần mềm. Trên một hệ thống BPMS (Business Process Management System) như Camunda hay Bizagi, User Task thường hiện ra dưới dạng một form trong worklist/inbox của nhân viên. Ví dụ: kế toán mở form "Duyệt chi phí" và bấm Approve.
- Service Task (biểu tượng bánh răng): Công việc do hệ thống tự động thực hiện, thường là gọi một API, một web service hoặc một đoạn code. Không có con người can thiệp. Ví dụ: gọi API ngân hàng để kiểm tra số dư, gọi service tính thuế.
- Send Task (biểu tượng phong bì tô đậm): Gửi một message ra ngoài cho một participant khác và quy trình tiếp tục ngay. Ví dụ: gửi đơn hàng sang hệ thống của nhà cung cấp.
- Receive Task (biểu tượng phong bì rỗng): Chờ nhận một message từ bên ngoài rồi mới tiếp tục. Ví dụ: chờ nhận xác nhận thanh toán từ cổng thanh toán.
- Manual Task (biểu tượng bàn tay): Công việc do con người làm hoàn toàn ngoài hệ thống, không có phần mềm hỗ trợ và engine không theo dõi được. Ví dụ: nhân viên kho dán nhãn vật lý lên thùng hàng.
- Business Rule Task (biểu tượng bảng): Gọi tới một bộ quy tắc nghiệp vụ hoặc một bảng quyết định (DMN) để lấy kết quả. Ví dụ: bảng quyết định "khách hạng nào được giảm bao nhiêu %". (Chi tiết về DMN sẽ học ở Bài 28.)
- Script Task (biểu tượng cuộn giấy): Engine tự chạy một đoạn script (Groovy, JavaScript, Python...) ngay bên trong nó. Ví dụ: tính lại tổng tiền sau khi áp mã giảm giá.
- Abstract/None Task (không biểu tượng): Task chưa xác định loại, dùng ở giai đoạn phác thảo sớm hoặc cho mục đích thuần tài liệu.
Sub-process — gói nhiều bước thành một khối
Khi một phần quy trình có quá nhiều bước, vẽ tất cả ra một mặt phẳng sẽ khiến sơ đồ rối như tô mì. Lúc này ta dùng Sub-process: một Activity chứa bên trong nó cả một luồng con với các Task, Gateway, Event riêng. Sub-process cho phép bạn áp dụng nguyên tắc "chia để trị" và phân tầng độ chi tiết.
Có hai cách hiển thị Sub-process:
- Collapsed (thu gọn): Hiển thị như một hình chữ nhật bo tròn bình thường nhưng có dấu cộng [+] ở cạnh dưới giữa. Người đọc bấm vào để "khoan sâu" xem bên trong. Đây là cách giữ sơ đồ cấp cao gọn gàng.
- Expanded (mở rộng): Hình chữ nhật được phóng to ra, hiển thị toàn bộ luồng con bên trong ngay trên cùng một trang.
- Embedded Sub-process: luồng con nằm gọn trong cùng một process, dùng chung dữ liệu của process cha. Đây là loại phổ biến nhất.
- Call Activity (đường viền đậm): gọi tới một process tái sử dụng được đã định nghĩa ở nơi khác — giống như "gọi hàm" trong lập trình. Ví dụ: quy trình "Xác thực KYC khách hàng" được dùng lại ở nhiều quy trình khác nhau.
- Event Sub-process (đường viền nét đứt): kích hoạt bởi một event, dùng để xử lý ngoại lệ — phần này gắn với Bài 21–22 về error handling.
Marker phụ trên Activity
Ngoài marker loại task, một Activity còn có thể mang thêm marker hành vi ở cạnh dưới: vòng lặp (loop), đa thực thể (multi-instance — học kỹ ở Bài 25), bù trừ (compensation — Bài 23) và Ad-hoc (~). Ở bài này bạn chỉ cần nhận diện chúng tồn tại; chi tiết sẽ được mổ xẻ ở các bài chuyên sâu.
Tình huống thực tế
Ví dụ 1 — Tiki: quy trình duyệt hoàn tiền
Đội vận hành của một sàn TMĐT lớn như Tiki xử lý hàng nghìn yêu cầu hoàn tiền mỗi ngày. Ban đầu nhóm BA vẽ toàn bộ quy trình bằng các hình chữ nhật chung chung: "Nhận yêu cầu", "Xử lý", "Hoàn tiền". Khi đưa cho đội developer để dựng trên Camunda, developer bó tay vì không biết bước nào máy làm, bước nào người làm.
Sau khi áp dụng đúng task types, sơ đồ trở thành:
- Receive Task "Nhận yêu cầu hoàn tiền" (chờ message từ app khách hàng).
- Business Rule Task "Phân loại yêu cầu" (gọi bảng quyết định: dưới 200.000đ thì auto-approve, trên thì cần người duyệt).
- User Task "Nhân viên CSKH thẩm định" (form hiện trong inbox của nhân viên, có nút Approve/Reject).
- Service Task "Gọi API cổng thanh toán hoàn tiền" (tự động chuyển tiền về ví khách).
- Send Task "Gửi email thông báo cho khách".
Ví dụ 2 — Một ngân hàng số: phân tầng bằng Sub-process
Một ngân hàng số giả định tại TP.HCM xây quy trình "Mở tài khoản online". Toàn bộ quy trình có khoảng 40 bước. Nếu vẽ phẳng, sơ đồ dài bằng cả màn hình, không ai duyệt nổi.
Nhóm kiến trúc quy trình chia thành 4 Sub-process ở cấp 0 (collapsed, mỗi cái một dấu [+]):
- Thu thập thông tin (Sub-process)
- Xác thực KYC — dùng Call Activity vì quy trình KYC này còn được tái sử dụng cho cả vay tiêu dùng và mở thẻ tín dụng.
- Thẩm định rủi ro (Sub-process)
- Kích hoạt tài khoản (Sub-process)
Bài học rút ra: Sub-process cho phép sếp nhìn 4 khối ở cấp cao mà vẫn hiểu toàn cảnh, trong khi developer khoan sâu để thấy chi tiết kỹ thuật. Đặc biệt, Call Activity giúp đội KYC chỉ cần bảo trì một quy trình duy nhất thay vì copy-paste sang ba nơi — sửa một chỗ, cả ba quy trình cùng cập nhật.
Ví dụ 3 — Một xưởng sản xuất: ranh giới Manual Task
Một công ty sản xuất đồ gỗ xuất khẩu tại Bình Dương số hóa quy trình đóng gói. Họ vướng vào tranh cãi: bước "công nhân dán tem QC lên sản phẩm" nên là loại Task nào?
Lúc đầu họ định để là User Task. Nhưng User Task ngụ ý có form trên hệ thống và engine theo dõi được tiến độ — trong khi công nhân chỉ cầm con tem dán tay, không hề chạm vào máy tính. Đúng ra đây phải là Manual Task: việc làm hoàn toàn ngoài hệ thống, engine không quản lý.
Họ chỉnh lại: "Dán tem QC" là Manual Task, còn bước ngay sau đó "Quét mã vạch xác nhận đã đóng gói" mới là User Task (công nhân quét bằng máy, dữ liệu đẩy về hệ thống).
Bài học rút ra: Phân biệt User Task và Manual Task không phải chuyện chữ nghĩa. Nó quyết định engine BPMN có kiểm soát và đo lường được bước đó hay không. Chọn sai, bạn sẽ kỳ vọng có số liệu mà thực tế không bao giờ thu được.
Hướng dẫn từng bước
Khi cần mô hình hóa phần "công việc" trong một quy trình, hãy làm theo trình tự sau:
- Liệt kê các bước công việc thô. Viết ra từng việc cần làm theo dạng động từ + danh từ: "Kiểm tra số dư", "Phê duyệt đơn", "Gửi thông báo". Chưa cần quan tâm loại Task.
- Hỏi từng bước: ai/cái gì thực hiện? Với mỗi bước, đặt câu hỏi: Con người làm trên hệ thống? → User Task. Hệ thống tự gọi API? → Service Task. Gửi/nhận thông điệp? → Send/Receive Task. Tra cứu quy tắc? → Business Rule Task. Người làm tay ngoài hệ thống? → Manual Task.
- Gán marker loại task. Trong công cụ vẽ (Camunda Modeler, Bizagi, draw.io), chọn đúng task type để biểu tượng góc trên hiện ra. Đừng để Task "trần" không marker nếu bạn đã biết bản chất của nó.
- Đếm số bước trên một mặt phẳng. Nếu một vùng có hơn 7–10 bước liên quan chặt chẽ, cân nhắc gom thành Sub-process. Nguyên tắc kinh nghiệm: mỗi cấp sơ đồ nên đọc hết trong khoảng 7±2 khối.
- Quyết định Embedded hay Call Activity. Nếu luồng con chỉ dùng một lần ở đây → Embedded Sub-process. Nếu nó được tái sử dụng ở nhiều quy trình → tách ra thành process riêng và gọi bằng Call Activity.
- Đặt tên động từ + danh từ nhất quán. Tên Activity phải mô tả hành động, không phải danh từ chung chung. Viết "Phê duyệt đơn hàng" thay vì "Đơn hàng". Một Task chỉ nên làm một việc.
- Kiểm tra tính nguyên tử. Với mỗi Task, tự hỏi: "Bên trong nó có còn luồng con nào tôi đang giấu không?" Nếu có và nó quan trọng, hãy nâng thành Sub-process. Nếu không, giữ nguyên là Task.
Lỗi thường gặp & mẹo
Lỗi 1 — Task "vạn năng" gắn nhãn mơ hồ. Vẽ "Xử lý đơn hàng" rồi nhét cả việc kiểm tra, duyệt, thanh toán vào đó. Mẹo: nếu tên Task chứa từ "xử lý", "quản lý", "thực hiện" chung chung, gần như chắc chắn bạn đang giấu một Sub-process bên trong.
Lỗi 2 — Để Task trần không marker dù đã biết loại. Bản vẽ trông "sạch" nhưng vô dụng cho developer. Mẹo: ở giai đoạn thiết kế để triển khai, mọi Task phải có task type rõ ràng.
Lỗi 3 — Nhầm User Task với Manual Task. Như ví dụ xưởng gỗ ở trên. Mẹo nhớ: User Task = có màn hình, Manual Task = không có màn hình, engine "mù" với Manual Task.
Lỗi 4 — Nhầm Send Task với Service Task. Service Task gọi một service và chờ kết quả trả về (request-response). Send Task chỉ bắn message đi rồi đi tiếp. Mẹo: nếu bạn cần dữ liệu trả lại để dùng tiếp, đó là Service Task.
Lỗi 5 — Lạm dụng Sub-process cho mọi thứ. Bọc một bước duy nhất vào Sub-process chỉ làm rối thêm. Mẹo: chỉ gom thành Sub-process khi bên trong thực sự có Start/End Event và nhiều bước.
Lỗi 6 — Sub-process expanded nhưng vẫn nhồi 30 bước. Mở rộng tại chỗ vẫn rối nếu quá nhiều bước. Mẹo: dùng collapsed [+] ở cấp cao, để chi tiết ở trang khoan sâu riêng.
Mẹo vàng: Một quy trình tự động hóa tốt thường là chuỗi xen kẽ Service Task (máy chuẩn bị dữ liệu) → User Task (người ra quyết định) → Service Task (máy thực thi quyết định). Nhìn ra nhịp điệu này giúp bạn thiết kế nhanh hơn rất nhiều.
Bài tập thực hành
Bài tập 1 — Phân loại Task. Cho các bước sau của quy trình "Đăng ký thẻ thành viên" tại một chuỗi cà phê. Hãy gán đúng task type cho từng bước:
- Khách điền form đăng ký trên kiosk → ?
- Hệ thống gọi API kiểm tra số điện thoại đã tồn tại chưa → ?
- Tra bảng quyết định để gán hạng thành viên ban đầu → ?
- Nhân viên pha chế đưa thẻ vật lý cho khách → ?
- Gửi SMS chào mừng → ?
Bài tập 2 — Tái cấu trúc bằng Sub-process. Bạn có một quy trình "Tuyển dụng nhân sự" gồm 18 bước trải dài: đăng tin, sàng lọc CV, phỏng vấn vòng 1, phỏng vấn vòng 2, kiểm tra tham chiếu, gửi offer, onboarding... Hãy nhóm 18 bước này thành 3–4 Sub-process collapsed ở cấp 0, và chỉ ra bước nào nên dùng Call Activity (gợi ý: phần nào có thể tái dùng cho nhiều vị trí?).
Bài tập 3 — Tìm Task ẩn. Lấy một quy trình bất kỳ ở nơi bạn làm việc, tìm một Task có tên chứa "xử lý" hoặc "quản lý". Khoan vào nó: liệt kê tất cả bước con bên trong và quyết định nên nâng thành Sub-process hay tách thành nhiều Task riêng.
Tóm tắt
Activity là phần "công việc thực sự" của một quy trình BPMN, luôn được vẽ bằng hình chữ nhật bo tròn góc. Có hai cấp:
- Task là đơn vị nguyên tử, không chia nhỏ thêm. BPMN 2.0 có 8 loại task chuẩn, mỗi loại một marker góc trên: User Task (người làm trên form BPMS), Service Task (máy gọi API), Send/Receive Task (gửi/chờ message), Manual Task (làm tay ngoài hệ thống), Business Rule Task (tra quy tắc/DMN), Script Task (chạy script), và None Task. Chọn đúng loại biến bản vẽ thành bản thiết kế chạy được.
- Sub-process gói nhiều bước thành một khối, hiển thị collapsed [+] hoặc expanded, giúp phân tầng độ chi tiết. Dùng Call Activity khi cần tái sử dụng một process ở nhiều nơi.