在这里插入图片描述

当大模型只会"瞎聊",ReAct如何让它学会"动手干活"?——从"搜索-思考-行动"的闭环中,看懂AI Agent的底层逻辑,掌握让LLM真正"落地"的核心方法论。


ReAct自动定价Agent
全章总结

核心概念篇

"ReAct范式: 推理+行动的交响"

"CoT思维链的局限"

"为什么需要'动手'而非'动嘴'"

架构设计篇

"搜索工具: 信息获取的触角"

"计算工具: 逻辑落地的基石"

"记忆模块: 上下文的纽带"

"LLM大脑: 决策的中枢"

实战流程篇

"需求解析: 定价任务的拆解"

"工具选择: 何时搜索何时算"

"循环执行: Thought-Action-Observation"

"结果整合: 输出可执行方案"

关键难点篇

"工具描述的精准性"

"错误恢复与重试机制"

"成本控制与效率平衡"

进阶优化篇

"多工具协同策略"

"自我反思与迭代"

"从定价到通用框架"

落地应用篇

"电商动态定价场景"

"金融风控定价场景"

"SaaS产品定价场景"

目录导航

  1. 核心概念篇:ReAct不是"更聪明",而是"更会干"
  2. 架构设计篇:四个模块搭起Agent的骨架
  3. 实战流程篇:一个定价任务的完整生命周期
  4. 关键难点篇:那些让你半夜调试的坑
  5. 进阶优化篇:从"能用"到"好用"的跃迁
  6. 落地应用篇:定价之外的广阔天地

嗨,大家好呀,我是你的老朋友精通代码大仙。接下来我们一起学习 《大模型应用开发_动手做AI_Agent》,震撼你的学习轨迹!


引入:别让大模型成为"纸上谈兵"的高手

“光说不练假把式”——这句老话放在AI领域,简直是为纯LLM应用量身定制的批评。

你有没有这样的经历?对着ChatGPT问"现在iPhone 15 Pro多少钱合适入手",它给你巴拉巴拉分析一通市场趋势、芯片性能、竞品对比,最后来一句"建议您关注官方渠道和电商平台的促销活动"。

听完你想摔键盘:我要的是具体数字!今天!京东!到手价!

这就是传统大模型的尴尬——它像一位学富五车的经济学家,能写论文却不去买菜。而ReAct(Reasoning + Acting)范式的出现,正是为了解决这个"知行分离"的顽疾。

本章我们要聊的自动定价Agent,就是ReAct思想的典型落地场景。定价这件事,既需要实时获取市场数据(搜索),又需要复杂的成本利润计算(计算),还需要根据结果反复调整策略(迭代)。这三板斧,恰恰对应了ReAct的核心能力。

新手最容易犯的错,是以为接个大模型API、写几个prompt就算做了Agent。等真到业务场景里,发现模型要么"幻觉"出不存在的价格,要么算不清简单的毛利率,要么陷入无限循环调同一个接口——这时候才意识到,让LLM"动手"比"动嘴"难十倍

但别担心,走完这一章,你会明白一个完整的ReAct Agent是怎么从0到1长出来的。


一、核心概念篇:ReAct不是"更聪明",而是"更会干"

点题:ReAct到底是什么?

ReAct,全称Reasoning and Acting,是普林斯顿大学在2022年提出的一个范式。它的核心思想简单粗暴:让语言模型交替进行"思考"(Reasoning)和"行动"(Acting)

用一张图看清它和纯CoT(思维链)的区别:

ReAct模式

问题

思考: 我需要先查数据

行动: 调用搜索工具

观察: 得到价格数据

思考: 现在可以计算了

行动: 调用计算工具

观察: 得到利润率

思考: 结果合理,输出

最终答案

纯CoT模式

问题

思考推理

最终答案

看到区别了吗?CoT是一次性"想完"再回答,ReAct是"边想边做、边做边看"。

痛点分析:为什么CoT不够用?

很多新手(包括两年前的我)第一次听说ReAct时,内心OS是:“不就是多调几次API吗?我用CoT也能写个多步骤的prompt啊!”

来,看个真实翻车的案例。

错误做法:纯CoT定价prompt

你是一个定价专家。请为以下产品制定价格:
产品:无线降噪耳机
成本:200元
目标毛利率:30%

请按步骤思考:
1. 调研竞品价格
2. 分析成本结构
3. 计算建议售价
4. 给出定价策略

[模型输出]
竞品价格:根据我的知识,苹果AirPods Pro约1899元,索尼WF-1000XM4约1699元...
建议售价:考虑到品牌溢价空间,建议定价599元,毛利率约66.6%...

