Skip to content

Conan Tool Plane ​

Trạng thái: đã dựng bản MVP trong conan-tool-plane/ · Phiên bản đặc tả: 0.1

Conan Tool Plane là lớp năng lực và quản trị đứng giữa các agent chạy trên cloud của Conan và mọi hệ thống chúng được phép chạm tới, GitHub, Cloudflare, và các API nội bộ.

Nó không phải một agent. Nó không suy luận, không lập kế hoạch, không quyết định việc gì nên làm. Nó chỉ trả lời đúng một câu hỏi: "agent này có được phép làm việc này không, và nếu có thì làm hộ nó rồi ghi lại."

Nguyên tắc gốc ​

Agent nhận NĂNG LỰC, không nhận CHỨNG THƯ

Một agent không bao giờ được cầm khoá riêng của GitHub App, token Cloudflare, hay chuỗi kết nối cơ sở dữ liệu. Nó chỉ thấy những cái tên:

text
github.create_pull_request
cloudflare.deploy_staging
conan.get_course

Tool Plane giữ chứng thư, xét quyền, rồi tự gọi API.

Vì sao ranh giới này quan trọng đến thế: một token nằm trong ngữ cảnh của model là một token đã rò. Nó đi vào prompt, đi vào log của nhà cung cấp, đi vào bản ghi hội thoại, và có thể bị moi ra bằng một câu hỏi khéo. Không có cách nào thu hồi một bí mật mà model đã đọc. Cách duy nhất an toàn là model chưa từng đọc nó.

Ba lớp, ba trách nhiệm ​

LớpQuyết địnhKhông bao giờ làm
Claude Managed AgentViệc gì nên làmGiữ chứng thư hạ tầng
Conan Tool PlaneCó được phép không, và thi hànhSuy luận, lập kế hoạch, viết prompt
CloudflareChỗ cả hai chạy,

Tool Plane chịu trách nhiệm gì ​

Khám phá tool · định nghĩa tool · thi hành tool · xác thực · phân quyền · quyền theo tài nguyên · giới hạn theo môi trường · quản bí mật · tích hợp API ngoài · tích hợp API nội bộ · nhật ký kiểm toán · giới hạn tần suất · phiên bản tool · chuẩn hoá lỗi · duyệt của người · ranh giới an toàn.

Không chịu trách nhiệm: suy luận, lập kế hoạch, kỹ thuật prompt, gọi model, trí nhớ dài hạn của agent, tính cách agent, hay đoán xem người dùng thật sự muốn gì. Tất cả những thứ đó thuộc về Managed Agents.

Đường đi của một lượt gọi ​

Có đúng một đường. Không có lối tắt, không có bước nào tuỳ chọn.

Trong mã, đó là src/invoke.ts, một hàm duy nhất. Thêm một tool nghĩa là thêm một định nghĩa và một nhánh executor; không bao giờ nghĩa là thêm một route mới. Route mới là đường vòng qua chính sách, và đường vòng qua chính sách là lý do lớp này tồn tại.

Quyết định phân quyền ​

Ba nguồn, xét theo thứ tự cố định (src/policy/policy-engine.ts):

  1. Tool tắt trong registry → từ chối. Không bàn thêm.
  2. Không có grant → từ chối. Mặc định là từ chối, luôn luôn.
  3. Grant khớp nhất quyết định, nhưng một deny tường minh thắng mọi allow.
  4. Chính sách toàn tổ chức chạy sau. Một deny ở đây thắng tất cả. Một require_approval chỉ siết được một allow; nó không nới được một deny.
  5. Cờ requires_approval của tool là sàn, không phải trần.

Điều then chốt, và nó được viết thành một bài kiểm riêng: không có tổ hợp nào của chính sách allow nới lỏng được một deny. Nới lỏng chỉ xảy ra bằng cách sửa grant, tức bằng một hành động có chủ đích của người, không phải bằng một luật mới tình cờ khớp.

Máy quyết định là hàm thuần: không I/O, không binding. Nhờ vậy toàn bộ bảng quyết định kiểm được bằng npm test, không cần cơ sở dữ liệu. Đó không phải sở thích kiến trúc, một lớp phân quyền không kiểm được là một lớp phân quyền không ai dám sửa.

Phạm vi tài nguyên ​

Quyền không cấp theo tool, mà theo tool × tài nguyên × môi trường:

