CodeGym /Các khóa học /ChatGPT Apps /Quy trình nhiều bước: tự động điều phối bởi mô hình và ki...

Quy trình nhiều bước: tự động điều phối bởi mô hình và kiểm soát vòng lặp

ChatGPT Apps
Mức độ , Bài học
Có sẵn

1. Run nhiều bước là gì và khác gì so với yêu cầu “đơn lẻ”

Khi bạn chỉ làm việc với ChatGPT App và MCP tools, bức tranh quen thuộc khá tuyến tính: có yêu cầu từ người dùng → GPT quyết định gọi một hoặc vài công cụ → bạn trả lời người dùng. Điều này vẫn có thể coi là “một bước logic”, ngay cả khi bên trong công cụ bạn làm điều gì đó phức tạp hơn.

Với agent, runmục tiêu + chuỗi bước. Ta không còn nghĩ theo kiểu “một prompt — một câu trả lời”, mà coi bài toán như một mini-project mà agent dẫn dắt từ đầu tới cuối.

Có thể hình dung sự khác nhau như sau:

Kiểu tương tác Mô hình làm gì Logic ở đâu
Gọi công cụ thông thường trong ChatGPT App Quyết định có gọi công cụ hay không, điền tham số, tạo câu trả lời dựa trên kết quả Logic nghiệp vụ chính và trình tự hành động — trong một công cụ hoặc trong backend
Run của agent (Agents SDK) Lập kế hoạch nhiều bước, quyết định khi nào và gọi tool nào, phân tích kết quả trung gian, có thể xem xét lại kế hoạch Logic “đi tới mục tiêu như thế nào” một phần trong system-instruction của agent, một phần do chính mô hình suy luận

Điểm quan trọng: bạn không bắt buộc trao hoàn toàn việc lập kế hoạch cho mô hình. Thường là mô hình lai: bạn mã hoá cứng các pha lớn của kịch bản (ví dụ, “trước tiên thu thập yêu cầu, rồi chọn quà, rồi chuẩn bị thẻ”), còn bên trong mỗi pha cho phép agent tự do sử dụng các công cụ của nó ở mức hợp lý.

Ví dụ nhỏ tương tự

Gọi công cụ một lần giống như gọi người giao hàng: “lấy một tài liệu và mang tới văn phòng”.

Run nhiều bước của agent run giống như một trợ lý cá nhân: “Hãy chuẩn bị quà cho đồng nghiệp vào sinh nhật: tìm hiểu người ấy thích gì, chọn vài phương án, kiểm tra giao hàng và ghép lại thành một bản trình bày đẹp.” Trợ lý tự quyết định các hành động trên đường đi.

Chút nữa trong bài, chúng ta cũng sẽ xem cách những run nhiều bước như vậy được tích hợp vào ngăn xếp quen thuộc Apps SDK → MCP → backend, để với ChatGPT và widget, logic agent trông như một MCP tool gọn gàng bình thường.

2. Cách mô hình tự lập kế hoạch các bước: cái nhìn tổng quan

Nói theo thuật ngữ của Agents SDK, mỗi run tiện được coi như bộ ba:

  1. Goal (mục tiêu): mô tả nhiệm vụ bằng văn bản, đi vào system/user-instructions của agent.
  2. Tools: tập các công cụ khả dụng với mô tả tốt và JSON Schema.
  3. State: lịch sử bước và trạng thái có cấu trúc mà bạn lưu bên ngoài (CSDL, Redis, v.v.).

Sau đó vòng lặp run quen thuộc bắt đầu: mô hình nhìn vào mục tiêu và các công cụ và ở mỗi bước quyết định:

  • “Giờ mình đã đủ thông tin — có thể trả kết quả cuối cho người dùng”;
  • hoặc “Mình cần gọi công cụ X với các tham số như thế này”;
  • hoặc “Mình đã nhận kết quả từ công cụ, giờ cần diễn giải, lọc, có thể gọi công cụ khác”.

