Skip to content

Latest commit

 

History

History
211 lines (151 loc) · 5.36 KB

File metadata and controls

211 lines (151 loc) · 5.36 KB

LLM 推理策略:ReAct 与多步推理

日期: 2024-12-21 主题: 大语言模型的复杂推理方法


背景

在开发广告合规分析系统时,发现简单的 prompt 难以处理复杂的分析任务。今天学习了两种推理策略:ReAct 和多步推理。


ReAct:思考与行动结合

原理

ReAct 让模型显式记录推理过程,形成完整的思维链:

思考 (Thought) → 行动 (Action) → 结果 (Result) → 循环

实现

def react_reasoning(question: str, context: str) -> str:
    prompt = f"""
    请使用 ReAct 方法逐步思考并回答问题。
    每一步需要:
    1. 思考(Thought): 分析当前情况
    2. 行动(Action): 确定下一步行动
    3. 结果(Result): 记录行动结果

    上下文: {context}
    问题: {question}

    让我们一步步思考:
    """

    response = llm_client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7
    )

    return response.choices[0].message.content

示例输出

思考(Thought 1): 首先需要分析营收增长趋势
行动(Action 1): 计算年度营收增长率
结果(Result 1): 2022年增长50%,2023年增长20%,增长率在放缓

思考(Thought 2): 需要分析利润率变化
行动(Action 2): 计算各年利润率
结果(Result 2): 利润率分别为10%、8%、8.3%,基本稳定

思考(Thought 3): 综合评估风险
行动(Action 3): 对比行业平均水平
结果(Result 3): 增长高于行业平均,利润率接近行业平均

多步推理:分而治之

原理

把复杂问题分解成多个步骤,逐步解决,每步的结果作为下一步的输入。

实现

class MultiStepReasoning:
    def __init__(self, llm_client):
        self.llm_client = llm_client

    async def multi_step_analysis(
        self,
        question: str,
        context: str,
        steps: List[Dict]
    ) -> Dict[str, str]:
        results = {}
        accumulated_context = context

        for step in steps:
            # 构建当前步骤的 prompt
            step_prompt = step["prompt"].format(
                question=question,
                context=accumulated_context
            )

            # 执行推理
            step_result = await self._step_reasoning(step_prompt)

            # 记录结果
            results[step["name"]] = step_result

            # 更新上下文,供下一步使用
            accumulated_context += f"\n{step['name']} 结果:\n{step_result}"

        return results

使用示例

steps = [
    {"name": "trend_analysis", "prompt": "分析营收和利润趋势"},
    {"name": "risk_assessment", "prompt": "基于趋势评估风险因素"},
    {"name": "recommendation", "prompt": "提供投资建议"}
]

results = await reasoner.multi_step_analysis(
    question="评估该公司投资价值",
    context=company_data,
    steps=steps
)

两种方法对比

方面 ReAct 多步推理
适用场景 需要连续思维链 可以明确分解的任务
可控性 较低,模型自主决定 较高,步骤预定义
可解释性 好,过程清晰 好,结构化输出
实现复杂度

混合使用

实际项目中可以结合两种方法:

class BusinessAnalyzer:
    async def analyze_report(self, report: str) -> Dict:
        # 第一阶段:ReAct 分析整体结构
        structure = await self.react_reasoning(
            "分析报告结构和关键要点",
            report
        )

        # 第二阶段:多步推理深入分析
        details = await self.multi_step_analysis(
            "深入分析报告内容",
            structure,
            [
                {"name": "market", "prompt": "分析市场情况"},
                {"name": "financial", "prompt": "分析财务状况"},
                {"name": "strategy", "prompt": "提供战略建议"}
            ]
        )

        return {"structure": structure, "details": details}

最佳实践

1. Prompt 设计

  • 每步给出清晰的指令
  • 包含必要的上下文
  • 明确期望的输出格式

2. 错误处理

def validate_step_result(result: str, expected_format: dict) -> bool:
    try:
        result_json = json.loads(result)
        return all(key in result_json for key in expected_format)
    except json.JSONDecodeError:
        return False

3. 性能优化

  • 独立步骤可以并行执行
  • 实现结果缓存
  • 设置合理的超时和重试

今日反思

今天学习的这两种推理方法,本质上都是在引导 LLM 进行结构化思考。

ReAct 更像"自由探索",让模型自己决定如何推理,适合开放性问题。多步推理更像"流程化处理",步骤预定义好,适合标准化任务。

在广告合规分析场景中,多步推理可能更适合——因为审查规则是固定的,可以把每条规则的检查定义为一个步骤,确保不遗漏。

另一个收获是理解了"上下文积累"的重要性。多步推理之所以有效,是因为每步的结果会加入上下文,后续步骤可以利用前面的分析结果。这种信息积累让复杂分析成为可能。


延伸学习

  • Chain-of-Thought 论文
  • ReAct 论文
  • Tree of Thoughts 方法
  • 提示词工程最佳实践