发现问题了吗?模型在"假装"调研——它用的是训练数据里的过时价格,可能是一年前的。而成本200元、售价599元,毛利率真的是66.6%吗?(599-200)/200=199.5%,模型连小学数学都算错了!

更隐蔽的问题是:如果业务方突然问"如果成本上涨到250元,定价怎么调",纯CoT方案需要重新跑一遍完整prompt,无法复用之前的调研结果。

解决方案:ReAct的"动手"哲学

ReAct的正确打开方式,是把思考过程显性化、工具调用外部化、观察结果结构化

修正后的ReAct流程

# 伪代码示意
def react_pricing_agent(query):
    context = {"product": "无线降噪耳机", "cost": 200, "target_margin": 0.3}
    
    # 第一轮:思考需要数据
    thought1 = llm.think(f"用户要定价,我需要先查竞品价格。当前已知:{context}")
    # 输出:Thought: 我需要搜索"无线降噪耳机 2024年价格 京东 天猫"
    
    # 第一轮:执行行动
    action1 = "search_tool"
    action_input1 = "无线降噪耳机 2024年价格 京东 天猫"
    observation1 = search_tool.run(action_input1)  # 真实返回:小米499, 华为799, 索尼1299...
    
    # 第二轮:思考如何计算
    thought2 = llm.think(f"竞品区间499-1299,成本200,目标毛利30%。我需要计算...")
    # 输出:Thought: 我应该用定价计算器,输入成本200和毛利30%
    
    # 第二轮:执行计算
    action2 = "calculator_tool"
    action_input2 = {"cost": 200, "target_margin": 0.3}
    observation2 = calculator_tool.run(action_input2)  # 返回:建议售价285.71元
    
    # 第三轮:验证与调整
    thought3 = llm.think("285元低于竞品下限499,可能损害品牌形象。需要重新计算...")
    # 最终调整策略...

三个关键改进:

维度纯CoTReAct
数据时效性依赖训练数据,可能过时实时搜索,数据新鲜
计算准确性模型自算,易出错专用工具,结果可靠
过程可追溯黑盒推理每步Thought/Action可审计
成本可控长prompt一次性消耗按需调用,灵活控制

小结

ReAct的本质不是让模型"更聪明",而是给它装上"手脚"和"眼睛"——手是工具调用能力,脚是循环执行机制,眼睛是观察反馈渠道。记住这个三角:Thought → Action → Observation,这是所有ReAct Agent的DNA。


二、架构设计篇:四个模块搭起Agent的骨架

点题:一个完整ReAct Agent的组成

把ReAct Agent拆开来看,就四个核心模块。它们的关系可以用一张架构图表示:

输入输出

循环控制器

LLM核心大脑

未完成

已完成

Observation

工具层

搜索工具
Serper/Bing/自建爬虫

计算工具
Python exec/专用计算器

记忆工具
向量数据库/Key-Value存储

大语言模型
GPT-4/Claude/Qwen等

ReAct Prompt模板
含工具描述、示例、格式要求

输出解析器
提取Thought/Action/Observation

执行器
调用对应工具

终止判断
是否得到最终答案

用户查询

最终答案

痛点分析:模块拆分的"过度设计"陷阱

新手看到上面这张图,常见反应是:“四个模块?我直接写个200行的脚本也能跑啊!”

确实能跑,但跑不远。我见过最典型的"一锅粥"代码:

错误做法:模块混杂的"面条代码"

def pricing_agent_bad(query):
    # 初始化(应该抽离)
    llm = OpenAI()
    
    # 第一次调用LLM(应该封装)
    response1 = llm.complete(f"分析这个定价需求:{query}")
    
    # 直接在这里写搜索逻辑(应该工具化)
    if "需要搜索" in response1:
        import requests
        headers = {"X-API-KEY": "sk-xxx"}  # 密钥硬编码!
        r = requests.get(f"https://serper.dev/search?q={query}")
        search_result = r.json()
        
        # 直接在这里解析HTML(应该专用工具)
        prices = []
        for item in search_result["organic"]:
            prices.append(extract_price_somehow(item["snippet"]))  # 魔法解析
        
        # 第二次调用LLM,手动拼接(应该标准化Observation格式)
        response2 = llm.complete(f"基于{prices},计算定价...")
        
        # 直接在这里算(应该计算工具)
        import re
        numbers = re.findall(r'\d+', response2)
        final_price = int(numbers[0]) * 1.2  # 魔法数字!
        
        return final_price

