LLM推理时计算技术详解:四种提升大模型推理能力的方法

简介: 2025年LLM发展新趋势:不卷训练,专攻推理!本文详解四大推理时计算技术——Chain-of-Thought(深度)、Self-Consistency(宽度)、Tree-of-Thoughts(搜索)、Reflexion/Self-Refine(迭代),配可运行代码与实战对比,助你在不重训模型前提下显著提升性能。

2025年LLM领域有个有意思的趋势:与其继续卷模型训练,不如在推理阶段多花点功夫。这就是所谓的推理时计算(Test-Time / Inference-Time Compute):在推理阶段投入更多计算资源,包括更多Token、更多尝试、更深入的搜索,但不会改动模型权重。

ARC-AGI基准测试就是个典型案例。通过推理时技术可以达到87.5%的准确率,但代价是每个任务超过1000美元的推理成本。没用这些技术的LLM通常只能拿到不到25%。

本文要讲四种主流的推理时计算技术:深度方向的Chain-of-Thought,宽度方向的Self-Consistency,搜索方向的Tree-of-Thoughts,以及迭代方向的Reflexion/Self-Refine。

预备知识:LLM调用封装

先把基础设施搭好。下面是通用的LLM调用接口和辅助函数:

 fromcollectionsimportCounter, deque
importre

# ---- LLM调用封装 ----
defllm(prompt: str, temperature: float=0.7, max_tokens: int=800) ->str:
    """
    LLM调用的占位函数。
    在实际使用中,可以替换为OpenAI、Claude或本地模型的API调用。

    参数:
        prompt: 输入提示词
        temperature: 采样温度,控制输出多样性
        max_tokens: 最大生成token数

    返回:
        模型生成的文本
    """
    # 示例:使用OpenAI API
    # from openai import OpenAI
    # client = OpenAI()
    # response = client.chat.completions.create(
    #     model="gpt-4",
    #     messages=[{"role": "user", "content": prompt}],
    #     temperature=temperature,
    #     max_tokens=max_tokens
    # )
    # return response.choices[0].message.content

    raiseNotImplementedError("请实现你的LLM调用逻辑")

# ---- 辅助函数:提取最终答案 ----
defextract_final_answer(text: str) ->str:
    """
    从模型输出中提取最终答案。

    寻找格式为 "FINAL: <答案>" 或 "Final: <答案>" 的模式。
    在实际应用中,建议:
    - 让模型输出JSON格式,如 {"final": "..."}
    - 或使用针对具体任务的解析逻辑

    参数:
        text: 模型的完整输出文本

    返回:
        提取的最终答案(最多200字符)
    """
    m=re.search(r"(FINAL|Final)\s*[:\-]\s*(.*)", text)
     return (m.group(2).strip() ifmelsetext.strip())[:200]

深度(Depth):链式思维推理

Chain-of-Thought(CoT)是最基础也用得最多的推理时技术。核心思想很直白:让模型「思考」久一点。

传统调用方式期望模型直接给答案,但复杂问题不是这么解决的。CoT让模型生成详细的中间推理步骤,在数学、逻辑推理、编程这些任务上效果很明显。

为什么管用?首先是分解作用,大问题拆成小步骤,每一步更容易做对。其次是中间步骤充当了一种「外部记忆」,帮模型追踪推理过程。第三是强制模型展示推理,减少直接「猜」答案的情况。最后,模型推理过程中可以自查前面步骤对不对。

触发CoT有几种常见办法:零样本提示就是加一句「Let's think step by step」;少样本提示是给2-3个带推理步骤的例子;指令微调是用带CoT标注的数据集训练;系统提示则是在system message里定义推理风格。

 defsolve_with_cot(question: str) ->str:
    """
    使用链式思维(Chain-of-Thought)解决问题。

    通过精心设计的提示词,引导模型:
    1. 进行逐步推理
    2. 展示中间计算过程
    3. 最后给出明确的最终答案

    参数:
        question: 需要解答的问题

    返回:
        包含推理过程和最终答案的完整响应
    """
    prompt=f"""You are a careful reasoner. Your task is to solve the following problem.

Instructions:
1. Break down the problem into smaller steps
2. Show your reasoning for each step
3. Double-check your calculations
4. End with a clear final answer

Format your response as:
Step 1: [your first step]
Step 2: [your second step]
...
FINAL: <your final answer>

Question: {question}
"""
    # 使用较低的temperature以获得更确定性的输出
    returnllm(prompt, temperature=0.2, max_tokens=900)

