Hướng dẫn xây dựng quy trình làm việc tự động hóa với OpenFang

10 phút đọc

Một Agent đơn lẻ có khả năng hạn chế, chỉ khi phối hợp nhiều Agent mới có thể đạt được tự động hóa toàn diện. Bài viết này sẽ giúp bạn làm chủ toàn bộ khả năng của công cụ quy trình làm việc OpenFang thông qua bốn ví dụ hoàn chỉnh: Bản tin ngành hàng ngày (Pipeline đơn giản), Giám sát và cảnh báo đối thủ (Fan-out + phân nhánh điều kiện), Quy trình sản xuất nội dung (Cộng tác đa Agent) và Phân loại & chuyển tiếp hỗ trợ khách hàng (Định tuyến có điều kiện).

Hướng dẫn xây dựng quy trình làm việc tự động hóa OpenFang: Từ Agent đơn lẻ đến đội ngũ Agent

Slug: openfang-workflow-automation-guide Danh mục: usage-guides (Hướng dẫn sử dụng) Từ khóa mục tiêu: Quy trình làm việc OpenFang, Quy trình tự động hóa OpenFang, Phối hợp Multi-Agent OpenFang Ý định tìm kiếm: Thông tin (Người dùng muốn xây dựng quy trình tự động hóa Agent phức tạp) Số lượng từ mục tiêu: ~2000 từ Ngôn ngữ: vi


Tại sao cần quy trình làm việc (Workflow)?

Các tác vụ mà một Agent đơn lẻ có thể hoàn thành là rất hạn chế. Khi bạn cần một quy trình khép kín như "Nghiên cứu chủ đề → Viết bài → Kiểm duyệt thực tế → Đăng tải → Giám sát phản hồi", bạn cần phối hợp nhiều Agent thành một quy trình làm việc.

Công cụ quy trình làm việc của OpenFang hỗ trợ ba chế độ phối hợp: Pipeline tuần tự (Pipeline), Phân phối song song (Fan-out) và Phân nhánh điều kiện (Conditional). Bạn có thể kết hợp các Hands và Agent thành các quy trình tự động hóa phức tạp giống như lắp ráp Lego.

Bài viết này sẽ dẫn dắt bạn làm chủ việc xây dựng quy trình làm việc trên OpenFang từ đơn giản đến phức tạp thông qua bốn ví dụ thực tế.

Các khái niệm cốt lõi về quy trình làm việc

Trước khi đi sâu vào các ví dụ, hãy tìm hiểu một số khái niệm cốt lõi:

Khái niệmGiải thích
TaskĐơn vị thực thi nhỏ nhất của quy trình, một Task tương ứng với một Hand hoặc một Agent
PipelineKết nối nhiều Task, đầu ra của Task trước tự động trở thành đầu vào của Task sau
Fan-outPhân phối một công việc cho nhiều Agent xử lý song song, sau đó tổng hợp kết quả
TriggerNguồn sự kiện kích hoạt quy trình: Lịch trình, Webhook, thay đổi tệp, lệnh tin nhắn
ContextTrạng thái chia sẻ được truyền giữa các bước trong quy trình, tương tự như phạm vi biến trong ngôn ngữ lập trình

Ví dụ 1: Bản tin ngành hàng ngày (Pipeline đơn giản)

Đây là quy trình Pipeline đơn giản nhất — tự động tạo bản tin ngành vào mỗi buổi sáng:

toml
[[workflows]]name = "daily_industry_briefing"description = "Tạo bản tin cập nhật ngành vào 8 giờ sáng mỗi ngày"[workflows.trigger]type = "schedule"cron = "0 8 * * 1-5"             # 8 giờ sáng các ngày trong tuần[[workflows.tasks]]id = "monitor"hand = "collector"config = { keywords = ["AI agent", "Rust framework"], sources = ["news", "github"] }timeout = 300[[workflows.tasks]]id = "summarize"hand = "researcher"config = { depth = "shallow", focus = "summary" }depends_on = ["monitor"]timeout = 600[[workflows.tasks]]id = "notify"channel = "slack"config = { channel = "#industry-news", format = "rich_text" }depends_on = ["summarize"][workflows.output]format = "slack_message"save_to = "workspace/briefings/{{date}}.md"

Quy trình thực thi: Collector thu thập → Researcher tóm tắt → Thông báo qua Slack. depends_on xác định mối quan hệ phụ thuộc giữa các Task.

Ví dụ 2: Giám sát và cảnh báo đối thủ (Song song + Tổng hợp)

Quy trình này giám sát đồng thời nhiều đối thủ cạnh tranh và tổng hợp kết quả thu thập song song để phân tích:

toml
[[workflows]]name = "competitor_monitor"description = "Giám sát song song 5 trang web đối thủ, tổng hợp thay đổi và gửi cảnh báo"[workflows.trigger]type = "schedule"cron = "0 */6 * * *"# Giai đoạn 1: Thu thập song song (Fan-out)[[workflows.tasks]]id = "check_competitor_a"hand = "collector"config = { target = "competitor-a.com", mode = "diff" }[[workflows.tasks]]id = "check_competitor_b"hand = "collector"config = { target = "competitor-b.com", mode = "diff" }[[workflows.tasks]]id = "check_competitor_c"hand = "collector"config = { target = "competitor-c.com", mode = "diff" }# Giai đoạn 2: Tổng hợp phân tích (Đợi tất cả thu thập hoàn tất)[[workflows.tasks]]id = "aggregate"hand = "researcher"config = { action = "merge_and_prioritize" }depends_on = ["check_competitor_a", "check_competitor_b", "check_competitor_c"]# Giai đoạn 3: Đánh giá điều kiện — chỉ thông báo nếu có thay đổi quan trọng[[workflows.tasks]]id = "check_significance"hand = "predictor"config = { action = "assess_impact" }depends_on = ["aggregate"]# Giai đoạn 4: Thông báo có điều kiện[[workflows.tasks]]id = "alert_high"channel = "telegram"config = { chat_id = "-100xxx", priority = "high" }depends_on = ["check_significance"]condition = "ctx.significance_score > 0.7"[[workflows.tasks]]id = "alert_low"channel = "email"config = { to = "[email protected]", priority = "low" }depends_on = ["check_significance"]condition = "ctx.significance_score <= 0.7"

Các mô hình chính ở đây là:

  • Fan-out: 5 Task thu thập ở Giai đoạn 1 chạy song song, không cần depends_on
  • Barrier: Task Aggregate ở Giai đoạn 2 phụ thuộc vào việc hoàn thành của cả 5 Task thu thập
  • Conditional: Giai đoạn 4 chọn kênh thông báo khác nhau dựa trên điểm số quan trọng

Ví dụ 3: Quy trình sản xuất nội dung (Cộng tác đa Agent)

Đây là kịch bản cộng tác đa Agent kinh điển — AI viết bài, AI kiểm duyệt, AI tạo ảnh:

toml
[[workflows]]name = "content_pipeline"description = "Quy trình sản xuất nội dung tự động từ chủ đề đến đăng tải"[workflows.trigger]type = "webhook"endpoint = "/webhook/content/new"secret = "${WEBHOOK_SECRET}"# Giai đoạn 1: Nghiên cứu[[workflows.tasks]]id = "research"hand = "researcher"config = {  depth = "deep",  source_types = ["academic", "news", "social"],  target_length = "3000_words"}timeout = 900# Giai đoạn 2: Viết bài (Sử dụng các model khác nhau)[[workflows.tasks]]id = "draft"hand = "researcher"              # Tái sử dụng Researcher Hand, nhưng dùng prompt khácconfig = {  model = "claude-opus-4-8",  instruction = "draft_article",  style = "professional_yet_approachable"}depends_on = ["research"]# Giai đoạn 3: Kiểm tra thực tế[[workflows.tasks]]id = "fact_check"hand = "researcher"config = {  model = "claude-haiku-4-5",   # Dùng model nhanh để kiểm tra  action = "verify_claims",  strictness = "high"}depends_on = ["draft"]# Giai đoạn 4: Tạo ảnh bìa[[workflows.tasks]]id = "generate_cover"hand = "clip"config = {  action = "generate_cover_image",  style = "modern_tech",  resolution = "1280x720"}depends_on = ["draft"]           # Không phụ thuộc vào kiểm tra thực tế, có thể chạy song song# Giai đoạn 5: Tối ưu hóa SEO[[workflows.tasks]]id = "seo_optimize"hand = "researcher"config = { action = "seo_optimize", target_keyword = "{{.keyword}}" }depends_on = ["fact_check"]# Giai đoạn 6: Đăng tải[[workflows.tasks]]id = "publish"channel = "webhook"config = { url = "{{.cms_endpoint}}", method = "POST" }depends_on = ["seo_optimize", "generate_cover"]# Giai đoạn 7: Quảng bá[[workflows.tasks]]id = "promote"channel = "twitter"config = { action = "post_thread", hashtags = ["#AI", "#Automation"] }depends_on = ["publish"]

Lưu ý rằng generate_cover ở Giai đoạn 4 chỉ phụ thuộc vào draft mà không phụ thuộc vào fact_check — điều này có nghĩa là việc tạo ảnh và kiểm tra thực tế sẽ được thực hiện song song, giúp giảm thời gian chờ đợi tổng thể.

