
Agent 原生
全棧框架
AI 倒幾多 code 出嚟,餃子都唔會爆。🥟
工程決策,交俾框架。100+ MCP 工具 · 實戰 Skills 工作流 · 運行時 Guard。
編碼代理一日寫一萬行,
邊個解決?
冇結構化護欄,AI 產生嘅 code 好快就變成一堆技術債。
功能蔓延
AI 代理建重複嘅工具函數,忽略現有模式,令你嘅 codebase 膨脹。
→ negotiate + Skills 保持結構統一
靜默失敗
藏喺生成函數入面嘅邏輯錯誤,過到基本測試但喺生產環境失敗。
→ ATE 自動寫測試並修復
架構漂移
AI 唔明白邊界就貼 code,你嘅整潔架構慢慢變差。
→ Guard 運行時強制邊界
入面有咩?
同一個指令,第三次咗?
一個 schema 檔。 API · 型別 · 測試 · 驗證自動生成。 代理走樣 Guard 運行時攔截。
架構,已經散咗?
層 · 命名 · 依賴規則運行時強制。 內置 FSD · Clean · Hexagonal 6 個預設。 代理走樣即刻拒絕。
// 偵測到層違規
Agent "claude" blocked.
Reason: layer-violation: shared → features
架構保持完整 ✅
API 30 行變 Filling 3 行。
Mandu.filling(contract, ctx => ctx.ok(data))。 中介軟件鏈用 .guard() 合成。 一個 ctx 包含 session · CSRF · DB。
代理理解 Mandu。
MCP 100+ 工具可查閱結構 · 合約 · 規則。 Claude/Codex 無需估都直接執行。 用工具呼叫取代 prompt engineering。
測試,仲自己寫?
ATE 由路由自動生成 Playwright spec。 揀 L0~L3 oracle 等級(smoke ~ 合約驗證)。 失敗時 LLM 提出修復 diff。
AI 失誤,一 click 還原。
mandu change begin 喺 AI 編輯前快照。 出錯就 rollback,正常就 commit。 冇分支嘅檔案級原子還原。
同 Next · Remix · Hono 有咩唔同?
| 功能 | Mandu 🥟 | Next.js | Remix | Hono |
|---|---|---|---|---|
| 運行時 | Bun-native | Node/Edge | Node/CF | Bun/Node/Deno |
| 型別 ↔ API | schema 檔 1 個 → 型別·OpenAPI·測試派生 | 手動同步 | 手動同步 | Zod middleware 手動 |
| 架構強制 | Guard 運行時 | ESLint | 冇 | 冇 |
| 測試自動化 | ATE 自動生成·修復 | 手動 | 手動 | 手動 |
| 代理介面 | MCP 100+ 工具內置 | Plugin | Plugin | Plugin |
| AI 編輯還原 | change begin/commit/rollback | git 手動 | git 手動 | git 手動 |
| 部署目標 | 4 edge + 7 deploy 適配器 | Vercel 優先 | Multi | Multi |
| DB 客戶端 | Bun.SQL (Postgres·MySQL·SQLite) | — | — | — |
| Auth / Session | session·JWT·OAuth·電郵內置 | 第三方 | 第三方 | 第三方 |
處理器 6 行,schema 8 行。
一個 30 行檔變兩個檔 14 行。同一個 /api/signup 端點。
import { z } from "zod";
import { NextRequest, NextResponse } from "next/server";
import { db, hash, isRateLimited } from "@/lib";
const SignupSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
export async function POST(req: NextRequest) {
const csrf = req.headers.get("x-csrf-token");
if (csrf !== req.cookies.get("__csrf")?.value)
return NextResponse.json({ error: "csrf" }, { status: 403 });
if (await isRateLimited(req.ip))
return NextResponse.json({ error: "rate" }, { status: 429 });
const raw = await req.json().catch(() => null);
const parsed = SignupSchema.safeParse(raw);
if (!parsed.success)
return NextResponse.json({ error: parsed.error.flatten() }, { status: 400 });
try {
const user = await db.user.create({
data: {
email: parsed.data.email,
password: await hash(parsed.data.password),
},
});
return NextResponse.json({ id: user.id }, { status: 201 });
} catch (err) {
if ((err as any).code === "P2002")
return NextResponse.json({ error: "duplicate" }, { status: 409 });
return NextResponse.json({ error: "internal" }, { status: 500 });
}
}import { Mandu } from "@mandujs/core"; import { SignupContract } from "@/spec/contracts/signup.contract"; export default Mandu.filling(SignupContract, async (ctx) => ctx.ok(await ctx.db.user.create({ ...ctx.body })) ).guard("auth").rateLimit({ rpm: 10 });
import { defineContract } from "@mandujs/core/contract"; import { z } from "zod"; export const SignupContract = defineContract({ method: "POST", request: z.object({ email: z.string().email(), password: z.string().min(8) }), response: z.object({ id: z.string() }), });
一條指令,七個地方。
平台設定檔由 Mandu 自動生成。wrangler.toml · vercel.json · Dockerfile · …
兼容