# 使用示例
if__name__=="__main__":
    question="一个农场有鸡和兔,共35个头和94只脚。请问有多少只鸡和多少只兔?"
    result=solve_with_cot(question)
    print(result)
     print("\n提取的最终答案:", extract_final_answer(result))

CoT适合数学应用题、逻辑推理、代码调试、规划任务这类需要多步计算的问题。简单事实问答用CoT有点浪费,创意写作也不太合适——过度结构化会限制发挥。

局限性也很明显。Token消耗会上升,输出越长成本越高。模型可能在推理链中犯错,错误还会传播。输出格式也不总是稳定,需要后处理。

宽度(Width):自洽性采样

Self-Consistency的想法很简单:与其相信单次输出,不如生成多个答案,选最一致的那个。

有点像集体决策——单条推理链可能出错,但如果多条独立路径都指向同一答案,那答案八成是对的。

这方法管用的原因:单次采样可能因为随机性出错,多次采样能平均掉这些错误。正确答案往往能通过多条不同路径得到。不同路径可能捕捉问题的不同侧面。答案的一致性程度还顺便反映了模型的「信心」。

做Self-Consistency有几个关键决策要做。

第一是采样多样性。这点至关重要。如果所有采样都走同一条推理路径,自洽性就没意义了。高多样性设置是temperature 0.7-0.9、top_p 0.9-0.95,加上多样的提示词变体。temperature太低或提示词太固定都不行。

第二是采样数量。3-5个边际收益最高,适合成本敏感场景;10-20个是常规配置;40个以上适合对准确率要求极高的场景,但边际收益已经很低了。

第三是聚合策略。最常用的是多数投票,选出现次数最多的答案。也可以加权投票,根据置信度加权。还可以把相似答案聚类后再投票。

 defsolve_with_self_consistency(
    question: str, 
    n: int=10,
    temperature: float=0.8
) ->dict:
    """
    使用自洽性(Self-Consistency)方法解决问题。

    通过高温度采样生成多个多样化的答案,
    然后通过多数投票选择最一致的答案。

    参数:
        question: 需要解答的问题
        n: 采样数量,建议10-20
        temperature: 采样温度,建议0.7-0.9以确保多样性

    返回:
        包含以下键的字典:
        - final: 最终答案(得票最多的)
        - votes: 该答案的得票数
        - confidence: 置信度(得票数/总数)
        - all_finals: 所有提取的答案列表
        - vote_distribution: 完整的投票分布
        - samples: 所有原始输出(用于调试)
    """
    prompt_template="""Solve this problem step by step. 
Show your reasoning, then end with 'FINAL: ...'

Question: {question}"""

    samples= []
    foriinrange(n):
        out=llm(
            prompt_template.format(question=question),
            temperature=temperature,  # 高温度确保多样性
            max_tokens=900
        )
        samples.append(out)

    # 提取所有最终答案
    finals= [extract_final_answer(s) forsinsamples]

    # 统计投票
    vote_counter=Counter(finals)
    most_common=vote_counter.most_common()
    winner=most_common[0]

    return {
        "final": winner[0],
        "votes": winner[1],
        "confidence": winner[1] /n,
        "all_finals": finals,
        "vote_distribution": dict(vote_counter),
        "samples": samples
    }