Ở mức giả mã, ý tưởng như sau (nhắc lại: đây là mô hình tư duy, không phải API thực):

while (!done && steps < MAX_STEPS) {
  const modelResponse = await callModel({
    system: agentPolicy,
    messages: history,
    tools,
  });

  if (modelResponse.type === "tool_call") {
    const toolResult = await callTool(modelResponse.toolName, modelResponse.args);
    history.push({ role: "tool", content: toolResult });
  } else {
    // câu trả lời cuối cùng
    done = true;
    return modelResponse.content;
  }

  steps++;
}

Trong Agents SDK thực, cả vòng lặp này đã được triển khai và “ẩn” trong thư viện. Bạn mô tả agent theo kiểu khai báo, còn SDK sẽ chạy mô hình và công cụ lặp lại cho đến khi có câu trả lời cuối cùng hoặc chạm giới hạn bước/thời gian.

Nhiệm vụ của kiến trúc sư là:

  • diễn đạt goal và system-instruction sao cho mô hình lập các bước hợp lý;
  • xây dựng tập công cụ không chồng chéo về ý nghĩa;
  • đặt giới hạn về số bước và thời gian;
  • suy nghĩ xem bước nào có thể chạy song song.

Khi có mục tiêu, công cụ và hình dung về trạng thái, câu hỏi tiếp theo là — đi tới mục tiêu bằng những bước nào. Không phải bước nào cũng như nhau: có bước buộc tuần tự, và có bước có thể song song.

3. Các bước tuần tự và song song

Giờ khi đã hiểu vòng lặp run của agent, cần nắm các loại bước trong quy trình như vậy. Trong agent workflow có hai loại chính: tuần tự và song song.

Các bước tuần tự

Đó là khi kết quả của bước A tối quan trọng cho bước B. Ví dụ trong GiftGenius học tập của chúng ta:

  1. Trước hết cần hiểu ai là người nhận quà: đồng nghiệp hay người thân, tuổi, sở thích.
  2. Sau đó chọn tập ứng viên qua tool search_gifts.
  3. Rồi lọc theo ngân sách và ràng buộc.
  4. Tiếp đến định dạng đẹp các thẻ cho widget.
  5. Và chỉ sau đó, có thể gợi ý chuyển sang checkout.

Mỗi bước tiếp theo phụ thuộc dữ liệu của bước trước, nên việc thực hiện buộc phải tuần tự.

Trong giả mã hành vi agent, “kế hoạch nội bộ” của mô hình có thể trông như sau:

1. Hỏi người dùng về người nhận và ngân sách
2. Gọi tool search_gifts(profile, budget)
3. Gọi tool filter_by_constraints(gifts, constraints)
4. Tạo danh sách cuối cùng và mô tả

Mô hình không viết danh sách như vậy bằng mã, nhưng ta có thể hướng nó tới cấu trúc tương tự qua system-instructions, ví dụ hội thoại và mô tả công cụ.

Các bước song song

Đôi khi có thể thực hiện các bước độc lập. Ví dụ, ta muốn so sánh đề xuất quà từ ba cửa hàng cùng lúc:

  • search_gifts_amazon
  • search_gifts_etsy
  • search_gifts_local_store

Với agent, đó là ba lần gọi công cụ độc lập, có thể chạy song song để rút ngắn tổng thời gian phản hồi.

Trong Agents SDK (và nói chung các framework agent hiện đại) thường có hỗ trợ sẵn cho các lời gọi công cụ song song nếu mô hình trong một bước đề xuất nhiều lời gọi cùng lúc. Kịch bản kinh điển: mô hình mô tả danh sách lời gọi trong câu trả lời, SDK gọi cạnh tranh, thu kết quả và đưa chúng vào như tập các thông điệp tool cho bước tiếp theo của mô hình.

Về mặt lập kế hoạch, trông như sau:

// Bước của agent: mô hình quyết định gọi ba công cụ
const calls = [
  { name: "search_gifts_amazon", args: {...} },
  { name: "search_gifts_etsy", args: {...} },
  { name: "search_gifts_local_store", args: {...} },
];

const results = await Promise.all(
  calls.map(c => callTool(c.name, c.args))
);

// Sau đó tất cả kết quả được thêm vào ngữ cảnh trước bước tiếp theo của mô hình

Nếu bạn từng viết frontend bằng JS/TS, bạn đã gặp ý tưởng yêu cầu song song: ví dụ khi dùng Promise.all để chạy nhiều fetch() đồng thời. Giờ cùng ý tưởng xuất hiện bên trong vòng lặp run của agent, chỉ khác là quyết định chính xác cái gì có thể chạy song song phần lớn do mô hình đưa ra.

4. Ví dụ workflow cho GiftGenius: các bước, mục tiêu và công cụ

Ở phần về bước tuần tự, ta đã trực giác chia hành vi của GiftGenius thành các giai đoạn. Giờ hãy chính thức hoá kịch bản nhiều bước này như một agent workflow: mô tả mục tiêu, các bước và gắn chúng vào công cụ và cấu hình agent. Trước mắt ta không ràng buộc với API Agents SDK cụ thể, mà mô tả cấu trúc và thêm chút mã TypeScript giả định để minh hoạ.

Mục tiêu (goal)

Giả sử mục tiêu như sau:

Giúp người dùng chọn 3–5 phương án quà cho một người nhận cụ thể, có xét ngân sách, dịp và ràng buộc giao hàng, và trả về danh sách thẻ quà có cấu trúc cho widget GiftGenius.

Các bước chính

Mô tả biến thể tối thiểu gồm 4 bước:

  1. Làm rõ bối cảnh người nhận
    Mục tiêu: thu thập thông tin về người nhận quà (tuổi, giới tính, sở thích, quan hệ với người tặng), cùng với ngân sách và ngày diễn ra sự kiện.
    Công cụ: có thể không cần công cụ nào, chỉ là đối thoại mô hình ↔ người dùng.
  2. Tìm kiếm và chọn lọc sơ bộ quà tặng
    Mục tiêu: lấy tập ứng viên “thô”.
    Công cụ: search_gifts(profile, budget) — tool truy cập catalog/hệ tìm kiếm của chúng ta và trả về danh sách ứng viên.
  3. Lọc và sắp xếp
    Mục tiêu: loại bỏ phương án không phù hợp (không giao tới vùng, vượt ngân sách, ràng buộc không phù hợp) và sắp xếp theo mức liên quan.
    Công cụ: filter_and_score_gifts(candidates, constraints) — công cụ thuần, idempotent.
  4. Định dạng kết quả cho widget
    Mục tiêu: đưa dữ liệu về định dạng thuận tiện cho UI: tiêu đề, mô tả ngắn, ảnh, giá, CTA.
    Công cụ: format_gift_cards(gifts) — có thể là công cụ mã (tạo cấu trúc) hoặc công cụ LLM (văn bản thẩm mỹ).

Trông như thế nào trong cấu hình agent

Giả sử ta có bộ dựng agent giả định (giả mã):

import { createAgent } from "@acme/agents-sdk";
import { tools } from "./gift-tools";

export const giftAgent = createAgent({
  name: "gift-guru",
  system: `
    Bạn là agent GiftGenius, giúp chọn quà.
    Mục tiêu: đề xuất 3–5 phương án có thể mua được,
    có xét hồ sơ người nhận, ngân sách và ràng buộc giao hàng.
    Trước tiên hãy làm rõ các chi tiết quan trọng, sau đó dùng công cụ tìm kiếm và lọc.
    Đừng gọi công cụ nếu bạn chưa biết ngân sách hoặc sở thích chính.
    Kết thúc khi bạn có danh sách thẻ quà tặng rõ ràng.
  `,
  tools, // ở đây sẽ có search_gifts, filter_and_score_gifts, format_gift_cards
  maxSteps: 12,
  timeoutMs: 15000,
});

