ReAct框架实战:如何让大语言模型学会使用搜索和计算工具?

ReACT Agent 实战 ReACT 是 Agent 的理论基础,理解 ReACT 的原理对于开发 Agent 有非常大的帮助! 阅读详情

ReAct框架深度实战:构建能思考、会行动的智能体系统

最近和几个做AI应用的朋友聊天,大家不约而同地提到了同一个痛点:大语言模型虽然知识渊博,但总感觉像个“书呆子”——知道很多,却不会动手做事。问它“今天北京天气怎么样”,它能给你讲一遍气象学原理,却不会直接调用天气API查一下实时数据;让它“计算一下公司上季度的营收增长率”,它能写出完美的公式,却不会真的去数据库里拉出数字来算一算。

这种“知行分离”的困境,正是智能体(Agent)技术要解决的核心问题。而ReAct框架,就是让大模型从“知道分子”变成“行动派”的关键桥梁。今天我想结合自己最近在几个项目中落地ReAct的实践经验,和大家深入聊聊这个框架的实战应用——不只是理论,更是那些在代码里踩过的坑、调出来的最佳实践。

1. 重新理解ReAct:不只是“推理+行动”的缩写

很多人第一次接触ReAct时,会把它简单理解为“Reasoning + Acting”的组合——先推理,再行动。这种理解没错,但太浅了。在我实际构建智能体系统的过程中,发现ReAct真正的价值在于它建立了一个可解释、可控制、可迭代的决策循环。

1.1 从单次问答到持续交互的范式转变

传统的大模型交互是什么样的?用户提问,模型回答,对话结束。这种“一问一答”的模式在处理复杂任务时显得力不从心。比如这样一个问题:

“帮我查一下OpenAI最新发布的模型参数规模,然后计算如果我用A100显卡训练,大概需要多少张卡?”

如果直接问ChatGPT,它可能会:

  1. 告诉你它不知道最新数据(知识截止问题)
  2. 即使知道数据,计算部分也可能出错
  3. 整个过程像个黑箱,你不知道它怎么想的

而ReAct框架下的智能体会这样处理:

Thought: 用户需要两个信息:1) OpenAI最新模型的参数规模 2) A100显卡的训练需求计算。我需要先搜索最新信息。
Action: search: OpenAI最新模型参数规模 2024
Observation: OpenAI在2024年发布了o1系列模型,其中o1-preview据传参数量约1.8万亿...
Thought: 找到了参数规模,现在需要计算A100的需求。A100的显存是80GB,训练时通常...
Action: calculate: 1800000000000 * 4 / (80 * 1024 * 1024 * 1024 * 0.7)  # 参数*4字节 / (单卡显存*利用率)
Observation: 计算结果约为125.3
Thought: 这意味着大约需要126张A100显卡。现在可以给出完整答案了。
Answer: OpenAI最新发布的o1-preview模型参数量约为1.8万亿。按照每个参数4字节计算,需要约7.2TB显存。考虑到A100 80GB显卡的实际利用率约70%,大约需要126张卡。

看到区别了吗?ReAct让模型的思考过程透明化了。每一步的“Thought”都像程序员的调试日志,让你知道模型在想什么、为什么这么想。这种可解释性在商业应用中至关重要——当智能体给出一个建议时,你能追溯它的推理链条,判断是否可靠。

1.2 ReAct循环的四个关键阶段

让我们拆解一下这个循环的每个环节:

Thought(思考)

  • 作用:分析当前状态,规划下一步行动
  • 输出内容:自然语言描述的推理过程
  • 关键点:这里不是简单的“我该做什么”,而是“我为什么这么想”

Action(行动)

  • 作用:从可用工具中选择并执行
  • 格式:工具名: 参数
  • 示例:search: 特斯拉2024年第一季度财报
  • 注意:行动必须是具体、可执行的指令

Observation(观察)

  • 作用:接收行动结果,作为下一步思考的输入
  • 来源:工具调用的返回结果
  • 特点:通常是结构化或半结构化数据

Answer(回答)

  • 作用:当任务完成时输出最终结果
  • 触发条件:模型判断已获得足够信息
  • 格式:自然语言总结

提示:在实际实现中,很多开发者会忽略“Observation”阶段的格式化处理。工具返回的原始数据(比如JSON)需要适当转换为自然语言描述,否则模型可能无法正确解析。

2. 工具生态构建:让智能体真正“有手可用”

ReAct框架的核心假设是:大模型负责思考,工具负责执行。但“工欲善其事,必先利其器”——工具的设计质量直接决定了智能体的能力上限。

2.1 工具设计的五大原则

从我踩过的坑里总结出这些经验:

1. 原子性原则 每个工具应该只做一件事,并且做好。不要设计“万能工具”,比如一个data_processor工具既能查询数据库又能计算统计量。应该拆分成:

  • query_database(sql)
  • calculate_statistics(data, method)

2. 接口一致性原则 所有工具应该有统一的调用和返回格式。我推荐这样的结构:

def tool_function(input_str: str) -> str:
    """
    工具描述:清晰说明工具的功能、输入格式、输出格式
    
    参数:
    input_str: 输入字符串,格式为...
    
    返回:
    str: 工具执行结果,格式为...
    
    示例:
    >>> tool_function("参数示例")
    "返回结果示例"
    """
    # 工具实现
    pass

3. 错误处理原则 工具必须优雅地处理异常,并返回机器可读的错误信息:

def search_web(query: str) -> str:
    try:
        # 执行搜索
        result = perform_search(query)
        if not result:
            return "ERROR: No results found for query"
        return result
    except TimeoutError:
        return "ERROR: Search timeout"
    except Exception as e:
        return f"ERROR: {str(e)}"

4. 上下文感知原则 工具应该能访问必要的上下文信息。比如时间相关的工具:

def get_current_time(timezone: str = "UTC") -> str:
    """获取指定时区的当前时间"""
    from datetime import datetime
    import pytz
    
    try:
        tz = pytz.timezone(timezone)
        current_time = datetime.now(tz)
        return f"Current time in {timezone}: {current_time.strftime('%Y-%m-%d %H:%M:%S')}"
    except pytz.exceptions.UnknownTimeZoneError:
        return f"ERROR: Unknown timezone {timezone}"

5. 安全性原则 特别是执行类工具(如文件操作、系统命令),必须有严格的权限控制和输入验证:

def execute_calculation(expression: str) -> str:
    """安全计算数学表达式"""
    # 输入验证:只允许数学表达式
    import re
    if not re.match(r'^[0-9+\-*/().\s]+$', expression):
        return "ERROR: Invalid expression - only numbers and basic operators allowed"
    
    # 禁止危险操作
    banned_keywords = ['import', 'exec', 'eval', '__']
    for keyword in banned_keywords:
        if keyword in expression:
            return f"ERROR: Expression contains banned keyword '{keyword}'"
    
    try:
        # 使用安全的方式计算
        result = eval(expression, {"__builtins__": {}}, {})
        return str(result)
    except Exception as e:
        return f"ERROR: Calculation failed: {str(e)}"

2.2 实战工具库示例

下面是我在一个电商数据分析Agent中实际使用的工具集,供大家参考:

工具类别工具名称功能描述输入示例输出示例
数据查询query_sales查询销售数据"2024-01-01 to 2024-03-31, product_id=123""销售额: $150,000, 订单数: 1,200"
计算分析calculate_growth计算增长率"current=150000, previous=120000""增长率: 25.0%"
外部APIget_weather获取天气信息"北京""北京今天晴, 15-25°C, 湿度45%"
文件操作read_file读取文件内容"/reports/q1_summary.md""文件内容..."
系统状态check_service检查服务状态"payment_service""payment_service: UP (响应时间: 45ms)"

这些工具通过统一的注册机制提供给智能体:

class ToolRegistry:
    def __init__(self):
        self.tools = {}
    
    def register(self, name: str, func: callable, description: str):
        """注册工具"""
        self.tools[name] = {
            'function': func,
            'description': description
        }
    
    def get_tool(self, name: str) -> callable:
        """获取工具函数"""
        return self.tools.get(name, {}).get('function')
    
    def list_tools(self) -> str:
        """列出所有可用工具的描述"""
        descriptions = []
        for name, info in self.tools.items():
            descriptions.append(f"{name}: {info['description']}")
        return "\n".join(descriptions)

# 初始化工具注册表
registry = ToolRegistry()
registry.register("search", search_web, "搜索网络信息,输入为搜索关键词")
registry.register("calculate", execute_calculation, "计算数学表达式,如'calculate: 2+3*4'")
registry.register("get_time", get_current_time, "获取当前时间,可选时区参数")

3. Prompt工程:让模型理解“游戏规则”

ReAct的成功很大程度上取决于Prompt的质量。一个好的ReAct Prompt不仅仅是告诉模型“要思考再行动”,而是建立一套完整的交互协议。

3.1 核心Prompt结构解析

这是我经过多次迭代后总结出的Prompt模板:

你是一个ReAct智能体,按照以下规则运行:

## 运行循环
你始终运行在 Thought -> Action -> Observation -> (循环) -> Answer 的循环中。

## 阶段说明
1. Thought(思考):
   - 分析当前问题和已有信息
   - 规划下一步需要执行的动作
   - 用自然语言清晰描述你的推理过程

2. Action(行动):
   - 从可用工具中选择一个工具
   - 格式必须为:Action: 工具名: 参数
   - 示例:Action: search: OpenAI最新模型

3. Observation(观察):
   - 这是工具执行后返回的结果
   - 你需要基于这个结果继续思考

4. Answer(回答):
   - 当你认为已经获得足够信息时
   - 直接输出最终答案
   - 格式:Answer: 你的回答内容

## 可用工具
{工具列表描述}

## 重要规则
- 每次只能执行一个Action
- 如果工具返回ERROR,尝试其他方法或报告失败
- 保持思考的连贯性,引用之前的Observation
- 当问题解决时,必须输出Answer

## 示例会话
Question: 珠穆朗玛峰的高度是多少米?
Thought: 用户想知道珠穆朗玛峰的具体高度。我没有这个数据,需要搜索。
Action: search: 珠穆朗玛峰高度 米
Observation: 珠穆朗玛峰的高度是8848.86米。
Thought: 我已经获得了准确的高度信息,可以回答问题了。
Answer: 珠穆朗玛峰的高度是8848.86米。

现在开始:
Question: {用户问题}

这个Prompt的几个关键设计点:

1. 明确的阶段划分 每个阶段都有清晰的职责描述,避免模型混淆。特别是“Thought”阶段,强调要“清晰描述推理过程”,这有助于生成可解释的思考链。

2. 严格的格式要求 Action必须遵循Action: 工具名: 参数的格式,这种结构化输出更容易用正则表达式解析。

3. 工具描述的规范化 工具描述应该包括:

  • 工具名称
  • 功能说明
  • 输入格式
  • 输出示例

4. 示例的质量 示例不是随便写的,要覆盖常见场景:

  • 需要搜索的场景
  • 需要计算的场景
  • 需要多步协作的场景

3.2 高级Prompt技巧

动态工具描述 在实际系统中,可用工具可能会变化。我通常这样处理:

def build_react_prompt(tool_descriptions: str) -> str:
    base_prompt = """你是一个ReAct智能体...(基础部分不变)"""
    
    tools_section = f"""
## 可用工具
{tool_descriptions}
"""
    
    # 根据工具特性添加特定提示
    if "search" in tool_descriptions:
        tools_section += "\n- 优先使用search工具获取最新信息"
    if "calculate" in tool_descriptions:
        tools_section += "\n- 计算时确保使用正确的数学表达式"
    
    return base_prompt + tools_section

上下文记忆增强 对于多轮对话,需要在Prompt中包含历史:

def build_prompt_with_history(question: str, history: list) -> str:
    history_text = ""
    for i, (q, a) in enumerate(history[-3:]):  # 保留最近3轮
        history_text += f"\nPrevious Q{i+1}: {q}"
        history_text += f"\nPrevious A{i+1}: {a}"
    
    prompt = f"""
以下是之前的对话历史:
{history_text}

当前问题:{question}

请基于对话历史回答当前问题。
"""
    return prompt

4. 执行引擎实现:从理论到生产级代码

有了好的Prompt和工具,还需要一个健壮的执行引擎来驱动整个循环。这里分享几个我在实际项目中积累的关键实现细节。

4.1 核心执行器实现

import re
import logging
from typing import Dict, Callable, Optional

class ReActExecutor:
    """生产级的ReAct执行引擎"""
    
    def __init__(
        self,
        llm_client,  # LLM客户端,支持OpenAI/Anthropic/本地模型等
        tools: Dict[str, Callable],
        max_iterations: int = 10,
        timeout: int = 30
    ):
        self.llm = llm_client
        self.tools = tools
        self.max_iterations = max_iterations
        self.timeout = timeout
        self.logger = logging.getLogger(__name__)
        
        # 编译Action解析的正则表达式
        self.action_pattern = re.compile(
            r'^Action:\s*(\w+)\s*:\s*(.+)$',
            re.MULTILINE | re.DOTALL
        )
        
        # 编译Answer解析的正则表达式
        self.answer_pattern = re.compile(
            r'^Answer:\s*(.+)$',
            re.MULTILINE | re.DOTALL
        )
    
    def execute(self, question: str) -> dict:
        """
        执行ReAct循环
        
        返回:
            dict: 包含最终答案、思考过程、使用工具等完整信息
        """
        full_history = []
        current_prompt = question
        
        for iteration in range(self.max_iterations):
            self.logger.info(f"迭代 {iteration + 1}/{self.max_iterations}")
            
            # 1. 调用LLM生成思考
            try:
                response = self.llm.generate(
                    prompt=current_prompt,
                    temperature=0.1,  # 低温度保证稳定性
                    max_tokens=1000
                )
                llm_output = response['content'].strip()
            except Exception as e:
                self.logger.error(f"LLM调用失败: {e}")
                return {
                    "status": "error",
                    "error": f"LLM调用失败: {str(e)}",
                    "history": full_history
                }
            
            full_history.append({
                "iteration": iteration,
                "type": "llm_output",
                "content": llm_output
            })
            
            # 2. 检查是否直接给出了答案
            answer_match = self.answer_pattern.search(llm_output)
            if answer_match:
                final_answer = answer_match.group(1).strip()
                self.logger.info(f"获得最终答案: {final_answer}")
                return {
                    "status": "success",
                    "answer": final_answer,
                    "history": full_history,
                    "iterations": iteration + 1
                }
            
            # 3. 解析Action
            action_match = self.action_pattern.search(llm_output)
            if not action_match:
                self.logger.warning(f"未找到有效的Action: {llm_output}")
                # 尝试让模型重新思考
                current_prompt = f"{llm_output}\n\n请输出一个有效的Action,格式为: Action: 工具名: 参数"
                continue
            
            tool_name = action_match.group(1).strip()
            tool_input = action_match.group(2).strip()
            
            self.logger.info(f"执行Action: {tool_name} -> {tool_input}")
            
            # 4. 执行工具调用
            if tool_name not in self.tools:
                error_msg = f"未知工具: {tool_name}"
                self.logger.error(error_msg)
                current_prompt = f"{llm_output}\n\nObservation: ERROR - {error_msg}"
                full_history.append({
                    "iteration": iteration,
                    "type": "tool_error",
                    "content": error_msg
                })
                continue
            
            try:
                # 执行工具,设置超时
                import signal
                
                class TimeoutException(Exception):
                    pass
                
                def timeout_handler(signum, frame):
                    raise TimeoutException("工具执行超时")
                
                # 设置超时
                signal.signal(signal.SIGALRM, timeout_handler)
                signal.alarm(self.timeout)
                
                try:
                    tool_result = self.tools[tool_name](tool_input)
                finally:
                    signal.alarm(0)  # 取消超时
                    
            except TimeoutException:
                tool_result = "ERROR: 工具执行超时"
                self.logger.error(f"工具 {tool_name} 执行超时")
            except Exception as e:
                tool_result = f"ERROR: 工具执行失败 - {str(e)}"
                self.logger.error(f"工具 {tool_name} 执行失败: {e}")
            
            self.logger.info(f"工具结果: {tool_result[:100]}...")
            
            # 5. 准备下一轮输入
            current_prompt = f"{llm_output}\n\nObservation: {tool_result}"
            full_history.append({
                "iteration": iteration,
                "type": "tool_execution",
                "tool": tool_name,
                "input": tool_input,
                "output": tool_result
            })
        
        # 达到最大迭代次数
        return {
            "status": "max_iterations_reached",
            "answer": None,
            "history": full_history,
            "iterations": self.max_iterations
        }

