设计自己的 Tool 系统
第一版 Tool 系统不要太复杂。建议只做 4 个模块:
text
Tool
ToolRegistry
ToolExecutor
ToolResultSerializer1
2
3
4
2
3
4
Tool
ts
export type Tool<Input = unknown, Output = unknown> = {
name: string
description: string
inputSchema: Schema<Input>
readonly: boolean
execute(input: Input, context: ToolContext): Promise<Output>
toText(output: Output): string
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
ToolRegistry
ts
export class ToolRegistry {
private tools = new Map<string, Tool>()
register(tool: Tool) {
if (this.tools.has(tool.name)) {
throw new Error(`Duplicate tool: ${tool.name}`)
}
this.tools.set(tool.name, tool)
}
get(name: string) {
const tool = this.tools.get(name)
if (!tool) throw new Error(`Unknown tool: ${name}`)
return tool
}
toModelSchemas() {
return [...this.tools.values()].map(tool => ({
name: tool.name,
description: tool.description,
input_schema: tool.inputSchema.toJSON(),
}))
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ToolExecutor
ts
export async function executeToolUse(
toolUse: ToolUse,
registry: ToolRegistry,
context: ToolContext,
) {
const tool = registry.get(toolUse.name)
const input = tool.inputSchema.parse(toolUse.input)
const output = await tool.execute(input, context)
return {
type: "tool_result",
tool_use_id: toolUse.id,
content: tool.toText(output),
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
什么时候再加复杂能力
按这个顺序演进:
- schema 校验。
- 读写工具。
- 权限网关。
- 工具并发。
- Hooks。
- MCP。
- 插件化。
不要在第一天就实现 Claude Code 的完整 Tool 接口。那个接口是大型产品演化后的结果,不是最小起点。