AI Agents

Workflow vs AI Agent: Khi Nào Nên Dùng Logic Deterministic Trong Production?

Agent không phải lúc nào cũng tốt hơn Workflow. Bài viết phân tích ranh giới control flow, autonomy và deterministic logic để thiết kế hệ thống AI vừa linh hoạt vừa đủ an toàn cho production.

Minh họa cho bài Workflow vs AI Agent: Khi Nào Nên Dùng Logic Deterministic Trong Production?
Mục lục bài viết

Hãy tưởng tượng bạn đang xây một AI assistant cho bộ phận chăm sóc khách hàng.

Người dùng nhắn:

“Tôi vừa bị trừ tiền hai lần. Kiểm tra giúp tôi và hoàn lại giao dịch bị trùng.”

Ở phiên bản đơn giản, hệ thống có thể dùng LLM để đọc câu hỏi, nhận ra đây là vấn đề thanh toán, truy vấn lịch sử giao dịch rồi soạn câu trả lời. Mọi thứ vẫn khá an toàn vì AI chủ yếu đọc và đề xuất.

Sau đó đội sản phẩm muốn tiến thêm một bước:

“Nếu đúng là giao dịch bị trùng thì cho AI tự hoàn tiền luôn.”

Thoạt nhìn, đây chỉ là việc thêm một tool refund_payment().

Nhưng kiến trúc hệ thống vừa thay đổi về bản chất.

Trước đây, một output sai có thể tạo ra một câu trả lời không chính xác. Bây giờ, một quyết định sai có thể thay đổi trạng thái của hệ thống thật: tiền được chuyển, đơn hàng bị hủy, database bị cập nhật hoặc một email được gửi ra ngoài.

Câu hỏi quan trọng lúc này không còn là:

“Model nào reasoning tốt hơn?”

Mà là:

AI nên được quyền quyết định phần nào của control flow, và phần nào phải tiếp tục nằm dưới quyền kiểm soát của code deterministic?

Đây chính là ranh giới giữa Workflow và Agent.

Anthropic mô tả Workflow là các hệ thống trong đó LLM và tools được điều phối theo những code path đã định nghĩa trước, trong khi Agent cho phép model tự quyết định quá trình và cách sử dụng tools ở runtime. Research ban đầu cũng tập trung đúng vào ranh giới quyền kiểm soát này: lựa chọn Workflow hay Agent thực chất liên quan đến predictability, chi phí, bảo mật, auditability và mức rủi ro mà hệ thống có thể chấp nhận. Vì vậy, cách hiểu hữu ích nhất không phải:

Text
Workflow = cũ
Agent    = mới

hay:

Text
Workflow = ngu
Agent    = thông minh

Mà là:

Text
Workflow
Developer quyết định:
"bước tiếp theo là gì?"

Agent
Model được phép quyết định:
"bước tiếp theo nên là gì?"

Và trong production, câu trả lời tốt nhất thường không nằm ở một trong hai cực.

Nó nằm ở kiến trúc lai: probabilistic reasoning bên trong deterministic boundaries.


Workflow và Agent khác nhau ở đâu?

Trước khi nói đến architecture pattern, chúng ta cần sửa một hiểu nhầm rất phổ biến:

Workflow không đồng nghĩa với một hệ thống hoàn toàn deterministic.

Một Workflow hoàn toàn có thể gọi LLM.

Ví dụ:

Text
Input
  │
  ▼
LLM: Extract fields
  │
  ▼
Validate schema
  │
  ▼
LLM: Summarize
  │
  ▼
Store result

Hai lần gọi LLM vẫn mang tính xác suất. Cùng một input, wording của summary có thể khác nhau.

Thứ được lập trình cố định ở đây là control flow:

Text
extract
→ validate
→ summarize
→ store

Model không được tự nhiên quyết định:

“Có lẽ tôi nên bỏ qua validation, tìm thêm dữ liệu trên Internet rồi gửi email cho CFO.”

Trong Workflow, application owns the path.

Ngược lại, một Agent thường hoạt động gần với mô hình này:

Text
                ┌──────────────┐
                │     Goal     │
                └──────┬───────┘
                       ▼
                ┌──────────────┐
          ┌────►│     LLM      │
          │     │ decide next  │
          │     └──────┬───────┘
          │            ▼
          │     ┌──────────────┐
          │     │  Tool call   │
          │     └──────┬───────┘
          │            ▼
          │     ┌──────────────┐
          └─────│ Observation  │
                └──────────────┘
                       │
                 Goal reached?
                  │         │
                 no        yes
                  │         ▼
                  └────── Result

Agent nhận một mục tiêu, quan sát trạng thái hiện tại, chọn hành động, gọi tool, xem kết quả rồi quyết định bước tiếp theo.

Anthropic mô tả agent thực tế gần như một LLM sử dụng tools trong một vòng lặp dựa trên feedback từ môi trường. OpenAI cũng nhấn mạnh đặc điểm tương tự: agent sử dụng LLM để quản lý quá trình thực thi workflow, tự chọn tools và xác định khi nào nhiệm vụ đã hoàn tất.

Một mental model đơn giản