这段代码的问题,资深工程师一眼能挑出十个:

  • 密钥硬编码,提交到GitHub就是安全事故
  • 搜索和解析逻辑耦合,换数据源要重写
  • 没有错误处理,API超时直接崩溃
  • LLM调用点分散,无法统一加日志/限流
  • 计算逻辑和模型输出纠缠,难以单元测试

最致命的是:这个"Agent"根本没法扩展。加个记忆功能?改计算规则?支持批量定价?每一项都是灾难级重构。

解决方案:模块化设计的"四件套"

正确的架构应该让每个模块职责单一、接口清晰、可替换可测试

1. LLM核心层:标准化接口

from abc import ABC, abstractmethod
from dataclasses import dataclass

@dataclass
class LLMResponse:
    thought: str      # 推理过程
    action: str       # 工具名,或"finish"
    action_input: dict # 工具参数,或最终答案
    
class BaseLLM(ABC):
    @abstractmethod
    def react_step(self, prompt: str, history: list) -> LLMResponse:
        """单步ReAct推理,返回结构化结果"""
        pass

class GPT4LLM(BaseLLM):
    def react_step(self, prompt, history):
        # 统一的prompt模板、解析逻辑、重试机制
        # 更换模型只需改这一处
        ...

2. 工具层:统一注册与描述

class ToolRegistry:
    def __init__(self):
        self._tools = {}
    
    def register(self, name: str, tool: BaseTool, description: str):
        """每个工具必须提供自然语言描述,供LLM理解何时调用"""
        self._tools[name] = {
            "instance": tool,
            "description": description,  # 关键:LLM靠这个选工具
            "parameters": tool.get_schema()  # JSON Schema约束
        }
    
    def get_prompt_description(self) -> str:
        """生成给LLM看的工具说明书"""
        docs = []
        for name, info in self._tools.items():
            docs.append(f"Tool: {name}\nDescription: {info['description']}\nParameters: {info['parameters']}")
        return "\n\n".join(docs)

# 注册示例
registry = ToolRegistry()
registry.register(
    "product_search",
    ProductSearchTool(api_key=settings.SERPER_KEY),  # 配置集中管理
    description="搜索电商平台上的商品价格信息,当需要了解竞品价格或市场行情时使用"
)
registry.register(
    "margin_calculator", 
    MarginCalculator(),
    description="根据成本和目标利润率计算建议售价,输入需包含cost和target_margin"
)

3. 循环控制器:状态机驱动

class ReActLoop:
    def __init__(self, llm: BaseLLM, tools: ToolRegistry, max_steps=10):
        self.llm = llm
        self.tools = tools
        self.max_steps = max_steps
    
    def run(self, query: str) -> str:
        history = []  # 记录所有Thought-Action-Observation
        
        for step in range(self.max_steps):
            # 组装prompt:系统指令 + 工具说明 + 历史 + 当前问题
            prompt = self._build_prompt(query, history)
            
            # LLM推理
            response = self.llm.react_step(prompt, history)
            
            # 终止条件
            if response.action == "finish":
                return response.action_input["answer"]
            
            # 执行工具
            tool = self.tools.get(response.action)
            observation = tool.run(response.action_input)
            
            # 记录本轮
            history.append({
                "step": step,
                "thought": response.thought,
                "action": response.action,
                "action_input": response.action_input,
                "observation": observation
            })
            
            # 关键:Observation要反馈给下一轮LLM
        
        raise MaxStepExceeded("Agent陷入循环或过于复杂")

4. 记忆模块:超越单轮对话

定价场景常需要"记住"之前查过的数据,避免重复搜索。简单的KV存储就能解决80%问题:

class WorkingMemory:
    """Agent的"草稿纸",跨步骤共享信息"""
    def __init__(self):
        self._facts = {}      # 已确认的事实
        self._cache = {}      # 工具调用缓存
    
    def remember(self, key: str, value: any, confidence: float = 1.0):
        """存储信息,可附加置信度"""
        self._facts[key] = {"value": value, "confidence": confidence}
    
    def recall(self, key: str) -> any:
        """回忆信息,LLM可在Thought中决定用不用"""
        return self._facts.get(key)
    
    def get_context(self) -> str:
        """生成给LLM看的记忆摘要"""
        return "\n".join([f"- {k}: {v['value']}" for k, v in self._facts.items()])

小结

好的架构不是"为了拆分而拆分",而是让每个变化点都有明确的归宿。换模型?改LLM层。换数据源?改工具层。调流程逻辑?改循环层。加业务规则?改prompt模板。 四件套各司其职,Agent才能从demo走向生产。