defsolve_with_weighted_consistency(
    question: str,
    n: int=10,
    score_fn=None
) ->dict:
    """
    带权重的自洽性方法。

    除了多数投票外,还可以根据每个答案的质量分数加权。

    参数:
        question: 需要解答的问题
        n: 采样数量
        score_fn: 评分函数,接受(question, answer)返回0-1的分数

    返回:
        包含加权投票结果的字典
    """
    samples= []
    for_inrange(n):
        out=llm(
            f"Solve step by step. End with 'FINAL: ...'\n\nQ: {question}",
            temperature=0.8,
            max_tokens=900
        )
        samples.append(out)

    finals= [extract_final_answer(s) forsinsamples]

    # 加权投票
    weighted_votes= {}
    forfinal, sampleinzip(finals, samples):
        weight=score_fn(question, sample) ifscore_fnelse1.0
        weighted_votes[final] =weighted_votes.get(final, 0) +weight

    winner=max(weighted_votes.items(), key=lambdax: x[1])

    return {
        "final": winner[0],
        "weighted_score": winner[1],
        "weighted_distribution": weighted_votes,
        "all_finals": finals
    }

# 使用示例
if__name__=="__main__":
    question="如果今天是星期三,那么100天后是星期几?"
    result=solve_with_self_consistency(question, n=10)

    print(f"最终答案: {result['final']}")
    print(f"得票数: {result['votes']}/{len(result['all_finals'])}")
    print(f"置信度: {result['confidence']:.1%}")
     print(f"投票分布: {result['vote_distribution']}")

Self-Consistency适合有确定答案的问题(数学、编程、事实问答)、答案空间有限的问题(选择题、是/否问题)、以及生产环境中需要高可靠性的场景。开放式问题答案空间太大,每次答案都不同,投票没意义。创意任务没有「正确」答案可投票,也不适用。

局限性:成本线性增长,N次采样就是N倍成本。如果模型系统性地偏向某个错误答案,投票也救不了。同一答案的不同表述可能被当作不同答案,答案标准化是个麻烦事。

搜索(Search):思维树探索

Tree-of-Thoughts(ToT)把推理过程当成搜索问题来做。每个节点是一个「思维状态」,也就是部分推理结果;每条边是一个「思维步骤」,即推理动作;目标是找到通向正确答案的路径。

跟线性的CoT不同,ToT允许分支(从一个状态探索多个可能的下一步)、回溯(放弃没希望的分支,回到之前的状态)、评估(判断当前状态离目标有多近)。

为什么有效?线性推理一旦犯错就没法恢复,ToT可以回溯。某些问题天然是树形结构,比如博弈、规划。通过评估函数引导搜索,避免盲目探索。只深入探索有希望的分支,Token利用率更高。