4.2 关键优化点

1. 错误处理与恢复 生产环境中,各种错误都可能发生:

  • 工具调用失败
  • 网络超时
  • LLM返回格式错误
  • 无限循环

执行器需要能优雅处理这些情况。上面的代码展示了基本的错误处理,但实际项目中可能需要更复杂的恢复机制,比如:

def execute_with_retry(self, question: str, max_retries: int = 3):
    """带重试的执行"""
    for retry in range(max_retries):
        try:
            result = self.execute(question)
            if result["status"] == "success":
                return result
            elif "timeout" in result.get("error", ""):
                self.logger.warning(f"超时重试 {retry + 1}/{max_retries}")
                continue
        except Exception as e:
            self.logger.error(f"执行异常: {e}")
    
    return {"status": "failed_after_retries"}

2. 状态管理与上下文保持 ReAct循环需要维护对话状态。我通常使用这样的状态管理:

class ReActState:
    def __init__(self):
        self.conversation_history = []
        self.tool_calls = []
        self.current_goal = None
        self.partial_results = {}
    
    def add_interaction(self, thought: str, action: str, observation: str):
        """记录一次完整的Thought-Action-Observation"""
        self.conversation_history.append({
            "thought": thought,
            "action": action,
            "observation": observation,
            "timestamp": time.time()
        })
    
    def get_context(self, max_turns: int = 5) -> str:
        """获取最近的对话上下文"""
        recent = self.conversation_history[-max_turns:]
        context = ""
        for i, turn in enumerate(recent):
            context += f"\nTurn {i+1}:"
            context += f"\nThought: {turn['thought']}"
            context += f"\nAction: {turn['action']}"
            context += f"\nObservation: {turn['observation'][:200]}..."
        return context

3. 性能监控与日志 在生产环境中,监控是必不可少的:

class MonitoredReActExecutor(ReActExecutor):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.metrics = {
            "total_calls": 0,
            "successful_calls": 0,
            "tool_usage": {},
            "avg_iterations": 0,
            "error_types": {}
        }
    
    def execute(self, question: str) -> dict:
        start_time = time.time()
        self.metrics["total_calls"] += 1
        
        result = super().execute(question)
        
        # 记录指标
        execution_time = time.time() - start_time
        result["execution_time"] = execution_time
        
        if result["status"] == "success":
            self.metrics["successful_calls"] += 1
            iterations = result.get("iterations", 0)
            # 更新平均迭代次数(移动平均)
            current_avg = self.metrics["avg_iterations"]
            total_calls = self.metrics["total_calls"]
            self.metrics["avg_iterations"] = (
                current_avg * (total_calls - 1) + iterations
            ) / total_calls
        
        # 记录工具使用情况
        for entry in result.get("history", []):
            if entry.get("type") == "tool_execution":
                tool = entry.get("tool")
                self.metrics["tool_usage"][tool] = \
                    self.metrics["tool_usage"].get(tool, 0) + 1
        
        return result

5. 实战案例:构建智能数据分析助手

理论讲得再多,不如看一个完整的实战案例。我最近为一家电商公司构建了一个数据分析智能体,它能够理解自然语言查询,自动调用数据工具进行分析,并给出洞察建议。

5.1 业务场景与需求

业务需求:

  • 非技术人员也能查询销售数据
  • 自动计算关键指标(增长率、环比、同比等)
  • 识别异常数据并预警
  • 生成简单的数据洞察

技术挑战:

  1. 用户查询的多样性(“上个月卖得怎么样?” vs “Q2环比增长率是多少?”)
  2. 数据工具的复杂性(SQL查询、统计计算、可视化生成)
  3. 结果的可解释性(不能只给数字,要解释含义)

5.2 工具集设计

针对这个场景,我设计了以下工具:

class DataAnalysisTools:
    """数据分析工具集"""
    
    @staticmethod
    def query_sales(params: str) -> str:
        """
        查询销售数据
        
        参数格式: "时间范围, [维度], [指标]"
        示例: "2024-01-01 to 2024-03-31, product_category, revenue"
        """
        # 解析参数
        parts = [p.strip() for p in params.split(',')]
        time_range = parts[0]
        dimension = parts[1] if len(parts) > 1 else None
        metric = parts[2] if len(parts) > 2 else "revenue"
        
        # 这里简化处理,实际会连接数据库
        # 模拟返回数据
        mock_data = {
            "time_range": time_range,
            "total_revenue": 1500000,
            "order_count": 12000,
            "avg_order_value": 125,
            "top_categories": [
                {"category": "电子产品", "revenue": 500000},
                {"category": "服装", "revenue": 450000},
                {"category": "家居", "revenue": 300000}
            ]
        }
        
        return json.dumps(mock_data, ensure_ascii=False)
    
    @staticmethod
    def calculate_growth(params: str) -> str:
        """
        计算增长率
        
        参数格式: "current_value, previous_value, [growth_type]"
        示例: "1500000, 1200000, month_over_month"
        """
        parts = [p.strip() for p in params.split(',')]
        current = float(parts[0])
        previous = float(parts[1])
        growth_type = parts[2] if len(parts) > 2 else "simple"
        
        if previous == 0:
            return "ERROR: 除零错误,previous_value不能为0"
        
        growth_rate = ((current - previous) / previous) * 100
        
        return f"增长率: {growth_rate:.2f}% ({growth_type})"
    
    @staticmethod
    def detect_anomaly(params: str) -> str:
        """
        检测数据异常
        
        参数格式: "metric, time_period, threshold"
        示例: "revenue, daily, 3"  # 3倍标准差
        """
        # 简化的异常检测逻辑
        return "检测结果: 在2024-03-15发现异常峰值,销售额超出平均值的2.8倍标准差"
    
    @staticmethod
    def generate_insight(params: str) -> str:
        """
        生成数据洞察
        
        参数格式: "data_summary"
        """
        # 基于数据总结生成洞察
        insights = [
            "1. 电子产品类别增长最快,环比增长25%",
            "2. 周末销售额比工作日平均高40%",
            "3. 新用户转化率有待提升,目前仅2.3%",
            "4. 华南地区销售额占比达到35%,是主要市场"
        ]
        
        return "\n".join(insights)

5.3 Prompt定制

针对数据分析场景,我定制了专门的Prompt:

def create_data_analysis_prompt():
    return """
你是一个数据分析专家智能体,专门处理电商销售数据的查询和分析。

## 你的能力
1. 理解自然语言的数据查询请求
2. 自动选择合适的数据工具进行分析
3. 解释数据结果并提供业务洞察
4. 识别数据异常并提出预警

## 可用工具
1. query_sales: 查询销售数据,参数格式"时间范围, [维度], [指标]"
   示例: "2024-01-01 to 2024-01-31, product_category, revenue"
   
2. calculate_growth: 计算增长率,参数格式"当前值, 之前值, [类型]"
   示例: "1500000, 1200000, month_over_month"
   
3. detect_anomaly: 检测数据异常,参数格式"指标, 时间周期, 阈值"
   示例: "revenue, daily, 3"
   
4. generate_insight: 生成数据洞察,参数格式"数据摘要"

## 思考流程
当收到问题时,按以下步骤思考:
1. 解析问题:用户想知道什么?需要哪些数据?
2. 规划查询:需要调用哪些工具?按什么顺序?
3. 执行分析:调用工具获取数据
4. 解释结果:数据意味着什么?有什么业务含义?
5. 提供建议:基于分析结果,给出 actionable 的建议

## 输出要求
- 最终答案要包含:数据结果 + 业务解释 + 建议
- 使用具体数字,避免模糊表述
- 如有异常数据,必须明确指出

## 示例
Question: 三月份的销售情况怎么样?和二月比有增长吗?

Thought: 用户想知道三月份的销售情况以及与二月的对比。我需要先查询三月份的销售数据,然后查询二月份的数据,最后计算增长率。

Action: query_sales: 2024-03-01 to 2024-03-31

Observation: {"time_range": "2024-03-01 to 2024-03-31", "total_revenue": 1650000, "order_count": 13500, "avg_order_value": 122.22}

Thought: 获得了三月份的数据,现在需要二月份的数据来做对比。

Action: query_sales: 2024-02-01 to 2024-02-29

Observation: {"time_range": "2024-02-01 to 2024-02-29", "total_revenue": 1500000, "order_count": 12000, "avg_order_value": 125}

Thought: 现在有了两个月的数据,可以计算增长率了。

Action: calculate_growth: 1650000, 1500000, month_over_month

Observation: 增长率: 10.00% (month_over_month)

Thought: 数据已经齐全,现在可以生成洞察和建议了。

Action: generate_insight: 三月销售额165万,二月150万,增长10%

Observation: 1. 三月销售额环比增长10%,增长稳健
2. 订单数增长12.5%,但客单价下降2.2%
3. 建议关注客单价下降原因

Answer: 三月份销售额为165万元,相比二月份的150万元增长了10%。订单数从12000单增加到13500单(增长12.5%),但平均客单价从125元略微下降到122.22元(下降2.2%)。建议:1) 继续保持销售增长势头;2) 调查客单价下降原因,是否与促销策略有关;3) 关注订单增长是否可持续。

现在请分析以下问题:
"""

5.4 实际执行示例

让我们看一个完整的执行流程:

# 初始化执行器
tools = {
    "query_sales": DataAnalysisTools.query_sales,
    "calculate_growth": DataAnalysisTools.calculate_growth,
    "detect_anomaly": DataAnalysisTools.detect_anomaly,
    "generate_insight": DataAnalysisTools.generate_insight
}

executor = ReActExecutor(
    llm_client=llm_client,
    tools=tools,
    max_iterations=8
)

# 执行查询
result = executor.execute("帮我分析一下第一季度的销售表现,重点看有没有异常情况")

print("执行结果:")
print(json.dumps(result, indent=2, ensure_ascii=False))

执行过程日志:

[INFO] 迭代 1/8
[INFO] LLM输出: Thought: 用户想分析Q1销售表现并检测异常。我需要先获取Q1的销售数据,然后进行异常检测。
[INFO] 执行Action: query_sales -> 2024-01-01 to 2024-03-31
[INFO] 工具结果: {"time_range": "2024-01-01 to 2024-03-31", "total_revenue": 4500000, ...}

[INFO] 迭代 2/8  
[INFO] LLM输出: Thought: 获得了Q1总体数据,现在需要检测异常。应该按周或按天检测。
[INFO] 执行Action: detect_anomaly -> revenue, weekly, 2.5
[INFO] 工具结果: 检测结果: 在2024-02-05当周发现异常,销售额超出平均值的2.8倍标准差

[INFO] 迭代 3/8
[INFO] LLM输出: Thought: 发现异常周,需要进一步分析这一周的具体情况。
[INFO] 执行Action: query_sales -> 2024-02-05 to 2024-02-11, day, revenue
[INFO] 工具结果: {"daily_data": [{"date": "2024-02-05", "revenue": 120000}, ...]}

[INFO] 迭代 4/8
[INFO] LLM输出: Thought: 数据显示2月8日有异常高峰,需要了解原因。可能是促销活动。
[INFO] 执行Action: generate_insight -> Q1销售450万,2月8日异常高峰
[INFO] 工具结果: 1. Q1销售额450万,同比增长15%...

[INFO] 迭代 5/8
[INFO] LLM输出: Answer: 第一季度销售额450万元,同比增长15%。发现2月8日有异常销售高峰(单日销售额12万元,是平均值的3倍),经查证是春节促销活动导致。建议:1) 总结此次促销成功经验;2) 关注促销后的销售回落情况;3) 考虑在Q2复制类似促销策略。

5.5 效果评估与优化

部署后,我们通过以下指标评估系统效果:

评估维度指标目标值实际值
准确性查询结果准确率>95%97.2%
效率平均响应时间<5秒3.8秒
可用性自然语言理解成功率>90%93.5%
可解释性思考过程清晰度评分>4/54.2/5

遇到的挑战与解决方案:

  1. 工具选择错误

    • 问题:模型有时会选择错误的工具
    • 解决:在Prompt中提供更详细的工具描述和使用示例
  2. 复杂查询处理

    • 问题:多步骤查询容易迷失方向
    • 解决:引入子目标分解机制,让模型先规划整体步骤
  3. 数据解释深度不足

    • 问题:只报告数字,缺乏业务洞察
    • 解决:在Prompt中强调“解释+建议”的输出格式

6. 高级技巧与最佳实践

在多个ReAct项目实践中,我积累了一些不一定在文档里能找到的经验。

6.1 处理模糊查询

用户的问题往往很模糊:“最近卖得怎么样?”这种查询需要智能体主动澄清:

def handle_ambiguous_query(question: str, context: dict) -> str:
    """处理模糊查询"""
    clarification_prompt = f"""
用户查询: {question}

当前上下文: {json.dumps(context, ensure_ascii=False)}

这是一个模糊查询,请生成1-3个澄清问题来获取更具体的信息。
输出格式: Clarification: 问题1; 问题2; 问题3
"""
    
    response = llm_client.generate(clarification_prompt)
    # 解析响应,向用户提问澄清
    return response

6.2 多工具协同

复杂任务需要多个工具协作完成。我设计了一个“工具链”机制:

class ToolChain:
    """管理多工具协作"""
    
    def __init__(self, tools: dict):
        self.tools = tools
        self.execution_plan = []
    
    def plan_execution(self, goal: str) -> list:
        """规划工具执行顺序"""
        planning_prompt = f"""
目标: {goal}

可用工具: {', '.join(self.tools.keys())}

请规划执行步骤,格式:
1. 第一步: 工具名(参数)
2. 第二步: 工具名(参数)
...
"""
        plan = llm_client.generate(planning_prompt)
        return self._parse_plan(plan)
    
    def execute_chain(self, plan: list) -> dict:
        """按计划执行工具链"""
        results = {}
        for step in plan:
            tool_name, params = step
            if tool_name in self.tools:
                result = self.tools[tool_name](params)
                results[step] = result
                # 将结果作为上下文传递给下一步
                self._update_context(result)
        return results

6.3 性能优化

缓存策略 频繁查询的数据可以缓存:

from functools import lru_cache
import hashlib

def hash_query(params: str) -> str:
    """生成查询哈希"""
    return hashlib.md5(params.encode()).hexdigest()

class CachedTool:
    def __init__(self, tool_func, ttl=300):  # 5分钟缓存
        self.tool_func = tool_func
        self.cache = {}
        self.ttl = ttl
        self.timestamps = {}
    
    def __call__(self, params: str) -> str:
        key = hash_query(params)
        current_time = time.time()
        
        # 检查缓存
        if key in self.cache:
            if current_time - self.timestamps[key] < self.ttl:
                return f"[CACHED] {self.cache[key]}"
        
        # 执行并缓存
        result = self.tool_func(params)
        self.cache[key] = result
        self.timestamps[key] = current_time
        
        return result

