Bạn có bao giờ tưởng tượng một công ty có thể vận hành gần như không cần sự can thiệp của con người, được điều hành bởi một đội ngũ các agent AI thông minh? Đó chính là tầm nhìn mà Paperclip, một giải pháp điều phối mã nguồn mở mạnh mẽ, hướng tới. Paperclip cung cấp một “mặt phẳng điều khiển” (control plane) để quản lý và vận hành toàn bộ một “công ty không người” (zero-human company), nơi các tác vụ được ủy quyền, chi phí được kiểm soát và mục tiêu được theo dõi một cách tự động.
Bài viết này là một hướng dẫn chuyên sâu, chắt lọc kiến trúc, các nguyên tắc và lựa chọn kỹ thuật đằng sau Paperclip, biến chúng thành một kế hoạch chi tiết mà bạn có thể sử dụng để xây dựng một hệ thống tương tự. Hãy đọc từ đầu đến cuối để có được một cái nhìn tổng thể và một kế hoạch cụ thể cho dự án của bạn.
—
Mục lục
Mục Lục
- 🤖 Paperclip Thực Sự Là Gì?
- 🧠 Mô Hình Tư Duy Cốt Lõi: Control Plane, Không Phải Framework
- 📐 10 Nguyên Tắc Thiết Kế Nền Tảng
- 🏗️ Kiến Trúc Tổng Quan
- 🗃️ Mô Hình Miền: Ánh Xạ “Một Công Ty” Thành Các Bảng Dữ Liệu
- 💚 Nhịp Tim Hệ Thống: Trái Tim Của Runtime
- 🔌 Adapters — “Mang Agent Của Riêng Bạn Đến”
- ✅ Hệ Thống Nhiệm Vụ & Kiểm Xuất Nguyên Tử
- ⚖️ Quản Trị, Phê Duyệt & Hội Đồng
- 💰 Ngân Sách & Kiểm Soát Chi Phí
- 🧩 Hệ Thống Plugin — Mở Rộng Dựa Trên Khả Năng
- 📡 Máy Chủ MCP — Các Agent Giao Tiếp Với API
- 🎓 Kỹ Năng — Hướng Dẫn Agent Sử Dụng API
- ⚙️ Ngăn Xếp Công Nghệ & Bố Cục Kho Lưu Trữ
- 🌐 Giao Diện REST API
- 🔒 Cách Ly Đa Công Ty & Khả Năng Di Chuyển
- 📋 Nhật Ký Kiểm Toán & Hoạt Động
- 📏 Quy Ước Kỹ Thuật
- 🗺️ Kế Hoạch Xây Dựng Từng Bước
- ⚠️ Cạm Bẫy, Đánh Đổi & Điều Nên Bỏ Qua Trước Tiên
—
🤖 1. Paperclip Thực Sự Là Gì?
Paperclip là một ứng dụng tự host được xây dựng trên **Node.js + React**, cho phép bạn điều hành một “công ty” gồm các agent AI. Đây không chỉ là một trình quản lý tác vụ thông thường (như Linear/Jira), mà còn là một cơ cấu tổ chức, công cụ quản lý ngân sách, hàng đợi phê duyệt, trình điều hành đa runtime và nhật ký kiểm toán — tất cả được thiết kế dành riêng cho **những người lao động phi nhân loại**.
Với Paperclip, bạn có thể:
- Xác định một công ty với các mục tiêu/sáng kiến rõ ràng.
- Tuyển dụng các agent (ví dụ: Claude Code, Codex, Cursor, bot CLI tùy chỉnh, bot HTTP – bạn chọn runtime).
- Gán nhiệm vụ (issues) và ngân sách cho từng agent.
- Một nhà điều hành hội đồng (con người) phê duyệt việc tuyển dụng, các kế hoạch chiến lược và việc ghi đè ngân sách.
- Một trình lập lịch (scheduler) chạy từng agent theo một nhịp tim (heartbeat – một khoảng thời gian thực thi ngắn) và theo dõi chi phí, trạng thái, các lệnh gọi công cụ và kết quả đầu ra.
Slogan của Paperclip là: “Nếu OpenClaw là một nhân viên, Paperclip là công ty.”
🧠 2. Mô Hình Tư Duy Cốt Lõi: Control Plane, Không Phải Framework
Đây là ý tưởng quan trọng nhất cần nắm vững trước khi xây dựng bất cứ điều gì. Paperclip là một “control plane” (mặt phẳng điều khiển), không phải một “framework” (khung làm việc) agent.
| Agent Framework (LangGraph, CrewAI…) | Control Plane (Paperclip) |
|---|---|
| Quyết định cách một agent suy nghĩ | Quyết định việc gì một agent làm |
| Sở hữu vòng lặp prompt + tool | Xem vòng lặp agent như một hộp đen |
| Một tiến trình, trong bộ nhớ | Nhiều tiến trình, trạng thái bền vững |
| Bạn triển khai mã | Bạn triển khai một triển khai (deployment) |
Những hệ quả cụ thể cho thiết kế:
- Hệ thống không bao giờ tự chạy vòng lặp “react+plan+act”. Đó là nhiệm vụ của adapter.
- Hệ thống sở hữu: danh tính, lập lịch, quyền sở hữu tác vụ, sổ cái chi phí, phê duyệt, kiểm toán, lưu trữ bền vững.
- Hợp đồng với một agent cực kỳ nhỏ gọn: “Tôi có thể gọi bạn, lấy trạng thái và hủy bạn.”
Nếu bạn bắt đầu xây dựng một hệ thống giống Paperclip và thấy mình đang viết các mẫu prompt hoặc bộ phân tích lệnh gọi công cụ trong phần lõi, bạn đã lạc vào lãnh địa framework — hãy quay lại.
📐 3. 10 Nguyên Tắc Thiết Kế Nền Tảng
Những nguyên tắc này được chắt lọc từ tài liệu kỹ thuật của Paperclip, hướng dẫn mọi quyết định thiết kế:
- Thực thi không định kiến (Unopinionated execution). Phần lõi không quan tâm agent sử dụng mô hình, prompt hay công cụ lập kế hoạch nào. Nó chỉ khởi chạy một tiến trình và chờ.
- Giao tiếp tập trung vào tác vụ (Task-centric communication). Các agent không giao tiếp trực tiếp với nhau. Ủy quyền = tạo tác vụ. Phối hợp = bình luận tác vụ. Trạng thái = cập nhật trường. Điều này giúp mọi thứ có thể quan sát và phát lại được.
- Công việc được theo dõi mục tiêu (Goal-traced work). Mọi tác vụ đều bắt nguồn từ một sáng kiến của công ty:
Sáng kiến → Dự án → Giai đoạn → Vấn đề → Vấn đề con. Không có công việc “mồ côi”. - Quyền sở hữu tác vụ nguyên tử (Atomic task ownership). Một tác vụ chỉ có thể thuộc sở hữu của duy nhất một agent tại một thời điểm, được thực thi ở tầng cơ sở dữ liệu (không phải trong mã ứng dụng).
- Hiển thị vấn đề rõ ràng (Visible problem surfacing). Các agent bị kẹt phải đánh dấu vấn đề là
blockedvà leo thang. Việc thử lại âm thầm là một anti-pattern. - Quyền hạn hội đồng con người (Human board authority). Mọi hành động không thể đảo ngược hoặc có rủi ro cao (tuyển dụng, chi tiêu lớn, phê duyệt chiến lược, chấm dứt hoạt động) đều yêu cầu bản ghi phê duyệt của con người.
- Chi phí đi kèm với công việc (Cost follows work). Chi phí được tính vào chuỗi tác vụ yêu cầu, không chỉ agent thực thi. Điều này giúp trả lời câu hỏi “ai tốn kém và tại sao”.
- Trần ngân sách cứng (Hard budget ceilings). Cảnh báo mềm ở 80%. Ở 100%, agent tự động bị tạm dừng và các lệnh gọi tiếp theo bị chặn. Không có “cố gắng hết sức”.
- Triển khai dần dần (Progressive deployment). Nó phải chạy trên laptop với Postgres nhúng, sau đó mở rộng quy mô lên tự host / đám mây — cùng một mã, cùng một schema.
- Có thể mở rộng bằng plugin, không phải fork (Plugin-extensible, not fork-extensible). Các khả năng mà phần lõi không cung cấp đến từ các plugin out-of-process với các khả năng được khai báo, có cổng kiểm soát.
Khi bạn thiết kế hệ thống của mình, hãy luôn để danh sách này hiển thị và kiểm tra mọi PR dựa trên nó.
🏗️ 4. Kiến Trúc Tổng Quan
Paperclip được xây dựng với một kiến trúc phân tán rõ ràng, đảm bảo khả năng mở rộng và bền vững.
┌────────────────────────────┐
│ React UI (Vite) │
│ Sơ đồ tổ chức · Tác vụ · Chi phí │
└──────────────┬─────────────┘
│ REST + SSE
▼
┌──────────────────────────────────────────────────────────────────┐
│ Node.js Server (TypeScript / Express) │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────┐ │
│ │ REST API │ │ Scheduler │ │ Phê duyệt │ │ Plugins │ │
│ │ (handlers) │ │ (nhịp tim) │ │ engine │ │ host │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └────┬────┘ │
│ │ │ │ │ │
│ └────────────────┼─────────────────┴──────────────┘ │
│ ▼ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Quản lý Adapter│───▶│ Agent runtime │ │
│ │ (claude_local, │ │ (tiến trình con /│ │
│ │ codex_local, │ │ webhook HTTP) │ │
│ │ http, process) │ └──────────────────┘ │
│ └──────────────────┘ │
└──────────────────────────┬───────────────────────────────────────┘
│
▼
┌──────────────────────────┐
│ PostgreSQL (hoặc PGlite)│
│ companies · agents · │
│ issues · heartbeats · │
│ costs · approvals · │
│ activity_log │
└──────────────────────────┘
Sidecar (tùy chọn):
┌───────────────────────────┐
│ Máy chủ MCP (REST mỏng) │ ◀─── agents gọi đến đây để đọc/ghi Paperclip
│ wrapper) │
└───────────────────────────┘
12 hệ thống con mà tài liệu kỹ thuật của Paperclip đề cập — đây là danh sách kiểm tra cho “phiên bản 1 hoàn chỉnh tính năng”:
- Danh tính & Truy cập (Identity & Access)
- Sơ đồ Tổ chức & Agents (Org Chart & Agents)
- Công việc & Hệ thống Nhiệm vụ (Work & Task System)
- Thực thi Nhịp tim (Heartbeat Execution)
- Không gian làm việc & Runtime (Workspaces & Runtime)
- Quản trị & Phê duyệt (Governance & Approvals)
- Ngân sách & Kiểm soát Chi phí (Budget & Cost Control)
- Thói quen & Lịch trình (Routines & Schedules)
- Plugins
- Bí mật & Lưu trữ (Secrets & Storage)
- Hoạt động & Sự kiện (Activity & Events)
- Khả năng Di chuyển Công ty (Company Portability – xuất/nhập)
🗃️ 5. Mô Hình Miền: Ánh Xạ “Một Công Ty” Thành Các Bảng Dữ Liệu
Đây là nơi tập trung phần lớn sự khéo léo trong thiết kế của Paperclip. Schema cơ sở dữ liệu nhỏ gọn nhưng mỗi cột đều có ý nghĩa quan trọng.
🏢 Companies
companies(
id uuid pk,
name text not null,
description text,
status text not null check (status in ('active','paused','archived')),
pause_reason text,
paused_at timestamptz,
issue_prefix text not null, -- e.g. "ACME"
issue_counter int not null, -- monotonic, used for ACME-123
budget_monthly_cents int default 0,
spent_monthly_cents int default 0,
attachment_max_bytes int,
require_board_approval_for_new_agents bool
)
Tại sao lại có
issue_prefix+issue_counter? Để các tác vụ có ID thân thiện với con người (ví dụ:ACME-42) ổn định, có thể sắp xếp và duy nhất cho mỗi công ty mà không làm lộ số đếm của các tenant khác.
🤖 Agents
agents(
id uuid pk,
company_id uuid not null references companies(id),
name text not null,
role text,
title text,
icon text,
status text not null check (status in ('active','paused','idle','running','error','pending_approval','terminated')),
reports_to uuid references agents(id), -- the org chart edge
capabilities text,
adapter_type text not null, -- claude_local | codex_local | http | ...
adapter_config jsonb, -- adapter-specific
runtime_config jsonb default '{}'::jsonb, -- timeouts, cwd, env
default_environment_id uuid,
context_mode text default 'thin' check (context_mode in ('thin','fat')),
budget_monthly_cents int default 0,
spent_monthly_cents int default 0
)
Tại sao lại có
adapter_type+adapter_config(jsonb)? Cho phép bạn hỗ trợ N runtime agent mà không cần N bảng. Tính đa hình sống trong mã (adapter manager) và JSON, không phải trong DDL.
📝 Issues (tasks)
issues(
id uuid pk,
company_id uuid not null references companies(id),
project_id uuid references projects(id),
goal_id uuid references goals(id),
parent_id uuid references issues(id),
title text not null,
description text,
status text not null check (status in ('backlog','todo','in_progress','in_review','done','blocked','cancelled')),
priority text check (priority in ('critical','high','medium','low')),
assignee_agent_id uuid references agents(id),
assignee_user_id uuid,
-- Atomic checkout fields:
checkout_run_id uuid,
execution_run_id uuid,
execution_agent_name_key text,
execution_locked_at timestamptz,
-- Provenance:
created_by_agent_id uuid references agents(id),
created_by_user_id uuid,
issue_number int not null,
identifier text not null, -- e.g. ACME-42
origin_kind text,
origin_id text,
origin_run_id uuid,
origin_fingerprint text,
request_depth int default 0, -- how deep the delegation chain is
billing_code text -- "cost follows work"
)
💚 Heartbeat runs (một hàng cho mỗi cửa sổ thực thi)
heartbeat_runs(
id uuid pk,
company_id uuid not null references companies(id),
agent_id uuid not null references agents(id),
invocation_source text not null check (invocation_source in ('scheduler','manual','callback')),
status text not null check (status in ('queued','running','succeeded','failed','cancelled','timed_out')),
started_at timestamptz,
finished_at timestamptz,
error text,
external_run_id text, -- adapter's run id, for resume
context_snapshot jsonb -- what was passed in
)
💰 Cost events (sổ cái)
cost_events(
id uuid pk,
company_id uuid not null references companies(id),
agent_id uuid not null references agents(id),
issue_id uuid references issues(id),
project_id uuid references projects(id),
goal_id uuid references goals(id),
billing_code text,
provider text,
model text,
input_tokens int,
output_tokens int,
cost_cents int,
occurred_at timestamptz
)
⚖️ Approvals (hàng đợi quản trị)
approvals(
id uuid pk,
company_id uuid not null references companies(id),
type text not null check (type in ('hire_agent','approve_ceo_strategy','budget_override_required','request_board_approval')),
requested_by_agent_id uuid references agents(id),
requested_by_user_id uuid,
status text not null check (status in ('pending','revision_requested','approved','rejected','cancelled')),
payload jsonb, -- the proposed change
decision_note text,
decided_by_user_id uuid,
decided_at timestamptz
)
📋 Activity log (băng ghi kiểm toán)
activity_log(
id uuid pk,
company_id uuid not null references companies(id),
actor_type text not null check (actor_type in ('agent','user','system')),
actor_id uuid,
action text not null, -- "issue.checked_out"
entity_type text,
entity_id uuid,
details jsonb,
created_at timestamptz
)
🔍 Các Chỉ Mục Quan Trọng (Đừng Bỏ Qua)
agents(company_id, status)
agents(company_id, reports_to) -- duyệt sơ đồ tổ chức
issues(company_id, status)
issues(company_id, assignee_agent_id, status) -- "những gì đang làm"
issues(company_id, parent_id) -- tác vụ con
issues(company_id, project_id)
cost_events(company_id, occurred_at)
cost_events(company_id, agent_id, occurred_at) -- tổng hợp theo từng agent
heartbeat_runs(company_id, agent_id, started_at desc)
approvals(company_id, status, type)
activity_log(company_id, created_at desc)
Bài học: mọi chỉ mục đều bắt đầu bằng
company_id. Việc cách ly tenant là một vấn đề liên quan đến kế hoạch truy vấn, không chỉ là vấn đề xác thực.
💚 6. Nhịp Tim Hệ Thống (The Heartbeat)
“Nhịp tim” là hạt nhân runtime. Mọi thứ khác chỉ là hệ thống ống nước xung quanh nó.
🔄 Vòng Đời của Một “Nhịp” Duy Nhất
1. Trình lập lịch (Scheduler) quyết định "agent A nên chạy bây giờ"
↓
2. Chèn hàng heartbeat_runs (status=queued)
↓
3. Trình quản lý Adapter tra cứu agents.adapter_type
↓
4. Adapter.invoke(agentConfig, context):
- Xây dựng prompt/context
- Khởi tạo tiến trình con HOẶC kích hoạt webhook HTTP
- Truyền session_id từ lần chạy trước nếu có thể tiếp tục
↓
5. Truyền nhật ký, trạng thái, lệnh gọi công cụ trở lại vào hàng chạy
↓
6. Chờ đến khi: thoát | hết giờ | hủy
- Khi hết giờ: gửi tín hiệu dừng, chờ graceSec, buộc dừng
↓
7. Lưu trữ: mức sử dụng token, các hàng cost_events, đoạn đầu ra, lỗi
↓
8. Cập nhật heartbeat_runs (status=succeeded|failed|timed_out)
↓
9. Phát ra mục activity_log; phát sóng SSE đến UI
⚡ Kích Hoạt Đánh Thức (Chỉ Bốn Loại)
| Kích hoạt | Ý nghĩa |
|---|---|
timer |
Giống Cron — “mỗi 5 phút” |
assignment |
Một tác vụ mới được gán cho agent này |
on_demand |
Con người hoặc API nhấn nút “Run now” |
automation |
Kích hoạt nội bộ hệ thống (trong tương lai) |
🔁 Hợp Nhất (Coalescing)
“Nếu một agent đã đang chạy, các yêu cầu đánh thức mới sẽ được hợp nhất (coalesced) thay vì khởi chạy các lần chạy trùng lặp.”
Quy tắc này giúp ngăn chặn 90% lỗi chi tiêu trùng lặp mà bạn có thể gặp phải.
▶️ Tiếp Tục Phiên (Session Resumption)
Đối với các adapter hỗ trợ nó (Claude CLI, Codex CLI), Paperclip lưu trữ `external_run_id` / ID phiên trong hàng heartbeat. Lần “tick” tiếp theo sẽ truyền lại nó để agent tải lại ngữ cảnh của nó. Các nhà điều hành có thể đặt lại phiên khi ngữ cảnh trở nên lỗi thời.
⚙️ Cấu Hình Runtime
runtime_config:
cwd: /workspaces/acme-engineering
timeoutSec: 1800 # thời gian chạy tối đa cho mỗi nhịp tim
graceSec: 30 # cửa sổ SIGTERM → SIGKILL
env:
ANTHROPIC_API_KEY: ${secret:anthropic_key}
promptTemplate: ... # adapter-specific
args: [...]
🛡️ An Toàn
“Các adapter CLI cục bộ chạy không sandbox trên máy chủ.”
Tài liệu kỹ thuật thành thật về điều này. Các biện pháp giảm thiểu: người dùng hệ điều hành riêng cho mỗi agent, `cwd` bị hạn chế, bí mật được quản lý bởi máy chủ (không trong prompt), và các plugin được kiểm soát khả năng cho bất cứ điều gì agent không thể làm trực tiếp.
🔌 7. Adapters — “Mang Agent Của Riêng Bạn Đến”
Adapter là trừu tượng duy nhất trên các runtime của agent. Nó được thiết kế nhỏ gọn có chủ đích.
interface Adapter {
invoke(agentConfig: AgentConfig, context?: HeartbeatContext): Promise<RunHandle>;
status(agentConfig: AgentConfig): Promise<AgentStatus>;
cancel(agentConfig: AgentConfig): Promise<void>;
}
Đó là toàn bộ hợp đồng. Ba phương thức.
🔌 Các Adapter Tích Hợp
| Adapter | Cơ chế |
|---|---|
process |
Khởi tạo một CLI tùy ý làm tiến trình con |
http |
POST đến một webhook; agent tồn tại ở bất cứ đâu |
claude_local |
Claude Code CLI, hỗ trợ tiếp tục phiên |
codex_local |
OpenAI Codex CLI |
cursor |
Chế độ headless của Cursor |
gemini-local, pi_local, opencode-local, hermes_local |
Các CLI cục bộ khác |
openclaw_gateway |
Gọi một dịch vụ đám mây được quản lý |
🏆 Tại Sao Thiết Kế Này Hiệu Quả
- Thêm một runtime agent là một PR độc lập. Chỉ cần thả một thư mục dưới
packages/adapters/<name>/. Không cần thay đổi lõi. - Hầu hết các adapter chỉ từ 100–300 dòng. Chúng chủ yếu là: khởi tạo tiến trình, kết nối stdin/stdout, phân tích JSON cuối cùng, báo cáo chi phí.
- Tính đa hình trong JSON, không phải kiểu dữ liệu.
adapter_config jsonbcho phép mỗi adapter định nghĩa cấu trúc riêng của nó; trình quản lý chỉ chuyển tiếp nó.
📊 Mức Độ Tích Hợp (Các Mức Độ “Hỗ Trợ” Chấp Nhận Được)
| Mức độ | Những gì adapter thực hiện |
|---|---|
| Tối thiểu | Có thể gọi; báo cáo mã thoát |
| Trạng thái | Báo cáo thành công/thất bại/tiến độ |
| Hoàn chỉnh | Báo cáo chi phí, cập nhật tác vụ, gọi lại API Paperclip |
Bạn không cần phải có đầy đủ công cụ ngay từ đầu. Một adapter mới có thể hoạt động ở mức “Tối thiểu” và vẫn hữu ích.
✅ 8. Hệ Thống Nhiệm Vụ & Kiểm Xuất Nguyên Tử
Hệ thống tác vụ là thứ ngăn hai agent thực hiện cùng một công việc cùng lúc. Đây là khái niệm runtime quan trọng thứ hai sau “nhịp tim”.
🌲 Phân Cấp
Sáng kiến (hướng đi cấp hội đồng, ví dụ: "Đạt 1 triệu USD ARR")
└── Dự án (ví dụ: "Thanh toán tự phục vụ")
└── Giai đoạn (ví dụ: "Beta công khai")
└── Vấn đề (ví dụ: "Thêm trình xử lý webhook Stripe")
└── Vấn đề con
Mọi tác vụ đều bắt nguồn từ một sáng kiến; không có công việc nào là “vô ích”.
🔐 Kiểm Xuất Nguyên Tử (SQL Phép Thuật)
// Yêu cầu
POST /issues/:issueId/checkout
{ "agentId": "uuid", "expectedStatuses": ["todo","backlog","blocked","in_review"] }
Phía máy chủ:
UPDATE issues
SET assignee_agent_id = :agentId,
status = 'in_progress',
started_at = COALESCE(started_at, now())
WHERE id = :issueId
AND status = ANY (:expectedStatuses)
AND (assignee_agent_id IS NULL OR assignee_agent_id = :agentId);
Nếu số lượng hàng là 0, trả về `409 Conflict` với chủ sở hữu/trạng thái hiện tại. Ngược lại, hàng đó được khóa cho agent đó.
Lần cập nhật duy nhất này là toàn bộ câu chuyện về đồng thời. Không hàng đợi, không khóa Redis, không thuê. Hàng cơ sở dữ liệu chính là khóa.
🤝 Công Việc Liên Đội & Quy Tắc Leo Thang
- Bất kỳ agent nào cũng có thể tạo một tác vụ cho bất kỳ agent nào khác (không có tường quyền — khả năng hiển thị là tổng thể).
- Agent nhận yêu cầu phải hoàn thành, chặn hoặc leo thang. Họ không thể hủy yêu cầu liên đội một cách âm thầm.
- Việc leo thang đi lên chuỗi `reports_to` của chính họ.
🏷️ Mã Thanh Toán (Billing Codes)
Khi agent X ủy quyền cho agent Y, `cost_events` của Y được gắn thẻ bằng mã thanh toán từ tác vụ của X. Việc tổng hợp trả lời câu hỏi “Sáng kiến #3 thực sự tốn bao nhiêu trên toàn bộ biểu đồ?”
🔄 Máy Trạng Thái
backlog ─→ todo ─→ in_progress ─→ in_review ─→ done (kết thúc)
│ │ │
│ └─→ blocked ←┘
│ │
└─→ cancelled (kết thúc)
Tác dụng phụ:
→ in_progress : đặt started_at nếu null
→ done : đặt completed_at
→ cancelled : đặt cancelled_at
⚖️ 9. Quản Trị, Phê Duyệt & Hội Đồng
“Hội đồng” là một nhà điều hành con người duy nhất (trong v1). Họ có quyền hạn không giới hạn — tạm dừng, tiếp tục, ghi đè, chấm dứt.
📥 Hàng Đợi Phê Duyệt
Bảng `approvals` là một cơ chế chung. Bốn loại yêu cầu được cung cấp theo mặc định:
| Loại | Ai đề xuất | Nội dung bị khóa |
|---|---|---|
hire_agent |
Agent CEO (hoặc bất kỳ agent nào nếu công ty yêu cầu) | Tạo một agent mới |
approve_ceo_strategy |
Agent CEO | Kế hoạch tổ chức/tác vụ ban đầu |
budget_override_required |
Bất kỳ agent nào | Chi tiêu vượt quá giới hạn cứng |
request_board_approval |
Bất kỳ agent nào | Bất cứ điều gì cần sự phê duyệt của con người |
Mỗi phê duyệt mang theo một `payload jsonb` mô tả thay đổi được đề xuất. Việc phê duyệt một yêu cầu phê duyệt là điều _gây ra_ thay đổi — yêu cầu không được áp dụng cho đến khi được quyết định.
🚀 Trình Tự Khởi Động
Đây là những gì xảy ra khi người dùng bắt đầu một công ty mới:
- Con người tạo Công ty + Sáng kiến
- Con người viết các tác vụ cấp cao ban đầu
- Con người tạo một agent “CEO” từ một template mặc định
- Agent CEO chạy, đề xuất:
- Cấu trúc tổ chức (các agent con cần tuyển)
- Phân tích tác vụ
- Phê duyệt tuyển dụng
- Hội đồng xem xét + phê duyệt
- CEO bắt đầu ủy quyền; công ty hoạt động
🔑 Quyền Hạn Quyết Định
Các agent có thể đề xuất bất cứ điều gì. Các agent chỉ có thể thực hiện các tác vụ mà họ sở hữu. Bất cứ điều gì khác đều phải thông qua quy trình phê duyệt. Đây là quy tắc ngăn chặn một agent, ví dụ, “quyết định” tạo ra 50 agent con và làm phá sản công ty.
💰 10. Ngân Sách & Kiểm Soát Chi Phí
Chi phí được xử lý giống như giới hạn tốc độ: cảnh báo mềm, sau đó là giới hạn cứng.
📊 Mức Độ Báo Cáo
| Mức độ | Câu hỏi được trả lời |
|---|---|
| Theo từng agent | “Agent này có tốn kém không?” |
| Theo từng tác vụ | “PR này có tốn quá nhiều không?” |
| Theo từng dự án | “Chi phí cho Dự án X của chúng ta là bao nhiêu?” |
| Theo mã thanh toán | “Sáng kiến #3 tốn bao nhiêu từ đầu đến cuối?” |
| Toàn công ty | “Công ty đã chi bao nhiêu trong tháng này?” |
🚧 Thực Thi
Ngưỡng cảnh báo mềm mặc định: 80%
Ở 100%:
- Đặt trạng thái agent thành tạm dừng
- Chặn các yêu cầu checkout/gọi mới cho agent đó
- Phát ra sự kiện hoạt động ưu tiên cao
Cơ chế “tự động tạm dừng” là toàn bộ giải pháp. Không có sự giảm hiệu suất dần dần, không có “hãy để nó hoàn thành tác vụ hiện tại.” Nó dừng lại.
⚙️ Cấu Hình Ngân Sách
- Chu kỳ:
daily | weekly | monthly | rolling - Ngân sách theo từng agent và theo từng công ty là độc lập. Cả hai phải cho phép chạy.
- “Không giới hạn” là một cài đặt; nếu bạn muốn, bạn phải đặt rõ ràng.
💳 Ghi Nhận Chi Phí
Các agent (hoặc adapter của chúng) POST đến:
POST /companies/:companyId/cost-events
{ agentId, issueId, provider, model, input_tokens, output_tokens, cost_cents, billing_code, occurred_at }
Máy chủ thực thi phạm vi công ty, chuẩn hóa thành các tổng hợp và chạy kiểm tra ngân sách. Các sự kiện chi phí chỉ có thể thêm vào — không chỉnh sửa, không xóa.
🧩 11. Hệ Thống Plugin
Plugins mở rộng Paperclip mà không cần fork mã nguồn. Kiến trúc gồm hai phần:
- Worker: Tiến trình Node.js chạy logic của plugin. Được thiết kế là out-of-process.
- UI: Các thành phần React được gắn vào các “slot” được đặt tên trong giao diện người dùng của máy chủ.
🛠️ Hợp Đồng Worker
import { definePlugin } from "@paperclipai/plugin-sdk";
export default definePlugin({
async setup(ctx) {
ctx.data.register("widget.summary", async (params) => { /* ... */ });
ctx.actions.register("widget.run", async (input) => { /* ... */ });
ctx.tools.register("widget.search", schema, async (input) => { /* ... */ });
ctx.events.on("issue.checked_out", async (e) => { /* ... */ });
ctx.jobs.register("daily.rollup", async () => { /* ... */ });
},
onConfigChanged(newConfig) {},
onShutdown() {},
onValidateConfig(config) {},
onWebhook(input) {},
onHealth() {},
});
🔐 Kiểm Soát Khả Năng (Capability Gating)
Mọi API trên `ctx` đều yêu cầu một khả năng được khai báo trong manifest của plugin:
companies.read, issues.read, issues.create,
events.subscribe, jobs.schedule,
agent.sessions.create, agents.invoke,
ui.sidebar.register, ui.detailTab.register, ...
Máy chủ thực thi chúng tại thời điểm gọi. Một plugin không có quyền `issues.create` không thể tạo một vấn đề, ngay cả khi nó cố gắng.
🖼️ Các Slot UI
Các plugin gắn React vào các slot được đặt tên:
page, sidebar, sidebarPanel, settingsPage, dashboardWidget,
globalToolbarButton, detailTab, taskDetailView,
projectSidebarItem, toolbarButton, contextMenuItem,
commentAnnotation, commentContextMenuItem
Phía UI nhận các React hook được gõ:
usePluginData<T>(key, params?) // lấy dữ liệu worker
usePluginAction(key) // gọi hành động worker
usePluginStream<T>(channel) // SSE
useHostContext() // { companyId, entityId, entityType }
🧱 Tại Sao Out-of-process?
- Một plugin bị crash không làm sập máy chủ.
- Plugins có thể ở bất kỳ ngôn ngữ nào có thể nói giao thức IPC.
- Kiểm soát khả năng có thể được thực thi ở ranh giới IPC, không chỉ bằng lòng tin.
📡 12. Máy Chủ MCP
`packages/mcp-server` là một **wrapper mỏng của Model Context Protocol quanh REST API**. Nó tồn tại để bất kỳ runtime agent nào có khả năng MCP (Claude Code, Cursor, v.v.) đều có thể đọc và ghi vào Paperclip mà không cần mã tích hợp riêng biệt.
Được cấu hình với:
PAPERCLIP_API_URL
PAPERCLIP_API_KEY
PAPERCLIP_COMPANY_ID (tùy chọn)
PAPERCLIP_AGENT_ID (tùy chọn)
PAPERCLIP_RUN_ID (tùy chọn)
Tool surface (đại diện)
Đọc:getMe, listAgents, listIssues, getIssue, listComments, listProjects, listGoals, listApprovals, …
Ghi:createIssue, updateIssue, checkoutIssue, addComment, suggestTask, requestConfirmation, decideApproval, …
Lối thoát khẩn cấp:paperclipApiRequest({ path, method, body }) — bị giới hạn ở các đường dẫn `/api` và body JSON, cho phép agent tiếp cận các endpoint chưa có công cụ chuyên dụng.
Bài học: máy chủ MCP không có logic nghiệp vụ. Nó là một lớp dịch thuật. Nguồn chân lý duy nhất = REST API. Đây là lý do tại sao nó có thể giữ kích thước nhỏ.
🎓 13. Kỹ Năng (Skills)
Một **kỹ năng** là một tệp markdown (kèm theo các ví dụ tùy chọn) dạy một agent _cách sử dụng API Paperclip_. Nó không phụ thuộc vào adapter — Claude, Codex, tùy chỉnh, tất cả đều đọc cùng một `SKILL.md`.
Các kỹ năng được đóng gói (dưới `/skills`) bao gồm:
paperclip— kỹ năng chính: CRUD tác vụ, báo cáo trạng thái, ghi nhật ký chi phí, quy tắc giao tiếp.paperclip-create-agent— cách đề xuất tuyển dụng một agent mới (ghi vào `approvals`).paperclip-create-plugin— tạo khung cho một plugin.paperclip-converting-plans-to-tasks— chuyển kế hoạch của CEO thành các vấn đề nguyên tử.paperclip-dev— kỹ năng meta để chỉnh sửa chính Paperclip.para-memory-files— quản lý bộ nhớ agent bền vững.
Một kỹ năng không phải là mã; nó là văn xuôi + ví dụ. Runtime của agent tải nó như một phần của ngữ cảnh hệ thống của nó. Điều này có nghĩa là nâng cấp một kỹ năng sẽ nâng cấp mọi agent sử dụng nó, không cần triển khai lại.
⚙️ 14. Ngăn Xếp Công Nghệ & Bố Cục Kho Lưu Trữ
| Mối quan tâm | Lựa chọn |
|---|---|
| Backend | Node.js 20+, TypeScript, Express (chỉ REST — không tRPC) |
| Frontend | React + Vite |
| DB | PostgreSQL; PGlite cho local/dev, Supabase hoặc Docker Postgres cho prod |
| ORM | Drizzle (drizzle.config.ts trong packages/db) |
| Auth | Better Auth |
| Tests | Vitest + Playwright |
| Package mgr | pnpm 9.15+ workspaces |
| License | MIT |
Bố cục cấp cao nhất
.agents/skills/ # Định nghĩa kỹ năng Agent
.claude/skills/ # Kỹ năng dành riêng cho Claude
.github/ # CI, templates
cli/ # `npx paperclipai onboard` v.v.
docker/ # Compose + Dockerfiles
docs/ # Trang tài liệu công khai
doc/ # SPEC.md nội bộ, SPEC-implementation.md
evals/ # Khung đánh giá Agent
packages/
adapters/ # claude-local, codex-local, cursor-local, ...
adapter-utils/ # các helper adapter dùng chung
db/ # Drizzle schema + migrations
mcp-server/ # MCP wrapper
plugins/
sdk/ # @paperclipai/plugin-sdk
create-paperclip-plugin/
sandbox-providers/e2b/
shared/ # types, utils
patches/ # các tệp pnpm patch
releases/ # các artifact phát hành
report/ # công cụ báo cáo
scripts/ # các script ops một lần
server/ # máy chủ Node
src/
scripts/
skills/ # các kỹ năng được đóng gói
tests/ # các bài kiểm tra đa gói
ui/ # ứng dụng React
Onboarding chỉ bằng một lệnh
npx paperclipai onboard --yes
# hoặc:
git clone https://github.com/paperclipai/paperclip.git && cd paperclip
pnpm install
pnpm dev
`pnpm dev` khởi động: máy chủ (với PGlite nhúng), UI (Vite), và một trình theo dõi.
🌐 15. Giao Diện REST API
Giao diện v1 đầy đủ, được nhóm lại. Sử dụng điều này làm đặc tả cho máy chủ của _bạn_.
🏢 Companies
GET /companies
POST /companies
GET /companies/:companyId
PATCH /companies/:companyId
PATCH /companies/:companyId/branding
POST /companies/:companyId/archive
🎯 Goals
GET /companies/:companyId/goals
POST /companies/:companyId/goals
GET /goals/:goalId
PATCH /goals/:goalId
DELETE /goals/:goalId
🤖 Agents
GET /companies/:companyId/agents
POST /companies/:companyId/agents
GET /agents/:agentId
PATCH /agents/:agentId
POST /agents/:agentId/pause
POST /agents/:agentId/resume
POST /agents/:agentId/terminate
POST /agents/:agentId/keys # tạo API key cho agent
POST /agents/:agentId/heartbeat/invoke # đánh thức thủ công theo yêu cầu
📝 Issues
GET /companies/:companyId/issues
POST /companies/:companyId/issues
GET /issues/:issueId
PATCH /issues/:issueId
POST /issues/:issueId/checkout # nguyên tử
POST /issues/:issueId/release
POST /issues/:issueId/admin/force-release # chỉ hội đồng
POST /issues/:issueId/comments
GET /issues/:issueId/comments
POST /companies/:companyId/issues/:issueId/attachments
GET /issues/:issueId/attachments
💰 Chi phí & Ngân sách
POST /companies/:companyId/cost-events
GET /companies/:companyId/costs/summary
GET /companies/:companyId/costs/by-agent
GET /companies/:companyId/costs/by-project
PATCH /companies/:companyId/budgets
PATCH /agents/:agentId/budgets
⚖️ Phê duyệt
GET /companies/:companyId/approvals?status=pending
POST /companies/:companyId/approvals
POST /approvals/:approvalId/approve
POST /approvals/:approvalId/reject
📊 Hoạt động & Dashboard
GET /companies/:companyId/activity
GET /companies/:companyId/dashboard
Lưu ý thiết kế
- Mọi thao tác ghi thay đổi trạng thái đều ghi một hàng vào
activity_logtrong cùng một giao dịch.- Ủy quyền là một mô hình: khóa API giải quyết thành một tác nhân (người dùng, agent hoặc hệ thống) và một phạm vi công ty. Cùng một trình xử lý phục vụ các yêu cầu UI và yêu cầu agent; chỉ có loại tác nhân khác nhau.
- Không RPC, không GraphQL. REST thuần túy giữ cho wrapper MCP cực kỳ mỏng.
🔒 16. Cách Ly Đa Công Ty & Khả Năng Di Chuyển
Việc triển khai là **đơn tenant cho nhà điều hành** (bạn chạy máy chủ của riêng mình), nhưng **đa công ty trong phạm vi triển khai** (một Paperclip có thể host nhiều tổ chức).
Cách ly được thực thi theo ba cách:
- Schema: mọi bảng miền đều có `company_id` và mọi chỉ mục đều dẫn đầu bằng nó.
- Ủy quyền: khóa API của tác nhân mang một phạm vi công ty; các trình xử lý từ chối sự không khớp.
- Lưu trữ: bí mật, tệp đính kèm, trạng thái plugin được đặt tên theo công ty.
📦 Khả Năng Di Chuyển (Portability)
- Xuất template — chỉ schema (sơ đồ tổ chức, vai trò, tác vụ mặc định). Hữu ích cho các “công ty khởi tạo”.
- Xuất snapshot — trạng thái đầy đủ bao gồm tác vụ, bình luận, chi phí. Với làm sạch bí mật trước khi tuần tự hóa.
- Các lần nhập là nguyên tử; toàn bộ công ty xuất hiện hoặc không có gì.
📋 17. Nhật Ký Kiểm Toán & Hoạt Động
Mọi thay đổi trạng thái đều tạo ra:
activity_log(
actor_type ∈ {agent, user, system},
actor_id,
action e.g. "issue.checked_out",
entity_type, entity_id,
details jsonb,
created_at
)
Hai hệ quả:
- Phát lại — bạn có thể tái tạo bất kỳ trạng thái nào trong quá khứ bằng cách duyệt nhật ký.
- Theo dõi lệnh gọi công cụ — khi một agent gọi máy chủ MCP, những lệnh gọi đó trở thành các mục hoạt động. “Agent X thực sự đã làm gì vào lúc 3:14 sáng?” là một truy vấn, không phải một cuộc điều tra.
📏 18. Quy Ước Kỹ Thuật
Đây là những hàng rào bảo vệ đáng để sao chép nguyên văn:
- Giữ các thay đổi trong phạm vi công ty. Mọi truy vấn, mọi khóa cache, mọi kiểm tra ủy quyền. Không có đường dẫn mã xuyên tenant tồn tại.
- Các hợp đồng phải đồng bộ. Schema DB, đặc tả OpenAPI, kiểu TypeScript và định nghĩa công cụ MCP được tạo từ một nguồn. Sự sai lệch là một lỗi.
- Các migration chỉ được thêm vào. Không bao giờ chỉnh sửa một migration sau khi nó đã được triển khai. Sử dụng `pnpm db:migrate` để tạo; không bao giờ viết SQL thủ công vào các tệp cũ.
- Một PR = một thay đổi logic.
- Mỗi PR khai báo mô hình đã viết nó. (Đáng yêu nhưng hữu ích cho telemetry.)
- Tất cả các bài kiểm tra phải vượt qua trước khi merge. CI xanh. Điểm công cụ đánh giá mã = 5/5.
- Thất bại phải hiển thị rõ ràng. Các agent gặp trạng thái không mong muốn sẽ đánh dấu tác vụ là `blocked`; máy chủ trả về lỗi; UI hiển thị chúng. Không có dự phòng âm thầm.
- Đọc SPEC-implementation.md khi có nghi ngờ. Khi `SPEC.md` và đặc tả triển khai không khớp, triển khai thắng thế cho v1.
🗺️ 19. Kế Hoạch Xây Dựng Từng Bước
Nếu bạn đang xây dựng một hệ thống giống Paperclip từ đầu, hãy làm theo thứ tự này. Mỗi bước đều có thể triển khai một cách độc lập.
🌱 Giai đoạn 0 — Khung sườn (1-2 ngày)
- Monorepo pnpm với
server/,ui/,packages/db,packages/shared. - Máy chủ Express, ứng dụng Vite React, Drizzle + PGlite cho phát triển.
- Endpoint kiểm tra sức khỏe, UI “hello world”.
🔐 Giai đoạn 1 — Công ty & Xác thực
- Bảng
companies. - Better Auth cho người dùng là con người.
- Mô hình API-key: mỗi khóa là
(actor_type, actor_id, company_id). - Middleware giải quyết khóa thành một `Actor` và từ chối nếu không khớp công ty.
🏢 Giai đoạn 2 — Sơ đồ tổ chức
- Bảng
agentsvới `reports_to`. - Các endpoint CRUD + chế độ xem sơ đồ tổ chức UI.
- Trường trạng thái với các chuyển đổi, nhưng chưa có runtime — các agent chỉ là dữ liệu.
📝 Giai đoạn 3 — Nhiệm vụ
- Các bảng
issues+goals+projectsvới hệ thống phân cấp đầy đủ. - Triển khai kiểm xuất nguyên tử (atomic checkout) với SQL chính xác như trên. Viết một bài kiểm tra hồi quy chạy 50 lượt kiểm xuất đồng thời và xác nhận chỉ có một lượt thắng.
- UI Kanban / danh sách.
💚 Giai đoạn 4 — Nhịp Tim (thời điểm dự án của bạn trở nên thực tế)
- Bảng
heartbeat_runs. - Giao diện trình quản lý adapter (3 phương thức: `invoke`, `status`, `cancel`).
- Xây dựng _một_ adapter trước tiên: `process` (chỉ khởi tạo một CLI bạn kiểm soát). Đừng bắt đầu với Claude.
- Trình lập lịch (Scheduler):
- Vòng lặp Cron cho các kích hoạt `timer`.
- Hook khi kiểm xuất vấn đề → phát ra đánh thức `assignment`.
- Nút “Run now” → `on_demand`.
- Hợp nhất (Coalescing): nếu một lần chạy đã `running` cho một agent, bỏ qua các yêu cầu đánh thức mới, đánh dấu chúng là đã hợp nhất.
- Thời gian chờ + ân hạn + buộc dừng.
💰 Giai đoạn 5 — Chi phí & Ngân sách
- Bảng
cost_events. - Các trường ngân sách trên
companiesvàagents. - Endpoint ghi nhận với kiểm tra phạm vi công ty.
- Trên mỗi lần chèn chi phí: tính toán lại chi tiêu / ngân sách; nếu vượt quá 100%, tạm dừng agent + phát ra hoạt động.
- Dashboards: tổng hợp theo từng agent, từng tác vụ, từng dự án (sử dụng các chỉ mục bạn đã xây dựng).
⚖️ Giai đoạn 6 — Phê duyệt & Quản trị
- Bảng
approvals; payload chung + loại. - Luồng `request_board_approval` từ đầu đến cuối.
- “Tuyển dụng agent” yêu cầu phê duyệt; việc phê duyệt yêu cầu _tạo_ hàng agent.
- UI hội đồng với một hộp thư đến “phê duyệt” duy nhất.
📋 Giai đoạn 7 — Nhật ký Hoạt động + SSE
- Thêm `activity_log` trong cùng một giao dịch với mọi thay đổi.
- Sự kiện do máy chủ gửi (Server-sent events) phát sóng hoạt động mới đến các UI đã đăng ký.
- Feed “Hoạt động gần đây” và lịch sử theo từng thực thể.
🔌 Giai đoạn 8 — Thêm adapter
- Bọc một CLI thực tế (Claude Code hoặc Codex). Tái sử dụng `adapter-utils` để định khung stdio và phân tích JSON.
- Thêm adapter `http` cho các agent từ xa.
- Bây giờ bạn có thể triển khai cho những người dùng đầu tiên.
📡 Giai đoạn 9 — Máy chủ MCP
- Gói độc lập gọi _API REST của bạn_.
- Một công cụ MCP cho mỗi endpoint quan trọng, cộng với lối thoát khẩn cấp `apiRequest`.
- Kiểm tra nó với Claude Code cục bộ.
🎓 Giai đoạn 10 — Kỹ Năng
- Chọn 3 điều hàng đầu mà các agent làm kém mà không có hướng dẫn và viết các tệp `SKILL.md` cho chúng.
- Phân phối qua `.agents/skills/` và yêu cầu các adapter tải chúng vào ngữ cảnh hệ thống.
🧩 Giai đoạn 11 — Plugins
- SDK worker out-of-process với `definePlugin`.
- IPC: đơn giản nhất là JSON qua stdio với tương quan request-id.
- Manifest với các khả năng được khai báo; máy chủ thực thi ở mỗi lệnh gọi IPC.
- Hệ thống slot UI: một registry được khóa bằng tên slot, các plugin gắn React qua iframe hoặc shadow DOM.
📦 Giai đoạn 12 — Khả Năng Di Chuyển
- `POST /companies/:id/export` → snapshot JSON, với một bước `secret_scrub`.
- `POST /companies/import` → nguyên tử, giao dịch.
✨ Giai đoạn 13 — Hoàn thiện
- Onboarding một lệnh (`npx
onboard`) tạo `.env`, chạy migration, mở trình duyệt. - Docker compose cho “tự host trên một hộp”.
- Telemetry (ẩn danh, có thể từ chối).
⚠️ 20. Cạm Bẫy, Đánh Đổi & Điều Nên Bỏ Qua Trước Tiên
🚫 Những điều _không nên_ làm, đặc biệt là giai đoạn đầu
- Đừng tự xây dựng vòng lặp agent của riêng bạn. Toàn bộ vấn đề là không định kiến. Bọc một CLI; triển khai.
- Đừng thêm tRPC / GraphQL. Nó làm cho wrapper MCP trở nên phức tạp. REST thuần túy là hợp đồng tồn tại.
- Đừng tập trung prompt trong máy chủ. Prompt thuộc về adapter hoặc kỹ năng. Phần lõi không có ý kiến gì về hành vi mô hình.
- Đừng coi ngân sách là mềm. Thực thi ngân sách “cố gắng hết sức” không phải là thực thi. Xây dựng tính năng tự động tạm dừng ngay từ ngày đầu.
- Đừng cho phép gọi trực tiếp giữa các agent. Buộc mọi thứ phải thông qua tác vụ/bình luận. Bạn sẽ cảm ơn mình khi gỡ lỗi.
- Đừng đặt `company_id` trên “hầu hết” các bảng. Hãy đặt nó trên _mọi_ bảng.
- Đừng sandbox plugin bằng lòng tin. Out-of-process + manifest khả năng, hoặc không có gì.
⚖️ Những đánh đổi trung thực mà Paperclip thực hiện
| Đánh đổi | Bạn có được gì | Bạn mất gì |
|---|---|---|
| Một nhà điều hành hội đồng con người duy nhất (v1) | Mô hình quyền hạn đơn giản | Không có quản trị đa bên liên quan |
| REST + đa hình jsonb | Dễ mở rộng, MCP đơn giản | Ít an toàn thời gian biên dịch hơn tRPC |
| Các adapter CLI cục bộ không sandbox | Tự do runtime tối đa | Bạn chịu trách nhiệm về câu chuyện bảo mật máy chủ |
| Kiểm xuất nguyên tử qua SQL | Cực kỳ đơn giản, không cần dịch vụ bổ sung | Không mở rộng ngoài một PostgreSQL duy nhất |
| Kỹ năng dưới dạng markdown | Có thể hoán đổi nóng; không phụ thuộc runtime | Hành vi phụ thuộc vào kỷ luật của adapter |
| Plugins out-of-process | Cách ly lỗi; đa ngôn ngữ | Độ trễ cao hơn so với in-process |
🔀 Nơi có thể thay đổi nếu miền của bạn khác biệt
- Nếu “agent” của bạn là con người trong vòng lặp, hãy giữ nguyên mô hình — thêm `assignee_user_id`, bạn đã có nó.
- Nếu bạn cần quản trị đa hội đồng, hãy khái quát hóa `decided_by_user_id` thành một bản ghi kiểu thăm dò trên `approvals`.
- Nếu chi phí không phải là $/token, hãy khái quát hóa `cost_events` thành `usage_events` với các đơn vị do nhà cung cấp định nghĩa. Giữ nguyên cấu trúc tổng hợp.
- Nếu bạn cần mở rộng quy mô theo chiều ngang, nút thắt cổ chai là trình lập lịch heartbeat. Chuyển nó sang một job runner được bầu chọn lãnh đạo; mọi thứ khác (REST, DB) đã có thể mở rộng.
—
💡 TL;DR – Tóm Tắt Cho Việc Xây Dựng Hệ Thống Của Riêng Bạn
- Đây là một control plane, không phải một framework. Hợp đồng adapter ba phương thức. Đừng giả vờ khác.
- Schema Postgres là kiến trúc. Làm đúng
companies / agents / issues / heartbeat_runs / cost_events / approvals / activity_logvà 80% hành vi sẽ tự nhiên xuất hiện. - Nhịp tim là hạt nhân. Hợp nhất (coalesce), thời gian chờ (timeout), lưu trữ các lần chạy, ghi nhật ký hoạt động.
- UPDATE SQL nguyên tử = câu chuyện đồng thời của bạn.
- Trần ngân sách cứng, không phải mềm.
- Tác vụ là kênh giao tiếp duy nhất giữa các agent.
- REST + MCP + kỹ năng, theo thứ tự đó. Mỗi cái là một lớp mỏng trên cái trước đó.
- Plugins out-of-process, có kiểm soát khả năng.
- Mọi bảng, truy vấn và chỉ mục đều bắt đầu bằng `company_id`.
- Nhật ký kiểm toán chỉ thêm vào trong cùng một giao dịch với mọi thay đổi.
Xây dựng mười điều đó và bạn sẽ có Paperclip. Mọi thứ khác chỉ là hoàn thiện.
—