搜索策略有几种选择。BFS广度优先,逐层探索,不会错过浅层解但内存消耗大。DFS深度优先,一条路走到底,内存效率高但可能陷入死胡同。Beam Search每层保留top-k状态,平衡效率和覆盖,但可能丢失最优解。A*用启发式函数引导,最优且高效,但需要好的启发函数。MCTS蒙特卡洛树搜索能处理大搜索空间,但需要大量模拟。

 deftot_bfs(
    question: str, 
    max_depth: int=4, 
    beam: int=3, 
    branch: int=4,
    external_evaluator=None
) ->dict:
    """
    使用BFS策略的思维树(Tree-of-Thoughts)方法。

    工作流程:
    1. 从空状态开始
    2. 对当前frontier中的每个状态,生成多个可能的下一步
    3. 评估所有新状态
    4. 保留得分最高的beam个状态作为新frontier
    5. 重复直到达到最大深度
    6. 从最佳状态生成最终答案

    参数:
        question: 需要解答的问题
        max_depth: 最大搜索深度
        beam: 每层保留的状态数(beam width)
        branch: 每个状态扩展的分支数
        external_evaluator: 外部评估函数(可选),
                           接受(question, state)返回分数

    返回:
        包含以下键的字典:
        - final_text: 最终答案
        - best_state: 最佳推理状态
        - best_score: 最佳状态的分数
        - search_tree: 搜索过程的记录(用于可视化)
    """

    defpropose_next_steps(state: str) ->list:
        """
        给定当前推理状态,生成多个可能的下一步。
        """
        prompt=f"""You are exploring different ways to solve a problem.

Question: {question}

Current reasoning state:
{stateifstateelse"(Starting from scratch)"}

Propose {branch} different possible next steps to continue the reasoning.
Each step should be a distinct approach or calculation.
Return as a numbered list:
1. [first possible step]
2. [second possible step]
...
"""
        raw=llm(prompt, temperature=0.9, max_tokens=400)

        # 解析编号列表
        steps= []
        forlineinraw.splitlines():
            line=line.strip()
            iflineandline[0].isdigit():
                # 移除编号前缀
                step=line.split(".", 1)[-1].strip()
                ifstep:
                    steps.append(step)

        returnsteps[:branch] ifstepselse [raw.strip()]

    defllm_score_state(state: str) ->float:
        """
        使用LLM评估一个推理状态的promising程度。

        注意:在实际应用中,使用外部评估器(如单元测试、规则检查)
        通常比LLM自我评估更可靠。
        """
        ifexternal_evaluator:
            returnexternal_evaluator(question, state)

        prompt=f"""Evaluate how promising this partial solution is.

Question: {question}

Current reasoning state:
{state}

Consider:
1. Is the reasoning logical and correct so far?
2. Is it making progress toward a solution?
3. Are there obvious errors or dead ends?

Rate from 0 to 10 (10 = very promising, likely to lead to correct answer).
Output only a number.
"""
        s=llm(prompt, temperature=0.0, max_tokens=10).strip()
        try:
            returnfloat(re.findall(r"\d+(\.\d+)?", s)[0])
        except:
            return5.0  # 默认中等分数

    # 初始化
    frontier= [""]  # 初始状态为空
    best_state=""
    best_score=-1.0
    search_tree= []  # 记录搜索过程

    fordepthinrange(max_depth):
        candidates= []
        depth_record= {"depth": depth, "states": []}

        forstateinfrontier:
            next_steps=propose_next_steps(state)

            forstepinnext_steps:
                # 构建新状态
                new_state= (state+"\n"+step).strip()

                # 评估新状态
                score=llm_score_state(new_state)
                candidates.append((score, new_state))

                depth_record["states"].append({
                    "state": new_state[:200] +"..."iflen(new_state) >200elsenew_state,
                    "score": score
                })

        search_tree.append(depth_record)

        # 排序并保留top-k
        candidates.sort(reverse=True, key=lambdax: x[0])
        frontier= [sfor_, sincandidates[:beam]]

        # 更新最佳状态
        ifcandidatesandcandidates[0][0] >best_score:
            best_score, best_state=candidates[0]

    # 从最佳状态生成最终答案
    final_prompt=f"""Based on the reasoning below, produce the final answer.

Question: {question}

Reasoning:
{best_state}

Provide a clear, concise final answer.
End with: FINAL: <your answer>
"""
    final=llm(final_prompt, temperature=0.2, max_tokens=400)

    return {
        "final_text": final,
        "final_answer": extract_final_answer(final),
        "best_state": best_state,
        "best_score": best_score,
        "search_tree": search_tree
    }