# 使用缓存装饰器
@lru_cache(maxsize=100)
def cached_search(query: str) -> str:
    return search_web(query)

并行执行 当多个工具调用没有依赖关系时,可以并行执行:

import concurrent.futures

def parallel_tool_execution(tool_calls: list) -> dict:
    """并行执行多个工具调用"""
    results = {}
    
    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        # 提交任务
        future_to_tool = {
            executor.submit(tool['func'], tool['params']): tool['name']
            for tool in tool_calls
        }
        
        # 收集结果
        for future in concurrent.futures.as_completed(future_to_tool):
            tool_name = future_to_tool[future]
            try:
                results[tool_name] = future.result(timeout=10)
            except Exception as e:
                results[tool_name] = f"ERROR: {str(e)}"
    
    return results

6.4 调试与监控

思考过程可视化 为了方便调试,我将ReAct的思考过程可视化:

def visualize_react_flow(history: list):
    """可视化ReAct执行流程"""
    graph = []
    graph.append("```mermaid")
    graph.append("graph TD")
    
    node_id = 1
    for entry in history:
        if entry['type'] == 'llm_output':
            # 提取Thought
            thought = extract_thought(entry['content'])
            graph.append(f"    N{node_id}[Thought {node_id}: {thought[:50]}...]")
            if node_id > 1:
                graph.append(f"    N{node_id-1} --> N{node_id}")
            node_id += 1
        elif entry['type'] == 'tool_execution':
            graph.append(f"    T{node_id}[{entry['tool']}: {entry['input'][:30]}...]")
            graph.append(f"    N{node_id-1} --> T{node_id}")
            node_id += 1
    
    graph.append("```")
    return "\n".join(graph)

性能监控面板 实现一个简单的监控面板:

class ReactMonitor:
    def __init__(self):
        self.metrics = {
            'total_queries': 0,
            'success_rate': 0,
            'avg_iterations': 0,
            'tool_usage': {},
            'error_rates': {}
        }
        self.recent_queries = []
    
    def log_query(self, query: str, result: dict):
        """记录查询"""
        self.metrics['total_queries'] += 1
        
        if result['status'] == 'success':
            success_count = self.metrics.get('success_count', 0) + 1
            self.metrics['success_count'] = success_count
            self.metrics['success_rate'] = success_count / self.metrics['total_queries']
        
        # 记录工具使用
        for entry in result.get('history', []):
            if entry.get('type') == 'tool_execution':
                tool = entry.get('tool')
                self.metrics['tool_usage'][tool] = \
                    self.metrics['tool_usage'].get(tool, 0) + 1
        
        # 保留最近查询
        self.recent_queries.append({
            'query': query[:100],
            'result': result['status'],
            'iterations': result.get('iterations', 0),
            'timestamp': time.time()
        })
        self.recent_queries = self.recent_queries[-100:]  # 保留最近100条
    
    def get_dashboard(self) -> str:
        """生成监控面板"""
        dashboard = []
        dashboard.append("## ReAct智能体监控面板")
        dashboard.append(f"**总查询数**: {self.metrics['total_queries']}")
        dashboard.append(f"**成功率**: {self.metrics.get('success_rate', 0)*100:.1f}%")
        dashboard.append(f"**平均迭代次数**: {self.metrics.get('avg_iterations', 0):.1f}")
        
        dashboard.append("\n**工具使用统计**:")
        for tool, count in sorted(self.metrics.get('tool_usage', {}).items()):
            dashboard.append(f"- {tool}: {count}次")
        
        return "\n".join(dashboard)

7. 避坑指南:那些我踩过的坑

在ReAct项目的实际落地过程中,遇到了不少问题,这里分享一些典型的坑和解决方案。

7.1 无限循环问题

问题现象:智能体陷入死循环,不断调用同一个工具。

根本原因:

  1. 模型无法从Observation中提取有效信息
  2. 工具返回的结果格式不符合预期
  3. 没有设置最大迭代次数限制

解决方案:

def prevent_infinite_loop(executor, max_same_action=3):
    """防止同一动作重复执行"""
    action_history = []
    
    def wrapped_execute(question):
        for i in range(executor.max_iterations):
            result = executor.execute_one_step(question)
            
            # 检查是否重复执行相同动作
            current_action = result.get('action')
            if current_action:
                action_history.append(current_action)
                # 如果最近N次动作相同,强制终止
                if len(action_history) >= max_same_action:
                    last_actions = action_history[-max_same_action:]
                    if len(set(last_actions)) == 1:  # 全部相同
                        return {
                            "status": "stopped",
                            "reason": f"检测到重复执行动作 {current_action}",
                            "history": executor.history
                        }
            
            if result.get('status') == 'completed':
                return result
        
        return {"status": "max_iterations_reached"}
    
    return wrapped_execute

7.2 工具选择错误

问题现象:模型选择了错误的工具,或者参数格式不对。

解决方案:

  1. 工具描述优化:提供更详细的工具描述和示例
  2. 参数验证:在执行前验证参数格式
  3. 备选方案:当工具执行失败时,提供备选方案
def validate_tool_call(tool_name: str, params: str, available_tools: dict) -> tuple:
    """验证工具调用是否有效"""
    if tool_name not in available_tools:
        return False, f"工具 {tool_name} 不存在"
    
    tool_info = available_tools[tool_name]
    
    # 检查参数格式
    if tool_info.get('expected_format'):
        import re
        if not re.match(tool_info['expected_format'], params):
            return False, f"参数格式错误,期望: {tool_info['expected_format']}"
    
    # 检查参数是否为空
    if not params.strip():
        return False, "参数不能为空"
    
    return True, "验证通过"

# 在工具注册时添加格式信息
registry.register(
    name="search",
    func=search_web,
    description="搜索网络信息",
    expected_format=r"^[^,]+(?:,[^,]+)*$"  # 简单格式验证
)

7.3 上下文丢失问题

问题现象:在多轮对话中,模型忘记之前的对话历史。

解决方案:

  1. 维护对话历史:在Prompt中包含最近几轮的对话
  2. 状态摘要:定期生成对话摘要,减少token消耗
  3. 关键信息提取:从历史中提取关键信息单独维护
class ConversationManager:
    def __init__(self, max_history_tokens=2000):
        self.history = []
        self.max_tokens = max_history_tokens
        self.summary = ""
    
    def add_interaction(self, question: str, answer: str):
        """添加对话交互"""
        self.history.append({
            "question": question,
            "answer": answer,
            "timestamp": time.time()
        })
        
        # 如果历史太长,生成摘要
        if self._estimate_tokens(str(self.history)) > self.max_tokens:
            self._generate_summary()
    
    def _generate_summary(self):
        """生成对话摘要"""
        summary_prompt = f"""
请总结以下对话历史的关键信息:

对话历史:
{self.history}

总结要求:
1. 提取重要的事实、数字、决定
2. 保留用户的重要需求
3. 用简洁的语言概括
4. 不超过200字
"""
        self.summary = llm_client.generate(summary_prompt)
        # 保留最近3轮完整对话
        self.history = self.history[-3:]
    
    def get_context(self) -> str:
        """获取对话上下文"""
        if self.summary:
            context = f"先前对话摘要:{self.summary}\n\n"
        else:
            context = ""
        
        # 添加最近对话
        for i, interaction in enumerate(self.history[-3:]):
            context += f"Q{i+1}: {interaction['question']}\n"
            context += f"A{i+1}: {interaction['answer'][:100]}...\n\n"
        
        return context

7.4 性能优化实践

批量处理:对于可以批量执行的任务,减少LLM调用次数

def batch_process_questions(questions: list, executor, batch_size=5):
    """批量处理问题"""
    results = []
    
    for i in range(0, len(questions), batch_size):
        batch = questions[i:i+batch_size]
        
        # 为批量问题生成统一计划
        batch_prompt = f"""
请为以下问题制定执行计划:
{chr(10).join(batch)}

要求:
1. 识别可以合并的工具调用
2. 规划最优执行顺序
3. 考虑数据依赖性
"""
        
        plan = llm_client.generate(batch_prompt)
        batch_result = executor.execute_batch(plan)
        results.extend(batch_result)
    
    return results

