Hướng dẫn AgentFlow

Ví dụ: quy trình và lượt chạy

Tìm và khởi chạy một quy trình, rồi đọc, tạm dừng, tiếp tục, hủy và chạy lại một lượt chạy — từng lệnh curl kèm phản hồi đã rút gọn.

Các lệnh dưới đây gọi API với tư cách một chủ thể dịch vụ. Đặt trước hai biến:

export ORIGIN=https://agentflow.example.com
export AGENTFLOW_KEY=afk_…

Phản hồi đã được rút gọn; … đánh dấu phần lược bỏ. Tên trường của biểu mẫu (so_luong, ghi_chu) là của một quy trình minh họa — hãy dùng tên trường của quy trình bạn.

1. Tìm quy trình được phép khởi chạy

curl -sS "$ORIGIN/api/v1/workflows/startable" \
  -H "Authorization: Bearer $AGENTFLOW_KEY"
{
  "items": [
    { "id": "3f6c…", "name": "Đề xuất mua sắm", "version_id": "a91d…" }
  ],
  "next_cursor": null,
  "prev_cursor": null
}
  • Danh sách chỉ có những quy trình đã xuất bản mà người gọi được phép khởi chạy; quy trình khác vắng mặt hẳn. version_id là phiên bản đang xuất bản.
  • sort là updated_at (mặc định) hoặc name. Không gửi dir thì updated_at sắp mới nhất trước, name sắp tăng dần. q tìm theo một phần của tên hoặc mô tả, không phân biệt hoa thường.
  • Danh sách phân trang như mọi danh sách khác. Xem Phân trang.

2. Đọc biểu mẫu khởi đầu

curl -sS "$ORIGIN/api/v1/workflow-versions/$VERSION_ID/start-form" \
  -H "Authorization: Bearer $AGENTFLOW_KEY"
{
  "form_definition": { … },
  "version_updated_at": "2026-09-01T08:12:44.201337Z",
  "form_updated_at": "2026-08-28T03:05:10.774120Z"
}

form_definition là null khi bước bắt đầu không gắn biểu mẫu nào. version_updated_at và form_updated_at cho biết phiên bản và biểu mẫu được sửa lần cuối lúc nào; yêu cầu khởi chạy ở bước 3 không có hai trường này.

3. Khởi chạy một lượt chạy

curl -sS -X POST "$ORIGIN/api/v1/workflows/$WORKFLOW_ID/instances" \
  -H "Authorization: Bearer $AGENTFLOW_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Đề xuất mua 10 laptop",
    "input_payload": { "so_luong": 10, "ghi_chu": "Cho nhóm kế toán" },
    "subject": { "kind": "record", "record_id": "7d2e…" }
  }'

201 Created:

{
  "id": "c04b…",
  "definition_id": "3f6c…",
  "version_id": "a91d…",
  "name": "Đề xuất mua 10 laptop",
  "status": "running",
  "starter": { "kind": "service_principal", "service_principal_id": "5b0e…" },
  "started_at": "2026-09-12T08:15:01.902551Z",
  "updated_at": "2026-09-12T08:15:01.902551Z",
  …
}
  • name là bắt buộc.
  • input_payload mang giá trị các trường của biểu mẫu khởi đầu, theo tên trường.
  • subject chỉ cần khi quy trình gắn với một hồ sơ. Một quy trình chạy trên nhiều hồ sơ cùng lúc không khởi chạy ở đây mà qua lượt chạy hàng loạt.
  • Mặc định lệnh trả về ngay với 201, và lượt chạy tiếp tục ở nền. Thêm wait_ms để chờ tối đa chừng ấy mili giây (bản triển khai đặt một giới hạn trên): 200 nếu trong lúc đó lượt chạy đã kết thúc hoặc dừng lại chờ, 202 nếu vẫn đang chạy.
  • Người gọi không được phép khởi chạy quy trình này: 403 FORBIDDEN.
  • 409 RUN_AS_UNRESOLVED khi chưa ai quyết định các lượt chạy của quy trình này hành động với tư cách ai.