deftot_dfs(
    question: str,
    max_depth: int=5,
    branch: int=3,
    threshold: float=3.0
) ->dict:
    """
    使用DFS策略的思维树方法。

    通过深度优先搜索探索解决方案空间,
    当某个分支的分数低于阈值时进行剪枝。

    参数:
        question: 需要解答的问题
        max_depth: 最大搜索深度
        branch: 每个状态扩展的分支数
        threshold: 剪枝阈值,分数低于此值的分支被放弃

    返回:
        包含最终答案和搜索路径的字典
    """
    best_result= {"state": "", "score": -1.0}
    visited_count= [0]  # 使用列表以便在嵌套函数中修改

    defpropose_steps(state: str) ->list:
        prompt=f"""Propose {branch} next reasoning steps.

Question: {question}
Current state:
{stateifstateelse"(empty)"}

Return as numbered list."""
        raw=llm(prompt, temperature=0.9, max_tokens=300)
        steps= [l.split(".", 1)[-1].strip() 
                 forlinraw.splitlines() 
                 ifl.strip()[:1].isdigit()]
        returnsteps[:branch] ifstepselse [raw.strip()]

    defscore_state(state: str) ->float:
        prompt=f"""Rate this partial solution 0-10.
Question: {question}
State: {state}
Output only a number."""
        s=llm(prompt, temperature=0.0, max_tokens=10).strip()
        try:
            returnfloat(re.findall(r"\d+(\.\d+)?", s)[0])
        except:
            return5.0

    defdfs(state: str, depth: int):
        visited_count[0] +=1

        ifdepth>=max_depth:
            score=score_state(state)
            ifscore>best_result["score"]:
                best_result["state"] =state
                best_result["score"] =score
            return

        forstepinpropose_steps(state):
            new_state= (state+"\n"+step).strip()
            score=score_state(new_state)

            # 剪枝:跳过低分分支
            ifscore<threshold:
                continue

            ifscore>best_result["score"]:
                best_result["state"] =new_state
                best_result["score"] =score

            dfs(new_state, depth+1)

    dfs("", 0)

    # 生成最终答案
    final=llm(
        f"""Produce final answer based on:
Question: {question}
Reasoning: {best_result['state']}
End with FINAL: ...""",
        temperature=0.2
    )

    return {
        "final_text": final,
        "final_answer": extract_final_answer(final),
        "best_state": best_result["state"],
        "best_score": best_result["score"],
        "states_visited": visited_count[0]
    }

# 使用示例
if__name__=="__main__":
    question="使用数字1, 5, 6, 7(每个只能用一次),通过加减乘除得到24。"

    result=tot_bfs(question, max_depth=3, beam=2, branch=3)

    print("=== BFS Tree-of-Thoughts ===")
    print(f"最佳推理路径:\n{result['best_state']}")
    print(f"\n最佳分数: {result['best_score']}")
     print(f"\n最终答案: {result['final_answer']}")

ToT适合组合问题(24点游戏、数独)、规划任务、博弈问题(象棋、围棋)、头脑风暴这类需要探索不同方向的场景。答案空间极大时可能需要配合启发式剪枝。简单问题用不着——直接CoT就够了。

局限性:计算成本高昂,需要大量LLM调用来评估和扩展节点。LLM自评估不太可靠,评估函数质量直接决定效果。实现复杂度比其他几种方法高不少。还有些问题压根没有明显的树形结构,ToT就不太适用。

迭代(Iteration):反思与自我改进

Reflexion和Self-Refine用的是经典的「生成-评估-改进」循环:模型先产生初始答案,拿到反馈后修正答案,如此反复直到满意或达到最大轮数。

人类学习不也是这样吗?很少有事情一次就做对,总是通过反馈不断改进。

但有个重要的坑要注意:没有可靠外部反馈的「自我纠正」可能适得其反。

研究表明,模型仅靠自己判断来「自我纠正」时,可能把正确答案改成错误答案,可能对错误判断过度自信,可能在无效修改上浪费Token。