Có thể xem hai kiến trúc như hai cách phân phối quyền quyết định.

Câu hỏi Workflow Agent
Ai quyết định bước tiếp theo? Application code LLM
Các nhánh chính có biết trước không? Thường có Có thể không
Số bước có cố định không? Thường tương đối cố định Có thể thay đổi
Tool nào được gọi? Code quyết định hoặc giới hạn rất chặt Model lựa chọn trong toolset
Dễ dự đoán latency/cost? Cao hơn Thấp hơn
Xử lý tình huống mới Hạn chế hơn Linh hoạt hơn
Debug control flow Dễ hơn Khó hơn
Error compounding Thường được giới hạn Cao hơn khi chạy nhiều bước
Phù hợp open-ended task Không phải điểm mạnh Rất phù hợp

Điểm cuối cùng đặc biệt quan trọng.

Không phải Agent tốt hơn Workflow. Agent chỉ mua cho hệ thống một thứ mà Workflow thiếu: khả năng lựa chọn đường đi ở runtime.

Đổi lại, bạn phải trả bằng complexity, latency, cost và uncertainty.


Tại sao Workflow thường nên là điểm bắt đầu?

Giả sử hệ thống phải xử lý hóa đơn:

  1. nhận PDF;
  2. extract invoice number;
  3. extract supplier;
  4. extract total amount;
  5. validate schema;
  6. kiểm tra duplicate;
  7. ghi dữ liệu vào hệ thống kế toán.

Bạn hoàn toàn có thể xây một Agent và nói:

“Hãy xử lý invoice này. Bạn có OCR tool, database tool và accounting API.”

Agent có thể tự lựa chọn thứ tự hành động.

Nhưng câu hỏi là: tại sao chúng ta cần nó tự chọn?

Nếu business process đã biết trước thì khả năng tự chủ không giải quyết thêm vấn đề nào. Nó chỉ mở thêm không gian trạng thái mà hệ thống phải kiểm thử.

Một Workflow đơn giản:

Text
Invoice
   │
   ▼
Extract
   │
   ▼
Schema Validation
   │
   ▼
Duplicate Check
   │
   ▼
Business Rules
   │
   ▼
Human Approval if needed
   │
   ▼
Accounting API

đã đủ.

Anthropic khuyến nghị bắt đầu bằng giải pháp đơn giản nhất và chỉ tăng complexity khi kết quả thực tế chứng minh rằng sự phức tạp đó cần thiết. Theo họ, Workflow phù hợp hơn cho những nhiệm vụ well-defined cần predictability và consistency, trong khi Agent phù hợp khi bài toán thực sự cần flexibility và model-driven decision-making.

OpenAI cũng đưa ra nguyên tắc gần như tương tự: agent đặc biệt có ích khi workflow chứa quyết định phức tạp, rule-set trở nên quá khó duy trì hoặc input chủ yếu là dữ liệu phi cấu trúc; nếu không có những đặc điểm đó, một deterministic solution có thể đã đủ.

Điều này dẫn tới một nguyên tắc kiến trúc rất hữu ích:

💡 Đừng hỏi “Agent có làm được không?”. Hãy hỏi “Tại sao task này cần quyền tự quyết ở runtime?”.

Nếu không trả lời được câu thứ hai, Agent nhiều khả năng là abstraction không cần thiết.


Từ Prompt Chain đến Agent: một thang độ tự chủ

Workflow và Agent không tạo thành hai chiếc hộp hoàn toàn tách biệt.

Giữa chúng tồn tại nhiều mức autonomy.

Một cách thiết kế tốt là tăng dần quyền tự quyết của model khi task yêu cầu.

Text
Ít autonomy
     │
     ▼
Single LLM Call
     │
     ▼
Prompt Chaining
     │
     ▼
Routing
     │
     ▼
Parallelization
     │
     ▼
Orchestrator → Workers
     │
     ▼
Evaluator ↔ Optimizer
     │
     ▼
Autonomous Agent
     │
     ▼
Nhiều autonomy

Các pattern như chaining, routing, parallelization, orchestrator-workers và evaluator-optimizer cũng xuất hiện trong hướng dẫn kiến trúc agent của Anthropic. Điểm quan trọng không phải nhớ tên pattern, mà hiểu quyền quyết định đang được chuyển từ code sang model đến mức nào.

Prompt Chaining: đường đi cố định, intelligence nằm trong từng node

Ví dụ một hệ thống viết báo cáo:

Text
Raw documents
      │
      ▼
Extract facts
      │
      ▼
Fact validation
      │
      ▼
Generate outline
      │
      ▼
Write report
      │
      ▼
Style validation

Mỗi node có thể dùng LLM, nhưng thứ tự execution đã biết.

Điểm mạnh của pattern này là failure localization.

Nếu report sai factual data, chúng ta có thể kiểm tra bước extraction và validation.

Nếu cấu trúc bài tệ, kiểm tra outline.

Nếu tone sai, kiểm tra writing stage.

Một call khổng lồ:

Text
documents → "hãy tự làm mọi thứ" → report

có ít control surface hơn rất nhiều.

