命令设计
命令是 Agent 与你的 Clip 之间的接口。好的命令设计会让 Clip 更容易被发现、更高效、更易用。
命令使用动词
Section titled “命令使用动词”list, get, search, create, add, update, delete, complete, send, read命令分组使用名词
Section titled “命令分组使用名词”当一个 Clip 有多种资源类型时,用名词把相关命令分组:
// Command groupsclip.commandGroup("message", { description: "Manage messages",});
clip.command("message send", { ... });clip.command("message list", { ... });clip.command("message read", { ... });
clip.commandGroup("channel", { description: "Manage channels",});
clip.command("channel list", { ... });clip.command("channel create", { ... });- 使用小写和连字符:用
get-details,不要用getDetails - 保持具体:用
search,不要用find(除非语义不同) - 避免冗余:用
list,不要用list-items(Clip 名称已经提供上下文) - 适用时使用标准 CRUD 动词
输入 schema 设计
Section titled “输入 schema 设计”明确声明类型
Section titled “明确声明类型”clip.command("search", { input: { query: { type: "string", description: "Search query", required: true, }, limit: { type: "number", description: "Maximum number of results", default: 10, }, sort: { type: "string", description: "Sort order", enum: ["recent", "relevant", "popular"], default: "relevant", }, }, handler: async ({ input }) => { ... },});每个参数都应该有:
- type ——
string、number、boolean、array、object - description —— 它的作用(Agent 会读取这个信息)
- required —— Agent 是否必须提供它
- enum —— 适用时列出合法值
- default —— 合理的默认值可以减少 Agent 决策
避免自由形式对象
Section titled “避免自由形式对象”// Bad: opaque object, Agent can't discover fieldsinput: { options: { type: "object" }}
// Good: explicit fieldsinput: { sort: { type: "string", enum: ["asc", "desc"] }, limit: { type: "number", default: 10 }, offset: { type: "number", default: 0 },}列表:精简且可行动
Section titled “列表:精简且可行动”// Good list response{ items: [ { id: "p1", title: "Top AI papers this week", score: 342, comments: 128 }, { id: "p2", title: "Show HN: My new project", score: 89, comments: 24 }, ], total: 2, hasMore: false,}好的列表响应具备这些关键属性:
- 每个条目都有 ID(支持后续行动)
- 包含用于决策的 关键字段(标题、状态、分数)
- 包含 分页元数据(
total、hasMore、nextCursor) - 不要有嵌套对象 —— 保持扁平
详情:完整且结构化
Section titled “详情:完整且结构化”// Good detail response{ id: "p1", title: "Top AI papers this week", url: "https://...", author: "dang", score: 342, comments: 128, created: "2026-05-30T10:00:00Z", content: "Full text content...", topComments: [ { id: "c1", author: "user1", text: "Great summary", score: 42 }, ],}Mutation:返回受影响实体
Section titled “Mutation:返回受影响实体”// Good: returns what changedclip.command("complete", { handler: async ({ input }) => { const task = await db.complete(input.id); return task; // The full updated task },});
// Bad: returns nothing usefulclip.command("complete", { handler: async ({ input }) => { await db.complete(input.id); return { success: true }; // Agent has to fetch again to see the result },});对于长时间运行的操作,使用 streaming:
clip.command("monitor", { description: "Monitor a feed in real-time", streaming: true, handler: async function* ({ input }) { while (true) { const update = await feed.poll(); if (update) { yield update; } await sleep(5000); } },});Streaming 命令可以用 pinix invoke <alias> <command> --stream 调用,也可以通过 streaming invoke RPC 调用。
Stdin 支持
Section titled “Stdin 支持”命令可以通过 stdin 接收大段文本输入:
clip.command("analyze", { description: "Analyze text content", stdin: true, handler: async ({ input, stdin }) => { // stdin contains the piped text const analysis = await analyze(stdin); return analysis; },});cat article.txt | pinix invoke my-clip analyze命令数量指南
Section titled “命令数量指南”| 命令数 | 建议 |
|---|---|
| 1-5 | 适合一个聚焦的 Clip |
| 6-10 | 使用命令分组组织结构 |
| 10+ | 考虑拆分成多个 Clip |
随着可选项增多,Agent 的有效性会下降。一个有 3 个设计良好的命令的 Clip,比一个有 15 个重叠命令的 Clip 更好。