问题
这是普通 Agent 代码:
client.messages.create({
model: this.model,
max_tokens: this.config.max_tokens || 2048,
messages,
tools: this.getToolSchemas(),
})这是ReAct Agent代码
client.messages.create({
model: this.model,
max_tokens: this.config.max_tokens || 2048,
messages,
system: this.buildReActPrompt(),
})可以看到这两个对比,
- 一个明确调用了tools,传递了非常明确的 tool schema
- 一个是把tool的描述放在系统提示词中
具体细节差异:
// Agent 调用 tools
private getToolSchemas(): Tool[] {
return Array.from(this.tools.values()).map(tool => ({
name: tool.name,
description: tool.desc,
input_schema: {
type: 'object',
properties: tool.params,
required: Object.keys(tool.params),
},
}))
}
// ReAct 通过 system prompt
const prompt = `
You are a ReAct (Reasoning and Acting) agent.
You solve problems by alternating between Thinking, Acting, and Observing.
## Available Tools:
${tool.name}: ${tool.desc}\nParameters:\n${params}
...
`对比
这两个使用起来其实是有些差异的。
使用Native Tool Use:
- 追求最高准确性
- 不需要看到中间推理
- 想要更快的执行速度
- 生产环境稳定性优先
使用 ReAct 模式:
- 需要可解释性和调试能力
- 想要完全控制推理过程
- 需要自定义 Thought 格式
- 教学或研究目的
建议
当然,如果想更完善的话,是先判断用户问题。
如果用户问题相对简单,可以直接用工具,那就使用 Native Tool Use,否则可以使用ReAct模式。
不过我们换个思路,这两个并不是冲突的。 我们只要区分好tools和system的职责边界,也需问题解答就会更容易些。
通过上面优缺点对比,明显看出来我们更应该使用Tool来进行生产问题的解决。 不仅快,而且更准确。 那就充分发挥优势。
那即是我们在系统提示词中,仅仅用做:
- 整体行为知道 (ReAct模式,思考步骤)
- 任务上下文 (角色、目标)
- 调用策略 (如何使用和组合工具)
- 输出格式
然后依然传递tools。
Important
Claude针对 tool schema还做了专门优化,实际使用效果也非常棒👍🏻。