Đổi lại, chaining thêm latency vì nhiều model call phải chạy tuần tự. Vì vậy nó hợp lý khi chia task thành các subproblem nhỏ thực sự giúp tăng chất lượng.

Routing: model quyết định “đi nhánh nào”, không quyết định toàn bộ hành trình

Một customer support system có thể làm:

Text
                      ┌─ Billing workflow
User → Intent Router ─┼─ Technical workflow
                      ├─ Account workflow
                      └─ Security workflow

Router có thể là LLM.

Như vậy một phần decision-making đã trở nên probabilistic.

Nhưng sau khi router chọn "billing", application vẫn điều khiển Billing Workflow.

Đây là ví dụ rất hay cho thấy:

Có sử dụng LLM để chọn nhánh không đồng nghĩa toàn bộ hệ thống đã trở thành autonomous agent.

Routing đặc biệt hữu ích khi mỗi category cần prompt, model, tools hoặc policy khác nhau.

Parallelization: nhiều reasoning path nhưng orchestration vẫn cố định

Một security review có thể chạy:

Text
                ┌─ Dependency reviewer ─┐
Code ───────────┼─ Auth reviewer ───────┼─ Aggregate
                ├─ Injection reviewer ──┤
                └─ Data reviewer ───────┘

Application đã quyết định bốn reviewer phải chạy.

Các LLM chỉ thực hiện phần reasoning được giao.

Pattern này có thể giảm wall-clock latency khi subtask độc lập, hoặc tăng coverage bằng cách cho nhiều evaluator nhìn vấn đề từ những góc khác nhau. Nhưng nó thường tăng tổng số token và compute.

Orchestrator-Workers: decomposition bắt đầu trở nên động

Đây là lúc ranh giới trở nên thú vị hơn.

Giả sử người dùng yêu cầu:

“Thêm authentication bằng OAuth vào repository này.”

Bạn không biết trước:

  • bao nhiêu file phải sửa;
  • framework nào đang dùng;
  • config ở đâu;
  • migration có cần không;
  • test nào cần cập nhật.

Một orchestrator có thể đọc repository rồi quyết định:

Text
               ┌─ Worker: inspect auth
               │
Task → Planner ┼─ Worker: modify API
               │
               ├─ Worker: update frontend
               │
               └─ Worker: add tests
                        │
                        ▼
                     Synthesis

Subtask được tạo ở runtime.

Đó là một bước tăng autonomy rất lớn so với parallelization, nơi các subtask đã được developer định nghĩa từ trước. Anthropic cũng dùng chính khả năng dynamic decomposition này làm điểm phân biệt quan trọng giữa hai pattern.

Evaluator-Optimizer: model được quyền thử lại

Một model tạo output.

Model khác đánh giá output theo rubric.

Nếu chưa đạt:

Text
Generator
    │
    ▼
Candidate
    │
    ▼
Evaluator
  │     │
 fail  pass
  │     │
  ▼     ▼
Feedback Result
  │
  └────────► Generator

Ngay khi có loop, chúng ta phải bắt đầu nghĩ đến những thứ mà workflow tuyến tính ít phải quan tâm:

  • maximum iterations;
  • timeout;
  • token budget;
  • progress condition;
  • quality threshold;
  • fallback.

Nếu không, "hãy cải thiện cho đến khi tốt" có thể trở thành một loop đắt tiền nhưng chất lượng gần như không đổi.


Agent thực sự cần thiết khi nào?

Có một dấu hiệu rất rõ:

Bạn không biết trước con đường giải quyết task, nhưng môi trường có thể cung cấp feedback để Agent kiểm tra xem hành động vừa rồi có đưa nó gần mục tiêu hơn hay không.

Coding là ví dụ gần như lý tưởng.

Một Agent sửa bug có thể:

Text
Read code
   │
   ▼
Form hypothesis
   │
   ▼
Modify code
   │
   ▼
Run tests
   │
   ├── fail ──► inspect error ──► modify again
   │
   └── pass ──► final verification

Model không cần developer hard-code tất cả các con đường như:

Python
if ImportError:
    ...
elif TypeError:
    ...
elif failing_test_A:
    ...
elif failing_test_B:
    ...

Environment đã cung cấp một signal tương đối khách quan:

Text
test passed / failed
compiler succeeded / failed
HTTP request succeeded / failed
file exists / does not exist

Đó là thứ Anthropic gọi là việc Agent thu nhận ground truth từ environment để đánh giá progress và điều chỉnh hành động. Họ cũng lưu ý Agent đặc biệt phù hợp với open-ended problems nơi số bước cần thiết khó dự đoán hoặc không thể hard-code trước.

Browser automation cũng có tính chất tương tự.

Agent có thể click một nút, quan sát trang mới rồi quyết định bước tiếp theo. Website là một environment thay đổi theo hành động của Agent.

Ngược lại, một task như:

“Lấy customer_id, kiểm tra balance rồi tính 2% service fee.”

không có gì thực sự cần khám phá.

Đưa một Agent vào đây chỉ để nó tự nghĩ:

“Bước tiếp theo tôi nên nhân với 0.02.”