所以最佳实践是尽量用外部反馈源。代码执行(单元测试、错误信息)和规则检查(格式验证、约束检查)最可靠。工具调用(计算器、搜索引擎)和人类反馈也不错。另一个LLM做交叉验证勉强能用。同一个LLM自评效果最差,缺乏外部参照。

 defself_refine(
    question: str, 
    score_fn, 
    rounds: int=3,
    improvement_threshold: float=0.1
) ->dict:
    """
    使用自我改进(Self-Refine)方法迭代优化答案。

    核心流程:生成 -> 评估 -> 根据反馈改进 -> 重复

    参数:
        question: 需要解答的问题
        score_fn: 评估函数,签名为:
                  score_fn(answer_text) -> (score: float, feedback: str)
                  - score: 0.0-1.0之间的分数
                  - feedback: 具体的改进建议
                  强烈建议使用外部评估器!
        rounds: 最大改进轮数
        improvement_threshold: 最小改进阈值,低于此值则提前停止

    返回:
        包含以下键的字典:
        - final: 最终答案
        - final_score: 最终分数
        - history: 完整的改进历史
        - rounds_used: 实际使用的轮数
    """
    # 生成初始答案
    initial_prompt=f"""Provide a thoughtful answer to this question.
Show your reasoning and end with FINAL: ...

Question: {question}
"""
    answer=llm(initial_prompt, temperature=0.4)
    history= []
    prev_score=-float('inf')

    forround_numinrange(rounds):
        # 评估当前答案
        score, feedback=score_fn(answer)

        history.append({
            "round": round_num+1,
            "answer": answer,
            "score": score,
            "feedback": feedback
        })

        # 检查是否有足够的改进
        ifround_num>0and (score-prev_score) <improvement_threshold:
            # 如果改进不明显,考虑提前停止
            ifscore>=prev_score:
                pass  # 继续,至少没有退步
            else:
                # 退步了,恢复上一个答案
                answer=history[-2]["answer"]
                score=history[-2]["score"]
                break

        # 如果分数已经很高,提前停止
        ifscore>=0.95:
            break

        prev_score=score

        # 根据反馈改进答案
        refine_prompt=f"""Improve your answer based on the feedback below.

Question: {question}

Your current answer:
{answer}

Feedback (score: {score:.2f}/1.00):
{feedback}

Instructions:
1. Keep what is correct in your current answer
2. Fix the issues mentioned in the feedback
3. Make sure not to introduce new errors
4. End with FINAL: ...

Improved answer:
"""
        answer=llm(refine_prompt, temperature=0.3)

    # 最终评估
    final_score, final_feedback=score_fn(answer)

    return {
        "final": answer,
        "final_answer": extract_final_answer(answer),
        "final_score": final_score,
        "history": history,
        "rounds_used": len(history)
    }

# ---- 示例评估函数 ----

defmake_code_evaluator(test_cases: list):
    """
    创建一个代码评估函数。

    参数:
        test_cases: 测试用例列表,每个元素是(input, expected_output)

    返回:
        评估函数
    """
    defevaluator(code_answer: str) ->tuple:
        # 提取代码块
        code_match=re.search(r"```python\n(.*?)```", code_answer, re.DOTALL)
        ifnotcode_match:
            return0.0, "No Python code block found. Please wrap your code in ```python ... ```"

        code=code_match.group(1)

        passed=0
        failed_cases= []

        forinp, expectedintest_cases:
            try:
                # 危险:实际应用中应使用沙箱!
                local_vars= {}
                exec(code, {"__builtins__": {}}, local_vars)

                # 假设代码定义了solve函数
                if'solve'inlocal_vars:
                    result=local_vars['solve'](inp)
                    ifresult==expected:
                        passed+=1
                    else:
                        failed_cases.append(f"Input: {inp}, Expected: {expected}, Got: {result}")
                else:
                    return0.0, "No 'solve' function found in your code."

            exceptExceptionase:
                failed_cases.append(f"Input: {inp}, Error: {str(e)}")

        score=passed/len(test_cases)

        iffailed_cases:
            feedback="Failed test cases:\n"+"\n".join(failed_cases[:3])  # 最多显示3个
            iflen(failed_cases) >3:
                feedback+=f"\n... and {len(failed_cases) -3} more failures"
        else:
            feedback="All test cases passed!"

        returnscore, feedback

    returnevaluator

defmake_math_evaluator(correct_answer):
    """
    创建一个数学答案评估函数。

    参数:
        correct_answer: 正确答案

    返回:
        评估函数
    """
    defevaluator(answer_text: str) ->tuple:
        extracted=extract_final_answer(answer_text)

        # 尝试数值比较
        try:
            extracted_num=float(re.findall(r"-?\d+\.?\d*", extracted)[0])
            correct_num=float(correct_answer)

            ifabs(extracted_num-correct_num) <0.01:
                return1.0, "Correct!"
            else:
                return0.0, f"Incorrect. Your answer: {extracted_num}, Expected: {correct_num}"
        except:
            pass

        # 字符串比较
        ifextracted.lower().strip() ==str(correct_answer).lower().strip():
            return1.0, "Correct!"
        else:
            return0.0, f"Incorrect. Your answer: {extracted}, Expected: {correct_answer}"

    returnevaluator