三、实战流程篇:一个定价任务的完整生命周期

点题:从"我要定价"到"这是方案"的全过程

理论讲完,来看一个真实案例的完整执行trace。假设用户输入:

“给我们新款智能手表定价,成本800元,目标毛利率25%,要对标Apple Watch和华为GT系列”

记忆模块 计算工具 搜索工具 LLM Agent 用户 记忆模块 计算工具 搜索工具 LLM Agent 用户 这里LLM发现矛盾! 定价需求 Step 0: 初始分析 Thought: 需要竞品价格 Action: product_search Input: "Apple Watch 2024价格" 调用搜索 Observation: [SE 1999, S9 2999, Ultra 6499] 存储: apple_watch_prices Step 1: 继续调研 Thought: 还需华为价格 Action: product_search Input: "华为GT4 手表价格" 调用搜索 Observation: [GT4 1488, GT4 Pro 2488] 存储: huawei_gt_prices Step 2: 分析定位 Thought: 竞品区间1488-6499 成本800,毛利25%→售价1066 但1066低于GT4,需重新评估 Step 3: 策略调整 Thought: 建议走性价比路线 Action: margin_calculator Input: {cost:800, target_margin:0.35} 计算35%毛利 Observation: 建议售价1230.77元 Step 4: 最终决策 Thought: 1230元介于GT4和SE之间 定位清晰,可输出 Action: finish 完整定价方案

痛点分析:流程中的"断点"与"乱流"

上面的理想流程,新手实现时常常踩这些坑:

坑1:LLM"不听话",不按要求格式输出

# 期望的输出
Thought: 我需要搜索竞品价格
Action: product_search
Action Input: {"query": "Apple Watch 价格 2024"}

# 实际的输出(常见翻车)
我觉得应该先了解一下市场上Apple Watch卖多少钱, 
还有华为的手表怎么样。我可以用搜索工具查一下。

LLM没有严格遵循格式,解析器直接报错。新手第一反应是"模型不行,换GPT-4",但根本原因是prompt engineering没到位

坑2:工具选择"选择困难症"

Thought: 我现在有了成本800和毛利25%,可以计算了。
Action: product_search  ← 错误!应该调用计算器
Action Input: "800元成本 25%毛利率 售价计算"

LLM明明该用计算器,却调了搜索。原因是工具描述写得像"说明书"而非"决策指南"

坑3:Observation"消化不良"

搜索工具返回了5000字的原始HTML,直接塞进prompt,LLM被淹没在噪声中,下一轮完全跑偏。

坑4:无限循环

Step 5: 搜索"智能手表市场趋势"
Step 6: 搜索"2024年可穿戴设备报告"  
Step 7: 搜索"消费者价格敏感度分析"
...
Step 15: 仍在搜索,从未计算

没有终止判断或最大步数限制,Agent变成"搜索狂魔"。

解决方案:每个环节的"防呆"设计

1. Prompt模板:少即是多,格式先行

REACT_PROMPT_TEMPLATE = """你是一位专业的定价分析师,通过思考-行动-观察的循环完成定价任务。

可用工具:
{tool_descriptions}

严格遵循以下格式,每行必须以指定前缀开头:
Thought: [你的推理过程,说明为什么采取下一步行动]
Action: [工具名称,必须是上面列出的工具之一]
Action Input: [JSON格式的工具参数]

当任务完成时,使用:
Thought: [总结推理]
Action: finish
Action Input: {{"answer": "你的最终定价方案"}}

开始!

任务:{query}
{memory_context}
{history}
Thought:"""  # 强制以Thought开头,引导模型进入正确格式

关键技巧:用stop sequence截断。设置stop=["\nObservation:"],让模型生成到Action Input就停,避免它"脑补"Observation。

2. 工具描述:突出"何时使用"

# 差的描述
search_desc = "搜索工具,可以搜索互联网信息"

# 好的描述  
search_desc = """用于获取实时市场价格信息。
使用时机:当你需要了解竞品当前售价、市场行情、消费者评价时。
不使用时机:当已有足够数据进行计算、或需要数学运算时。
输入:具体搜索关键词,如"Apple Watch Series 9 京东价格 2024年4月"
输出:结构化价格列表,包含商品名、价格、来源平台"""

calc_desc = """用于精确的数学计算,特别是定价公式。
使用时机:当你需要计算毛利率、售价、成本分摊等数值时。
不使用时机:当需要获取外部数据时。
输入:{{"cost": 成本金额, "target_margin": 目标毛利率(如0.25表示25%)}}
输出:{{"suggested_price": 建议售价, "actual_margin": 实际毛利率}}"""