là dùng probabilistic reasoning để thay thế một phép toán deterministic đã có lời giải chính xác.

🔬 Deep Dive — Verifiable feedback quan trọng hơn “reasoning mạnh”

Một Agent có thể reasoning rất tốt nhưng vẫn khó vận hành nếu hệ thống không biết đánh giá tiến độ.

Hãy so sánh:

Task A

Text
Fix repository cho đến khi toàn bộ test pass.

Ta có verifier:

Bash
pytest

Task B

Text
Hãy cải thiện chiến lược công ty cho đến khi chiến lược đủ tốt.

“Đủ tốt” không có một verifier khách quan tương đương.

Agent có thể liên tục tạo thêm analysis mà không có một signal mạnh để biết lần thứ năm thực sự tốt hơn lần thứ tư.

Vì vậy, khi đánh giá một use case agentic, ngoài complexity hãy hỏi:

Text
Sau mỗi action, hệ thống lấy evidence nào
để biết Agent đang đi đúng hướng?

Nếu không có câu trả lời tốt, autonomy thường phải được giới hạn nhiều hơn.


Deterministic logic thực sự có nghĩa là gì trong một hệ thống AI?

Từ “deterministic” rất dễ bị dùng quá rộng.

Trong ngữ cảnh architecture, điều quan trọng không phải biến toàn bộ AI system thành một hàm:

Text
same input → exact same bytes output

Thực tế còn có:

  • database state;
  • network response;
  • time;
  • concurrent transactions;
  • external APIs;
  • model version;
  • retry;
  • distributed systems.

Một cách hiểu hữu ích hơn là:

Những invariants và state transition quan trọng được quyết định bởi executable rules mà application kiểm soát, thay vì được model tự suy diễn.

Ví dụ:

Python
def calculate_refund(order):
    refundable = order.paid_amount - order.already_refunded

    if refundable <= 0:
        raise RefundNotAllowed()

    if order.age_days > 30:
        raise RefundWindowExpired()

    return refundable

LLM có thể hiểu câu:

“Tôi mua nhầm gói và muốn lấy lại tiền.”

Nhưng không nên tự tính rule hoàn tiền bằng cách đọc policy rồi improvisation mỗi lần.

Ta có thể tách responsibility:

Text
LLM
Hiểu ngôn ngữ tự nhiên
        │
        ▼
Structured intent
{
  "action": "request_refund",
  "order_id": "ORD-123"
}
        │
        ▼
Deterministic policy engine
- authentication
- ownership
- refund window
- previous refund
- amount
        │
        ▼
Approved action
        │
        ▼
Payment API

Đây là một design pattern mạnh bởi mỗi thành phần làm đúng thứ nó giỏi.

LLM xử lý:

  • ambiguity;
  • intent;
  • unstructured text;
  • semantic interpretation.

Code xử lý:

  • arithmetic;
  • permissions;
  • invariant;
  • transaction;
  • idempotency;
  • policy enforcement.

Một nguyên tắc đáng nhớ

Reason with AI. Enforce with code.

Không phải mọi application đều cần tuân thủ tuyệt đối nguyên tắc này, nhưng khi blast radius tăng thì nó càng có giá trị.


Vì sao không nên để Agent nắm toàn bộ critical path?

Vấn đề không đơn giản là “LLM có thể hallucinate”.

Trong Agent, uncertainty có thể tích lũy qua nhiều bước.

Giả sử mỗi decision point có xác suất đúng rất cao:

Text
Step 1: 98%
Step 2: 98%
Step 3: 98%
Step 4: 98%
Step 5: 98%

Nếu các lỗi độc lập — một giả định đơn giản hóa nhưng hữu ích để xây intuition — xác suất toàn bộ chuỗi năm quyết định đều đúng là:

Text
0.98^5 ≈ 90.4%

Điều này không có nghĩa mọi Agent năm bước chỉ chính xác 90,4%. Thực tế các lỗi không độc lập và nhiều Agent có khả năng tự sửa nhờ feedback.

Nhưng phép tính cho thấy một vấn đề kiến trúc:

Reliability của từng decision chưa đủ. Ta phải quan tâm reliability của cả trajectory.

Một lỗi đầu tiên có thể làm thay đổi context cho bước thứ hai.

Bước hai lại được reasoning dựa trên state sai.

Sau vài iteration, hệ thống không chỉ có một output sai; nó có thể đang ở một trạng thái khác hoàn toàn so với trạng thái mà developer dự kiến.

Anthropic cũng cảnh báo autonomy làm tăng cost và nguy cơ compounding errors, vì thế agent nên có testing, sandbox và guardrails thích hợp.

Failure mode 1: loop không giới hạn

Agent:

Text
search → evaluate → search → evaluate → search → ...

Không có:

Text
max_turns
timeout
budget

thì failure mode không còn là “output kém”.

Nó trở thành resource exhaustion.

Failure mode 2: action đúng về cú pháp nhưng sai về ý nghĩa

Tool schema:

Json
{
  "tool": "cancel_subscription",
  "customer_id": "123"
}

hoàn toàn valid.

Nhưng customer chỉ hỏi:

“Nếu tôi cancel thì có mất dữ liệu không?”