缓存优化:对常见查询结果进行缓存

from functools import lru_cache
import pickle
import hashlib

class SmartCache:
    def __init__(self, cache_dir=".react_cache"):
        self.cache_dir = cache_dir
        os.makedirs(cache_dir, exist_ok=True)
    
    def get_cache_key(self, prompt: str, tools: list) -> str:
        """生成缓存键"""
        content = prompt + "|" + "|".join(sorted(tools))
        return hashlib.sha256(content.encode()).hexdigest()
    
    def get(self, key: str):
        """获取缓存"""
        cache_file = os.path.join(self.cache_dir, key)
        if os.path.exists(cache_file):
            with open(cache_file, 'rb') as f:
                return pickle.load(f)
        return None
    
    def set(self, key: str, value):
        """设置缓存"""
        cache_file = os.path.join(self.cache_dir, key)
        with open(cache_file, 'wb') as f:
            pickle.dump(value, f)

# 使用缓存
cache = SmartCache()

def cached_react_execute(question: str, tools: list, executor):
    """带缓存的执行"""
    cache_key = cache.get_cache_key(question, tools)
    cached_result = cache.get(cache_key)
    
    if cached_result:
        logger.info(f"缓存命中: {cache_key[:10]}...")
        return cached_result
    
    # 执行并缓存
    result = executor.execute(question)
    cache.set(cache_key, result)
    
    return result

8. 未来展望与进阶思考

虽然ReAct框架已经相当强大,但在实际应用中仍然有提升空间。最近我在几个项目中尝试了一些进阶的改进方向,效果还不错。

8.1 动态工具发现与加载

传统的ReAct需要预先定义所有工具,但在实际系统中,工具可能是动态变化的。我实现了一个工具发现机制:

class DynamicToolRegistry:
    def __init__(self):
        self.tools = {}
        self.tool_descriptions = {}
    
    def discover_tools(self, base_path: str):
        """自动发现并加载工具"""
        for file in os.listdir(base_path):
            if file.endswith('_tool.py'):
                module_name = file[:-3]
                module = importlib.import_module(f"tools.{module_name}")
                
                # 查找所有工具函数
                for attr_name in dir(module):
                    attr = getattr(module, attr_name)
                    if callable(attr) and hasattr(attr, 'tool_metadata'):
                        metadata = attr.tool_metadata
                        self.register(
                            name=metadata['name'],
                            func=attr,
                            description=metadata['description']
                        )
    
    def register(self, name: str, func: callable, description: str):
        """注册工具"""
        self.tools[name] = func
        self.tool_descriptions[name] = description
    
    def get_tool_description_prompt(self) -> str:
        """生成工具描述Prompt"""
        descriptions = []
        for name, desc in self.tool_descriptions.items():
            descriptions.append(f"- {name}: {desc}")
        return "\n".join(descriptions)

# 工具装饰器,用于自动注册
def tool(name: str, description: str):
    def decorator(func):
        func.tool_metadata = {
            'name': name,
            'description': description
        }
        return func
    return decorator

# 使用示例
@tool(name="weather", description="获取天气信息,参数:城市名")
def get_weather_tool(city: str) -> str:
    return f"{city}的天气是..."

8.2 多智能体协作

对于复杂任务,单个智能体可能不够。我尝试了多智能体协作的方案:

class MultiAgentSystem:
    def __init__(self):
        self.agents = {
            'planner': ReActAgent(specialty='任务规划'),
            'researcher': ReActAgent(specialty='信息收集'),
            'analyst': ReActAgent(specialty='数据分析'),
            'writer': ReActAgent(specialty='报告生成')
        }
        self.coordinator = ReActAgent(specialty='协调调度')
    
    def solve_complex_task(self, task: str) -> str:
        """多智能体协作解决复杂任务"""
        # 1. 规划阶段
        plan = self.agents['planner'].execute(
            f"请为以下任务制定执行计划:{task}"
        )
        
        # 2. 分配子任务
        subtasks = self._parse_plan(plan)
        results = {}
        
        for subtask in subtasks:
            # 根据任务类型分配给不同的智能体
            agent_type = self._assign_agent(subtask['type'])
            result = self.agents[agent_type].execute(subtask['content'])
            results[subtask['id']] = result
        
        # 3. 整合结果
        final_result = self.agents['writer'].execute(
            f"请基于以下结果生成最终报告:{json.dumps(results)}"
        )
        
        return final_result
    
    def _assign_agent(self, task_type: str) -> str:
        """根据任务类型分配智能体"""
        mapping = {
            'research': 'researcher',
            'analysis': 'analyst',
            'calculation': 'analyst',
            'writing': 'writer'
        }
        return mapping.get(task_type, 'researcher')

8.3 自我优化与学习

让智能体从执行历史中学习:

class LearningReActAgent(ReActExecutor):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.learning_db = {}  # 存储成功案例
        self.failure_db = {}   # 存储失败案例
    
    def learn_from_execution(self, task: str, result: dict):
        """从执行结果中学习"""
        if result['status'] == 'success':
            # 记录成功案例
            key = self._generate_task_key(task)
            self.learning_db[key] = {
                'task': task,
                'solution': result['history'],
                'timestamp': time.time()
            }
            
            # 如果类似任务多次成功,可以优化Prompt
            similar_tasks = self._find_similar_tasks(task)
            if len(similar_tasks) > 3:
                self._optimize_prompt_for_task_type(task)
        
        else:
            # 分析失败原因
            key = self._generate_task_key(task)
            self.failure_db[key] = {
                'task': task,
                'error': result.get('error'),
                'history': result['history'],
                'timestamp': time.time()
            }
    
    def _optimize_prompt_for_task_type(self, task: str):
        """为特定任务类型优化Prompt"""
        # 分析成功案例的共同模式
        successful_patterns = self._extract_patterns(task)
        
        # 更新Prompt,添加针对性的指导
        optimized_section = f"""
对于类似"{task[:50]}..."的任务,建议:
1. {successful_patterns[0]}
2. {successful_patterns[1]}
3. {successful_patterns[2]}
"""
        
        # 将优化内容添加到Prompt中
        self.system_prompt += f"\n\n{optimized_section}"

8.4 实时工具能力感知

让智能体能够动态了解工具的状态和能力:

class ToolCapabilityAwareAgent(ReActExecutor):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.tool_status = {}
        self.update_tool_status()
    
    def update_tool_status(self):
        """更新工具状态"""
        for tool_name, tool_func in self.tools.items():
            # 检查工具是否可用
            status = self._check_tool_availability(tool_func)
            self.tool_status[tool_name] = status
            
            # 获取工具的能力描述
            capability = self._get_tool_capability(tool_func)
            self.tool_capabilities[tool_name] = capability
    
    def _check_tool_availability(self, tool_func) -> dict:
        """检查工具可用性"""
        try:
            # 尝试调用工具的测试方法或检查连接
            if hasattr(tool_func, 'test_connection'):
                result = tool_func.test_connection()
                return {'available': result, 'latency': 0}
            else:
                # 简单ping测试
                start_time = time.time()
                # 这里可以添加具体的测试逻辑
                return {'available': True, 'latency': time.time() - start_time}
        except Exception as e:
            return {'available': False, 'error': str(e)}
    
    def get_enhanced_prompt(self) -> str:
        """获取增强的Prompt,包含工具状态"""
        base_prompt = super().get_prompt()
        
        # 添加工具状态信息
        status_section = "## 工具当前状态\n"
        for tool_name, status in self.tool_status.items():
            availability = "✅ 可用" if status['available'] else "❌ 不可用"
            if 'latency' in status:
                status_section += f"- {tool_name}: {availability} (延迟: {status['latency']:.2f}s)\n"
            else:
                status_section += f"- {tool_name}: {availability}\n"
        
        return base_prompt + "\n\n" + status_section