3. Observation后处理:提取关键信息

class ObservationProcessor:
    def process(self, raw_observation: str, tool_name: str) -> str:
        """将原始工具输出压缩为LLM易消化的格式"""
        
        if tool_name == "product_search":
            # 提取结构化价格,丢弃HTML噪声
            prices = self._extract_prices(raw_observation)
            return json.dumps({
                "price_range": f"{min(prices)}-{max(prices)}",
                "median": statistics.median(prices),
                "count": len(prices),
                "examples": prices[:3]  # 只给3个示例
            }, ensure_ascii=False)
        
        elif tool_name == "margin_calculator":
            # 计算结果直接可用
            return raw_observation
        
        return raw_observation[:500]  # 兜底截断

4. 循环控制:多重保险

class LoopController:
    def should_continue(self, history: list) -> tuple[bool, str]:
        """判断是否应该继续循环"""
        
        # 保险1:最大步数
        if len(history) >= self.max_steps:
            return False, "达到最大步数限制"
        
        # 保险2:重复检测
        recent_actions = [h["action"] + str(h["action_input"]) for h in history[-3:]]
        if len(set(recent_actions)) == 1 and len(recent_actions) == 3:
            return False, "检测到重复操作,可能陷入循环"
        
        # 保险3:成本预算
        total_cost = sum(h.get("cost", 0) for h in history)
        if total_cost > self.budget_limit:
            return False, "超出调用成本预算"
        
        # 保险4:任务完成信号
        if history and history[-1]["action"] == "finish":
            return False, "任务已完成"
        
        return True, "继续执行"

小结

实战流程的核心是可控的循环:每一步LLM的决策要受限,工具返回要加工,异常路径要兜底。把ReAct想象成开车——LLM是驾驶员,但要有车道线(格式约束)、导航仪(工具描述)、安全气囊(异常处理),才能安全到达目的地。


四、关键难点篇:那些让你半夜调试的坑

点题:生产环境的"暗礁"

开发环境跑通的Agent,放到真实业务里往往千疮百孔。这一节聚焦三个最隐蔽、最耗时的坑。

难点一:工具描述的"语义鸿沟"

痛点场景

你写了完美的工具代码,LLM却永远不调它。或者更糟——该调A的时候调了B,参数还传得乱七八糟。

真实案例:我曾有个price_predictor工具,用机器学习模型预测最优价格。但LLM总是优先调简单的margin_calculator,因为后者的描述里有"计算"这个关键词,而前者说的是"预测"。

# 导致混淆的描述
tools = {
    "margin_calculator": "根据成本和目标利润率计算售价",
    "price_predictor": "基于历史数据预测最优价格"  # LLM:预测?我不需要预测,我要计算!
}

解决方案:描述即接口设计

工具描述不是文档,是LLM的调用决策依据。要站在LLM的角度写:

# 重写的描述
tools = {
    "margin_calculator": {
        "description": "简单定价公式:售价 = 成本 / (1 - 毛利率)。适用于成本导向定价,不考虑市场竞争。",
        "when_to_use": "当你只需要快速验证一个毛利率对应的售价时",
        "when_not_to_use": "当你需要考虑竞品价格、品牌定位、市场需求等复杂因素时"
    },
    "price_predictor": {
        "description": "智能定价引擎:综合考虑成本、竞品价格、品牌指数、季节性因素,输出最优售价区间。",
        "when_to_use": "当你需要制定面向市场的最终售价,而非仅验证数学公式时",
        "when_not_to_use": "当你只需要简单的成本加成计算时(会浪费计算资源)"
    }
}

更进一步的技巧:给工具起好名字simple_calculator vs advanced_pricing_engine,LLM从名字就能get到层级关系。

难点二:错误恢复与"韧性"

痛点场景

搜索API超时了怎么办?计算工具返回负数价格怎么办?LLM生成的JSON格式错误怎么办?

新手代码往往是" happy path only ":

# 脆弱的代码
observation = search_tool.run(action_input)  # 一旦抛异常,整个Agent崩溃
next_thought = llm.think(f"观察结果:{observation}")  # observation可能是None

解决方案:分层容错架构

渲染错误: Mermaid 渲染失败: Parse error on line 5: ...回错误Observation
"搜索服务暂时不可用"] D -- -----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'STR'

代码实现:

class ResilientToolExecutor:
    def __init__(self):
        self.retry_policy = RetryPolicy(max_attempts=3, backoff_factor=2)
    
    def execute(self, tool: BaseTool, action_input: dict) -> Observation:
        # 第一层:网络容错
        try:
            with self.retry_policy:
                raw_result = tool.run(action_input)
        except NetworkError as e:
            return Observation(
                status="error",
                type="network",
                message=f"服务暂时不可用,请稍后重试或换用其他工具。详情:{e}",
                data=None
            )
        
        # 第二层:业务校验
        validation = tool.validate(raw_result)
        if not validation.ok:
            return Observation(
                status="error", 
                type="business",
                message=f"工具返回结果异常:{validation.error}",
                data={"raw": raw_result, "suggestion": validation.fix_hint}
            )
        
        # 第三层:数据后处理
        processed = tool.process(raw_result)
        return Observation(status="success", data=processed)

# LLM看到错误Observation后的处理
def handle_error_observation(obs: Observation, history: list) -> LLMResponse:
    error_prompt = f"""
    上一步操作遇到错误:
    类型:{obs.type}
    信息:{obs.message}
    
    请决定:
    1. 如果可修复,生成修复后的Action
    2. 如果不可修复,生成替代方案或优雅降级的说明
    3. 如果完全无法继续,使用finish返回当前已知信息
    """
    return llm.react_step(error_prompt, history)

难点三:成本控制与效率平衡

痛点场景

ReAct Agent的调用链可能很长:LLM生成Thought → 调搜索(付费)→ LLM再生成 → 调计算 → LLM总结… 一个简单的定价任务,成本可能飙到几毛钱,吞吐量还低。

解决方案:成本意识的架构设计

策略实现方式效果
缓存复用相同搜索词的结果缓存1小时减少60%搜索调用
模型分级简单步骤用GPT-3.5,关键决策用GPT-4成本降低70%
预计算常见品类价格每日批量更新,不走实时搜索响应速度提升10倍
提前终止设置confidence阈值,高置信时提前finish减少30%步骤
异步化非关键数据预加载,不阻塞主流程延迟降低50%
class CostAwareAgent:
    def __init__(self):
        self.cache = RedisCache()
        self.model_router = ModelRouter()  # 根据任务复杂度选模型
        
    async def run(self, query: str) -> Result:
        # 检查缓存
        cache_key = self._hash_query(query)
        if cached := await self.cache.get(cache_key):
            return Result.from_cache(cached)
        
        # 选择模型:简单查询用轻量模型
        complexity = self._estimate_complexity(query)
        llm = self.model_router.select(complexity)
        
        # 执行循环,带成本追踪
        cost_tracker = CostTracker(budget=0.1)  # 单任务预算10美分
        
        while not cost_tracker.exceeded():
            step_cost = await self._step(llm, ...)
            cost_tracker.add(step_cost)
            
            if self._confidence_high_enough(history):
                break  # 提前终止
        
        # 缓存结果
        await self.cache.set(cache_key, result, ttl=3600)
        return result

小结

生产级的ReAct Agent,20%的代码在实现功能,80%的代码在处理异常。工具描述要当"用户界面"来设计,错误处理要当"免疫系统"来建设,成本控制要当"运营指标"来监控。这三关过了,Agent才能从"玩具"变成"工具"。


五、进阶优化篇:从"能用"到"好用"的跃迁

点题:让Agent具备"自我进化"能力

基础ReAct跑通后,还有很大的优化空间。这一节介绍三个进阶方向:多工具协同、自我反思、框架通用化。

优化一:多工具协同的"编排艺术"

复杂定价场景需要工具组合。比如:

“给新款耳机定价,要参考竞品价格、预测未来3个月销量、计算不同售价下的利润”

这需要搜索 + 预测模型 + 计算工具的流水线。

串行依赖

结果合并

并行执行

搜索: 竞品A价格

搜索: 竞品B价格

搜索: 市场趋势

价格聚合
趋势分析

销量预测模型
依赖: 价格区间+趋势

利润计算
依赖: 预测销量+成本

实现关键:依赖图(DAG)调度

from typing import Set

class ToolDependency:
    def __init__(self):
        self.graph = {}  # tool_name -> {deps: Set[str], ready: bool}
    
    def can_execute(self, tool_name: str, completed: Set[str]) -> bool:
        return self.graph[tool_name]["deps"].issubset(completed)
    
    def get_parallel_ready(self, completed: Set[str]) -> list:
        """返回当前可并行执行的所有工具"""
        return [
            name for name, info in self.graph.items()
            if not info["ready"] and self.can_execute(name, completed)
        ]