Schema validation không phát hiện được lỗi semantic này.

Failure mode 3: retry một hành động không idempotent

Agent gọi:

Text
charge_card(100)

Network timeout.

Agent không biết server đã process chưa nên retry.

Kết quả:

Text
charge #1 = success
charge #2 = success

Đây là distributed-systems problem, không phải prompt-engineering problem.

Một production architecture cần idempotency key, transaction semantics hoặc reconciliation logic.

Failure mode 4: authority quá rộng

Một Agent có:

Text
read_customer
update_customer
refund_payment
delete_account
send_email

Không có nghĩa nó nên có quyền dùng tất cả tools trong mọi context.

Security boundary phải nằm ngoài model.

Authentication và authorization không thể chỉ là một đoạn system prompt:

Text
"Please don't refund more than $500."

Nếu $500 là policy thật, enforce nó bằng code.

OpenAI cũng khuyến nghị tool safeguards dựa trên các yếu tố như read/write access, reversibility, account permissions và financial impact; với high-risk action, hệ thống có thể yêu cầu guardrail hoặc human escalation.


Khi nào cần đặt deterministic boundary?

Không có một checklist duy nhất áp dụng cho mọi hệ thống, nhưng sáu câu hỏi sau thường đủ để kiến trúc sư biết autonomy nên dừng ở đâu.

Dimension Autonomy có thể cao hơn Nên tăng deterministic control
Predictability Path khó biết trước Process đã biết rõ
Reversibility Action dễ undo Action khó hoặc không thể đảo ngược
Failure impact Sai sót chỉ gây inconvenience nhỏ Có financial, legal, security hoặc safety impact
Verifiability Environment cung cấp feedback mạnh Không có verifier đáng tin
Authority Read-only hoặc sandbox Write/delete/payment/privileged operation
Auditability Chỉ cần answer cuối Phải giải thích chính xác policy và state transition

Điểm quan trọng là đừng đánh giá “task” như một khối duy nhất.

Một workflow có thể chứa cả vùng low-risk và high-risk.

Ví dụ loan-processing assistant:

Text
User document
     │
     ▼
LLM extracts information       ← probabilistic OK
     │
     ▼
Schema validation              ← deterministic
     │
     ▼
LLM detects missing context    ← probabilistic OK
     │
     ▼
Customer provides data
     │
     ▼
Eligibility rules             ← deterministic
     │
     ▼
Risk model / policy
     │
     ▼
Approval checkpoint           ← controlled
     │
     ▼
Loan system update            ← deterministic transaction

Không cần lựa chọn:

Text
"toàn bộ Agent"

hoặc:

Text
"không dùng AI"

Ta chọn autonomy theo từng boundary.

🏗️ Production Note — High-risk không có nghĩa “cấm AI”

Trong các hệ thống chịu regulatory exposure, mục tiêu thường không phải loại AI khỏi toàn bộ pipeline.

Mục tiêu là thiết kế oversight và control phù hợp với risk.

NIST Generative AI Profile nhấn mạnh rằng deployment của generative AI có thể đòi hỏi human review, tracking, documentation và management oversight bổ sung tùy context.

EU AI Act cũng yêu cầu các high-risk AI systems thuộc phạm vi điều chỉnh phải được thiết kế để con người có thể thực hiện oversight hiệu quả; Article 14 còn nêu khả năng người giám sát hiểu giới hạn của hệ thống, bỏ qua hoặc đảo ngược output, can thiệp và dừng hệ thống khi thích hợp. Article 15 đặt thêm yêu cầu về accuracy, robustness và cybersecurity.

Điều này củng cố một principle rộng hơn:

Càng tăng consequence và autonomy, architecture càng cần nhiều control mechanism nằm ngoài LLM.


Kiến trúc production mạnh nhất thường là Hybrid

Rất ít hệ thống enterprise cần chọn tuyệt đối giữa:

Text
100% Workflow

và:

Text
100% Autonomous Agent

Một thiết kế thực tế thường trông giống như:

Text
┌───────────────────────────────┐
│       Deterministic Shell     │
│                               │
│   Auth / Policy / Budget      │
│   Audit / State / Approval    │
│                               │
│       ┌───────────────┐       │
│       │ Agentic Zone  │       │
│       │               │       │
│       │ reason        │       │
│       │ search        │       │
│       │ plan          │       │
│       │ inspect       │       │
│       └───────┬───────┘       │
│               │               │
│        Structured proposal    │
│               │               │
│               ▼               │
│        Policy validation      │
│               │               │
│               ▼               │
│        Controlled action      │
└───────────────────────────────┘

Agent được tự do trong vùng mà ambiguity có giá trị.

Nhưng freedom dừng lại trước những state transition quan trọng.

Pattern 1: Agent inside Workflow

Workflow là backbone.

Text
Validate request
      │
      ▼
Agent investigates issue
      │
      ▼
Structured result
      │
      ▼
Business rule
      │
      ▼
Approval
      │
      ▼
Execute

Ví dụ customer support refund:

Agent có thể:

  • đọc ticket;
  • tìm transaction;
  • đọc policy;
  • tìm dấu hiệu duplicate;
  • giải thích tình huống.

