Giảm lượng token MCP tiêu thụ: cách chúng tôi cắt 60% định nghĩa công cụ
Mỗi công cụ MCP mà agent của bạn có thể gọi là một khối JSON mà mô hình có thể đọc ở mọi yêu cầu. Của chúng tôi nặng khoảng 95.000 token. Đây là cách đo của bạn trong hai phút, những gì chúng tôi cắt mà không bỏ một công cụ nào, và phép kiểm tra ngân sách giúp nó không phình to trở lại.
Ngày 27 tháng 10, một người dùng trả phí đã hủy gói AgentsRoom và nêu lý do là token. Trước khi tranh luận, chúng tôi đo xem ứng dụng của mình thêm gì vào mỗi agent mà nó khởi chạy.
Con số lớn nhất không nằm ở chỗ chúng tôi nghĩ. Hướng dẫn khởi động của chúng tôi khá nhỏ. Còn các công cụ MCP mà chúng tôi trao cho mọi agent (backlog, bộ nhớ dự án, hộp thư giữa các agent, terminal, SSH, cơ sở dữ liệu và phần còn lại) là 191 công cụ và khoảng 380 KB JSON. Với khoảng 4 byte mỗi token, đó là khoảng 95.000 token định nghĩa công cụ. Một tuần trước con số là 78.000. Không ai quyết định điều đó; mỗi công cụ mới chỉ đơn giản thêm đoạn văn của riêng nó.
Chúng tôi phát triển AgentsRoom, một ứng dụng desktop chạy Claude Code, Codex và các CLI lập trình khác song song, và trao cho chúng những công cụ này. Đây là những gì chúng tôi đo được, những gì chúng tôi cắt mà không bỏ một công cụ nào, và phép kiểm tra giữ cho nó không quay lại. Bạn có thể áp dụng tất cả cho các máy chủ MCP của chính mình.
Câu trả lời ngắn
- Định nghĩa công cụ là JSON mà mô hình có thể đọc ở mọi yêu cầu: tên, mô tả, schema đầu vào. Tính khoảng 4 byte mỗi token.
- Bạn có phải trả nó ở mỗi lượt hay không là tùy CLI. Claude Code mặc định hoãn nạp công cụ MCP và nạp một định nghĩa khi cần. Một số CLI gửi mọi schema kèm mọi yêu cầu.
- Đo trước khi cắt.
/contexttrong Claude Code, hoặc một script 40 dòng hỏi bất kỳ máy chủ nào danh sách công cụ của nó. - Rút gọn văn bản, giữ nguyên công cụ. Mô tả nói làm gì và khi nào. Phần hướng dẫn sử dụng chuyển sang một tài liệu mà agent đọc khi cần. Của chúng tôi giảm từ khoảng 95.000 xuống khoảng 38.000 token, ít hơn 2,5 lần.
- Đặt mức trần trong bản build. Không có nó, định nghĩa sẽ tự phình to trở lại.
Một định nghĩa công cụ tốn bao nhiêu, và ai trả
Khi một client MCP kết nối tới máy chủ, nó hỏi danh sách công cụ. Mỗi mục gồm một tên, một mô tả viết cho mô hình, và một JSON schema của các tham số. Client biến danh sách đó thành các định nghĩa công cụ gửi tới mô hình: đó là cách mô hình biết công cụ tồn tại và cách gọi nó.
Vậy mọi từ trong một mô tả đều là đầu vào mà mô hình đọc. Mô hình đọc nó thường xuyên đến đâu là tùy client:
- Claude Code mặc định hoãn nạp công cụ MCP. Tài liệu của nó, đọc ngày 3 tháng 11 năm 2026 với Claude Code 2.1.314 đã cài, nói rằng khi bắt đầu phiên chỉ có tên công cụ và hướng dẫn của máy chủ được nạp, và một định nghĩa được nạp qua tính năng tìm kiếm công cụ khi Claude cần công cụ đó. Với
ENABLE_TOOL_SEARCH=false, vớiautodưới ngưỡng 10% cửa sổ ngữ cảnh, trên các mô hình cũ hơn Claude Opus 4 và Sonnet 4, hoặc với một máy chủ được đánh dấualwaysLoad, các định nghĩa được nạp ngay từ đầu. - Các CLI khác làm khác. Trong thử nghiệm riêng của chúng tôi ngày 28 tháng 10, với một agent được yêu cầu trả lời "OK": Claude Code mở đầu ở 67.500 token với công cụ của chúng tôi được hoãn nạp, Codex CLI 0.164 mở đầu ở 25.000 token và không gửi schema của chúng tôi thành một khối, còn OpenCode nạp 175 công cụ của chúng tôi cộng 19 công cụ trình duyệt ngay khi kết nối và gửi chúng kèm mọi yêu cầu. Cùng một máy chủ, hóa đơn rất khác nhau.
Cache prompt làm nhẹ chi phí khi danh sách công cụ không đổi: sau yêu cầu đầu tiên, một phần đầu ổn định được đọc từ cache với giá chỉ bằng một phần nhỏ giá đầu vào. Nó không trả lại chỗ trống. Các định nghĩa vẫn nằm trong cửa sổ ngữ cảnh ở mọi yêu cầu, bên cạnh code và cuộc trò chuyện của bạn. Và chế độ hoãn nạp cũng có chi phí riêng: một bước tìm kiếm trước lần dùng đầu tiên của mỗi công cụ.
Đo của bạn trong hai phút
Trong Claude Code, chạy /context. Lệnh này chia cửa sổ theo nguồn và đánh dấu các công cụ MCP được hoãn nạp hoặc nạp khi cần. Chạy nó trong một phiên mới trong dự án của bạn, trước khi gõ bất cứ thứ gì, và bạn sẽ thấy cấu hình của mình tốn bao nhiêu trước khi công việc bắt đầu.
Với bất kỳ máy chủ nào và bất kỳ CLI nào, hãy hỏi trực tiếp máy chủ. Một máy chủ MCP qua stdio nói JSON-RPC, mỗi dòng một thông điệp: bạn gửi initialize, rồi tools/list, và đo những gì trả về. Script này làm đúng như vậy, với Node và không có dependency nào:
// Usage: node mcp-tool-cost.mjs <command that starts the server> [args...]
import { spawn } from 'node:child_process';
const [cmd, ...args] = process.argv.slice(2);
const server = spawn(cmd, args, { stdio: ['pipe', 'pipe', 'ignore'], shell: process.platform === 'win32' });
const tools = [];
let buffer = '';
const send = (msg) => server.stdin.write(JSON.stringify({ jsonrpc: '2.0', ...msg }) + '\n');
const listTools = (cursor) => send({ id: 2, method: 'tools/list', params: cursor ? { cursor } : {} });
server.stdout.on('data', (chunk) => {
buffer += chunk;
let end;
while ((end = buffer.indexOf('\n')) >= 0) {
const line = buffer.slice(0, end).trim();
buffer = buffer.slice(end + 1);
if (line) handle(JSON.parse(line));
}
});
function handle(msg) {
if (msg.id === 1) {
send({ method: 'notifications/initialized' });
listTools();
} else if (msg.id === 2) {
tools.push(...msg.result.tools);
if (msg.result.nextCursor) listTools(msg.result.nextCursor);
else { report(); server.kill(); }
}
}
function report() {
const rows = tools
.map((tool) => ({ name: tool.name, bytes: Buffer.byteLength(JSON.stringify(tool)) }))
.sort((a, b) => b.bytes - a.bytes);
const total = rows.reduce((sum, row) => sum + row.bytes, 0);
for (const row of rows.slice(0, 10)) {
console.log(`${String(row.bytes).padStart(7)} bytes ~${Math.round(row.bytes / 4)} tokens ${row.name}`);
}
console.log(`${rows.length} tools, ${total} bytes, about ${Math.round(total / 4)} tokens`);
}
send({
id: 1,
method: 'initialize',
params: { protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'tool-cost', version: '1.0.0' } },
});
Chạy nó với đúng lệnh mà CLI của bạn dùng để khởi động máy chủ, ví dụ node mcp-tool-cost.mjs npx -y @playwright/mcp@latest. Nó in ra mười công cụ nặng nhất và tổng. Kết quả của chúng tôi ngày 3 tháng 11 năm 2026:
| Máy chủ | Công cụ | JSON | Khoảng |
|---|---|---|---|
@modelcontextprotocol/server-filesystem 2.1.0 | 14 | 12.554 byte | 3.100 token |
@playwright/mcp 0.0.84 | 25 | 21.034 byte | 5.300 token |
| Công cụ AgentsRoom, ngày 28 tháng 10 trước khi cắt | 191 | khoảng 380.000 byte | 95.000 token |
| Công cụ AgentsRoom, ngày 28 tháng 10 sau khi cắt | 191 | khoảng 152.000 byte | 38.000 token |
| Công cụ AgentsRoom, ngày 3 tháng 11 | 203 | 159.957 byte | 40.000 token |
Bốn byte mỗi token là một ước lượng, đủ tốt để so sánh các máy chủ và nhìn ra xu hướng, không đủ để dự đoán hóa đơn. Tokenizer thật thay đổi theo mô hình và văn bản, như chúng tôi đã thấy khi đếm 3,8 tỷ token của chính mình.
Các máy chủ file ở trên có kích thước hợp lý. Vấn đề là tổng cộng: năm máy chủ cỡ đó đã là 20.000 token, trước cả khi có một máy chủ như của chúng tôi.
Những gì chúng tôi cắt, và những gì không đụng tới
Quy tắc chúng tôi đặt ra: không bỏ công cụ nào, không bỏ tham số nào, không bỏ giá trị cho phép hay trường bắt buộc nào. Agent phải giữ mọi khả năng. Chỉ văn bản được phép thay đổi.
- Mô tả công cụ nói làm gì và khi nào, trong một đến ba câu. Không nói làm thế nào. Phần làm thế nào chính là nơi chứa các byte: quy tắc, giá trị mặc định, trường hợp đặc biệt, ví dụ, cảnh báo viết thêm sau khi một agent từng dùng sai công cụ.
- Một tham số được một câu, hoặc không gì cả khi tên, kiểu và danh sách giá trị cho phép đã nói đủ. Các tham số lặp lại ở nhiều công cụ (
project,author, mã ticket) nhận cùng một câu chuẩn ở mọi nơi. - Phần hướng dẫn sử dụng được chuyển đi, không bị xóa. Mỗi nhóm công cụ có một file hướng dẫn mà agent đọc trước lần gọi đầu tiên tới nhóm đó. Với công cụ lớn nhất của chúng tôi, công cụ lưu một team agent, toàn bộ tài liệu tham chiếu các trường giờ được trả về qua một lần gọi công cụ khi agent yêu cầu, thay vì đi kèm trong schema.
- Lượt rà soát thứ hai kiểm tra từng dữ kiện. Mỗi câu bị bỏ khỏi mô tả đều được tra trong các file hướng dẫn, và được đưa vào đó nếu còn thiếu.
Một vài kết quả, tính bằng byte JSON mỗi công cụ:
| Công cụ | Trước | Sau |
|---|---|---|
teams_save | 19.705 | 9.791 |
triggers_save | 16.014 | 4.071 |
backlog_update | 13.150 | 4.253 |
backlog_create | 11.565 | 4.399 |
Tổng cộng, 380 KB còn 152 KB. Mười ba công cụ từng vượt 4 KB; bốn công cụ vẫn còn vượt, vì số trường mà chúng mang. Ý tưởng đằng sau cả lượt cắt: để chọn một công cụ, mô hình cần biết nó tồn tại và khi nào nên gọi. Chi tiết có thể đợi đến lúc nó thực sự dùng.
Nếu bạn viết một máy chủ MCP, Claude Code cho bạn thêm một lý do. Nó cắt mô tả công cụ được nạp từ đầu ở 4.096 ký tự, và khi so khớp một lượt tìm kiếm với mô tả, nó chỉ đọc phần nằm trong giới hạn đó. Bất cứ điều gì quan trọng nằm sau điểm đó có thể không bao giờ được đọc.
Cùng mẹo đó cho một file khởi động
Schema công cụ không phải là chi phí cố định duy nhất. Agent của chúng tôi còn đọc một file hướng dẫn về các công cụ trước khi dùng, và file đó đã phình tới 57,7 KB, khoảng 14.000 token, được đọc toàn bộ ở mỗi lần khởi động và mỗi lần tiếp tục phiên. Một người dùng báo rằng một agent Codex được tiếp tục đã chạm giới hạn ngữ cảnh làm việc chỉ sau vài phút.
Cách sửa dùng cùng ý tưởng. File đó trở thành một mục lục khoảng 11 KB: các quy tắc áp dụng cho mọi công cụ, và mỗi nhóm công cụ một dòng trỏ tới file riêng của nhóm. 31 file nhóm chỉ được đọc trước lần gọi đầu tiên tới nhóm đó. Nội dung của chúng không đổi, từng chữ một. Một agent chỉ làm việc với backlog sẽ không bao giờ đọc phần nói về cơ sở dữ liệu.
Cách này cũng dùng được cho một CLAUDE.md hay AGENTS.md dài: giữ trong file luôn được nạp những gì mọi tác vụ cần, và đặt liên kết tới phần còn lại. Chúng tôi viết thêm về điều này trong hướng dẫn về AGENTS.md và các file ngữ cảnh.
Một ngân sách làm push thất bại
Con số khiến chúng tôi lo nhất không phải 95.000. Mà là 78.000 một tuần trước đó. Mỗi công cụ thêm một đoạn văn, mỗi đoạn văn đều hợp lý, và tổng cộng tăng 20% trong bảy ngày.
Vì vậy kích thước trở thành một bước kiểm tra trong bản build. Một file JSON giữ ngân sách:
{
"totalBytes": 160000,
"perToolBytes": 4000,
"oversized": {
"teams_save": 9791,
"triggers_save": 4071,
"backlog_update": 4253,
"backlog_create": 4399
}
}
Một script khởi động các máy chủ MCP của chúng tôi trong sandbox, hỏi từng máy chủ danh sách công cụ, đo JSON.stringify(tool) theo byte và thoát với lỗi khi tổng vượt totalBytes hoặc khi một công cụ vượt perToolBytes. Bốn công cụ vốn đã quá lớn được liệt kê kèm kích thước: một cơ chế bánh cóc. Chúng có thể nhỏ lại, không bao giờ lớn thêm, và khi một công cụ nhỏ lại, script yêu cầu hạ con số xuống. Nó chạy trước mỗi lần push và trong bản build phát hành. Nâng mức trần vẫn làm được, nhưng đó là một quyết định ghi trong file, không phải cách để vượt qua phép kiểm tra.
Ngày 3 tháng 11, sáu ngày sau, cùng phép kiểm tra đó đọc được 203 công cụ và 159.957 byte: thêm mười hai công cụ, dưới mức trần 43 byte. Công cụ tiếp theo sẽ phải tự tìm chỗ cho mình. Đó chính là mục đích của phép kiểm tra.
Tắt những gì bạn không dùng
Token rẻ nhất là công cụ mà agent của bạn không bao giờ nhìn thấy.
- Giới hạn máy chủ trong các dự án cần đến chúng. Một máy chủ khai báo ở cấp người dùng sẽ theo bạn vào mọi repo. Trong Claude Code, một
.mcp.jsoncủa dự án giữ nó ở nơi nó có ích. - Chỉ dành
alwaysLoadcho một vài công cụ. Tài liệu của Claude Code nói thẳng: mỗi công cụ nạp từ đầu chiếm ngữ cảnh lẽ ra dành cho cuộc trò chuyện của bạn. - Theo dõi những gì kết quả công cụ thêm vào, không chỉ định nghĩa. Một công cụ trả về cả một trang hay cả một bảng có thể tốn trong một lần gọi nhiều hơn định nghĩa của nó tốn cả ngày.
Trong AgentsRoom, Cài đặt > Công cụ AgentsRoom liệt kê mọi nhóm công cụ của chúng tôi kèm trọng lượng, và bạn có thể tắt một nhóm hoặc một công cụ riêng lẻ, cho mọi dự án, một dự án, một thư mục hoặc một agent. Công cụ đã tắt hoàn toàn không được liệt kê cho agent, nên không tốn chút ngữ cảnh nào. Trang AgentsRoom MCP mô tả các công cụ, và dấu vết phiên cho thấy những gì đã lấp đầy ngữ cảnh của một agent, kể cả công cụ MCP, xếp theo kích thước.
Những gì chúng tôi không thay đổi
Hai chi phí khác lộ ra từ cùng phép đo, và chúng tôi cố ý để nguyên.
- Bản brief khởi động cho mỗi agent biết vai trò của nó và cách báo trạng thái: trung vị khoảng 5.000 token với Claude, khoảng 2,5% của một cửa sổ 200.000 token, và được đọc từ cache kể từ yêu cầu thứ hai.
- File trạng thái mà mỗi agent ghi ở cuối một lượt: đo trên 71 transcript Claude cục bộ, khoảng 2,5% số token ngữ cảnh.
Thu nhỏ một trong hai sẽ tiết kiệm chưa tới 3% cửa sổ và đánh cược chất lượng công việc của agent. Định nghĩa công cụ thì nặng 95.000 token. Đó là nơi chúng tôi dồn thời gian.
Những câu hỏi người ta thật sự đặt ra
Công cụ MCP dùng bao nhiêu token?
Mỗi công cụ tốn đúng bằng toàn bộ định nghĩa của nó: tên, mô tả và schema đầu vào, gửi dưới dạng JSON. Quy tắc ước lượng là 4 byte mỗi token. Đo ngày 3 tháng 11 năm 2026: máy chủ filesystem chính thức có 14 công cụ, khoảng 3.100 token, Playwright MCP có 25 công cụ, khoảng 5.300 token. Các công cụ của AgentsRoom nặng khoảng 95.000 token trước khi chúng tôi rút gọn, hiện tại khoảng 40.000.
Claude Code có nạp mọi công cụ MCP vào cửa sổ ngữ cảnh không?
Mặc định thì không. Tính năng tìm kiếm công cụ của Claude Code (tool search) hoãn việc nạp định nghĩa công cụ MCP: khi bắt đầu phiên chỉ có tên công cụ và hướng dẫn của máy chủ được nạp, và Claude nạp một định nghĩa khi cần đến công cụ đó. Đặt ENABLE_TOOL_SEARCH=false, dùng mô hình cũ hơn Claude Opus 4 và Sonnet 4, hoặc một máy chủ được đánh dấu alwaysLoad sẽ đưa các định nghĩa trở lại ngữ cảnh ngay từ đầu.
Máy chủ MCP có giúp giảm lượng token tiêu thụ không?
Có thể, khi một công cụ trả về câu trả lời ngắn thay cho thứ mà agent lẽ ra phải đọc toàn bộ, chẳng hạn một truy vấn cơ sở dữ liệu thay vì một bản dump. Nhưng định nghĩa tốn ngữ cảnh, và kết quả cũng vậy: Claude Code cảnh báo khi một kết quả MCP vượt 10.000 token và mặc định cắt nó ở 25.000. Một máy chủ MCP chỉ tiết kiệm token khi kết quả của nó nhỏ hơn thứ nó thay thế.
Làm sao xem các công cụ MCP của tôi chiếm bao nhiêu ngữ cảnh?
Trong Claude Code, chạy /context: lệnh này chia ngữ cảnh theo nguồn và đánh dấu các công cụ MCP được hoãn nạp. Với bất kỳ máy chủ nào và bất kỳ CLI nào, hãy hỏi máy chủ danh sách công cụ của nó rồi đo JSON, đó chính là việc mà đoạn script 40 dòng trong bài này làm.
Thế nào là một mô tả công cụ MCP tốt?
Từ một đến ba câu nói công cụ làm gì và khi nào nên gọi, với những từ mà agent sẽ tìm kiếm đặt ở gần đầu. Một tham số được một câu, hoặc không gì cả khi tên, kiểu và các giá trị cho phép đã nói đủ. Quy tắc, trường hợp đặc biệt và ví dụ dài đưa vào một tài liệu mà agent đọc khi cần. Dù sao Claude Code cũng cắt một mô tả được nạp từ đầu ở 4.096 ký tự.
Làm sao để định nghĩa công cụ không phình to trở lại?
Cho chúng một ngân sách mà bản build có thể kiểm tra. Chúng tôi giữ một file JSON với mức trần tổng và mức trần cho từng công cụ, một script khởi động các máy chủ MCP của chúng tôi, đo từng công cụ và thoát với lỗi khi vượt một trong hai giới hạn, và chúng tôi chạy nó trước mỗi lần push. Những công cụ vốn đã quá lớn có thể nhỏ lại, không bao giờ lớn thêm.
Phiên bản ngắn gọn
Các công cụ MCP của bạn là văn bản mà mô hình đọc, và không ai review văn bản đó như review code. Hãy đo nó một lần: /context trong Claude Code, hoặc script ở trên cho bất kỳ máy chủ nào. Sau đó cho mỗi mô tả nói làm gì và khi nào, chuyển phần làm thế nào vào một file mà agent đọc khi cần, và đặt một con số vào bản build để nó không thể trôi ngược trở lại.
Chúng tôi đã giảm từ khoảng 95.000 xuống khoảng 38.000 token mà không bỏ một công cụ nào. Nếu bạn chạy nhiều agent với cùng bộ công cụ, AgentsRoom tải về miễn phí, và trang Máy chủ MCP cho thấy cách khai báo một máy chủ một lần cho mọi CLI và mọi dự án.
Tải AgentsRoom
Chạy tất cả agent AI của bạn, trên mọi dự án, trong một cửa sổ duy nhất.
Ứng dụng đồng hành: theo dõi agent khi đi đường
Sử dụng Claude, Codex, Antigravity CLI hoặc nhà cung cấp AI khác.
Gửi lỗi và yêu cầu thẳng vào backlog công khai của bạn.
Đọc thêm
Token trong Claude là gì và hoạt động thế nào? Chúng tôi đã đếm 3,8 tỷ token
Token là một mảnh của từ, và Claude đếm bốn loại token: input, ghi cache, đọc cache và output. Chúng tôi đã đếm 30 ngày phiên Claude Code của chính mình, 3,8 tỷ token: 98% là cuộc trò chuyện được đọc lại từ cache, 0,3% là những gì Claude viết ra. Mỗi loại tốn bao nhiêu, vì sao một phiên nặng dần sau mỗi lượt, và khung thời gian 5 giờ thực sự đo cái gì.
Đọc bài viếtCách Giảm Chi Phí Token Claude Code Mà Không Làm Chậm Lại
Claude Code tính phí bạn theo token, và hầu hết chi phí là vô hình: ngữ cảnh phình to, mô hình sai, PDF thô, các tác nhân đọc lại cùng một tệp. Đây là nơi tiền thực sự đi và cách để cắt giảm nó, với những thói quen và công cụ giúp giữ hóa đơn của bạn thấp mà không làm chậm bạn lại.
Đọc bài viếtCách xem agent lập trình AI của bạn chạy gì trên máy chủ của bạn
Agent của bạn đang ở trên một máy chủ production và terminal chỉ nói rằng nó đang gọi một công cụ. Nó đã chạy lệnh nào, và máy đã trả lời gì? Transcript cho bạn biết điều đó khi mọi chuyện đã xong. Đây là cách chúng tôi làm cho nó hiện ra ngay khi đang diễn ra, những gì chúng tôi đã thử trước, và cách có được điều tương tự mà không cần ứng dụng của chúng tôi.
Đọc bài viết