AI 人工智能··19 阅读·预计 13 分钟

从零构建 AI Agent:深入理解 ReAct 模式与工具调用机制

背景

2023 年被称为 AI Agent 元年。从 AutoGPT 的爆火到 LangChain 的兴起,再到各大厂纷纷推出 Agent 平台,AI Agent 已经从实验室走向生产环境。但很多人对 Agent 的理解还停留在"对话机器人"的层面,不清楚它究竟是如何实现自主决策和工具调用的。

本文将深入剖析 AI Agent 的核心机制——ReAct(Reasoning + Acting)模式,并手把手教你从零构建一个具备工具调用能力的 Agent。

核心概念

什么是 ReAct 模式?

ReAct 是一种让大模型"边思考边行动"的范式。它的核心思想非常简单:

思考(Reasoning)→ 行动(Acting)→ 观察(Observation)→ 循环

传统的对话模型是"一次性回答",而 ReAct 模式让模型能够:

  1. 思考:分析当前任务,决定下一步该做什么
  2. 行动:调用外部工具获取信息或执行操作
  3. 观察:获取工具返回的结果
  4. 循环:基于观察结果继续思考,直到任务完成

工具调用的本质

工具调用的本质是让大模型输出结构化的 JSON 指令,然后由外部系统解析执行。以 OpenAI 的 Function Calling 为例:

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    tools=tools,
    tool_choice="auto"
)

当模型决定调用工具时,它会返回一个 tool_calls 字段,包含函数名和参数。你的代码负责执行这个函数,并将结果返回给模型继续对话。

实战案例:构建一个天气查询 Agent

让我们从零构建一个能够查询天气的 Agent,完整展示 ReAct 模式的工作流程。

Step 1:定义工具

const tools = [
    {
        name: "get_weather",
        description: "获取指定城市的实时天气信息",
        parameters: {
            type: "object",
            properties: {
                city: {
                    type: "string",
                    description: "城市名称,如:北京、上海、深圳"
                }
            },
            required: ["city"]
        },
        execute: async (params) => {
            const response = await fetch(
                `https://api.weather.com/v1/current?city=${encodeURIComponent(params.city)}`
            );
            return await response.json();
        }
    },
    {
        name: "search_web",
        description: "在网络上搜索信息",
        parameters: {
            type: "object",
            properties: {
                query: {
                    type: "string",
                    description: "搜索关键词"
                }
            },
            required: ["query"]
        },
        execute: async (params) => {
            const results = await searchAPI(params.query);
            return results.slice(0, 5);
        }
    }
];

Step 2:实现 ReAct 循环

async function runAgent(userMessage) {
    const messages = [
        {
            role: "system",
            content: "你是一个智能助手,可以使用工具帮助用户完成任务。"
        },
        { role: "user", content: userMessage }
    ];
    
    let iteration = 0;
    const maxIterations = 5;
    
    while (iteration < maxIterations) {
        iteration++;
        const response = await callLLM(messages);
        
        if (response.toolCalls && response.toolCalls.length > 0) {
            for (const toolCall of response.toolCalls) {
                const tool = tools.find(t => t.name === toolCall.function.name);
                const result = await tool.execute(toolCall.function.arguments);
                
                messages.push({
                    role: "tool",
                    content: JSON.stringify(result),
                    tool_call_id: toolCall.id
                });
            }
        } else {
            return response.content;
        }
    }
    
    return "抱歉,我无法在有限步骤内完成任务。";
}

Step 3:运行示例

const answer = await runAgent("北京今天天气怎么样?适合户外运动吗?");

// Agent 执行流程:
// 1. Thought: 用户想知道北京天气,需要调用 get_weather 工具
// 2. Action: get_weather({city: "北京"})
// 3. Observation: {city:"北京",temperature:22,condition:"晴",humidity:45,wind:"微风"}
// 4. Thought: 已获取天气信息,可以回答用户问题
// 5. Final Answer: 北京今天天气晴朗,气温22度,非常适合户外运动!

最佳实践

1. 工具设计原则

  • 单一职责:每个工具只做一件事,便于理解和调试
  • 清晰描述:工具描述要准确,让模型知道何时使用
  • 参数验证:执行前验证参数,避免无效调用
  • 错误处理:工具返回错误信息时,让模型能理解并调整策略

2. 提示词工程

你是一个专业的助手。请严格遵循 ReAct 格式:

Thought: 思考当前状态和下一步行动
Action: 工具调用(JSON 格式)或 "None"
Observation: 工具返回结果(由系统填充)

注意:
- 不要编造信息,必须使用工具获取实时数据
- 如果工具调用失败,尝试其他方案
- 给用户明确、有帮助的回答

3. 迭代次数限制

设置合理的最大迭代次数(通常 5-10 次),防止 Agent 陷入无限循环。复杂任务可以适当增加。

4. 工具结果格式化

工具返回的结果应该清晰、结构化,便于模型理解:

{
    "success": true,
    "data": {},
    "message": "查询成功"
}

常见问题

Q1:模型一直调用错误的工具怎么办?

检查工具描述是否清晰,参数说明是否准确。可以在 system prompt 中添加工具使用示例。

Q2:如何处理需要多个工具组合的场景?

在 ReAct 循环中,模型会自动判断是否需要继续调用工具。确保每个工具都有明确的输入输出格式。

Q3:Agent 执行时间太长怎么办?

  • 优化工具执行效率
  • 设置超时机制
  • 对于复杂任务,考虑拆分成多个子任务

Q4:如何保证工具调用的安全性?

  • 敏感操作需要用户确认
  • 限制工具的权限范围
  • 记录所有工具调用日志
  • 对输出进行安全过滤

总结

AI Agent 的核心在于让大模型具备"思考-行动"的循环能力。ReAct 模式通过结构化的思维过程,让模型能够:

  1. 分解复杂任务
  2. 调用外部工具获取实时信息
  3. 根据反馈调整策略
  4. 最终给出可靠的答案

掌握 ReAct 模式和工具调用机制,是构建实用 AI Agent 的基础。无论是客服机器人、智能助手,还是自动化工作流,都离不开这套核心思想。

下一步,你可以尝试:

  • 接入更多类型的工具(数据库、API、文件操作)
  • 实现 Agent 记忆和持久化
  • 构建多 Agent 协作系统
  • 添加自我反思和优化机制

AI Agent 的世界才刚刚开始,期待你构建出更强大的应用!

0 评论

评论区

登录 后参与评论