Sau đó trả:

Json
{
  "order_id": "ORD-123",
  "recommended_action": "refund",
  "reason": "duplicate_charge",
  "transaction_ids": ["TX1", "TX2"]
}

Nhưng Agent không tự quyết định số tiền cuối cùng.

Backend tính:

Python
refund_amount = calculate_refund(order, transactions)

và policy engine quyết định:

Python
if refund_amount > AUTO_REFUND_LIMIT:
    require_human_approval()

Agent cung cấp intelligence.

Workflow giữ authority.

Đây thường là pattern an toàn nhất cho enterprise automation.


Pattern 2: Workflow as a Tool

Một Agent cần xử lý hành trình mở, nhưng một số nghiệp vụ phải chạy theo SOP cố định.

Thay vì cho Agent access vào hàng chục low-level APIs:

Text
search_flight()
hold_seat()
calculate_tax()
create_booking()
charge_card()
issue_ticket()
send_confirmation()

ta có thể expose một capability có boundary rõ hơn:

Text
create_confirmed_booking(...)

Bên dưới:

Text
Agent
  │
  ▼
BookFlight Tool
  │
  ├─ validate passenger
  ├─ validate itinerary
  ├─ calculate price
  ├─ reserve seat
  ├─ payment authorization
  ├─ commit transaction
  └─ issue confirmation

Agent quyết định khi nào nghiệp vụ này cần chạy.

Nhưng không tự điều phối những invariant bên trong nó.

Đây là abstraction cực kỳ quan trọng.

Một tool tốt không nhất thiết tương ứng với một database function.

Tool có thể đại diện cho một business capability hoàn chỉnh.

🔬 Deep Dive — Tool granularity là một security decision

Hãy so sánh hai toolset.

Toolset A

Text
execute_sql(sql)
http_request(method, url, body)
run_shell(command)

Toolset B

Text
get_customer_profile(customer_id)
create_refund_request(order_id, reason)
check_refund_status(refund_id)

Toolset A linh hoạt hơn rất nhiều.

Nhưng model cũng có action space lớn hơn rất nhiều.

Nó có thể tạo ra những combination mà developer chưa bao giờ nghĩ tới.

Toolset B hạn chế hơn, nhưng mỗi operation có:

  • schema rõ;
  • authorization rõ;
  • validation rõ;
  • audit semantics rõ;
  • blast radius nhỏ hơn.

Vì vậy thiết kế tool không chỉ là chuyện developer ergonomics.

Nó là thiết kế capability boundary.


Một kiến trúc mẫu: từ user request đến controlled execution

Giả sử chúng ta xây một Agent nội bộ có thể xử lý yêu cầu hoàn tiền.

Một naive implementation có thể là:

Python
while True:
    action = llm.decide(context)

    if action.tool:
        result = execute(action.tool, action.args)
        context.append(result)
    else:
        return action.response

Đây là một agent loop hợp lệ về mặt ý tưởng.

Nhưng production system cần nhiều thứ hơn.

Python
MAX_TURNS = 8

for turn in range(MAX_TURNS):
    decision = agent.decide(
        context=context,
        allowed_tools=get_allowed_tools(user)
    )

    if decision.type == "final_answer":
        return decision.message

    if decision.type != "tool_call":
        raise InvalidAgentAction()

    tool = TOOL_REGISTRY[decision.tool]

    authorize(
        user=user,
        capability=tool.required_capability
    )

    validated_args = tool.schema.validate(decision.arguments)

    risk = assess_action_risk(
        tool=tool,
        args=validated_args
    )

    if risk.requires_human_approval:
        return create_approval_request(
            tool=tool.name,
            args=validated_args
        )

    result = tool.execute(
        validated_args,
        idempotency_key=create_idempotency_key()
    )

    audit_log.write(
        actor=user.id,
        tool=tool.name,
        args=validated_args,
        result=result
    )

    context.append(result)

raise AgentTurnLimitExceeded()

Điểm đáng chú ý là phần thực sự tạo reliability không chỉ nằm trong:

Python
agent.decide(...)

mà nằm ở toàn bộ harness xung quanh nó:

Text
allowed tools
authorization
schema validation
risk classification
approval
idempotency
audit logging
turn limits

Model có thể đề xuất một action.

Nhưng application quyết định action đó có được phép trở thành reality hay không.

Đó là sự khác biệt giữa demo và production system.


Human-in-the-loop nên đặt ở đâu?

Một hiểu nhầm khác là:

“Có human approval thì Agent tự động an toàn.”

Không hẳn.

Nếu mọi hành động đều bắt người duyệt, hệ thống mất phần lớn giá trị automation.

Nếu chỉ duyệt ở bước cuối nhưng UI cung cấp quá ít context, người dùng có thể click “Approve” theo thói quen.

Human-in-the-loop hiệu quả phải đặt tại điểm risk concentration.

Ví dụ:

Text
Read CRM                  → auto
Search knowledge base     → auto
Draft reply               → auto
Update internal note      → maybe auto
Cancel subscription       → approval
Refund $20                → policy dependent
Refund $20,000            → approval
Delete customer account   → approval

