Appearance
课 2 · ReAct 循环与多步任务
本课目标
实现 ReAct 模式的 Agent 循环,处理多步任务的拆解与执行。课后你会拿到一个能自主完成多步任务的 Agent。
上一课实现了工具调用。但那些都是"一问一答"——用户问天气,模型调一次 API 就结束了。
真实任务往往需要多步执行:查资料 → 分析 → 调用接口 → 验证结果 → 汇总。Agent 需要一个循环机制来自主推进。
ReAct 模式
ReAct(Reasoning + Acting)是最主流的 Agent 工作模式,循环三步:
ReAct 循环
Thought分析当前情况,决定下一步
→
Action调用工具执行动作
→
Observation读取工具返回结果
↺
Final Answer任务完成后输出
只要任务还没完成,模型就会基于 Observation 再次 Thought,继续选择下一步。
- Thought:模型分析当前情况,决定下一步做什么
- Action:调用工具执行动作
- Observation:拿到工具返回的结果
然后模型基于 Observation 再次 Thought,决定是否需要继续执行,还是可以给出最终答案。
具体例子
用户:帮我分析一下知识库里关于 React 性能优化的内容,然后创建一个学习计划
Thought: 用户想了解 React 性能优化并制定学习计划。
我先搜索知识库找到相关内容。
Action: searchDocs({ query: "React 性能优化" })
Observation: 找到 3 篇文档:React.memo、useCallback/useMemo、虚拟列表...
Thought: 搜到了性能优化的核心技术点。现在创建学习计划。
Action: createTodo({ title: "学习 React.memo", priority: "high" })
Observation: 待办已创建
Thought: 继续创建其他学习项。
Action: createTodo({ title: "学习 useCallback/useMemo", priority: "medium" })
Observation: 待办已创建
Thought: 学习计划创建完成,可以汇总回复用户了。
Final: "我在知识库中找到了 React 性能优化的内容,核心包括...
已为你创建了以下学习计划:..."Vercel AI SDK 中的 ReAct
好消息:Vercel AI SDK 的 generateText 配合 stopWhen: stepCountIs(n) 后,天然支持 ReAct 循环。
typescript
const result = await generateText({
model,
tools: { /* 工具定义 */ },
stopWhen: stepCountIs(10), // 允许最多 10 步循环
system: `你是一个任务助手。对于复杂任务,请一步步执行:
1. 先分析任务需要哪些步骤
2. 逐步调用工具完成每个步骤
3. 最终汇总结果`,
prompt: userInput,
})模型会自动在"思考 → 调用工具 → 拿结果 → 再思考"之间循环,直到它认为任务完成或达到 stepCountIs(...) 设定的上限。
多步任务拆解
一个好的 Agent 能把复杂任务自动拆解成可执行的步骤。
关键在 System Prompt 中引导:
typescript
const systemPrompt = `
<role>
你是一个任务执行 Agent,能调用工具完成用户交给你的任务。
</role>
<workflow>
1. 理解用户意图,拆解为具体的执行步骤
2. 按顺序逐步执行,每步调用适当的工具
3. 如果某步失败,分析原因后重试或跳过
4. 所有步骤完成后,用自然语言汇总执行结果
</workflow>
<rules>
- 每次只执行一个步骤,不要跳步
- 执行前简要说明当前步骤的目的
- 遇到错误时最多重试 2 次,仍失败则告知用户
</rules>
`错误处理
工具执行可能失败——网络超时、参数错误、权限不足。Agent 需要处理这些异常。
在工具内处理错误
typescript
const searchTool = tool({
description: '搜索知识库',
inputSchema: z.object({
query: z.string().describe('搜索关键词'),
}),
execute: async ({ query }) => {
try {
const results = await search(query)
return { success: true, results }
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : '搜索失败',
}
}
},
})返回结构化的错误信息,模型可以据此决定是重试还是换个方式。
onStepFinish 回调
Vercel AI SDK 提供 onStepFinish 回调,可以追踪每一步的执行:
typescript
const result = await generateText({
model,
tools: { /* ... */ },
stopWhen: stepCountIs(10),
prompt: userInput,
onStepFinish: ({ text, toolCalls, toolResults, usage }) => {
console.log(`步骤完成:`)
if (toolCalls?.length) {
for (const tc of toolCalls) {
console.log(` 工具: ${tc.toolName}(${JSON.stringify(tc.args)})`)
}
}
if (text) {
console.log(` 输出: ${text.slice(0, 100)}`)
}
console.log(` Token: ${usage.totalTokens}`)
},
})终止条件
Agent 循环必须有终止条件,否则可能无限执行。
自然终止
模型判断任务完成,不再调用工具,直接返回文本——这是最理想的情况。
步数上限强制终止
typescript
stopWhen: stepCountIs(10) // 超过 10 步强制停止自定义终止逻辑
typescript
let stepCount = 0
const MAX_COST = 0.1 // 最多花 $0.1
let totalCost = 0
const result = await generateText({
model,
tools: { /* ... */ },
stopWhen: stepCountIs(20),
prompt: userInput,
onStepFinish: ({ usage }) => {
stepCount++
// 粗算 Token 成本
totalCost += (usage.promptTokens * 3 + usage.completionTokens * 15) / 1_000_000
if (totalCost > MAX_COST) {
throw new Error('超出成本预算,终止执行')
}
},
})实际场景:研究型 Agent
一个完整的研究型 Agent 示例:
typescript
const researchAgent = async (question: string) => {
return generateText({
model,
system: `你是一个研究助手。用户会给你一个技术问题,你的任务是:
1. 先搜索知识库
2. 分析搜索结果是否充分
3. 如果不够,尝试不同的搜索词再搜一次
4. 整理信息后给出结构化的回答`,
tools: {
searchKnowledgeBase: tool({
description: '在知识库中搜索文档',
inputSchema: z.object({
query: z.string(),
}),
execute: async ({ query }) => { /* 实际搜索逻辑 */ },
}),
saveNote: tool({
description: '保存研究笔记',
inputSchema: z.object({
title: z.string(),
content: z.string(),
}),
execute: async ({ title, content }) => { /* 保存逻辑 */ },
}),
},
stopWhen: stepCountIs(8),
prompt: question,
})
}本课产物
- ✅ ReAct 循环(Thought → Action → Observation)
- ✅ 多步任务自动拆解与执行
- ✅ 工具错误处理与重试机制
- ✅ 终止条件设计(自然终止、步数上限、成本预算)
- ✅ 研究型 Agent 的完整实现
完整代码在 basic/examples/05-agent/02-react/index.ts。
试试看
bash
cd daqi-ai-agent
pnpm exec tsx basic/examples/05-agent/02-react/index.ts- 给一个需要多步推理的任务(如「先查 A,再根据结果决定是否查 B」),观察 Thought → Action → Observation 的循环次数
- 给一个超出 Agent 能力范围的任务,看它在哪一步停下或如何降级
- 修改步数上限(
stepCountIs(...)),对比 5 步和 20 步对复杂任务完成度的影响
面试追问
Q:ReAct 模式怎么工作?
三步循环:Thought(分析当前情况、决定下一步)→ Action(调用工具执行)→ Observation(获取结果)。模型基于 Observation 再次 Thought,决定继续执行还是返回最终答案。Vercel AI SDK 中可用 stopWhen: stepCountIs(n) 开启多步循环并限制最大步数。
Q:Agent 不稳定的原因是什么?
几个常见原因:模型对工具描述理解不准确导致选错工具、参数格式错误导致工具执行失败、上下文过长导致模型"忘记"任务目标、没有终止条件导致无限循环。缓解方式:完善工具描述、做参数校验、控制 stopWhen: stepCountIs(...)、加 onStepFinish 监控。
Q:工具调用失败怎么处理?
工具内捕获异常返回结构化错误信息,模型可以据此重试或换方案。设置最大重试次数防止无限重试。对于关键操作,可以加 human-in-the-loop——失败后暂停询问用户是否继续。