📖 Nội dung bài học
Video
What is tool use?
Quy trình làm việc hiện tại của bạn phụ thuộc vào nhiều công nghệ khác nhau — phần mềm quản lý dự án, cơ sở dữ liệu, tệp. Claude không thể tự kiểm tra những thứ này. Thay vào đó, nó dựa vào tools, cung cấp cho Claude quyền truy cập vào dữ liệu và hành động bên ngoài.
Tool là gì
Nói một cách đơn giản, tool là một hàm bạn định nghĩa và cung cấp cho Claude. Bạn mô tả chức năng của nó và các đầu vào mà nó nhận, và Claude sẽ quyết định khi nào gọi nó.
Đây là điểm mấu chốt cần ghi nhớ: Claude không thực thi tool — code của bạn mới thực hiện. Luồng hoạt động như sau:
- Claude yêu cầu gọi tool.
- Code của bạn thực thi hàm đó.
- Kết quả được trả về cho Claude, và quá trình tiếp tục.
Cách định nghĩa tools
Tools là các JSON schema với ba phần: một name, một description, và một input schema. Bạn truyền chúng cho Claude trong request body dưới dạng một mảng tools.
Description là thứ Claude đọc để quyết định có nên gọi tool hay không. Nếu bạn viết mô tả mơ hồ, bạn sẽ gặp vấn đề khi sử dụng tool. Đây là lý do số một khiến agent hoạt động sai hoặc không chọn đúng tool có sẵn cho chúng. Hãy cụ thể.
Đây là hình thức định nghĩa tool:
{
"name": "lookup_building_code",
"description": "Tra cứu một phần mã xây dựng cụ thể bằng định danh của nó. Trả về toàn bộ văn bản của phần mã đó.",
"input_schema": {
"type": "object",
"properties": {
"section": {
"type": "string",
"description": "Phần mã xây dựng cần tra cứu"
}
},
"required": ["section"]
}
}
Vậy điều gì xảy ra khi chúng ta sử dụng cái này? Giả sử chúng ta gửi một báo cáo tuân thủ cho một agent. Ở lượt đầu tiên, Claude trả về stop_reason: "tool_use" — đó là tín hiệu của chúng ta. Đây là hình thức phản hồi đó:

Vòng lặp của chúng ta gọi lookup_building_code với tham số Claude yêu cầu, sau đó đưa kết quả trở lại dưới dạng tool result — một tin nhắn người dùng chứa một khối tool_result được liên kết với id của lệnh gọi tool:

