Phá bỏ rào cản ngữ cảnh của AI
Tôi đã dành sáu tháng qua để thử nghiệm giới hạn của Claude Code trong môi trường production. Mặc dù nó rất giỏi trong việc viết code mẫu (boilerplate), nhưng cuối cùng nó vẫn vấp phải một rào cản: nó không biết về các API nội bộ, các bảng Jira riêng tư, hay cách team của bạn xử lý các triển khai (deployment) cụ thể. Claude Code là agent CLI của Anthropic chuyên xử lý code và quy trình git, nhưng nó chỉ thông minh dựa trên dữ liệu mà nó có thể truy cập.
Để biến nó thành một cộng sự thực thụ, bạn cần xây dựng các “skill” (kỹ năng) tùy chỉnh. Những kỹ năng này được vận hành bởi Model Context Protocol (MCP). Hãy coi MCP server như một chiếc cầu nối cho phép Claude bước ra khỏi môi trường thử nghiệm (sandbox) một cách an sau để tương tác với hạ tầng của bạn. Theo kinh nghiệm của tôi, chỉ cần thêm hai hoặc ba công cụ tùy chỉnh có thể giúp bạn tiết kiệm 20% thời gian tra cứu thủ công hàng ngày.
Thiết lập trong 5 phút: Skill tùy chỉnh đầu tiên của bạn
Cách nhanh nhất để bắt đầu là sử dụng bộ khởi tạo TypeScript MCP. Điều này cho phép Claude thực thi các logic cục bộ do chính bạn viết.
1. Khởi tạo dự án
# Tạo dự án cho trình lấy dữ liệu Jira hoặc Wiki tùy chỉnh
mkdir claude-internal-tools && cd claude-internal-tools
# Khởi tạo khung cho một MCP server mới
npx @modelcontextprotocol/create-server internal-docs-server
2. Định nghĩa một công cụ thực tế
Mở file src/index.ts. Thay vì một ví dụ chung chung, hãy xây dựng một công cụ lấy thông số môi trường dev nội bộ. Điều này giúp Claude không phải đoán xem nên sử dụng port hay URL nào.
server.tool(
"get_service_config",
"Lấy thông tin port và URL môi trường dev từ registry nội bộ",
{ serviceName: z.string().description("Tên của microservice, ví dụ: 'auth-api'") },
async ({ serviceName }) => {
// Trong thực tế, đây sẽ là một lệnh gọi Axios đến registry nội bộ của bạn
const mockData = { "auth-api": "Port: 8081, DB: pg-dev-01", "gateway": "Port: 3000" };
return {
content: [{ type: "text", text: mockData[serviceName] || "Không tìm thấy dịch vụ" }]
};
}
);
3. Liên kết Skill với Claude Code
Claude Code cần biết server của bạn nằm ở đâu. Hãy chỉnh sửa file claude_desktop_config.json. Trên macOS, file này nằm tại ~/Library/Application Support/Claude/. Trên Windows, hãy kiểm tra %APPDATA%\Claude\.
{
"mcpServers": {
"internal-docs": {
"command": "node",
"args": ["/Users/yourname/dev/claude-internal-tools/build/index.js"]
}
}
}
Khởi động lại phiên làm việc Claude Code. Giờ đây, bạn chỉ cần hỏi: “auth-api sử dụng port nào?” và nó sẽ gọi code của bạn để tìm câu trả lời.
Nghệ thuật thiết kế giao diện ngữ nghĩa
Khi bạn xây dựng một skill, bạn không chỉ viết code; bạn đang viết hướng dẫn cho một mô hình ngôn ngữ. Claude sử dụng các trường description (mô tả) để quyết định khi nào nên kích hoạt một công cụ. Nếu mô tả sơ sài, Claude sẽ bỏ qua công cụ đó hoặc tự tạo ra (hallucinate) các tham số sai lệch.
Tôi từng mất hai giờ để debug tại sao Claude không chịu sử dụng công cụ database mà tôi đã xây dựng. Thủ phạm chính là một mô tả mơ hồ. Thay vì để “Truy vấn cơ sở dữ liệu”, tôi đã đổi thành: “Truy vấn cơ sở dữ liệu production PostgreSQL để tìm bản ghi người dùng bằng định dạng địa chỉ email chuẩn.” Tỷ lệ thành công ngay lập tức tăng từ 40% lên gần 100%.
Các thành phần chính của một Skill:
- Name: Sử dụng tên rõ ràng, theo định dạng snake_case như
fetch_sentry_errors. - Description: Cực kỳ cụ thể. Đề cập đến định dạng dữ liệu và các trường hợp sử dụng chính xác.
- Input Schema: Sử dụng Zod để định nghĩa chặt chẽ những gì Claude có thể gửi. Điều này ngăn mô hình gửi giá trị “hôm qua” khi API của bạn yêu cầu một mốc thời gian ISO.
Xử lý các tác vụ phức tạp: State và quy trình bất đồng bộ
Các công cụ cơ bản rất tuyệt, nhưng sức mạnh thực sự nằm ở việc xử lý các tác vụ chạy lâu. Claude Code có giới hạn thời gian (timeout) cho các phản hồi từ công cụ. Nếu một tác vụ mất hơn 30 giây—như chạy toàn bộ bộ test CI—đừng bắt Claude phải chờ. Hãy sử dụng mô hình “Job ID”.
// Công cụ 1: Bắt đầu quy trình dài
server.tool("trigger_deploy", { cluster: z.string() }, async ({ cluster }) => {
const jobId = "job_" + Math.random().toString(36).substring(7);
return { content: [{ type: "text", text: `Quá trình triển khai đã bắt đầu trên ${cluster}. ID: ${jobId}. Hãy hỏi lại trạng thái sau 60 giây.` }] };
});
// Công cụ 2: Kiểm tra kết quả
server.tool("get_deploy_status", { jobId: z.string() }, async ({ jobId }) => {
return { content: [{ type: "text", text: "Trạng thái: Thành công" }] };
});
Mẹo tối ưu cho môi trường Production
Sau khi xây dựng hàng chục skill như thế này, tôi đã rút ra một vài quy tắc không thể thỏa hiệp để đảm bảo độ tin cậy:
1. Cung cấp Stack Trace cho Claude. Nếu công cụ của bạn gặp lỗi, đừng chỉ nói “Đã có lỗi xảy ra.” Hãy trả về thông báo lỗi cụ thể. Claude thường có thể đọc lỗi, nhận ra mình đã gõ sai tham số đầu vào và tự động thử lại lệnh gọi mà bạn không cần can thiệp.
2. Debug qua Stderr. MCP sử dụng stdin và stdout để giao tiếp. Nếu bạn sử dụng console.log() để debug, bạn sẽ làm hỏng luồng JSON và gây ngắt kết nối. Thay vào đó, hãy sử dụng console.error(); Claude Code sẽ bỏ qua nó, nhưng nó vẫn sẽ hiển thị trong terminal của bạn để phục vụ việc debug.
3. Giữ cho các công cụ luôn tập trung. Tránh tạo ra một “God Tool” (công cụ vạn năng) cố gắng làm mọi thứ. Thà có năm MCP server chuyên biệt còn hơn là một cái khổng lồ và gây nhầm lẫn. Điều này giúp ngữ cảnh của prompt luôn sạch sẽ và giúp mô hình tập trung vào nhiệm vụ hiện tại.
Các skill tùy chỉnh biến Claude Code từ một chatbot thông thường thành một cộng sự kỹ thuật chuyên nghiệp. Bằng cách kết nối nó với hệ thống riêng của mình, bạn không còn là người trung gian giữa AI và dữ liệu nữa. Điều này cho phép bạn tập trung vào kiến trúc trong khi AI xử lý việc tra cứu API và kiểm tra trạng thái lặp đi lặp lại.