defmake_llm_evaluator(criteria: str):
    """
    创建一个基于LLM的评估函数(不推荐作为唯一评估源)。

    参数:
        criteria: 评估标准描述

    返回:
        评估函数
    """
    defevaluator(answer_text: str) ->tuple:
        prompt=f"""Evaluate this answer based on the following criteria:

Criteria: {criteria}

Answer to evaluate:
{answer_text}

Provide:
1. A score from 0.0 to 1.0
2. Specific feedback on what's wrong and how to improve

Format:
SCORE: [number]
FEEDBACK: [your feedback]
"""
        response=llm(prompt, temperature=0.0)

        try:
            score=float(re.search(r"SCORE:\s*([\d.]+)", response).group(1))
            score=min(1.0, max(0.0, score))
        except:
            score=0.5

        try:
            feedback=re.search(r"FEEDBACK:\s*(.+)", response, re.DOTALL).group(1).strip()
        except:
            feedback=response

        returnscore, feedback

    returnevaluator

# 使用示例
if__name__=="__main__":
    # 示例1:代码任务
    question="编写一个函数solve(n),返回n的阶乘。"
    test_cases= [
        (0, 1),
        (1, 1),
        (5, 120),
        (10, 3628800)
    ]

    result=self_refine(
        question=question,
        score_fn=make_code_evaluator(test_cases),
        rounds=3
    )

    print("=== Self-Refine for Code ===")
    print(f"最终分数: {result['final_score']:.2%}")
    print(f"使用轮数: {result['rounds_used']}")
    print(f"\n改进历史:")
    forhinresult['history']:
        print(f"  Round {h['round']}: score={h['score']:.2f}")

    # 示例2:数学任务
    question="计算 17 * 23 + 45 - 12"
    correct=17*23+45-12

    result=self_refine(
        question=question,
        score_fn=make_math_evaluator(correct),
        rounds=2
    )

    print("\n=== Self-Refine for Math ===")
    print(f"最终答案: {result['final_answer']}")
    print(f"正确答案: {correct}")
     print(f"最终分数: {result['final_score']:.2%}")

Self-Refine适合代码生成(有单元测试作为外部反馈)、格式化任务(有明确规范可检查)、约束满足问题(可验证约束是否满足)、事实核查(可通过检索验证)。主观任务需要人类反馈或多模型交叉验证。没有反馈来源时别用——纯LLM自评不靠谱。

局限性:反馈质量决定上限,垃圾反馈只会导致垃圾改进。模型有时候会在不同版本之间来回「改」,出现震荡。每轮迭代都消耗Token,成本会累积。也无法保证收敛——模型可能根本没法利用反馈真正改进。


技术对比与选择指南

四种技术各有特点。CoT思考更深,Token消耗低,LLM只调用一次,实现简单,不需要外部反馈,适合推理链问题。Self-Consistency采样更广,Token消耗中等,LLM调用N次,实现也简单,不需要外部反馈,适合有确定答案的问题。ToT探索更多,Token消耗高,LLM调用次数是分支数乘以深度,实现复杂,外部反馈可选但推荐,适合组合和规划问题。Self-Refine改进更好,Token消耗中等,LLM调用次数是轮数乘以2,实现复杂度中等,强烈推荐外部反馈,适合可迭代改进的问题。

选择思路如下,需要分步推理就先试CoT,不稳定的话加上Self-Consistency。有确定答案且需要可靠性,直接用Self-Consistency。组合或搜索问题用ToT。有外部反馈源就用Self-Refine。不确定用什么就先用CoT,看效果再定。

这些技术可以组合使用。CoT加SC是每次采样都用CoT然后多数投票。ToT加SC是ToT生成多个最终答案用SC选择。ToT加SR是用SR迭代改进ToT的最佳结果。复杂任务可能需要把多种技术串成流水线。

 defcombined_approach(question: str, score_fn) ->str:
    """
    组合使用多种推理时技术。

    流程:
    1. 用ToT探索解决方案空间
    2. 用Self-Consistency从多个ToT结果中选择
    3. 用Self-Refine迭代改进最终答案
    """
    # 第一阶段:ToT探索(运行3次)
    tot_results= []
    for_inrange(3):
        result=tot_bfs(question, max_depth=3, beam=2, branch=3)
        tot_results.append(result['final_answer'])

    # 第二阶段:Self-Consistency选择
    vote=Counter(tot_results).most_common(1)[0][0]

    # 第三阶段:Self-Refine改进
    final_result=self_refine(
        question=question,
        score_fn=score_fn,
        rounds=2
    )

     returnfinal_result['final_answer']