Lưu ý một vài điểm:

  • Trong system-instruction, ta nói rõ agent phải làm rõ chi tiết trước, rồi mới gọi công cụ tìm kiếm. Điều này giảm rủi ro mô hình gọi công cụ khi ngữ cảnh còn quá mơ hồ.
  • Ta giới hạn maxSteps để agent không rơi vào vòng lặp vô hạn.
  • timeoutMs là để toàn bộ run không kéo dài quá lâu với người dùng.

5. Tự động điều phối bởi mô hình: phần nào “để mô hình quyết”, phần nào nên cố định

Agent là sự cân bằng giữa tự do của mô hình và cấu trúc cứng mà bạn đặt ra.

Nếu cho mô hình quá nhiều tự do và không đặt ranh giới, bạn sẽ nhận “sự sáng tạo hỗn loạn”: gọi tool thừa, bước lặp lại, vòng lặp khó hiểu. Nếu ngược lại mã hoá cứng mọi thứ ở backend như một máy trạng thái hữu hạn, mô hình sẽ thành người “trang trí văn bản” chứ không phải một tác nhân thông minh.

Thường để mô hình quyết

Trong bối cảnh GiftGenius và tương tự, hợp lý khi tin cậy mô hình ở:

  • cách đặt câu hỏi cho người dùng (làm rõ sở thích, cách hỏi ngân sách cho phù hợp);
  • quyết định khi nào thông tin đã đủ để bắt đầu tìm kiếm;
  • lựa chọn dùng chính xác công cụ nào trong một pha (ví dụ chọn tool tìm kiếm cửa hàng nào nếu có nhiều);
  • sinh văn bản mô tả, giải thích, so sánh.

Nên cố định cứng

Đồng thời nên cố định trước:

  • các pha lớn của kịch bản (“Thu thập thông tin” → “Tìm kiếm” → “Lọc” → “Định dạng” → “Kết thúc”);
  • giới hạn số bước và thời gian;
  • điều kiện khi agent bắt buộc “dừng” và nói thẳng với người dùng rằng bài toán không thể giải (ví dụ ngân sách 5 đô nhưng cần thiết bị điện tử đắt giao trong ngày mai);
  • chính sách idempotency của công cụ và chiến lược retry.

Ví dụ hybrid: pha là state, chi tiết để mô hình

Có thể thêm vào state của agent trường phase nhận các giá trị "collect_profile" | "search" | "filter" | "format" | "done". Khi đó backend của bạn (hoặc chính Agents SDK, nếu hỗ trợ state machine tuỳ biến) sẽ kiểm soát công cụ nào được phép ở mỗi pha.

Giả mã:

type Phase = "collect_profile" | "search" | "filter" | "format" | "done";

interface GiftAgentState {
  phase: Phase;
  profile?: UserProfile;
  candidates?: GiftCandidate[];
  finalGifts?: GiftCard[];
}

System-instruction cho agent có thể bao gồm mô tả ngắn về các pha, và bạn trong mã sẽ giới hạn danh sách tools hiển thị cho mô hình tuỳ theo pha hiện tại. Đây là ví dụ về tool gating, sẽ được bàn kỹ hơn trong mô-đun về workflow.

6. Kiểm soát vòng lặp vô hạn và lặp lại vô ích

Nếu để vòng lặp run của agent không kiểm soát, sớm muộn nó sẽ cư xử như sinh viên trước hạn chót: “làm rõ và viết lại” vô tận để khỏi nộp bài. Nhiệm vụ của ta là không để nó treo.

Có ba nguồn điển hình của vòng lặp vô hạn:

  1. Mô hình không chắc câu trả lời và tiếp tục diễn đạt lại cùng một yêu cầu tới công cụ với thay đổi nhỏ.
  2. Công cụ liên tục trả lỗi hoặc rỗng, còn agent cứ “thử lại”.
  3. Agent mắc kẹt giữa hai công cụ, lúc gọi cái này, lúc gọi cái kia, không tiến tới câu trả lời cuối.