Gửi lại mà không khởi chạy hai lần

Gửi kèm một Idempotency-Key. Ví dụ này khởi chạy có chờ, và kết nối rớt trước khi phản hồi về tới:

export IDEMPOTENCY_KEY=$(uuidgen)

curl -sS -i -X POST "$ORIGIN/api/v1/workflows/$WORKFLOW_ID/instances" \
  -H "Authorization: Bearer $AGENTFLOW_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -d '{
    "name": "Đề xuất mua 10 laptop",
    "input_payload": { "so_luong": 10, "ghi_chu": "Cho nhóm kế toán" },
    "wait_ms": 5000
  }'

Gửi lại đúng lệnh đó, với cùng khóa. Lượt chạy đã được khởi động ở lần trước, nên phản hồi nói về chính nó:

HTTP/1.1 202 Accepted
Content-Type: application/json
Idempotent-Replayed: true

{ "id": "c04b…", "name": "Đề xuất mua 10 laptop", "status": "running", … }
  • Cùng id với lượt chạy đã khởi động: không có lượt chạy thứ hai.
  • Lần phát lại không chờ lại: 202 khi lượt chạy còn đang chạy, 200 khi nó đã kết thúc hoặc dừng lại chờ.
  • Giữ nguyên cả wait_ms: nó nằm trong thân yêu cầu, nên đổi nó là một yêu cầu khác (422 IDEMPOTENCY_KEY_MISMATCH).
  • Chi tiết nằm ở Thử lại an toàn.

4. Đọc lượt chạy

curl -sS "$ORIGIN/api/v1/instances/$INSTANCE_ID" \
  -H "Authorization: Bearer $AGENTFLOW_KEY"
{
  "id": "c04b…",
  "name": "Đề xuất mua 10 laptop",
  "workflow_name": "Đề xuất mua sắm",
  "status": "running",
  "updated_at": "2026-09-12T08:15:02.418305Z",
  "active_tasks": [ … ],
  "node_runs": [ … ],
  "timeline": [ … ],
  …
}

Một khóa đọc được những lượt chạy do các khóa của chủ thể đó khởi động, hoặc mọi lượt chạy khi có instance.read.any hay instance.admin. Lượt chạy khác trả 404, y như không tồn tại.

Để liệt kê, dùng GET /api/v1/instances:

curl -sS -G "$ORIGIN/api/v1/instances" \
  -H "Authorization: Bearer $AGENTFLOW_KEY" \
  --data-urlencode "status=running" \
  --data-urlencode "q=laptop" \
  --data-urlencode "limit=20"
{
  "items": [
    { "id": "c04b…", "name": "Đề xuất mua 10 laptop", "workflow_name": "Đề xuất mua sắm", "status": "running", … }
  ],
  "next_cursor": null,
  "prev_cursor": null
}
  • q tìm theo một phần của tên lượt chạy, id của nó hoặc tên quy trình, không phân biệt hoa thường.
  • sort là started_at; không gửi dir thì lượt chạy khởi động gần nhất đứng trước.

5. Tạm dừng

curl -sS -X POST "$ORIGIN/api/v1/instances/$INSTANCE_ID/pause" \
  -H "Authorization: Bearer $AGENTFLOW_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Chờ xác nhận ngân sách"}'
{ "status": "paused", "paused": 3, "already_terminal": 0 }
  • Tạm dừng áp cho cả dòng: lượt chạy này và mọi lượt chạy con còn sống của nó. paused đếm số lượt chạy vừa được tạm dừng.
  • reason không bắt buộc; có thể bỏ cả thân yêu cầu.
  • Tạm dừng không thu hồi việc đã nằm trong hàng đợi: một lệnh gọi mô hình hay một email đã xếp hàng trước đó vẫn chạy.
  • Chỉ người khởi động hoặc quản trị viên được tạm dừng: nếu không, 403 FORBIDDEN.
  • 409 PAUSE_OWNED_BY_ROOT khi một lượt chạy trong dòng đã thuộc một lần tạm dừng khác. 409 PAUSE_CASCADE_CONTENTION khi lượt chạy sinh con nhanh hơn tốc độ tạm dừng — gửi lại nguyên yêu cầu.