这些进阶功能让ReAct智能体更加智能和健壮。在实际项目中,我从简单的ReAct实现开始,然后逐步添加这些功能,每次迭代都能看到明显的效果提升。

最后想说的是,ReAct框架最大的价值在于它提供了一种可解释的、可控的方式让大模型与现实世界交互。不像有些黑箱方案,你永远不知道模型为什么做出某个决定。ReAct的每一步思考都是透明的,这对于企业级应用来说至关重要——当智能体给出一个商业建议时,你需要知道它是基于什么数据、通过什么推理得出的。

我在电商数据分析项目上线后,最常听到的反馈不是“准确率提高了多少”,而是“现在我知道它为什么这么想了”。这种可解释性带来的信任感,是很多其他方案无法提供的。当然,ReAct也不是银弹,它增加了复杂性和延迟,但对于需要可靠性、可解释性的场景,它确实是目前最好的选择之一。

【Agent】ReAct:最经典的Agent设计框架 在早期的大语言模型(LLM)应用中,提示工程(Prompt Engineering)是连接用户意图与模型输出的核心手段。然而,纯提示驱动的方案在多步推理、工具调用和动态环境交互中常显不足。 阅读详情

相关推荐

LangChain实战(十一):Agents - 让LLM自主使用工具

本文介绍了LangChain中的Agents(代理)功能,让大语言模型能够自主选择和使用工具。文章涵盖核心概念(LLM大脑、工具集、代理类型)、ReAct决策框架,以及如何配置环境和使用内置工具(计算器、搜索引擎等)。通过不同代理类型的对比(如ZERO_SHOT_REACT和对话型CONVERSATIONAL_REACT),展示了构建智能应用的灵活性。最后以"智能研究助手"实战案例,演示了如何集成多工具实现复杂查询功能。该技术突破了预定义工作流限制,使AI系统具备自主决策能力。

厚积薄发的博客 1065

ReAct框架解析:让大语言模型学会思考与行动

在人工智能领域,大语言模型(LLM)通过理解和生成自然语言,展现了强大的认知能力。然而,传统模型在解决复杂、动态问题时,常因缺乏实时信息获取和精确计算能力而受限。其核心原理在于,通过“思考-行动-观察”的循环机制,将模型的内部推理与外部工具调用相结合,从而扩展了单一模型的能力边界。这种协同设计不仅提升了答案的准确性和事实依据,还使推理过程透明化,便于调试和优化。在工程实践中,ReAct框架通过模块化的智能体引擎、可扩展的工具生态系统和精心的提示词工程,为开发者构建能够自动使用工具完成复杂任务的AI应用提供了

weixin_33747129的博客 1139

ReAct框架:大语言模型智能体的推理与行动核心实现

在人工智能领域,智能体(Agent)是一种能够感知环境、进行决策并执行行动以实现目标的系统。其核心原理在于将推理(Reasoning)与行动(Acting)相结合,使模型不仅能处理信息,还能通过调用外部工具与环境交互。这一技术价值在于突破了传统大语言模型(LLM)仅能进行文本生成的局限,赋予了模型解决复杂、多步骤现实任务的能力。其应用场景广泛,从自动化客服、数据分析到智能助手和工作流自动化,都离不开智能体的核心范式。本文聚焦的ReAct(Reasoning + Acting)框架,正是实现这一范式的经典方法

weixin_30635053的博客 589

ReAct框架详解:如何让大语言模型学会自主调用工具完成任务?

本文深入解析了ReAct框架,这是一种引导大语言模型通过“推理-行动-观察”循环自主调用工具完成任务的方法论。文章详细阐述了其核心的Thought-Action-Observation循环机制,并通过一个从零构建的实战案例,展示了如何利用该框架打造具备自主推理与行动能力的智能体(Agent),从而让大语言模型从“聊天”走向“实干”。

l3m4n的博客 904

一文详解ReAct Agent:让AI学会思考与行动的下一代智能体框架

ReAct框架突破传统LLM局限,实现推理与行动的协同闭环。该框架通过"思考→行动→观察"循环模拟人类决策过程,有效解决幻觉问题并支持复杂任务分解。文章详细解析了ReAct的架构设计、技术优势,并基于LangChain提供完整实现示例,展示如何构建具备搜索和计算能力的智能体。同时探讨了ReAct在科研、网络安全等领域的创新应用及优化策略,展望其向自主智能方向的发展潜力。ReAct代表LLM从内容生成向决策智能的跨越,为构建真正智能的AI系统提供了可行路径。

女王の专属领地 9061

12.8 LangChain Agent 的灵魂:ReAct 框架理论与实战解析

在《实战 LangChain 版 Auto-GPT》中,我们将结合 ReAct 与长期记忆系统,打造能够自主完成复杂目标的智能体。:LangChain Agent、ReAct 框架、大模型推理与执行、自主智能体、LLM 工具调用、AutoGPT 原理。本节将深入剖析 ReAct 的设计哲学,并通过代码实战展示其在 LangChain 中的落地应用。:某商品原价 200 元,先涨价 20%,再降价 25%,最终价格是多少?ReAct 框架将大模型的推理能力与程序化工具结合,打开了。动作: 调用工具执行。

yonggeit的博客 3295

重塑智能体决策路径:深入理解 ReAct 框架

ReAct(Reason + Act)框架由 Google Research 于 2022 年提出,是一种面向大型语言模型智能体的思维与行动协同架构。让语言模型在完成复杂任务时,不仅输出答案,还能显式地产生中间推理过程(Thought)和相应动作(Action),并基于环境反馈继续思考。结论内容✅ ReAct 优点可解释性强、适合人机交互、推理链清晰、Prompt 架构简单易复用✅ ART 优点工具调用更智能、对复杂任务处理能力更强、支持训练调度策略、可扩展性高⚠️ 结合可能性。

hello! 2747

ReAct框架解析:让大语言模型实现链式推理与工具调用

在人工智能领域,大语言模型(LLM)通过思维链(Chain-of-Thought)技术显著提升了复杂推理能力,但其核心局限在于无法与外部环境交互。为解决这一问题,ReAct(Reasoning + Acting)框架应运而生,它将推理与行动结合,形成“思考-行动-观察”的闭环机制。这一技术突破的核心价值在于使模型不仅能进行逻辑推演,还能调用外部工具执行具体操作,从而将AI从纯文本生成升级为可执行任务的智能体。在工程实践中,ReAct框架通过清晰的模块化设计——分离智能体、工具集与执行引擎——实现了灵活扩展与

weixin_33730836的博客 458

ReAct Agent框架的基础理论

ReAct Agent是用于提示大语言模型的框架,不同于前端的React框架,它是众多主流Agent开发架构变种的基础。该框架于2022年10月在论文《ReAct: Synergizing Reasoning and Acting in Language Models》中首次引入,并在2023年3月修订。其核心作用是协同大语言模型的推理和行动能力,使模型更强大、通用且可解释,让智能体在产生想法和执行特定任务的行动之间动态交替。相关参考网站ReAct官网。

qq_43588095的博客 1822

解决nfs挂载根文件系统报错:VFS: Unable to mount root fs via NFS, trying floppy.

解决nfs挂载根文件系统报错的问题:VFS: Unable to mount root fs via NFS, trying floppy.

汉尼拔勇闯天涯 4577

告别命令行恐惧!用TBtools的MCScanX插件,5分钟搞定拟南芥和水稻的基因组共线性分析

本文介绍如何利用TBtools的MCScanX插件快速完成拟南芥和水稻的基因组共线性分析,无需命令行操作,5分钟即可生成专业可视化结果。通过图形化界面简化传统MCScanX的复杂流程,特别适合非生物信息背景的研究者,显著提升基因组数据分析效率。

dianzhuique8587的博客 377

12LangChain实战课 - ReAct框架与代理的应用

ReAct框架是一种指导大语言模型(LLMs)进行推理和行动的思维框架,它通过协同推理(Reasoning)和行动(Acting)来解决任务。推理阶段包括对环境的观察和生成推理轨迹,而行动阶段则涉及到与外部源的交互和收集信息。

Y2483490891的博客 1122

2024年五大革新图像分割模型解析:架构创新与实战应用指南

本文深入解析2024年五大革新图像分割模型,包括SAM2、Mask2Former、DINOv2和Swin Transformer等,探讨其架构创新与实战应用。从多尺度处理、提示交互到自监督学习,这些模型在精度提升、效率优化和交互增强方面取得突破,广泛应用于医疗影像、工业质检和智慧城市等领域。

hadoop5ranger的博客 894

用 ReAct 框架打造一个具备实时搜索能力的 AI Agent(基于通义千问)

通过 结合推理(Reasoning)与行动(Acting),AI 可以在回答问题前先分析是否需要查询最新信息,再通过工具获取外部数据,最后整合结果给出回答。然而,LLM 受限于其训练数据的时效性,无法获取最新信息。ReAct(Reasoning + Acting)是一种让 AI 既能思考(Reasoning)又能执行任务(Acting)的方法。这样,AI 具备了类似人类的思考 + 搜索 + 总结能力,而不是单纯依赖静态训练数据。这样,AI 就能像人类一样,先分析问题,再利用工具,最终给出准确答案。

qq605982691的博客 1338

软件测试面试题汇总

软件测试面试题汇总 测试技术面试题 ........................................................................................................................................................................ 5 1、什么是兼容

晴天的专栏 2万+

温度实时检测预警系统(STC89C51RC+DS18B20)

温度实时检测预警系统

1 兴趣 2 实践 1499

ReAct框架:让大语言模型学会思考与行动交互的智能体构建指南

在人工智能领域,大语言模型(LLM)通过预训练掌握了海量知识,但其传统工作模式是“输入-输出”的单次生成,面对需要动态获取外部信息或执行多步骤推理的复杂任务时,往往力不从心,甚至产生“幻觉”。为解决这一核心挑战,一种结合“推理”与“行动”的范式应运而生,其核心原理是引导模型进行结构化思考,并调用外部工具执行具体操作,形成“思考-行动-观察”的迭代循环。这种模式的技术价值在于,它极大地扩展了LLM的能力边界,使其不再受限于静态知识,能够主动探索、验证信息,从而显著提升任务解决的可靠性、事实准确性与可解释性。其

weixin_30619101的博客 677

空间节省算法在Rowhammer防御中的应用与优化

空间节省算法(Space-Saving)是一种高效的流式数据处理算法,主要用于在有限内存条件下实时识别数据流中的高频项。其核心原理是通过维护固定大小的计数器表,动态跟踪最活跃的元素,适用于处理无限数据流场景。该算法在内存安全领域具有重要价值,特别是在Rowhammer攻击防御中,能够有效检测异常高频访问的DRAM行地址。通过结合计数器衰减策略(如DSAC)和混合架构设计,空间节省算法可以在保证低硬件开销的同时,提供高精度的攻击检测能力。这些技术已成功应用于现代DDR5内存控制器,展现出优异的工程实践价值。

weixin_31139479的博客 606

LangChain Agent 实战入门:让大模型学会自主思考与调用工具

Agent 不仅让语言模型具备“推理”与“规划”能力,还能主动调用外部工具(如搜索、计算、数据库等),从而实现真正的“智能体思维”——即模型不仅能理解问题,还能动态决策、调用资源、执行任务、生成结果。本文将通过一个**简化且实用的 Python 示例**,带你从零理解 LangChain Agent 的工作原理与实际应用。

cooldream2009的博客 1143

STK之Commu模块之三仿真卫星通信链路参数计算

考虑上述衰减的影响,可以得到卫星接收机输入端的载波功 [C] = [PT] +[GT] +[GR] -[L] -[L1] -[L2] (

juanhuokang2681的博客 8268

Python爬虫实战:深度解析携程/飞猪酒店评论API与大数据采集

本文详细介绍了如何通过Python爬虫技术获取携程和飞猪平台的酒店评论数据。我们涵盖了从API分析、反爬虫对策到数据存储和处理的完整流程。API逆向分析:通过浏览器开发者工具发现和分析API接口反爬虫对策:使用请求头随机化、IP代理、浏览器自动化等技术异步处理:使用asyncio提高爬取效率数据质量:实现数据清洗和质量检查机制系统架构:构建可扩展的分布式爬虫系统未来改进方向:机器学习识别验证码分布式爬虫架构实时数据流处理更智能的反反爬虫策略。

2201_76125261的博客 602

【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动

ReAct框架作为AI Agent领域的重要突破,正在推动整个人工智能行业向更加智能、自主的方向发展。更强的推理能力:随着大语言模型的不断进步,ReAct Agent的推理能力将更加接近人类水平更丰富的工具生态:越来越多的专业工具将被集成到ReAct框架中,形成强大的工具生态系统更好的用户体验:通过优化交互设计和响应速度,ReAct Agent将提供更加流畅的用户体验更广泛的应用场景:从简单的问答到复杂的决策支持,ReAct将在更多领域发挥重要作用。

python12345_的博客 504

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

ReAct框架实战指南:构建会思考、能行动的大语言模型智能体

在人工智能应用开发领域,大语言模型(LLM)的推理与执行能力是核心挑战。传统提示工程方法常面临模型幻觉和无法调用外部工具等局限。为解决这些问题,ReAct(Reasoning-Acting)框架应运而生,它通过“思考-行动-观察”的循环机制,将思维链推理与外部工具调用相结合,实现了从静态文本生成到动态问题解决的范式跃迁。这一技术显著提升了AI在复杂任务中的事实核查与多步骤执行能力,尤其在需要实时信息获取、API调用和数据分析的场景中价值突出。本文以智能体开发为例,深入解析ReAct的原理与实战,涵盖工具设计

weixin_32642109的博客 306

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

提示词工程学习笔记:提示词ReAct框架

ReAct 是一种提示词设计范式,使大语言模型不仅能“思考”,还具备“行动”能力。Thought: 内部语言推理Action: 工具/API调用: 获取反馈,继续推理ReAct 提示可大幅提升模型处理复杂任务的能力,是构建多轮 Agent 的基础。

weixin_45304576的博客 1882

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

LangChain-25 ReAct框架详解:大语言模型推理与行动融合的核心原理与应用场景

ReAct(Reasoning and Acting)框架由普林斯顿大学与谷歌研究院于2022年提出,是大语言模型(LLM)发展中的重要里程碑。该框架通过结合**推理(Reasoning)与行动(Acting)**两大核心机制,使模型不仅能思考,还能执行。ReAct打破了传统文本生成的局限,让LLM能调用API、执行代码、访问数据库或外部工具,实现“思考—行动—观察”闭环交互。动态任务规划:根据中间反馈实时调整决策;多工具协作:可并行调用地图、支付、数据接口等; 高可解释性:每一步推理路径清晰透明。

谢谢你的喜欢 我们一起无限进步 8482

代理(Agents):让LLM学会使用工具,从机械执行到自主决策

自主性:代理能自主规划、执行多步骤任务工具化:通过工具集成,突破了LLM的纯文本限制迭代性:通过思考-行动-观察循环,逐步逼近解决方案可解释性:ReAct格式提供了透明的决策过程实际应用建议从简单工具和明确场景开始,逐步增加复杂度为每个工具编写清晰、具体的描述文档实施严格的迭代限制和错误处理机制在生产环境中添加监控和日志记录LangChain代理框架为你提供了构建智能助手、自动化工作流和复杂问题解决系统的强大基础。随着工具生态的丰富和模型能力的提升,代理将成为连接AI能力与现实世界需求的桥梁。

xiaoyu❅的博客 1837
上一篇: PyTorch Lightning中的Mini-batch优化陷阱:为什么你的模型收敛不稳定?
下一篇: GPT-4、GPT-4O和GPT-4O-mini怎么选?开发者必看的成本与性能对比指南
vim8coder
博客等级 码龄1天 0粉丝 1693原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值