OpenAI khuyến nghị đặc biệt cân nhắc human intervention khi Agent vượt failure threshold hoặc chuẩn bị thực hiện các high-risk action như cancel order, large refund hay payment.

Một useful distinction là:

Text
Human-in-the-loop
con người phải duyệt trước action.

Human-on-the-loop
hệ thống tự chạy nhưng con người quan sát
và có khả năng can thiệp.

Human-out-of-the-loop
hệ thống tự quyết và tự thực thi.

Không phải task nào cũng cần mức đầu tiên.

Nhưng mức autonomy phải phù hợp với blast radius.


6 sai lầm phổ biến khi thiết kế Workflow và Agent

1. Dùng Agent chỉ vì task có nhiều bước

Multi-step không có nghĩa agentic.

Nếu năm bước đã biết từ đầu:

Text
A → B → C → D → E

thì Workflow có thể là abstraction chính xác hơn.

Agent cần thiết khi sequence phải được khám phá hoặc điều chỉnh ở runtime.


2. Cho LLM thực thi business rule mà code có thể biểu diễn rõ ràng

Ví dụ không nên hỏi:

Text
"Khách hàng này có được hoàn tiền không?
Policy: dưới 30 ngày..."

rồi tin hoàn toàn vào:

Text
YES

nếu rule thực sự là:

Python
eligible = (
    order.age_days <= 30
    and not order.was_refunded
    and order.status == "paid"
)

LLM có thể giúp parse policy từ tài liệu.

Nhưng một khi rule đã được formalize, executable rule thường là enforcement mechanism tốt hơn.


3. Coi structured output là deterministic correctness

JSON schema giúp đảm bảo:

Json
{
  "amount": 100,
  "currency": "USD"
}

có đúng shape.

Nó không chứng minh:

Text
amount = 100

là đúng.

Syntax correctness và semantic correctness là hai vấn đề khác nhau.


4. Đưa toàn bộ authorization vào system prompt

Text
"Only managers can delete accounts."

là instruction.

Nó không phải access-control system.

Authorization phải được enforce tại tool/service layer:

Python
if not user.has_permission("account.delete"):
    raise Forbidden()

Model thậm chí không nên có khả năng bypass check đó.


5. Không giới hạn Agent loop

Production Agent cần ít nhất một số boundary:

Text
max turns
time budget
token budget
tool budget
retry limit
stop condition

Không phải vì model chắc chắn chạy vô tận.

Mà vì bounded execution là property cần thiết của một hệ thống có thể vận hành.


6. Bắt đầu bằng multi-agent architecture

Một diagram như:

Text
Planner Agent
   │
   ├─ Research Agent
   ├─ Coding Agent
   ├─ Critic Agent
   ├─ Security Agent
   └─ Manager Agent

trông rất hấp dẫn.

Nhưng mỗi Agent mới tạo thêm:

  • context boundary;
  • failure mode;
  • token usage;
  • state transition;
  • communication protocol;
  • evaluation surface.

Nếu một Agent với tools rõ ràng giải quyết được task, multi-agent system có thể chỉ làm debugging khó hơn.

Cả Anthropic và OpenAI đều khuyến khích tăng orchestration complexity một cách incremental thay vì bắt đầu ngay bằng architecture phức tạp.


Một framework thực tế để chọn Workflow hay Agent

Thay vì bắt đầu từ framework hoặc model, hãy bắt đầu từ workload.

Câu 1 — Tôi có biết trước các bước không?

Nếu:

Text
Có

hãy ưu tiên Workflow.

Nếu:

Text
Không, mỗi request có thể cần một sequence khác

Agent bắt đầu có giá trị.


Câu 2 — Environment có cho Agent feedback đáng tin không?

Ví dụ tốt:

Text
compiler
test suite
database query
API status
filesystem
browser DOM

Ví dụ yếu hơn:

Text
"bài này đã đủ hay chưa?"
"chiến lược này đã tối ưu chưa?"

Feedback càng objective, autonomy càng dễ kiểm soát.


Câu 3 — Một action sai gây hậu quả gì?

Text
Draft email sai
→ sửa được.

Refund nhầm
→ mất tiền.

Delete production database
→ catastrophic.

Blast radius càng lớn, quyền quyết định càng phải dịch ra khỏi model.


Câu 4 — Action có reversible không?

Một Agent tự thêm tag vào internal document khác rất nhiều so với Agent:

Text
send payment
publish public statement
delete account
deploy production

Irreversibility là một signal mạnh để thêm approval hoặc deterministic gate.


Câu 5 — Business cần audit gì?

Nếu sau sáu tháng auditor hỏi:

“Tại sao transaction này được approve?”

câu trả lời:

“Model reasoning như vậy.”

thường không đủ.

Bạn có thể cần:

Text
policy_version = 17
rule = REFUND_30_DAY
order_age = 12
customer_role = owner
approval_id = APR-92
transaction_id = TX-83

Auditability phải được thiết kế từ data model và execution path, không phải thêm log vào phút cuối.


Câu 6 — Autonomy tăng lên có cải thiện metric thật không?