Và Claude tiếp tục. Tại thời điểm đó, chúng ta có thể tiếp tục gọi tools và trả về kết quả cho Claude cho đến khi nó có những gì cần thiết.
Nhiều tools: để Claude chọn
Một tool là hữu ích, nhưng điều thú vị là cung cấp cho Claude nhiều tools và xem nó chọn cái nào để sử dụng, theo thứ tự nào.
Hãy tưởng tượng kịch bản này: bạn đang đóng gói đồ cho chuyến đi ba ngày đến Denver, và bạn muốn biết thời tiết hôm nay cũng như dự báo cho vài ngày tới. Vì vậy, chúng ta khai báo hai tools thay vì một:
const tools = [
{
name: "get_weather",
description: "Lấy thời tiết hiện tại hôm nay cho một thành phố.",
input_schema: {
type: "object",
properties: {
city: { type: "string", description: "Thành phố cần kiểm tra" }
},
required: ["city"]
}
},
{
name: "get_forecast",
description: "Lấy dự báo thời tiết cho vài ngày tới cho một thành phố.",
input_schema: {
type: "object",
properties: {
city: { type: "string", description: "Thành phố cần kiểm tra" }
},
required: ["city"]
}
}
];
Vòng lặp giống hệt như các vòng lặp agent mà chúng ta đã thấy. Phần mới duy nhất là một hàm runTool sẽ phân nhánh dựa trên tên tool bằng một câu lệnh switch — khối code này chỉ là nơi code của bạn thực sự chạy:
function runTool(name, input) {
switch (name) {
case "get_weather":
return getWeather(input.city);
case "get_forecast":
return getForecast(input.city);
}
}
while (true) {
const response = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages,
tools,
});
if (response.stop_reason !== "tool_use") {
// Claude đã xong — đây là câu trả lời cuối cùng
break;
}
messages.push({ role: "assistant", content: response.content });
const toolResults = response.content
.filter((block) => block.type === "tool_use")
.map((block) => ({
type: "tool_result",
tool_use_id: block.id,
content: runTool(block.name, block.input),
}));
messages.push({ role: "user", content: toolResults });
}
Và đó là toàn bộ quy trình. Muốn thêm tool thứ ba? Thêm nó vào mảng, thêm một case vào switch, và bạn đã hoàn thành.
Chạy cái này, bạn sẽ thấy Claude gọi get_weather rồi get_forecast — đôi khi trong cùng một lượt, đôi khi lần lượt. Sau đó nó trả lời: hãy mang theo nhiều lớp quần áo, dự kiến có tuyết rơi hôm nay, và ấm dần trong tuần.
Bây giờ hãy chú ý cách Claude đã chọn. Nó đọc các mô tả, ánh xạ prompt của bạn tới "thời tiết hôm nay" và "vài ngày tới", và chọn đúng tool cho mỗi cái. Đó là lý do tại sao mô tả tool của bạn thực sự quan trọng.
Tool runner: bỏ qua boilerplate
Bạn có lẽ đã nhận thấy hai điểm đáng ngờ với những gì chúng ta vừa viết:
- Đó là rất nhiều code cho hai lần tra cứu đơn giản.
- Trong một codebase thực tế, bạn không muốn tự viết JSON schema cho mọi hàm bạn có. Nó giống như viết code của bạn hai lần.
Đó là lúc tool runner xuất hiện. Nó có sẵn trong Claude SDK cho TypeScript, Python và Ruby. Tool runner nhận các hàm thực tế của bạn, đọc các kiểu dữ liệu và tài liệu để tự động xây dựng schema cho bạn, và xử lý toàn bộ vòng lặp tool use / tool result bên trong.
Code của bạn được rút gọn thành: mô tả tool, gửi prompt, chờ kết quả. Đây là bản demo hai tool thời tiết giống hệt như chúng ta đã chạy thủ công:
// Hai lần tra cứu giống hệt như chúng ta đã chạy thủ công — chỉ là các hàm TypeScript thuần túy
function getWeather(city: string) {
// ... tra cứu hiện có
}
function getForecast(city: string) {
// ... tra cứu hiện có
}
const runner = client.beta.messages.toolRunner({
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [
{
role: "user",
content:
"Tôi đang đóng gói đồ cho chuyến đi ba ngày đến Denver. Thời tiết hôm nay và trong vài ngày tới thế nào?",
},
],
tools: [getWeather, getForecast],
});
// Trả về tin nhắn trợ lý cuối cùng sau khi tất cả các lần trao đổi tool đã ổn định
const finalMessage = await runner.untilDone();
Cùng một kịch bản, ít code hơn đáng kể:
- Không có vòng lặp while, không có switch stop reason, không tự đẩy tool result vào messages — runner xử lý tất cả những điều đó.
- Không có JSON schema, vì vậy bạn không viết mọi thứ hai lần.
- Hai hàm này là các lần tra cứu giống hệt như chúng ta đã chạy thủ công một phút trước, chỉ là TypeScript thuần túy.
runner.untilDone()trả về tin nhắn trợ lý cuối cùng khi mọi thứ đã ổn định.
Chạy nó, và bạn nhận được cùng một câu trả lời.
Tools thực tế bao bọc code hiện có của bạn
Trong thực tế, tools của bạn sẽ không phải là dữ liệu thời tiết được mã hóa cứng. Chúng sẽ bao bọc các hàm thực tế mà bạn đã có trong ứng dụng của mình.
Hãy xem xét một agent đánh giá tuân thủ: các tools của nó là các lớp bọc mỏng xung quanh các hàm lookup_building_code và search_building_code đã tồn tại trong codebase. Với tool runner, bạn truyền trực tiếp các hàm đó, và agent sẽ trích dẫn các phần mã cụ thể trong mọi phát hiện mà nó viết — không cần viết schema:

Tóm tắt
- Tools cung cấp cho Claude quyền truy cập vào hệ thống của bạn. Một tool là một hàm bạn định nghĩa và cung cấp; Claude quyết định khi nào gọi nó, và code của bạn thực thi nó.
- Tools là các JSON schema với name, description, và input schema, được truyền trong request dưới dạng một mảng
tools. - Viết mô tả cụ thể. Mô tả mơ hồ là lý do số một khiến agent hoạt động sai.
stop_reason: "tool_use"là tín hiệu để bạn chạy tool và đưa kết quả trở lại dưới dạng tool result.- Đối với nhiều tools, phân nhánh dựa trên tên tool. Thêm một tool có nghĩa là thêm vào mảng và thêm một case.
- Tool runner của SDK (TypeScript, Python, Ruby) xây dựng schema từ các hàm thực tế của bạn và xử lý toàn bộ vòng lặp — hoặc bạn có thể tự chạy vòng lặp.
- Bạn thực thi, hoặc bạn ủy quyền vòng lặp. Ở đầu xa của phổ đó, managed agents ủy quyền toàn bộ agent cho Anthropic.
🎬 Bản ghi video
Source video:
Ao759wXbRc0
Không có transcript — xem phần nội dung bài học bên trên.
🔁 Bài học liên quan
- Bài tiếp: What is thinking?
- Bài trước: The agent loop explained
- Thuộc lộ trình: Path C
- Docs tham khảo: Glossary · Skills atlas · By use-case
📚 Nguồn & ghi nhận
- Bài học gốc Anthropic Academy: https://anthropic.skilljar.com/claude-platform-101/486255
- © 2025 Anthropic. Chỉ dùng cho mục đích giáo dục, fair-use.
- Crawl: 2026-06-27 · Chuẩn hoá: 2026-06-27