Giới hạn số bước (maxSteps)

Cơ chế đơn giản và bắt buộc — giới hạn số bước. Trong hầu hết triển khai Agents SDK bạn có thể chỉ định maxSteps khi chạy run hoặc trong cấu hình agent. Khi chạm giới hạn, SDK kết thúc run với trạng thái đặc biệt (ví dụ aborted_by_max_steps). Sau đó bạn quyết định hiển thị với người dùng ra sao.

Trong GiftGenius, ta có thể cho rằng một lượt chọn quà hợp lý nằm trong khoảng ~10 bước (vài lần làm rõ, vài lần tìm, lọc, định dạng). Đặt ví dụ 12–15 bước có đệm và xử lý cẩn thận khi chạm giới hạn:

const run = await giftAgent.run({
  input: userGoal,
  maxSteps: 12, // ghi đè mặc định
});

if (run.status === "max_steps_exceeded") {
  // Hiển thị thông báo rõ ràng cho người dùng
}

Giới hạn thời gian (timeout)

Đôi khi vấn đề không phải số bước, mà là tổng thời lượng. Công cụ có thể chậm, mạng không ổn định. Vì vậy hữu ích khi đặt timeoutMs cả ở mức từng lần gọi tool và ở mức toàn bộ run.

Ví dụ, bạn có thể quyết định rằng:

  • mỗi lần gọi API bên ngoài (tìm quà ở đối tác) không nên quá 3–5 giây;
  • toàn bộ run chọn quà nên hoàn tất trong 15 giây.

Nếu timeout kích hoạt, bạn kết thúc run một cách gọn gàng, có thể hiển thị kết quả một phần kèm giải thích rằng “một phần nguồn không phản hồi kịp”.

Phát hiện lặp lại

Mẫu nâng cao (nhưng hữu ích) — phát hiện các lần gọi công cụ lặp với cùng tham số. Nếu bạn thấy agent đã ba lần liên tiếp gọi search_gifts(profile, budget) với cùng tham số, đó là tín hiệu nó đang mắc kẹt.

Bạn có thể thêm vào state một bộ đếm theo khoá (toolName, argsHash) và nếu vượt ngưỡng, hoặc:

  • dừng run và trả về lỗi dễ hiểu cho người dùng;
  • hoặc đưa thêm instruction cho mô hình: “bạn đã thử gọi công cụ này ba lần với cùng tham số, hãy đổi chiến lược hoặc hỏi người dùng”.

Giả mã:

function shouldAbortToolCall(toolName: string, args: unknown, state: GiftAgentState) {
  const key = `${toolName}:${hashArgs(args)}`;
  const count = state.toolCallCounts[key] ?? 0;

  if (count >= 3) return true;

  state.toolCallCounts[key] = count + 1;
  return false;
}

Trong đó hashArgs — bất kỳ hàm tuần tự hoá tham số mang tính quyết định nào (ví dụ JSON.stringify với sắp xếp khóa).

7. Tiêu chí kết thúc nhiệm vụ rõ ràng

Một trong khác biệt chính giữa agent “đồ chơi” và agent sản xuất là có tiêu chí kết thúc dễ hiểu. Nếu không có, mô hình có thể hoặc bỏ dở quá sớm (“đây là vài món quà, phần còn lại tự xử”), hoặc ngược lại, tiếp tục “cải thiện” vô tận.

Trong GiftGenius có thể đặt quy tắc đơn giản:

  • Agent kết thúc khi có từ 3 đến 5 món quà với các trường đã điền: id, title, shortDescription, price, imageUrl, purchaseUrl, và chúng đã qua lọc theo ngân sách và giao hàng.
  • Nếu sau tối đa N lần tìm và lọc mà quà phù hợp ít hơn 3, agent nói thẳng với người dùng rằng không tìm được gì ổn và đề nghị tăng ngân sách hoặc nới ràng buộc.