# LLM生成执行计划后,由调度器优化执行顺序
class ParallelExecutor:
    async def execute_plan(self, plan: ExecutionPlan) -> dict:
        completed = set()
        results = {}
        
        while len(completed) < len(plan.tools):
            ready = plan.get_parallel_ready(completed)
            
            # 并行执行所有就绪工具
            tasks = [self.run_tool(t) for t in ready]
            batch_results = await asyncio.gather(*tasks)
            
            for tool_name, result in zip(ready, batch_results):
                results[tool_name] = result
                completed.add(tool_name)
                plan.mark_ready(tool_name)
        
        return results

优化二:自我反思与迭代

让Agent在失败后能"复盘"改进。ReAct原论文就提到了这种扩展。

class SelfReflectiveAgent:
    def run_with_reflection(self, query: str, max_attempts=3) -> Result:
        for attempt in range(max_attempts):
            # 正常执行
            result = self.react_loop.run(query)
            
            if result.success:
                return result
            
            # 失败时:生成反思
            reflection = self.llm.generate(
                f"""任务执行失败。
                原始查询:{query}
                执行历史:{result.history}
                失败原因:{result.error}
                
                请分析:
                1. 失败的根本原因是什么?
                2. 如果重新执行,应该调整哪些策略?
                3. 是否需要更换工具或调整参数?
                
                输出改进建议:"""
            )
            
            # 用反思优化下一轮
            query = self._augment_query(query, reflection)
        
        return result  # 最终尝试结果

更强大的变体:Reflexion框架,让Agent维护一个"经验记忆库",长期积累成功/失败模式。

优化三:从定价到通用ReAct框架

把定价Agent抽象为可配置框架:

@dataclass
class AgentConfig:
    tools: List[ToolConfig]
    prompt_template: str
    max_steps: int = 10
    reflection_enabled: bool = False
    parallel_execution: bool = False

class ReActFramework:
    """通用ReAct引擎,通过配置适应不同场景"""
    
    def from_config(cls, config: AgentConfig) -> "ReActAgent":
        tools = ToolRegistry()
        for t in config.tools:
            tools.register(t.name, t.instance, t.description)
        
        llm = LLMFactory.create(config.llm_model)
        loop = ReActLoop(llm, tools, config.max_steps)
        
        if config.reflection_enabled:
            loop = SelfReflectiveWrapper(loop)
        
        if config.parallel_execution:
            loop = ParallelExecutorWrapper(loop)
        
        return ReActAgent(loop, config.prompt_template)

# 使用:定价场景
pricing_agent = ReActFramework.from_config(
    AgentConfig(
        tools=[search_tool, calculator_tool, predictor_tool],
        prompt_template=PRICING_PROMPT,
        reflection_enabled=True
    )
)

# 使用:客服场景(完全不同工具,同一框架)
service_agent = ReActFramework.from_config(
    AgentConfig(
        tools=[knowledge_base_tool, ticket_tool, escalation_tool],
        prompt_template=SERVICE_PROMPT
    )
)

小结

进阶优化的本质是分离"控制逻辑"和"业务逻辑"。多工具协同解决"效率"问题,自我反思解决"质量"问题,框架抽象解决"复用"问题。这三板斧下来,你的Agent就从"定制脚本"进化成"可配置平台"。


六、落地应用篇:定价之外的广阔天地

点题:ReAct思想的迁移价值

本章以定价为例,但ReAct的适用范围远不止于此。理解其核心模式后,可以快速迁移到多种业务场景。

场景一:智能客服(多轮交互+知识检索)

用户:我的订单为什么还没发货?
Agent Thought: 需要查询订单状态,但缺少订单号
Agent Action: ask_user_for_info
Observation: 用户提供了订单号 #12345

Agent Thought: 现在可以查询物流系统
Agent Action: query_order_status
Observation: 订单已打包,等待揽收,预计明天发出

Agent Thought: 需要解释当前状态并安抚用户
Agent Action: finish
Answer: 您的订单#12345已完成打包,正在等待快递公司揽收,预计明天发出...

与定价的区别:多轮对话状态管理更复杂,需要维护用户意图和槽位填充

场景二:代码助手(分析+执行+验证)

用户:帮我优化这个SQL查询
Agent Thought: 需要先分析现有SQL的执行计划
Agent Action: explain_sql
Observation: 全表扫描,未使用索引

Agent Thought: 建议添加索引,但需要确认表结构
Agent Action: describe_table
Observation: 表结构,字段类型...