Ví dụ 4: Phân loại và chuyển tiếp hỗ trợ khách hàng (Định tuyến có điều kiện)

Đây là quy trình hỗ trợ khách hàng thông minh, tự động định tuyến đến các quy trình xử lý khác nhau dựa trên loại vấn đề:

toml
[[workflows]]name = "support_triage"description = "Hỗ trợ khách hàng thông minh: Phân loại → Định tuyến → Xử lý → Chuyển tiếp"[workflows.trigger]type = "message"channel = "whatsapp"pattern = "/help *"# Phân loại[[workflows.tasks]]id = "classify"hand = "researcher"config = {  model = "claude-haiku-4-5",  action = "classify_intent",  categories = ["billing", "technical", "feature_request", "complaint"]}# Loại thanh toán → Truy vấn hệ thống[[workflows.tasks]]id = "handle_billing"channel = "webhook"config = { url = "https://billing-api.company.com/lookup" }depends_on = ["classify"]condition = "ctx.intent == 'billing'"# Loại kỹ thuật → Tìm kiếm cơ sở tri thức[[workflows.tasks]]id = "search_kb"hand = "researcher"config = { action = "search_knowledge_base", max_results = 3 }depends_on = ["classify"]condition = "ctx.intent == 'technical'"# Yêu cầu tính năng → Ghi vào Product Board[[workflows.tasks]]id = "log_feature"channel = "webhook"config = { url = "https://productboard-api.company.com/notes" }depends_on = ["classify"]condition = "ctx.intent == 'feature_request'"# Khiếu nại → Chuyển tiếp ngay cho nhân viên[[workflows.tasks]]id = "escalate"channel = "slack"config = { channel = "#urgent-support", mention = "@oncall" }depends_on = ["classify"]condition = "ctx.intent == 'complaint'"# Phản hồi cuối cùng[[workflows.tasks]]id = "reply"channel = "whatsapp"config = { reply_to = "{{.original_message.id}}" }depends_on = ["handle_billing", "search_kb", "log_feature", "escalate"]

Gỡ lỗi và kiểm thử quy trình

Trước khi triển khai thực tế, bạn nên sử dụng chế độ Dry Run để kiểm thử quy trình:

bash
# Dry run (không thực hiện các thao tác bên ngoài thực tế)openfang workflow run competitor_monitor --dry-run# Chỉ chạy đến Task được chỉ địnhopenfang workflow run content_pipeline --until draft# Xem lịch sử thực thi quy trìnhopenfang workflow history competitor_monitor --limit 10# Xem nhật ký chi tiết của một lần thực thiopenfang workflow inspect competitor_monitor --run-id abc123

Các phương pháp hay nhất cho quy trình làm việc

  1. Thiết lập thời gian chờ (timeout) hợp lý: Mỗi Task nên được thiết lập timeout để tránh việc một bước bị treo làm ảnh hưởng toàn bộ quy trình
  2. Thêm cơ chế thử lại (retry): Các Task liên quan đến yêu cầu mạng nên cấu hình retry = 3 và cơ chế chờ lũy tiến (exponential backoff)
  3. Sử dụng điều kiện (condition): Tránh thực thi các Task không cần thiết để tiết kiệm chi phí gọi API
  4. Ghi nhật ký thực thi: Cấu hình log_level = "debug" để phục vụ việc xử lý sự cố
  5. Giám sát sức khỏe quy trình: Kết nối các chỉ số quy trình vào Prometheus/Grafana

Câu hỏi thường gặp

Một quy trình hỗ trợ tối đa bao nhiêu Task?
Không có giới hạn cứng. Tuy nhiên, chúng tôi khuyến nghị nên kiểm soát số lượng Task trong một quy trình dưới 20 để đảm bảo tính bảo trì. Các quy trình phức tạp hơn nên được chia nhỏ thành nhiều quy trình con.
Làm thế nào để xử lý khi Task thực thi thất bại?
Mỗi Task có thể cấu hình chiến lược thất bại độc lập:

``toml
[workflows.tasks.fallback]
on_failure = "continue" # continue / retry / abort / escalate
retry_count = 3
retry_delay_seconds = 60
fallback_task = "manual_review" # Task dự phòng sau khi thất bại
``

Các quy trình có thể gọi lẫn nhau không?
Có. Sử dụng trigger.type = "workflow" để cho phép một quy trình kích hoạt quy trình khác. Kết hợp với điều kiện (condition) có thể tạo ra logic lồng nhau phức tạp.
Làm thế nào để truyền tham số động trong quy trình?
Sử dụng cú pháp mẫu {{.variable_name}}. Nguồn dữ liệu ngữ cảnh bao gồm: dữ liệu từ trigger, đầu ra của các Task trước đó và các biến cấu hình toàn cục.

Bước tiếp theo