Các tiêu chí này có thể mã hoá ngay trong system-instruction của agent và/hoặc trong kiểm tra kết quả sau run.

Ví dụ kiểm tra kết quả sau run:

if (run.status === "completed") {
  const gifts = run.output.gifts; // giả sử agent trả về JSON có cấu trúc

  if (!gifts || gifts.length < 3) {
    // Agent "đã kết thúc" nhưng kết quả yếu — có thể:
    // 1) hiển thị giải thích minh bạch,
    // 2) đề nghị người dùng đổi điều kiện.
  } else {
    // Ổn — hiển thị widget quà tặng
  }
}

Đừng chờ mô hình “tự hiểu” thành công nghiệp vụ. Là nhà phát triển, bạn phải diễn đạt rõ điều kiện “đủ tốt” và kiểm tra chúng.

8. Điều phối được hiện thực ở đâu: agent, backend, widget

Trước đó ta đã nói điều phối có thể sống ở nhiều tầng: trong agent, trong backend, trong widget.

Theo góc nhìn quy trình nhiều bước, logic xấp xỉ như sau.

Agent (Agents SDK) chịu trách nhiệm về workflow “tư duy”:

  • cách chia mục tiêu thành các bước;
  • gọi công cụ nào và theo thứ tự nào;
  • hỏi người dùng những câu hỏi bổ sung nào.

Backend thường đảm bảo:

  • hiện thực các công cụ (tìm kiếm, lọc, commerce, v.v.);
  • lưu trạng thái và checkpoint;
  • các ràng buộc nghiệp vụ cứng (giới hạn ngân sách, quyền, khả dụng theo vùng).

Widget (Apps SDK) quản lý:

  • hiển thị tiến độ (stepper, thanh tiến trình, “bước 2/4”);
  • các form nhập liệu;
  • các chi tiết UX như disable nút khi dữ liệu chưa đủ.

Thực hành tốt — nghĩ thế này: agent dàn dựng công việc của công cụ và đối thoại, còn UI widget dàn dựng trải nghiệm thị giác của người dùng. Chúng trao đổi qua dữ liệu có cấu trúc (ToolOutput, agent run output).

9. Ví dụ mã nhỏ: chạy agent nhiều bước GiftGenius từ một MCP tool

Giờ, như đã hứa ở đầu bài, ta nối khái niệm mới với ngăn xếp quen thuộc Apps SDK → MCP → backend và đưa ví dụ nhỏ về cách MCP tool có thể gọi một run của agent.

Giả sử trong app/mcp/route.ts của bạn có tool run_gift_workflow, công cụ này:

  • nhận yêu cầu văn bản của người dùng (mục tiêu của họ);
  • khởi chạy agent giftAgent;
  • trả về kết quả có cấu trúc cho widget.

Mã rút gọn và giả định, nhưng cho thấy cách kết nối:

// app/mcp/route.ts
import { server } from "@modelcontextprotocol/sdk/server";
import { z } from "zod";
import { giftAgent } from "@/agents/giftAgent";

server.registerTool(
  "run_gift_workflow",
  {
    title: "Chọn quà tặng",
    description: "Khởi chạy agent nhiều bước để chọn quà",
    inputSchema: {
      userGoal: z
        .string()
        .describe("Mục tiêu của người dùng, ví dụ: muốn quà cho đồng nghiệp dưới $50"),
    },
  },
  async ({ userGoal }) => { 		
    const run = await giftAgent.run({		// ở đây ta chạy agent với 12 bước và timeout 15 giây
      input: userGoal,
      maxSteps: 12,
      timeoutMs: 15000,
    });

    return {
      status: run.status,
      gifts: run.output?.gifts ?? [],
      debug: run.debugInfo, // có thể loại bỏ sau
    };
  }
);

Sau đó ChatGPT App có thể gọi MCP tool này như bất kỳ tool nào khác, và widget GiftGenius của bạn xây UI dựa trên gifts. Bạn có workflow nhiều bước “bên dưới nắp ca-pô”, trong khi với ChatGPT mọi thứ trông như một tool gọn gàng duy nhất.