text
engineering-agent
  github.create_pull_request   resource = dac2205/*        env = *
  cloudflare.deploy_staging    resource = api-conan-school env = staging
  cloudflare.deploy_production DENY

Cách khớp cố tình ngu ngốc: chỉ có *, tiền tố abc*, khớp đúng, và danh sách ngăn bởi dấu phẩy. Không có regex lấy từ cơ sở dữ liệu. Một scope viết sai thì trượt, chứ không nới quyền ra ngoài ý định. Sai theo hướng chặt hơn là sai chấp nhận được; sai theo hướng lỏng hơn thì không.

Một grant có phạm vi không thoả mãn được bởi lượt gọi không có tài nguyên. resource = null chỉ khớp *.

Việc chạy lâu ​

Một request Worker không được mở suốt thời gian một lượt deploy chạy. Tool chạy lâu ghi một operation, khởi động việc bằng waitUntil, rồi trả ngay operation_id:

json
{ "operation_id": "e2b1…", "status": "pending", "poll_with": "plane.get_operation" }

Agent tiếp tục suy luận và hỏi lại sau. Không có kết nối HTTP nào bị giữ.

Duyệt của người ​

require_approval không chặn một request để chờ người, nó đỗ lượt gọi lại, trả approval_id, rồi kết thúc. Khi người duyệt ở bảng điều khiển, agent gọi lại đúng lượt gọi cũ kèm approval_id, và nó chạy đúng một lần.

"Đúng một lần" là toàn bộ điểm mấu chốt: một phê duyệt bị tiêu thụ khi dùng, nên một lượt deploy production đã duyệt không thể bị phát lại thành ba lượt deploy. Phê duyệt cũng gắn chặt vào tài nguyên và môi trường đã duyệt, duyệt cho api-conan-school không duyệt cho thứ khác.

Deploy đi qua CI, không đi qua Tool Plane ​

cloudflare.deploy_staging không gọi API deploy của Cloudflare. Nó kích hoạt workflow CI của repo (workflow_dispatch). Lưu ý (03.09.2026): các deploy-*.yml của app chưa khai workflow_dispatch, nên hiện chỉ ba workflow tool-plane kích được, xem câu 28.

Đây không phải vòng vo thừa. Luật nền tảng là không deploy từ máy, và một Worker deploy hộ agent chính là "deploy từ máy", chỉ khác chỗ đặt cái máy. Đi qua GitHub Actions giữ nguyên một đường deploy duy nhất, một chỗ xem lịch sử, một chỗ hỏng để sửa.

Hệ quả cố ý: một Worker không có trong bảng DEPLOY_WORKFLOWS thì không deploy được qua Tool Plane. Đó là kết quả mong muốn, không phải thiếu sót.

Hai bề mặt, không thể hoán đổi ​

/mcp/admin/*
Ai gọiAgentNgười vận hành
Xác thựcBearer token của agent (chỉ lưu sha256)ADMIN_TOKEN
Làm được gìGọi tool đã được cấpCấp quyền, duyệt, đọc vết
Agent gọi được không,Không bao giờ

Một agent cấp được quyền cho chính nó thì không còn lớp quản trị nào cả. Ranh giới này là ranh giới thật, không phải quy ước đặt tên.

Bảng trong D1 ​

agents · tools · agent_tools · policies · audit_logs · operations · approvals · rate_counters. Chi tiết ở Tool Plane, bí mật và an toàn.

Registry có hai nửa, và sự bất đối xứng giữa chúng là chủ ý:

  • Mã là nguồn sự thật cho tool là gì: tên, schema, executor, tài nguyên nó chạm. Một tool không có trong src/registry/tools.ts thì không gọi được, dù cơ sở dữ liệu nói gì.
  • Cơ sở dữ liệu giữ trạng thái vận hành người vận hành đổi được mà không cần deploy: enabled, requires_approval, risk_level.

Khi đồng bộ, mô tả và schema bị ghi đè từ mã; enabled và requires_approval chỉ ghi khi hàng còn mới. Người vận hành tắt một tool giữa sự cố mà lượt deploy sau lặng lẽ bật lại nó là đúng loại hỏng mà hệ vẫn trông như đang chạy.

Sandbox và Tool Plane khác nhau chỗ nào ​

Hay bị lẫn, nên nói thẳng:

Cloudflare SandboxConan Tool Plane
Là gìMáy tính tạm của agentQuyền có kiểm soát của agent
Dùng chocode, file, bash, npm, git, test, buildGitHub, Cloudflare, API Conan, D1, việc production
Hỏng thì mất gìMột thư mục tạmCó thể là dữ liệu thật

Agent sửa code, chạy test, build, tất cả trong Sandbox của nó. Chỉ khi cần chạm vào thế giới, mở PR, deploy, nó mới đi qua Tool Plane.

Vòng lặp cần chứng minh ​

MVP tồn tại để chứng minh đúng một vòng, không phải để có nhiều tool:

Chạy được vòng này một cách ổn định thì kiến trúc đã được xác nhận. Trước đó, mọi tool thêm vào đều là phỏng đoán.

Đọc tiếp ​

Tài liệu nội bộ nền tảng Conan School.