Đây là bước thường bị bỏ qua.

Hãy đo:

Text
task success rate
cost / successful task
latency
human escalation rate
unsafe action rate
tool error rate
iterations / task

Nếu Agent phức tạp hơn nhưng:

Text
success +1%
cost ×4
latency ×6
debugging khó hơn rất nhiều

thì architecture có thể không đáng.

Anthropic đặc biệt nhấn mạnh rằng complexity chỉ nên được thêm khi nó demonstrably improves outcomes.


Production Agent không phải một model — nó là một control system

Đây có lẽ là mental model quan trọng nhất của toàn bộ bài.

Khi mới học Agent, ta thường nhìn thấy:

Text
Prompt
  +
LLM
  +
Tools

và nghĩ đó là hệ thống.

Trong production, architecture thực tế gần hơn với:

Text
                     ┌────────────────┐
User ───────────────►│ Authentication │
                     └───────┬────────┘
                             ▼
                     ┌────────────────┐
                     │ Input policies │
                     └───────┬────────┘
                             ▼
                     ┌────────────────┐
                     │     Agent      │
                     │ plan / reason  │
                     └───────┬────────┘
                             ▼
                     ┌────────────────┐
                     │ Tool proposal  │
                     └───────┬────────┘
                             ▼
              ┌────────────────────────────┐
              │ Deterministic control plane│
              │                            │
              │ authorization              │
              │ schema validation          │
              │ risk policy                │
              │ budgets                    │
              │ approval                   │
              │ idempotency                │
              └──────────────┬─────────────┘
                             ▼
                     ┌────────────────┐
                     │ Real systems   │
                     │ DB/API/SaaS    │
                     └───────┬────────┘
                             ▼
                     ┌────────────────┐
                     │ Observation    │
                     └───────┬────────┘
                             │
                             └────► Agent

Model cung cấp adaptive intelligence.

Harness cung cấp operational reliability.

Tools cung cấp capabilities.

Policy layer cung cấp authority boundaries.

Environment cung cấp ground truth.

Evaluation cho biết hệ thống có thực sự tốt lên hay không.

Nhìn theo cách này, cuộc tranh luận:

“Workflow hay Agent?”

không còn là lựa chọn giữa hai công nghệ cạnh tranh.

Nó trở thành bài toán phân bổ quyền điều khiển.


Kết luận: hãy trao autonomy đúng chỗ, không phải nhiều nhất có thể

Quay lại hệ thống refund ở đầu bài.

Câu trả lời tốt không phải:

“Không bao giờ để AI hoàn tiền.”

Cũng không phải:

“Model mới đủ thông minh rồi, cứ cho Agent toàn quyền.”

Một architecture trưởng thành có thể để AI:

  • hiểu yêu cầu của khách hàng;
  • thu thập dữ liệu;
  • phân tích context;
  • nhận diện transaction nghi ngờ;
  • tìm policy liên quan;
  • đề xuất hành động;
  • giải thích lý do.

Nhưng application vẫn có thể giữ quyền:

  • authentication;
  • authorization;
  • tính số tiền;
  • kiểm tra eligibility;
  • enforce limit;
  • yêu cầu approval;
  • commit transaction;
  • audit.

Đó chính là điểm gặp nhau giữa Workflow và Agent.

Workflow đem lại structure.

Agent đem lại adaptability.

Deterministic logic bảo vệ invariants.

Human oversight xử lý những quyết định có consequence cao.

Không có lý do gì phải hy sinh một bên để lấy bên còn lại.

Nếu phải giữ lại vài nguyên tắc, hãy giữ những điều này:

  1. Workflow và Agent khác nhau chủ yếu ở quyền kiểm soát control flow, không phải ở việc hệ thống có dùng LLM hay không.
  2. Nếu đường giải quyết đã biết trước, hãy ưu tiên Workflow; autonomy chỉ đáng giá khi runtime thực sự chứa uncertainty.
  3. Agent mạnh nhất khi environment cung cấp feedback có thể kiểm chứng để nó quan sát, sửa sai và tiếp tục.
  4. Những invariant quan trọng như authorization, arithmetic, transaction, policy enforcement và irreversible action nên được bảo vệ bằng deterministic controls.
  5. Production Agent nên được nhìn như một control system có boundaries, budgets, permissions, audit và evaluation — chứ không chỉ là một LLM biết gọi tools.

Mục tiêu cuối cùng của AI Engineering không phải xây hệ thống có mức autonomy cao nhất.

Mục tiêu là xây hệ thống có đúng lượng autonomy cần thiết để giải quyết vấn đề, trong một phạm vi mà chúng ta vẫn có thể kiểm soát hậu quả khi nó sai.

Nguồn tham khảo

  • Anthropic — Building Effective AI Agents
  • Anthropic — Effective Context Engineering for AI Agents
  • Anthropic — Trustworthy Agents in Practice
  • Anthropic — Demystifying Evals for AI Agents
  • OpenAI — A Practical Guide to Building Agents
  • NIST — Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile (NIST AI 600-1)
  • European Union — Regulation (EU) 2024/1689, Artificial Intelligence Act, Articles 14–15