10. Lỗi điển hình khi thiết kế quy trình nhiều bước

Lỗi số 1: “Để mô hình tự lo, tôi chỉ đưa cho nó tất cả công cụ”.
Khi agent có hàng chục tools chồng chéo ý nghĩa mà không có system-instruction và các pha rõ ràng, mô hình sẽ bối rối: gọi cùng một việc theo nhiều cách, trùng lặp yêu cầu, rơi vào vòng lặp. Tốt hơn hãy đầu tư vào thiết kế: chia kịch bản thành pha, giới hạn danh sách công cụ trong mỗi pha và viết rõ chiến lược trong system prompt.

Lỗi số 2: Thiếu giới hạn bước và thời gian.
Nếu không đặt maxStepstimeout, trong sản xuất bạn sẽ sớm có các run “lang thang” ngốn tài nguyên, còn người dùng không thấy gì. Giới hạn không phải “tuỳ chọn” mà là vệ sinh cơ bản. Đồng thời cần xử lý có ý nghĩa khi vượt giới hạn, không phải rơi lỗi 500 câm lặng.

Lỗi số 3: Không có tiêu chí kết thúc rõ ràng.
Mô hình kết thúc run khi nó nghĩ “đã đủ”, nhưng “đủ” của nó có thể xa yêu cầu nghiệp vụ. Nếu không chính thức hoá tiêu chí thành công (bao nhiêu quà, những trường nào, qua những lọc nào) và không kiểm tra, bạn sẽ có UX thất thường: hôm nay năm phương án xuất sắc, ngày mai một phương án “tàm tạm” và ba bản trùng.

Lỗi số 4: Không theo dõi lời gọi công cụ lặp lại.
Agent có thể mắc mẫu “nhận lỗi → diễn đạt lại yêu cầu thêm 2 từ → lại gọi cùng công cụ”. Nếu bạn không theo dõi lời gọi lặp theo (toolName, args), các vòng lặp này sẽ vô hình cho tới khi bạn nhìn vào log và hoảng hốt. Các bộ đếm đơn giản và hash tham số giúp rất nhiều.

Lỗi số 5: Trộn điều phối và thực thi nghiệp vụ trong một công cụ.
Đôi khi người ta cố giấu cả workflow vào một MCP tool hoặc một hàm của agent: vừa tìm kiếm, vừa lọc, vừa định dạng, vừa ra quyết định. Kết quả là agent mất ý nghĩa — mô hình không thể kiểm soát quá trình theo bước, bạn mất tính minh bạch và khả năng tái sử dụng phần kịch bản. Tốt hơn tách các giai đoạn thành tools độc lập và cho agent phối hợp chúng.

Lỗi số 6: Thiếu liên kết với trạng thái và checkpoint.
Quy trình nhiều bước không lưu trạng thái trung gian và checkpoint sẽ thành khối mong manh: nếu có gì đó rơi giữa chừng, người dùng phải bắt đầu lại. Điều này đặc biệt quan trọng cho kịch bản người dùng đi tới lui giữa các bước hoặc quay lại sau một thời gian. Hãy dùng kho lưu state, lưu pha, hồ sơ, ứng viên và cho agent khả năng tiếp tục từ đúng chỗ.

Lỗi số 7: Bỏ qua lớp UX.
Đôi khi nhà phát triển quá mải mê workflow bên trong của agent và quên rằng người dùng chỉ thấy widget và tin nhắn trong chat. Nếu UI không có tiến độ rõ ràng, trạng thái “đang tìm quà…”, “đang lọc phương án…”, người dùng sẽ nghĩ App “bị treo” hay “không làm gì”, dù agent đang điều phối một quy trình phức tạp. Khi lập kế hoạch run nhiều bước, hãy nghĩ ngay nó sẽ hiện ra trong giao diện như thế nào.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION