Hầu hết các cơ sở mã tác nhân đều chứa một tệp mà không ai muốn duy trì. Tệp đó chứa bốn mươi định nghĩa công cụ, mỗi định nghĩa là một lược đồ JSON được viết thủ công mô tả một điểm cuối mà bản thân nó đã có lược đồ ở nơi khác. Khi nhóm API xuất xưởng một trường bắt buộc mới, đặc tả cập nhật, tài liệu cập nhật, và tác nhân vẫn tiếp tục gửi tải trọng cũ cho đến khi ai đó nhận thấy các lỗi 400.
Bạn đã có một mô tả máy đọc được của mọi điểm cuối. Đó chính là tài liệu OpenAPI. Công việc là biến nó thành các định nghĩa công cụ mà mô hình có thể gọi, và giữ cho hai thứ này đồng bộ tự động thay vì phải ghi nhớ.
Hướng dẫn này bao gồm cách các hoạt động OpenAPI ánh xạ tới các lược đồ công cụ, những gì trình tạo cần sửa chữa trong quá trình, cách cắt giảm một đặc tả 200 điểm cuối thành thứ mà mô hình có thể xử lý, và cách kiểm tra xem các công cụ được tạo ra có hoạt động đúng không. Nếu bạn ở giai đoạn sớm hơn trong ngăn xếp công nghệ, bài viết của chúng tôi về liệu bạn có còn cần một công cụ API khi các tác nhân tự viết mã hay không sẽ đặt ra ngữ cảnh rộng hơn.
Apidog quan trọng ở đây vì đặc tả phải chính xác trước khi bất cứ thứ gì được tạo ra từ nó có thể hoạt động. Một định nghĩa công cụ kế thừa mọi lỗ hổng trong tài liệu mà nó được tạo ra.
Chi phí của các định nghĩa công cụ được viết thủ công
Việc viết thủ công các công cụ cảm thấy ổn với năm điểm cuối. Nó bắt đầu không ổn khi đạt khoảng hai mươi điểm cuối, vì ba lý do.
Các định nghĩa bị lệch. Đặc tả được tạo từ mã hoặc được duy trì bởi nhóm API. Tệp công cụ được duy trì bởi bất cứ ai xây dựng tác nhân. Không có gì kết nối chúng, vì vậy chúng âm thầm phân kỳ, và triệu chứng đầu tiên là một tác nhân "đột nhiên" ngừng hoạt động.
Mô tả trở nên sơ sài. Khi một người viết bốn mươi lược đồ bằng tay, hai mươi lược đồ cuối cùng chỉ có mô tả một dòng. Các mô hình chọn công cụ bằng cách đọc các mô tả đó, vì vậy văn bản sơ sài trực tiếp làm giảm chất lượng lựa chọn công cụ. Bài viết của chúng tôi về thiết kế lược đồ công cụ API cho tác nhân đi sâu hơn vào lý do tại sao cách diễn đạt lại quan trọng đến vậy.
Lỗi không thể nhìn thấy cho đến khi chạy. Một lược đồ được viết thủ công nói rằng một trường là kiểu chuỗi trong khi API muốn kiểu số nguyên sẽ tạo ra lỗi 422 ngay lần đầu tiên tác nhân thử nó, trong môi trường sản xuất, trên một tác vụ thực.
Tạo từ đặc tả khắc phục cả ba vấn đề cùng lúc. Có một nguồn chân lý duy nhất, mô tả đến từ cùng một văn bản mà tài liệu của bạn sử dụng, và các kiểu dữ liệu đến từ cùng một lược đồ mà máy chủ dùng để xác thực.
Cách một hoạt động OpenAPI trở thành một công cụ
Việc ánh xạ trực tiếp hơn bạn nghĩ. Lấy một hoạt động duy nhất:
paths:
/orders/{orderId}/refund:
post:
operationId: refundOrder
summary: Refund an order
description: >
Issues a full or partial refund against a completed order.
Refunds are irreversible. Partial refunds require an amount
no greater than the remaining refundable balance.
parameters:
- name: orderId
in: path
required: true
schema: { type: string }
description: The order to refund.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [reason]
properties:
amount:
type: integer
description: Amount in cents. Omit for a full refund.
reason:
type: string
enum: [duplicate, fraudulent, requested_by_customer]
Định nghĩa công cụ được tạo ra từ đó:
{
"name": "refundOrder",
"description": "Issues a full or partial refund against a completed order. Refunds are irreversible. Partial refunds require an amount no greater than the remaining refundable balance.",
"input_schema": {
"type": "object",
"required": ["orderId", "reason"],
"properties": {
"orderId": { "type": "string", "description": "The order to refund." },
"amount": { "type": "integer", "description": "Amount in cents. Omit for a full refund." },
"reason": { "type": "string", "enum": ["duplicate", "fraudulent", "requested_by_customer"] }
}
}
}
Bốn quy tắc thực hiện phần lớn công việc:
operationIdtrở thành tên công cụ. Nếu một hoạt động không cóoperationId, hãy tạo một tên ổn định từ phương thức cộng với đường dẫn, sau đó thêm nó vào đặc tả.- Các tham số đường dẫn, truy vấn và thân yêu cầu được làm phẳng thành một đối tượng thuộc tính duy nhất. Mô hình không quan tâm giá trị được truyền đi đâu. Trình thực thi của bạn thì có, vì vậy hãy giữ một bảng phụ ghi lại tham số nào đi đến đâu.
summarycộng vớidescriptiontrở thành mô tả công cụ. Cả hai, được nối lại. Tóm tắt một mình thường quá ngắn gọn để hướng dẫn lựa chọn.- Mảng yêu cầu được hợp nhất. Một tham số đường dẫn bắt buộc và một trường thân yêu cầu bắt buộc đều nằm trong cùng một danh sách
required.
Trình thực thi là một nửa còn lại, và nó rất nhỏ gọn:
def execute(tool_name, args, spec_index, http):
op = spec_index[tool_name] # method, path template, param locations
path = op.path
query, body = {}, {}
for name, value in args.items():
location = op.locations[name] # "path" | "query" | "header" | "body"
if location == "path":
path = path.replace("{" + name + "}", str(value))
elif location == "query":
query[name] = value
elif location == "body":
body[name] = value
return http.request(op.method, path, params=query, json=body or None)
Đó là toàn bộ cầu nối. Mọi thứ khác chỉ là dọn dẹp trong quá trình.
Những gì trình tạo cần sửa chữa
Việc đổ đặc tả một cách ngây thơ vào các lược đồ công cụ sẽ tạo ra các công cụ mà các mô hình xử lý kém hiệu quả. Năm điều chỉnh sau đây quan trọng.
Giải quyết các con trỏ $ref. Hầu hết các API gọi công cụ chấp nhận một tập hợp con của JSON Schema và sẽ không theo các tham chiếu vào phần components. Hãy nội tuyến chúng. Cẩn thận với các lược đồ đệ quy, việc nội tuyến sẽ mở rộng chúng vô hạn; cắt đệ quy ở một độ sâu cố định và mô tả cấu trúc sâu hơn bằng văn xuôi.
Bỏ qua các từ khóa không được hỗ trợ. oneOf, allOf, discriminator, và nullable phổ biến trong các đặc tả và được hỗ trợ kém bởi các lược đồ công cụ. Gộp allOf bằng cách hợp nhất các thuộc tính. Đối với oneOf, hãy chọn biến thể chính hoặc chia hoạt động thành hai công cụ, mỗi công cụ một hình dạng. Tùy chọn thứ hai đó thường mang lại lựa chọn công cụ tốt hơn.
Làm phẳng các lồng ghép sâu. Một thân yêu cầu lồng ghép sâu ba cấp độ khó để mô hình điền đúng cách. Nếu tải trọng tạo đơn hàng của bạn lồng ghép customer.address.postal_code, hãy xem xét một bề mặt công cụ phẳng hơn và lắp ráp lại hình dạng lồng ghép trong trình thực thi.
Cắt bỏ các lược đồ phản hồi. Định nghĩa công cụ mô tả đầu vào. Lược đồ phản hồi đầy đủ không thuộc về định nghĩa, và việc bao gồm nó sẽ làm lãng phí ngữ cảnh. Hình dạng của phản hồi quan trọng khi kết quả trả về, và đó là một vấn đề riêng biệt được đề cập trong bài viết của chúng tôi về giữ các phản hồi API trong cửa sổ ngữ cảnh của tác nhân.
Mang theo các cờ an toàn. Các hoạt động ghi nên được đánh dấu để trình thực thi của bạn có thể định tuyến chúng qua một cổng phê duyệt. Nếu đặc tả của bạn sử dụng một phần mở rộng như x-agent-requires-approval, hãy đọc và tôn trọng nó. Kết hợp điều này với các mẫu trong hướng dẫn AI agent guardrails của chúng tôi.
Không cung cấp cho mô hình tất cả 200 điểm cuối
Vấn đề thực tế lớn nhất không phải là chuyển đổi. Đó là khối lượng. Một API trưởng thành có hàng trăm hoạt động, và việc dán tất cả chúng vào danh sách công cụ sẽ tạo ra hai thất bại cùng lúc: ngữ cảnh bị lấp đầy bởi các lược đồ trước khi tác vụ bắt đầu, và độ chính xác lựa chọn giảm vì mô hình phải chọn giữa các tùy chọn gần như giống hệt nhau.
Ba cách để giảm bớt, gần đúng theo thứ tự hiệu quả.
Lọc theo thẻ. Các hoạt động OpenAPI mang thẻ, và các thẻ thường ánh xạ tới các khu vực sản phẩm. Một tác nhân xử lý hoàn tiền cần các thẻ orders và payments, chứ không phải admin hay analytics. Đây là một bộ lọc một dòng và nó thường loại bỏ hầu hết bề mặt.
Quản lý danh sách cho phép (allowlist). Viết ra các hoạt động mà tác nhân này được phép gọi, bằng operationId, và chỉ tạo ra những hoạt động đó. Điều này cũng có tác dụng như một biện pháp kiểm soát bảo mật, vì một tác nhân không có công cụ cho một điểm cuối thì không thể gọi nó một cách ngẫu nhiên. Bài viết của chúng tôi về ngăn chặn các tác nhân hủy hoại API của bạn ủng hộ chính xác loại bề mặt hẹp này.
Truy xuất công cụ theo yêu cầu. Đối với các API rất lớn, hãy lập chỉ mục các hoạt động và chọn một vài hoạt động mỗi lượt dựa trên tác vụ. Điều này bổ sung một bước truy xuất và các chế độ lỗi riêng của nó, vì vậy chỉ nên sử dụng nó sau khi việc lọc và quản lý không còn đủ nữa.
Ngoài ra còn có tuyến đường giao thức. Giao thức Ngữ cảnh Mô hình (Model Context Protocol) chuẩn hóa cách máy chủ hiển thị các công cụ cho máy khách, và một máy chủ MCP được hỗ trợ bởi tài liệu OpenAPI của bạn cung cấp cho bạn một điểm tích hợp duy nhất thay vì một điểm cho mỗi framework. Bài giải thích của chúng tôi về MCP là gì bao gồm mô hình, và xây dựng máy chủ MCP với Apidog bao gồm quá trình xây dựng.

Đặc tả phải đúng trước tiên
Việc tạo ra chuyển vấn đề chất lượng lên phía trước. Một mô tả mơ hồ trong tài liệu OpenAPI của bạn trở thành một mô tả công cụ mơ hồ, và mô hình chọn sai điểm cuối. Một trường tùy chọn mà máy chủ thực sự yêu cầu trở thành một công cụ mà tác nhân gọi sai ngay lần thử đầu tiên.
Vì vậy, hãy kiểm tra đặc tả dưới góc nhìn của một tác nhân trước khi bạn tạo bất cứ thứ gì:
- Mọi hoạt động đều có một
operationId, và nó đọc giống như một động từ cộng với một danh từ. - Mọi hoạt động đều có một mô tả nói rõ nó làm gì, nó thay đổi gì và khi nào không nên sử dụng nó. "Xóa người dùng" là không đủ. "Xóa vĩnh viễn một người dùng và tất cả các phiên của họ. Không thể hoàn tác. Sử dụng deactivateUser để tạm thời vô hiệu hóa quyền truy cập." mới là đủ.
- Mọi tham số đều có mô tả với đơn vị và định dạng.
amountlà mơ hồ. "Số tiền tính bằng xu, tối thiểu 50" thì không. - Các kiểu liệt kê (enum) được khai báo thay vì mô tả bằng văn xuôi, để mô hình nhận được một tập hợp đóng thay vì phải đoán.
- Trường bắt buộc là chính xác. Các đặc tả có xu hướng đánh dấu mọi thứ là tùy chọn, điều này đẩy lỗi xác thực vào thời gian chạy.
Đây là vệ sinh đặc tả thông thường, và nó mang lại lợi ích gấp đôi, vì cùng một văn bản được dùng cho tài liệu công khai của bạn. Trong Apidog, đặc tả, tài liệu, máy chủ mô phỏng và các bài kiểm tra đều xuất phát từ một dự án, vì vậy việc thắt chặt một mô tả sẽ cải thiện tất cả chúng cùng một lúc. Hướng dẫn của chúng tôi về quản lý phiên bản API trong Apidog bao gồm phần còn lại của việc giữ cho các công cụ được tạo ra trung thực theo thời gian.
Chia sẻ bộ công cụ, đừng sao chép nó
Một bộ công cụ được tạo ra là cấu hình, và cấu hình nằm trong một nhánh phát triển của một nhà phát triển sẽ bị lệch giống như các lược đồ viết thủ công. Danh sách bộ lọc, danh sách cho phép (allowlist) và phiên bản đặc tả được ghim nên là các tạo phẩm được chia sẻ, được gắn phiên bản bên cạnh đặc tả mà chúng được tạo ra.
Một số nền tảng biến điều này thành đơn vị mặc định. Trong Sharkly, một Tác nhân là một cấu hình làm việc được lưu trữ thay vì một lời nhắc dùng một lần: các hướng dẫn, Thời gian chạy (Runtime), Kỹ năng (Skills), kho lưu trữ và cài đặt chạy của nó đi kèm và có thể được chia sẻ trong một Không gian, do đó, một thiết lập công cụ hoạt động trở thành thứ mà một nhóm có thể tái sử dụng thay vì mỗi người phải xây dựng lại. Thời gian chạy bên dưới vẫn là Claude Code, Codex hoặc bất cứ thứ gì bạn đã chạy. Điều thay đổi là cấu hình xung quanh nó không còn là cục bộ nữa.

Kiểm tra các công cụ được tạo ra
Các công cụ được tạo ra có thể thất bại theo những cách mà các công cụ viết thủ công không mắc phải, vì vậy hãy kiểm tra cả quá trình tạo ra lẫn các lệnh gọi.
Bắt đầu với kiểm tra vòng lặp lược đồ. Đối với mỗi công cụ được tạo ra, hãy xây dựng một ví dụ hợp lệ từ lược đồ và gửi nó. Bất cứ điều gì trả về 400 hoặc 422 có nghĩa là lược đồ công cụ và máy chủ không đồng bộ, và đặc tả là thứ cần sửa.
Sau đó kiểm tra lựa chọn. Viết một bộ nhỏ các lời nhắc tác vụ với một công cụ đúng đã biết, chạy chúng và ghi lại công cụ nào mà mô hình đã chọn. Đây là một bộ kiểm thử hồi quy giá rẻ giúp phát hiện ngày ai đó đổi tên một hoạt động hoặc rút ngắn mô tả. Vì đầu ra không xác định, hãy khẳng định dựa trên tên công cụ chứ không phải các đối số chính xác, theo hướng dẫn của chúng tôi về kiểm tra các tác nhân không xác định.
Cuối cùng, hãy chạy tác nhân trên các máy chủ giả lập trước khi chạy thực tế. Một máy chủ giả lập được tạo từ cùng một đặc tả sẽ cung cấp cho bạn các phản hồi thực tế mà không gây ra tác dụng phụ, và nó cho phép bạn chèn các lỗi 500 và thời gian chờ mà logic thử lại của bạn phải xử lý.
Điều này đưa bạn đến đâu
Đặc tả là hợp đồng, và danh sách công cụ nên là một phép chiếu của nó, chứ không phải một bản sao song song được duy trì thủ công. Hãy tạo ra các công cụ, lọc chúng kỹ lưỡng, giữ cho mô tả trung thực, và kiểm tra cả hình dạng lẫn lựa chọn.
Bắt đầu bằng cách xuất tài liệu OpenAPI của bạn và đếm số lượng hoạt động không có mô tả. Con số đó chính là khối lượng công việc ngăn cách bạn với các công cụ tác nhân đáng tin cậy. Tải Apidog nếu bạn muốn có đặc tả, máy chủ giả lập và các bài kiểm tra ở một nơi trong khi bạn sửa chữa nó.
Các câu hỏi thường gặp
Tôi có thể tạo công cụ từ tài liệu Swagger 2.0 không? Có, nhưng trước tiên hãy chuyển đổi nó sang OpenAPI 3.x. Mô hình thân yêu cầu 2.0 khác biệt đủ nhiều khiến các trình tạo xử lý nó không nhất quán, và 3.x là mục tiêu của các công cụ hiện tại. Kho lưu trữ đặc tả OpenAPI ghi lại các khác biệt.
Một mô hình có thể xử lý bao nhiêu công cụ cùng lúc? Độ chính xác bắt đầu suy giảm rất lâu trước giới hạn kỹ thuật, và giới hạn thực tế thường là vài chục. Hãy coi bất kỳ danh sách nào vượt quá con số đó như một tín hiệu để lọc theo thẻ hoặc quản lý danh sách cho phép (allowlist) thay vì coi đó là một giới hạn để kiểm tra.
Tên công cụ có nên khớp chính xác với operationId không? Có, khi operationId dễ đọc. Nó cung cấp cho bạn một tra cứu trực tiếp từ lệnh gọi công cụ trở lại hoạt động đặc tả, giúp việc theo dõi và gỡ lỗi dễ dàng hơn nhiều. Hãy đổi tên trong đặc tả nếu tên không tốt, chứ không phải trong trình tạo.
Còn về API GraphQL thì sao? Ý tưởng tương tự được áp dụng với một nguồn khác: kiểm tra lược đồ và tạo một công cụ cho mỗi truy vấn hoặc mutation. Vấn đề về khối lượng tồi tệ hơn vì lược đồ GraphQL phơi bày nhiều bề mặt hơn, vì vậy việc lọc càng trở nên quan trọng hơn.
Tôi có vẫn cần viết thủ công bất kỳ công cụ nào không? Một vài cái. Các công cụ tổng hợp (composite tools) nối nhiều lệnh gọi thành một hành động, và các công cụ gói gọn thứ gì đó không phải HTTP, vẫn cần được viết thủ công. Vấn đề là các trình bao bọc một điểm cuối thông thường không còn là công việc thủ công nữa.
Làm thế nào để ngăn tác nhân gọi các điểm cuối ghi trong quá trình kiểm tra? Tạo một bộ công cụ chỉ đọc cho các lần chạy kiểm thử bằng cách lọc theo phương thức HTTP, và hướng tác nhân đến một máy chủ giả lập cho bất kỳ thứ gì có ghi. Bài viết của chúng tôi về tại sao tác nhân nên truy cập máy chủ giả lập, không phải môi trường sản xuất bao gồm phần thiết lập.