Agent Thought: 可以给出优化建议了
Agent Action: finish
Answer: 建议在xxx字段添加索引,改写后的SQL为...

与定价的区别:需要代码执行环境(沙箱),安全风险更高

场景三:科研辅助(文献检索+数据分析)

用户:总结近五年关于Transformer效率优化的研究
Agent Thought: 需要分年份检索文献
Agent Action: search_papers
Action Input: {"query": "Transformer efficiency optimization", "year": 2020}
...(多轮检索)

Agent Thought: 现在需要分析这些论文的方法分类
Agent Action: analyze_methods
Observation: 方法分布:量化35%,剪枝28%,稀疏注意力22%...

Agent Thought: 可以生成综述了
Agent Action: finish

与定价的区别:处理非结构化文本,需要更强的摘要和归纳能力

场景对比总结

场景核心工具特殊挑战ReAct变体
自动定价搜索、计算、预测实时性、准确性基础ReAct
智能客服KB检索、工单系统、转人工多轮状态、情感识别ReAct + 对话状态跟踪
代码助手代码分析、执行沙箱、测试安全、环境隔离ReAct + 代码专用模型
科研辅助文献库、数据分析、可视化长文本处理、知识整合ReAct + 长上下文优化
医疗诊断症状库、检验指标、知识图谱合规、可解释性ReAct + 约束推理

小结

ReAct是一种元能力——让LLM与外部世界交互的通用模式。定价只是它的练兵场,真正掌握后,你可以用它构建各种"会思考、能动手"的AI应用。关键不是记住代码,而是内化"推理-行动-观察"的循环逻辑


写在最后

走到这里,你已经完整经历了ReAct自动定价Agent从概念到落地的全过程。我们聊了范式本质、架构设计、实战流程、生产难点、进阶优化、场景迁移——这六个维度,构成了AI Agent开发的完整知识图谱。

我想坦诚地说:做Agent开发,没有"银弹"。ReAct很棒,但它不是万能的。有些场景更适合Plan-and-Solve(先规划再执行),有些需要Multi-Agent协作,还有些简单的任务用Prompt Chain就够了。理解 trade-off,比死记硬背模式更重要

但ReAct确实是一个极佳的起点。它足够简单,几小时就能跑通demo;又足够深刻,生产中的大部分问题都能在这个框架下找到答案。更重要的是,它培养了一种思维方式:不要把LLM当黑盒神谕,而要把它当作一个需要配备工具、需要反馈循环、需要错误处理的智能组件

编程之路不易,但每一步成长都算数。从"调API"到"搭Agent",你正在跨越的,是AI应用开发的关键分水岭。保持好奇,持续动手,你也能成为那个让大模型真正"落地"的人。

下次见,我是精通代码大仙,咱们下章继续!


关注私信备注:“资料代找获取”,全网计算机学习资料代找:例如:
《课程:2026 年多模态大模型实战训练营》
《课程:AI 大模型工程师系统课程 (22 章完整版 持续更新)》
《课程:AI 大模型系统实战课第四期 (2026 年开课 持续更新)》
《课程:2026 年 AGI 大模型系统课 23 期》
《课程:2026 年 AGI 大模型系统课 21 期》
《课程:AI 大模型实战课 8 期 (2026 年 2 月最新完结版)》
《课程:AI 大模型系统实战课三期》
《课程:AI 大模型系统课程 (2026 年 2 月开课 持续更新)》
《课程:AI 大模型全阶课程 (2025 年 12 月开课 2026 年 6 月结课)》
《课程:AI 大模型工程师全阶课程 (2025 年 10 月开课 2026 年 4 月结课)》
《课程:2026 年最新大模型 Agent 开发系统课 (持续更新)》
《课程:LLM 多模态视觉大模型系统课》
《课程:大模型 AI 应用开发企业级项目实战课 (2026 年 1 月开课)》
《课程:大模型智能体线上速成班 V2.0》
《课程:Java+AI 大模型智能应用开发全阶课》
《课程:Python+AI 大模型实战视频教程》
《书籍:软件工程 3.0: 大模型驱动的研发新范式.pdf》
《课程:人工智能大模型系统课 (2026 年 1 月底完结版)》
《课程:AI 大模型零基础到商业实战全栈课第五期》
《课程:Vue3.5+Electron + 大模型跨平台 AI 桌面聊天应用实战 (2025)》
《课程:AI 大模型实战训练营 从入门到实战轻松上手》
《课程:2026 年 AI 大模型 RAG 与 Agent 智能体项目实战开发课》
《课程:大模型训练营配套补充资料》

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