6. Tiếp tục

Lệnh tiếp tục cần expected_updated_at: giá trị updated_at của lượt chạy, đọc sau khi tạm dừng. Ví dụ này dùng jq để lấy nó:

UPDATED_AT=$(curl -sS "$ORIGIN/api/v1/instances/$INSTANCE_ID" \
  -H "Authorization: Bearer $AGENTFLOW_KEY" | jq -r '.updated_at')

curl -sS -X POST "$ORIGIN/api/v1/instances/$INSTANCE_ID/resume" \
  -H "Authorization: Bearer $AGENTFLOW_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"expected_updated_at\": \"$UPDATED_AT\"}"
{ "status": "running", "resumed": 3, "ticked": 3 }
  • Chỉ tiếp tục được lượt chạy gốc — lượt đã được tạm dừng. Gọi trên một lượt chạy con trong dòng: 409 PAUSE_NOT_ROOT.
  • status là trạng thái thật của lượt chạy gốc sau đó: thường là running, nhưng giữ trạng thái kết thúc nếu nó đã kết thúc trong lúc bị giữ.
  • ticked đếm số lượt chạy thực sự được chạy tiếp.
  • 409 INSTANCE_NOT_PAUSED khi lượt chạy không bị tạm dừng. 409 STALE_VERSION khi expected_updated_at đã cũ — đọc lại rồi gửi lại.

7. Hủy

curl -sS -X POST "$ORIGIN/api/v1/instances/$INSTANCE_ID/cancel" \
  -H "Authorization: Bearer $AGENTFLOW_KEY"
{ "status": "cancelled", "cancelled": 4, "already_terminal": 1 }
  • Hủy là không đảo ngược, và cũng áp cho cả dòng. cancelled đếm lượt chạy vừa bị hủy — lượt này và các lượt chạy con còn sống; already_terminal đếm những lượt đã kết thúc từ trước và không bị đụng tới. Muốn dừng tạm thời, hãy tạm dừng.
  • 404 khi lượt chạy không tồn tại hoặc đã kết thúc.
  • 409 khi lượt chạy sinh con nhanh hơn tốc độ hủy: chưa lượt nào bị hủy, hãy gửi lại.

8. Chạy lại một lượt chạy thất bại

curl -sS -X POST "$ORIGIN/api/v1/instances/$INSTANCE_ID/retry" \
  -H "Authorization: Bearer $AGENTFLOW_KEY"
{
  "status": "running",
  "retried": 2,
  "ticked": 2,
  "already_completed": 5,
  "unretryable_failed": 0,
  "unretryable_cancelled": 0
}
  • Chạy lại áp cho lượt chạy failed và mọi lượt chạy thất bại bên dưới nó. Bước đã hoàn thành không chạy lại.
  • Lượt chạy luôn chạy trên bản chụp cố định của quy trình, nên chạy lại chỉ có ích khi lỗi ban đầu là tạm thời — ví dụ một dịch vụ bên ngoài đã hoạt động trở lại. Lỗi cấu hình cần xuất bản lại và khởi chạy một lượt mới.
  • status là trạng thái thật của lượt chạy gốc sau đó.
  • 409 khi không chạy lại được: RETRY_LINEAGE_BUSY tự hết sau ít lâu (đang chờ một lượt chạy còn chạy) — thử lại sau; RETRY_LINEAGE_BLOCKED là vĩnh viễn; INSTANCE_PAUSED cần tiếp tục lượt chạy trước.

On this page