AI代理详解:什么是ReAct循环及其工作原理?

AI代理详解:什么是ReAct循环及其工作原理?

AI代理详解:什么是ReAct循环及其工作原理?

📰 来源:Towards Data Science | 📅 翻译日期:2026年7月4日
🔗 原文查看原文
🤖 翻译:DeepSeek AI · 仅供参考

在上一篇文章中,我们讨论了工具调用(Tool Calling)。工具调用是一种机制,允许AI模型决定使用哪个函数以及传入什么参数,而不仅仅是生成文本输出。文章最后,我们实现了一个系统,可以调用 get_current_weatherconvert_currency,或者并行同时调用两者,或者都不调用而直接生成文本。简而言之,模型决定下一步需要做什么,我们(其余代码)执行该决定,将结果传回给模型,模型最终以文本形式向用户提供基于信息的回答。

这种循环的更高级版本不会在“模型决定 → 代码执行 → 传回结果 → 模型回答”仅一轮后停止。模型不会在最后直接生成响应,而是利用一次工具调用的结果来决定是否以及调用哪个下一个工具。正如工具调用文章末尾所提到的,这就是ReAct循环(Reason + Act),也正是让代理能够处理无法在单次调用中解决的任务的关键。

但这样的任务是什么样的呢?在前一篇文章的并行调用示例中,我们问“雅典的天气如何?100美元等于多少欧元?”这是两个独立的问题,需要两个独立的工具来回答,但它们彼此无关。换句话说,我们可以独立、同时地回答这两个问题,不需要从第一个问题中获取任何信息来回答第二个问题。

但如果我们问:“我和朋友打赌100欧元,赌今天雅典会下雨。如果我赢了,那相当于多少美元?”这里,模型首先需要调用 get_current_weather 了解是否真的下雨,才能决定是否需要调用 convert_currency。简单来说,第二个问题的答案完全取决于第一个问题的结果。这正是并行工具调用无法在一轮中解决的依赖关系,也正是ReAct循环的用途所在。

让我们一探究竟!

🍨 DataCream 是一份关于AI、数据和科技的通讯。如果你对这些话题感兴趣,请在此订阅!

什么是ReAct循环?

ReAct循环只是三个步骤重复进行:

  • Reason(推理)
  • Act(行动)
  • Observe(观察)

循环开始时,模型推理自己已知的信息以及为了正确回答用户查询还缺少哪些信息。然后它通过调用适当的工具来行动,以获取这些缺失的信息。最后,当相应的工具调用执行完成并将结果传回给模型时,模型观察结果(将工具的结果添加到其上下文中)。然后,它会循环回到推理阶段,不过这次上下文中包含了新的观察结果。这个循环一直重复,直到模型评估现有信息足以回答用户查询,此时它停止调用工具,仅以文本形式响应。

但这和我们已知的工具调用难道不是一样的吗?有点像,但不完全一样。与《工具调用》文章中介绍的内容相比,不同之处在于循环本身。在单次工具调用中,模型请求某样东西,得到它,然后这次调用的事务就结束了。而在ReAct循环中,对话保持开放,因为每个新的观察结果都会成为下一步推理的新上下文,模型可以根据刚刚学到的内容改变计划。

相同的工具,新的技巧

为了具体说明,我们回到引言中的打赌示例,思考模型需要做什么才能给我们一个可靠的答案。问题是:“我和朋友打赌100欧元,赌今天雅典会下雨。如果我赢了,那相当于多少美元?”注意其中的条件语句:“如果我赢了”。模型是否需要转换货币完全取决于天气调用的返回值。如果下雨了,模型需要调用 convert_currency,输入参数为 100 EUR,并返回转换后的奖金。如果没下雨,打赌输了,convert_currency 就不相关了,模型应该直接返回相应的文本,而不进行第二次调用。

换句话说,模型确实无法提前规划完整的工具调用序列。它必须先检查天气,观察结果,推理该结果对打赌条件意味着什么,然后才决定是否需要进行第二次工具调用。与并行工具调用能很好地回答“雅典的天气如何?100美元等于多少欧元?”不同,这个问题需要一个循环。

ReAct循环的好处在于它不需要新的工具。我们仍然可以使用相同的函数,只是以不同的方式使用。因此,我们将使用与上次完全相同的 get_current_weatherconvert_currency,它们分别使用 Open-Meteo 获取天气和 Frankfurter 进行货币兑换(两者仍然不需要 API 密钥):

import requests
import json
from openai import OpenAI

client = OpenAI(api_key="your_api_key")

def get_current_weather(city: str, unit: str = "celsius") -> dict:
    # Step 1: geocode the city name to coordinates
    geo = requests.get(
        "https://geocoding-api.open-meteo.com/v1/search",
        params={"name": city, "count": 1}
    ).json()
    lat = geo["results"][0]["latitude"]
    lon = geo["results"][0]["longitude"]

    # Step 2: fetch current weather
    weather = requests.get(
        "https://api.open-meteo.com/v1/forecast",
        params={
            "latitude": lat,
            "longitude": lon,
            "current": "temperature_2m,precipitation",
            "temperature_unit": unit
        }
    ).json()

    return {
        "city": city,
        "temperature": weather["current"]["temperature_2m"],
        "precipitation_mm": weather["current"]["precipitation"],
        "unit": unit
    }

def convert_currency(amount: float, from_currency: str, to_currency: str) -> dict:
    response = requests.get(
        f"https://api.frankfurter.app/latest",
        params={"amount": amount, "from": from_currency, "to": to_currency}
    ).json()
    return {
        "amount": amount,
        "from": from_currency,
        "to": to_currency,
        "converted_amount": response["rates"][to_currency]
    }

通过ReAct循环,模型能够迭代地推理和行动,处理更复杂的任务。


📌 *本文由 DeepSeek AI 自动翻译排版,如有不准确之处欢迎指正* 🏠 [返回首页](https://www.suiyuanlu.cn) · 📖 [查看原文](https://towardsdatascience.com/ai-agents-explained-what-is-a-react-loop-and-how-does-it-work/)
©版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

评论已关闭