实践建议

别一上来就用最复杂的技术。推荐的顺序是:先直接提问作为baseline,然后加CoT提示,再加Self-Consistency,最后才考虑ToT或Self-Refine。

对于Self-Refine和ToT,评估器质量直接决定效果。花时间构建好的评估器比调参更重要。

推理时技术能大幅提升性能,但成本也会大幅增加。建议设置Token预算上限,记录每个任务的实际消耗,根据任务重要性调整投入。

部署到生产环境前做A/B测试,找到最佳的性能/成本权衡点。

总结

推理时计算技术代表了LLM能力释放的新范式。在推理阶段多投入一些计算,同一个模型不重新训练就能有明显提升。本文介绍的四种技术——CoT、Self-Consistency、Tree-of-Thoughts、Self-Refine——各有特点和适用场景。理解原理和局限性,选择合适的技术或组合,是LLM应用开发的关键技能。

随着这一领域的发展,会有更多创新的推理时技术出现。但核心原则不会变:给模型更多「思考」的空间,让它展示真正的推理能力。

https://avoid.overfit.cn/post/2bb5bb4e569a4687a272dc6e9fe6809a

目录
相关文章
|
10天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
6天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
4418 13
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
|
5天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
3743 10
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
8天前
|
人工智能 JavaScript 应用服务中间件
零门槛部署本地AI助手:Windows系统Moltbot(Clawdbot)保姆级教程
Moltbot(原Clawdbot)是一款功能全面的智能体AI助手,不仅能通过聊天互动响应需求,还具备“动手”和“跑腿”能力——“手”可读写本地文件、执行代码、操控命令行,“脚”能联网搜索、访问网页并分析内容,“大脑”则可接入Qwen、OpenAI等云端API,或利用本地GPU运行模型。本教程专为Windows系统用户打造,从环境搭建到问题排查,详细拆解全流程,即使无技术基础也能顺利部署本地AI助理。
7004 15
|
6天前
|
存储 人工智能 机器人
OpenClaw是什么?阿里云OpenClaw(原Clawdbot/Moltbot)一键部署官方教程参考
OpenClaw是什么?OpenClaw(原Clawdbot/Moltbot)是一款实用的个人AI助理,能够24小时响应指令并执行任务,如处理文件、查询信息、自动化协同等。阿里云推出的OpenClaw一键部署方案,简化了复杂配置流程,用户无需专业技术储备,即可快速在轻量应用服务器上启用该服务,打造专属AI助理。本文将详细拆解部署全流程、进阶功能配置及常见问题解决方案,确保不改变原意且无营销表述。
4569 4
|
4天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
2526 5
|
8天前
|
人工智能 JavaScript API
零门槛部署本地 AI 助手:Clawdbot/Meltbot 部署深度保姆级教程
Clawdbot(Moltbot)是一款智能体AI助手,具备“手”(读写文件、执行代码)、“脚”(联网搜索、分析网页)和“脑”(接入Qwen/OpenAI等API或本地GPU模型)。本指南详解Windows下从Node.js环境搭建、一键安装到Token配置的全流程,助你快速部署本地AI助理。(239字)
4619 23
|
14天前
|
人工智能 API 开发者
Claude Code 国内保姆级使用指南:实测 GLM-4.7 与 Claude Opus 4.5 全方案解
Claude Code是Anthropic推出的编程AI代理工具。2026年国内开发者可通过配置`ANTHROPIC_BASE_URL`实现本地化接入:①极速平替——用Qwen Code v0.5.0或GLM-4.7,毫秒响应,适合日常编码;②满血原版——经灵芽API中转调用Claude Opus 4.5,胜任复杂架构与深度推理。
8556 13