Xây dựng AI Agent với Claude: Các mẫu điều phối thực sự hiệu quả
31 tháng 3, 2026 · 12 phút đọc
Một khách hàng yêu cầu bot hỗ trợ của bạn tra cứu đơn hàng, kiểm tra chính sách đổi trả, và xử lý hoàn tiền. Bot tra cứu đơn hàng, rồi dừng lại. Trả về một câu trả lời dang dở. Khách hàng phải bắt đầu lại từ đầu. Đây không phải là vấn đề của mô hình — mà là vấn đề kiến trúc. Vòng lặp của agent kết thúc quá sớm vì đoạn mã kiểm tra nội dung văn bản thay vì tín hiệu hoàn thành thực sự.
Chỉ một lỗi đó — kiểm tra sai trường — chính là khoảng cách giữa một bản demo và một hệ thống sản xuất thực thụ. Các mẫu dưới đây bám sát những gì Anthropic kiểm tra trong kỳ thi chứng chỉ, và chúng liên tục xuất hiện trong các dự án thực tế.
Vòng đời của agentic loop
Mọi agent dựa trên Claude đều chạy theo cùng một chu trình bốn bước:
- Gửi một yêu cầu đến Claude thông qua Messages API, bao gồm toàn bộ lịch sử hội thoại và bất kỳ kết quả tool nào từ vòng lặp trước.
- Kiểm tra
stop_reasontrong phản hồi — đây là tín hiệu đáng tin cậy duy nhất cho biết điều gì sẽ xảy ra tiếp theo. - Nếu
stop_reasonlà"tool_use": thực thi (các) tool được yêu cầu, thêm kết quả vào lịch sử hội thoại, gửi cuộc hội thoại đã cập nhật trở lại cho Claude. - Nếu
stop_reasonlà"end_turn": agent đã hoàn thành. Trả về phản hồi cuối cùng.
Vòng lặp cốt lõi bằng TypeScript:
typescriptCopy
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
async function runAgent(userPrompt: string, tools: Anthropic.Tool[]) {
const messages: Anthropic.MessageParam[] = [
{ role: "user", content: userPrompt }
];
while (true) {
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
tools,
messages,
});
// The ONLY reliable completion signal
if (response.stop_reason === "end_turn") {
const text = response.content.find(b => b.type === "text");
return text?.text ?? "";
}
// Append assistant response to history
messages.push({ role: "assistant", content: response.content });
// Execute each tool call and append results
const toolResults = response.content
.filter(b => b.type === "tool_use")
.map(toolUse => ({
type: "tool_result" as const,
tool_use_id: toolUse.id,
content: executeTool(toolUse.name, toolUse.input),
}));
messages.push({ role: "user", content: toolResults });
}
}Bước 2 là nơi mọi thứ dễ đi sai hướng. Trường stop_reason có tính tất định và không mơ hồ. Ba anti-pattern phổ biến phá vỡ nguyên tắc này, và chúng xuất hiện trong sản xuất thường xuyên hơn bạn tưởng:
Kiểm tra response.content[0].type === "text" — Claude có thể trả về văn bản cùng với các lệnh gọi tool trong cùng một phản hồi. Một tin nhắn như "Để tôi tra cứu đơn hàng của bạn" theo sau bởi một khối tool_use có văn bản ở vị trí 0, nhưng agent còn lâu mới hoàn thành.
Phân tích ngôn ngữ tự nhiên như "Tôi đã xong" hay "hoàn thành nhiệm vụ" — Claude có thể nói "Tôi đã phân tích xong tệp đầu tiên" trong khi vẫn có ý định tiếp tục với các tệp khác. Ngôn ngữ tự nhiên vốn dĩ mơ hồ. stop_reason thì không.
Giới hạn số vòng lặp tùy ý làm cơ chế dừng chính — đặt "dừng sau 10 vòng lặp" hoặc cắt ngang công việc hữu ích, hoặc chạy các vòng lặp không cần thiết. Giới hạn số vòng lặp chấp nhận được như một lưới an toàn. Chúng rất tệ khi làm cơ chế điều khiển chính. Nếu giới hạn của bạn kích hoạt trong hoạt động bình thường, có gì đó khác đang bị hỏng.
Để tìm hiểu sâu hơn, xem Agentic Loops.
Single-agent hay multi-agent: khi nào nên tách
Phần lớn vấn đề không cần nhiều agent. Một agent duy nhất với bộ tool được chọn lọc kỹ càng xử lý được đa số tác vụ — và việc xây dựng, gỡ lỗi, bảo trì nó đơn giản hơn nhiều. Cám dỗ over-architect (thiết kế thừa) là có thật. Hãy cưỡng lại nó cho đến khi bằng chứng buộc bạn phải hành động.
Tách thành nhiều agent khi:
- Tác vụ có các chuyên môn riêng biệt. Nghiên cứu đòi hỏi tìm kiếm web, phân tích tài liệu, và tổng hợp sẽ được lợi từ các agent được tối ưu riêng cho từng vai trò. Một agent tổng quát cố gắng cân cả ba việc sẽ cho ra kết quả tầm thường ở mọi mặt.
- Cô lập ngữ cảnh (context) là điều quan trọng. Một agent review code không nên thấy toàn bộ lịch sử hội thoại của một phiên lập kế hoạch. Các agent được cô lập chỉ nhận những gì liên quan đến công việc của chúng.
- Thực thi song song mang lại giá trị. Các tác vụ con độc lập — ví dụ như tìm kiếm ở ba nguồn khác nhau — có thể chạy đồng thời trên nhiều agent và hoàn thành trong thời gian ngắn hơn nhiều.
Giữ nguyên một agent duy nhất khi:
- Các tool có liên quan chặt chẽ với nhau và luồng công việc là tuyến tính.
- Toàn bộ ngữ cảnh vừa vặn thoải mái trong một cuộc hội thoại.
- Bạn không thể chỉ ra lợi ích cụ thể nào từ độ phức tạp điều phối tăng thêm.
So sánh các mẫu điều phối
| Mẫu | Cách hoạt động | Phù hợp nhất cho | Cần lưu ý |
|---|---|---|---|
| Single agent | Một agent với nhiều tool | Luồng công việc tuyến tính, tác vụ đơn giản | Ngữ cảnh phình to với tác vụ phức tạp |
| Sequential pipeline | Đầu ra của Agent A làm đầu vào cho Agent B | Chuỗi xử lý tài liệu | Điểm lỗi đơn lẻ ở mỗi giai đoạn |
| Parallel fan-out | Nhiều agent chạy đồng thời, kết quả được tổng hợp | Các tác vụ con nghiên cứu độc lập | Chi phí điều phối khi tổng hợp |
| Coordinator/specialist | Coordinator trung tâm giao việc cho các subagent chuyên biệt | Tác vụ phức tạp, đa lĩnh vực | Coordinator trở thành nút thắt cổ chai nếu thiết kế kém |
Kỳ thi ưu ái mạnh mẽ mẫu coordinator/specialist cho các tình huống phức tạp. Đây là mẫu đáng để hiểu thấu đáo.
Mẫu coordinator/specialist
Hãy hình dung mô hình hub-and-spoke (trung tâm và các nhánh). Một coordinator agent ngồi ở trung tâm, nhận tác vụ, phân rã nó thành các tác vụ con, giao việc cho các specialist subagent, tổng hợp kết quả, và xử lý lỗi.
Một quy tắc bất di bất dịch: mọi giao tiếp đều phải đi qua coordinator. Các subagent không bao giờ nói chuyện trực tiếp với nhau. Không phải vì hiệu quả. Không phải vì tiện lợi. Không vì bất kỳ lý do gì. Điều này không thể thương lượng.
Tại sao? Ba lý do, và chúng cộng dồn với nhau:
- Khả năng quan sát (observability) — mọi tin nhắn đều đi qua một điểm duy nhất. Bạn có thể ghi log và giám sát toàn bộ hệ thống từ một chỗ. Khi có sự cố lúc 3 giờ sáng, bạn sẽ biết ơn điều này.
- Xử lý lỗi nhất quán — coordinator áp dụng các chính sách khôi phục thống nhất thay vì để mỗi agent tự ứng biến theo cách riêng.
- Kiểm soát luồng thông tin — coordinator quyết định ngữ cảnh nào mỗi subagent nhận được. Không agent nào thấy nhiều hơn những gì nó cần.
Nguyên tắc cô lập
Điều này khiến hầu hết mọi người bất ngờ: các subagent không kế thừa lịch sử hội thoại của coordinator. Khi coordinator sinh ra một subagent, subagent đó chỉ khởi đầu với những gì coordinator đưa vào rõ ràng trong prompt của nó. Không có quyền truy cập system prompt của coordinator. Không có quyền truy cập các tin nhắn trước đó. Không có quyền truy cập kết quả từ các subagent khác. Không có gì được ngầm định.
Các subagent cũng không có bộ nhớ giữa các lần gọi. Gọi search agent hai lần thì lần gọi thứ hai không biết gì về lần gọi thứ nhất. Một trang giấy trắng.
Điều này buộc coordinator phải chủ động và có chủ đích trong việc truyền ngữ cảnh. Nếu synthesis agent cần kết quả tìm kiếm, coordinator phải truyền chúng một cách rõ ràng. Không có bộ nhớ chung hay trạng thái toàn cục nào để dựa vào. Điều này ban đầu có vẻ gò bó, nhưng nó loại bỏ hẳn cả một nhóm lỗi liên quan đến ngữ cảnh lỗi thời hoặc bị rò rỉ.
Lỗi phân rã hẹp
Kỳ thi kiểm tra trực tiếp mẫu này. Một coordinator được yêu cầu nghiên cứu "tác động của AI lên các ngành công nghiệp sáng tạo." Nó phân rã chủ đề chỉ thành các chủ đề con về nghệ thuật thị giác — bỏ sót hoàn toàn âm nhạc, viết lách, phim ảnh, và game.
Kết quả đầu ra rất kỹ lưỡng về nghệ thuật thị giác. Trống rỗng về mọi thứ khác. Sai ở đâu?
Không phải search agent — nó tìm kiếm chính xác những gì được giao. Không phải synthesis agent — nó tổng hợp chính xác mọi thứ nó nhận được. Lỗi nằm trọn vẹn ở việc phân rã tác vụ của coordinator. Nó chỉ giao một hạng mục duy nhất trong các ngành công nghiệp sáng tạo.
Đây là bài học đáng ghi nhớ cho kỳ thi: khi một hệ thống multi-agent cho ra kết quả thiếu sót về phạm vi (chứ không phải độ sâu), hãy truy ngược lỗi về việc phân rã của coordinator. Ném thêm subagent vào vấn đề hay cải thiện câu truy vấn tìm kiếm sẽ không sửa được một sự phân rã đã sai ngay từ đầu.
Claude Agent SDK
Agent SDK cung cấp một khung làm việc có cấu trúc để xây dựng agent. Các khái niệm chính:
Agent definitions (định nghĩa agent) chỉ định model, system prompt, tool, và ràng buộc cho từng agent:
pythonCopy
from claude_agent_sdk import Agent
research_agent = Agent(
name="research",
model="claude-sonnet-4-20250514",
system_prompt="You are a research specialist. Search thoroughly and return structured findings with sources.",
tools=["web_search", "document_reader"],
max_tokens=4096,
)Lifecycle hooks (hook vòng đời) cho phép bạn can thiệp và kiểm soát hành vi của agent tại các điểm cụ thể:
- PreToolUse — kích hoạt trước khi một tool thực thi. Dùng để xác thực, ghi log, hoặc chặn các thao tác nguy hiểm.
- PostToolUse — kích hoạt sau khi một tool trả về. Dùng để xác thực hoặc biến đổi kết quả.
- SubagentStart / SubagentStop — kích hoạt khi subagent được sinh ra và hoàn thành. Dùng để theo dõi và kiểm soát tầng điều phối.
Thực thi theo lập trình là nơi hook phát huy giá trị thực sự. Đối với các thao tác tài chính, bảo mật, hoặc tuân thủ quy định, hướng dẫn bằng prompt là không đủ. Tỷ lệ thất bại 8% khi xác minh danh tính trước khi hoàn tiền là không thể chấp nhận — chấm hết. Một hook PreToolUse trên tool process_refund có thể kiểm tra xem get_customer đã trả về ID đã xác minh hay chưa, chặn thao tác một cách tất định bất kể mô hình quyết định làm gì.
Kỳ thi vạch ra một ranh giới rõ ràng ở đây: hướng dẫn dựa trên prompt hoạt động hiệu quả 90-95% thời gian. Thực thi theo lập trình hoạt động hiệu quả mọi lúc. Đối với các thao tác rủi ro cao, câu trả lời luôn luôn là thực thi theo lập trình. Luôn luôn. Kỳ thi sẽ cố gắng cám dỗ bạn bằng "thêm một ví dụ few-shot" hay "viết lại system prompt" như các phương án thay thế. Đừng mắc bẫy.
Để tìm hiểu chi tiết đầy đủ, xem Workflow Enforcement and Handoff.
Guardrail quan trọng trong sản xuất
Khiến agent hoạt động trong bản demo là phần dễ. Sản xuất mới là nơi mọi thứ trở nên thú vị.
Giới hạn số vòng lặp an toàn — đặt số vòng lặp tối đa (ví dụ: 20) làm phương án dự phòng để ngăn agent chạy mất kiểm soát. Đây là lưới an toàn, không phải cơ chế dừng chính. Nếu nó kích hoạt trong hoạt động bình thường, logic vòng lặp của bạn đã bị hỏng và giới hạn đó chỉ đang che giấu vấn đề thực sự.
Cổng điều kiện tiên quyết (prerequisite gate) — chặn các tool ở tầng dưới cho đến khi các điều kiện tiên quyết được đáp ứng. Mẫu hoàn tiền trước khi xác minh là ví dụ kinh điển, nhưng nguyên tắc tương tự áp dụng ở bất kỳ đâu có luồng công việc nhiều bước với các phụ thuộc. Hãy đặt cổng ở từng bước. Đừng tin tưởng mô hình sẽ sắp xếp đúng thứ tự mọi lần.
Giao thức bàn giao có cấu trúc — khi một agent leo thang lên con người, phần bàn giao phải bao gồm ID khách hàng, tóm tắt cuộc hội thoại, phân tích nguyên nhân gốc rễ, và hành động được đề xuất. Nhân viên hỗ trợ không có quyền truy cập bản ghi cuộc hội thoại. Bản tóm tắt bàn giao là tất cả những gì họ nhận được. Nếu nó không đầy đủ, khách hàng phải giải thích lại từ đầu.
Thực thi ngưỡng — giới hạn các thao tác tài chính, rate-limit các lệnh gọi API, hạn chế phạm vi. Đây là các kiểm soát ở tầng mã nguồn mà mô hình không thể ghi đè, và đó chính xác là mục đích.
Domain 1 thực sự kiểm tra điều gì
Domain 1 (Kiến trúc Agentic & Điều phối) chiếm 27% kỳ thi — lĩnh vực nặng ký nhất. Các câu hỏi dựa trên tình huống. Bạn sẽ nhận được một tình huống với một hệ thống agent bị hỏng hoặc chưa tối ưu, bốn đáp án nghe có vẻ hợp lý, và một chẩn đoán đúng duy nhất.
Năm mẫu xuất hiện lặp đi lặp lại:
- Kết thúc vòng lặp quá sớm — cách khắc phục luôn luôn là
stop_reason, không bao giờ là giới hạn số vòng lặp hay phân tích văn bản. Mọi lần đều vậy. - Khoảng trống phạm vi trong hệ thống multi-agent — hãy truy ngược về việc phân rã của coordinator, không phải các agent ở tầng dưới.
- Lỗi ngữ cảnh của subagent — coordinator đã không truyền đủ ngữ cảnh. Subagent không bị hỏng; nó chỉ đơn giản chưa bao giờ nhận được những gì nó cần.
- Lỗi tuân thủ trong các thao tác tài chính — luôn là thực thi theo lập trình, không bao giờ là prompt được cải thiện hay ví dụ few-shot. Không có ngoại lệ.
- Đề xuất giao tiếp trực tiếp giữa các subagent như một cải tiến — hãy loại bỏ. Mọi giao tiếp đều phải đi qua coordinator. Kỳ thi sẽ khiến phương án giao tiếp trực tiếp nghe có vẻ hiệu quả và hợp lý. Nó vẫn sai.
Nếu bạn có thể nhận diện năm mẫu này ngay khi nhìn thấy, bạn sẽ xử lý được đa số câu hỏi Domain 1 một cách dễ dàng.
Bắt đầu với toàn bộ chương trình học Domain 1, hoặc chuyển thẳng đến bài thi thử để tự kiểm tra trong điều kiện thi thật. Cẩm nang ôn thi hướng dẫn cách phân bổ thời gian ôn tập cho cả năm domain.