大部分人只会「用大模型」,但真正有趣的,是让大模型学会用工具做事——这就是智能体(Agent)世界的入口。

手把手写一个本地可跑的 Mini ReAct 智能体,让它学会「自己想一想,然后调用工具帮你算复杂的表达式」。

同时,我们也会顺带把三种经典智能体范式捋清楚:

  • ReAct:边想边干
  • Plan-and-Solve:先规划再执行
  • Reflection:做完再自我批改

如果你是:

  • 会一点 Python
  • 听说过「大模型」「Agent」,但感觉很虚

那这篇就是给你的「入门版实战」 👇


一、从大模型到智能体:三种经典范式长啥样?

先用生活类比来理解三个范式。

1. ReAct:边想边干型同学

遇到一道综合题,他的做法是:

  1. 想一想:「我要不要先查下某个知识点?」
  2. 去翻书 / 上网搜(行动)
  3. 看完结果,再想下一步要干嘛
  4. 如此循环,直到写出答案

对应到智能体世界,就是经典的三段式:

Thought(思考) → Action(行动) → Observation(观察) → … → Finish(最终答案)

每一轮:

  • Thought:模型的内心独白,分析现在要干啥
  • Action:决定用哪个工具、传什么参数
  • Observation:工具返回的结果

2. Plan-and-Solve:先写提纲的同学

他的做题方式是:

  1. 先把整道题拆成「步骤 1、2、3、4…」
  2. 然后按步骤一个个往下算

对应到智能体:

  • 第一阶段:先让模型生成一个完整计划(steps 列表)
  • 第二阶段:再按计划一步步执行

适合那种逻辑特别清晰、可以明显拆解成多步的任务,比如应用题、报告结构设计等。

3. Reflection:写完再自己当老师改作业的同学

流程是:

  1. 先写一版答案
  2. 换个角度「审题」,看看有没有错误/可以优化的地方
  3. 根据自我点评,改出第二版、第三版…

在智能体里,就是:

Execution(执行) → Reflection(反思) → Refinement(优化) 的循环

非常适合:代码生成、论文写作这类对质量要求特别高的任务。


二、为什么先从 ReAct 开始练手?

三种范式里,ReAct 是最贴近「人正常做事方式」的一种

  • 我们本来就是一边观察,一边调整下一步
  • 它天然支持「调用搜索、数据库、计算器等工具」
  • 从工程实现上,难度适中,非常适合作为「第一个手写智能体」

这一篇我们就专注在 ReAct 上:让一个大模型学会用「计算器工具」,自己完成复杂计算,并用中文说出结果。


三、ReAct 的脑回路:Thought → Action → Observation

先用一个简单例子走一遍:

问题: 「请帮我计算 (123 + 456) * 7 / 8 等于多少?再用一句话告诉我结果。」

如果你用 ReAct 的方式做,它的过程可能是这样:

第 1 步:

  • Thought:

    这是一个算式题,我自己算容易出错,最好调用 Calculator 工具来算。

  • Action:

    Calculator[(123 + 456) * 7 / 8]

  • Observation(工具返回):

    结果是: 506.625(举例)

第 2 步:

  • Thought:

    已经有了计算结果,现在可以整理成一句自然语言给用户。

  • Action:

    Finish[计算结果是 506.625。]

整个过程就是:

Thought: 想下一步要干什么Action: 要么用工具 Tool[input],要么 Finish[最终答案]Observation: 工具输出

而我们的代码要做的,其实就是两件事:

  1. 教模型按这个格式说话(提示词)
  2. 读懂它的 Action,帮它真的去调工具(Python 函数)

四、环境准备:给智能体装上「大脑」

这一部分很快带过,重点不在这里。

1. 安装依赖

pip install openai python-dotenv
  • openai:跟大语言模型对话的 SDK
  • python-dotenv:从 .env 文件里读 API key、模型 ID 等配置

2. 配置 .env

在你的项目根目录下新建 .env 文件:

LLM_API_KEY="你的 Key"LLM_MODEL_ID="你的模型名"LLM_BASE_URL="你的模型服务地址"

3. 一个简单的 LLM 客户端 HelloAgentsLLM

你可以按照书里的写法封装一个类,这里用口语概括它要做的事情:

  • 启动时:从 .env 里读模型 ID、API Key、Base URL
  • 提供一个 think(messages, temperature=0) 方法:
  • 入参是 OpenAI 格式的 messages 列表
  • 内部调用 client.chat.completions.create(...)
  • 把模型完整输出拼成字符串返回

只要你有这么一个 HelloAgentsLLM 类,并且 think() 能返回一整段字符串,下面的 Mini ReAct 就能直接用。


五、从 0 写一个 Mini ReAct Agent(本地可跑)

下面是一个精简到不能再精简的 ReAct 示例:

  • 只有一个工具:Calculator
  • 用你自己的 HelloAgentsLLM 做大脑
  • 只实现核心循环:Thought → Action → Observation → Finish

你可以把这段代码保存为 mini_react_local.py

⚠️ 代码略长,但大部分是注释,真正的逻辑非常清晰。

# mini_react_local.py"""一个可以本地跑通的极简 ReAct 示例:- 工具只有一个:Calculator(计算器)- 使用你自己封装的 HelloAgentsLLM 作为大模型客户端"""from typing import Dict, Callable, Listimport math# 从你自己的 llm_client 文件中导入 HelloAgentsLLM# ⚠️ 如果你的文件名不是 llm_client.py,请改掉这一行from llm_client import HelloAgentsLLM# ========== 1. 一个非常简单的“工具箱” ==========def calculator(expression: str) -> str:    """    一个非常简单的计算器工具。    输入:数学表达式字符串,比如 "1 + 2 * 3"    输出:计算结果(字符串)    """    print(f"🧮 [Calculator] 正在计算: {expression}")    try:        # 真实项目中不要直接使用 eval,这里仅作教学用示例        result = eval(expression, {"__builtins__": {}}, {"math": math})        returnf"结果是: {result}"    except Exception as e:        returnf"计算出错: {e}"class SimpleToolBox:    """    极简工具箱:名字 -> 函数 + 描述    """    def __init__(self):        self.tools: Dict[str, Dict[str, Callable]] = {}    def register(self, name: str, description: str, func: Callable):        self.tools[name] = {            "description": description,            "func": func,        }    def get(self, name: str) -> Callable:        return self.tools.get(name, {}).get("func")    def describe(self) -> str:        """        把所有工具整理成一段说明文字,塞给大模型看。        """        lines = []        for name, info in self.tools.items():            lines.append(f"- {name}: {info['description']}")        return"\n".join(lines)# ========== 2. ReAct 提示词模板(极简中文版) ==========REACT_PROMPT_TEMPLATE = """你是一个会“边想边用工具”的智能助理。现在你有这些工具可以用:{tools}请严格按下面格式回答(用中文):Thought: 这里写你的思考过程(一两句话即可)Action: 这里写你接下来要做的事,只能是下面两种之一:1) 调用工具: 工具名[参数]   例如: Calculator[(1 + 2) * 3]2) 直接给出最终答案: Finish[你的最终答案]现在要解决的问题是:Question: {question}下面是之前的行动历史(如果有):History:{history}"""# ========== 3. 极简 ReAct 智能体核心类 ==========class MiniReActAgent:    def __init__(self, llm_client: HelloAgentsLLM, max_steps: int = 5):        """        llm_client: 书里定义的 HelloAgentsLLM 实例        max_steps: 最大循环步数,防止死循环        """        self.llm = llm_client        self.max_steps = max_steps        # 初始化工具箱,只放一个计算器工具        self.toolbox = SimpleToolBox()        self.toolbox.register(            name="Calculator",            description="用于计算数学表达式,例如 1+2*3 或 (123+456)*7/8。",            func=calculator        )        self.history: List[str] = []    def _call_llm(self, question: str) -> str:        """        根据当前 question + history + tools 描述,调用一次大模型。        """        tools_desc = self.toolbox.describe()        history_str = "\n".join(self.history) if self.history else"(目前还没有历史记录)"        prompt = REACT_PROMPT_TEMPLATE.format(            tools=tools_desc,            question=question,            history=history_str        )        messages = [{"role": "user", "content": prompt}]        # 调用你自己的 HelloAgentsLLM.think(它会返回完整字符串)        response_text = self.llm.think(messages=messages, temperature=0)        print("\n🧠 LLM 原始输出:")        print(response_text)        print("-" * 60)        return response_text or""    def _parse_thought_action(self, text: str):        """        从大模型输出中,提取 Thought 和 Action。        为了简单,不用正则,只按行来找以 'Thought:' / 'Action:' 开头的行。        """        thought = None        action = None        for line in text.splitlines():            line = line.strip()            if line.startswith("Thought:"):                thought = line[len("Thought:"):].strip()            elif line.startswith("Action:"):                action = line[len("Action:"):].strip()        return thought, action    def _parse_action_detail(self, action_text: str):        """        把 Action 具体拆开:        比如 "Calculator[(1 + 2) * 3]" ->            工具名: "Calculator"            参数: "(1 + 2) * 3"        特别地:        Finish[...] -> 工具名 "Finish",参数是最终答案        """        ifnot action_text:            returnNone, None        # Finish[...] 单独处理        if action_text.startswith("Finish[") and action_text.endswith("]"):            inner = action_text[len("Finish["):-1].strip()            return"Finish", inner        # 其它格式:ToolName[xxx]        left = action_text.find("[")        right = action_text.rfind("]")        if left == -1or right == -1or right <= left:            returnNone, None        tool_name = action_text[:left].strip()        tool_input = action_text[left + 1:right].strip()        return tool_name, tool_input    def run(self, question: str):        """        对外的主入口:给一个问题,让 ReAct 智能体去解决。        """        self.history = []  # 每次运行前清空历史        for step in range(1, self.max_steps + 1):            print(f"\n===== 第 {step} 步 =====")            # 1. 让大模型根据当前情况,输出 Thought + Action            response_text = self._call_llm(question)            # 2. 解析 Thought 和 Action            thought, action_text = self._parse_thought_action(response_text)            print(f"🧐 Thought(思考): {thought}")            print(f"🎯 Action(行动): {action_text}")            ifnot action_text:                print("⚠️ 没有解析出 Action,结束。")                break            # 3. 进一步解析 Action 细节            tool_name, tool_input = self._parse_action_detail(action_text)            # 3.1 如果是 Finish,直接输出最终答案            if tool_name == "Finish":                print("\n🎉 最终答案:")                print(tool_input)                return tool_input            # 3.2 否则应该是调用工具            tool_func = self.toolbox.get(tool_name)            ifnot tool_func:                observation = f"错误:没有叫 {tool_name} 的工具。"            else:                observation = tool_func(tool_input)            print(f"👀 Observation(观察): {observation}")            # 4. 把这一轮的 Thought / Action / Observation 记入历史            self.history.append(f"Thought: {thought}")            self.history.append(f"Action: {action_text}")            self.history.append(f"Observation: {observation}")        print("\n⏹ 达到最大步数,未能给出最终答案。")        returnNone# ========== 4. 使用示例 ==========if __name__ == "__main__":    # 初始化你的 LLM 客户端(从 .env 读取配置)    llm_client = HelloAgentsLLM()    agent = MiniReActAgent(llm_client)    # 你可以在这里改问题试试    question = "请帮我计算 (123 + 456) * 7 / 8 等于多少?并用一句话告诉我结果。"    agent.run(question)

六、跑起来:ReAct 在终端里长什么样?

当你执行:

python mini_react_local.py

理想情况下,你会在终端看到类似这样的过程(示意):

===== 第 1 步 =====🧠 LLM 原始输出:Thought: 这个问题是一个数学表达式的计算,我可以使用 Calculator 工具来获得准确的结果。Action: Calculator[(123 + 456) * 7 / 8]------------------------------------------------------------🧐 Thought(思考): 这个问题是一个数学表达式的计算,我可以使用 Calculator 工具来获得准确的结果。🎯 Action(行动): Calculator[(123 + 456) * 7 / 8]🧮 [Calculator] 正在计算: (123 + 456) * 7 / 8👀 Observation(观察): 结果是: 506.625===== 第 2 步 =====🧠 LLM 原始输出:Thought: 我已经得到了计算结果,现在可以用一句话告诉用户具体的数值。Action: Finish[计算结果是 506.625。]------------------------------------------------------------🧐 Thought(思考): 我已经得到了计算结果,现在可以用一句话告诉用户具体的数值。🎯 Action(行动): Finish[计算结果是 506.625。]🎉 最终答案:计算结果是 506.625。

你会清楚看到:

  • 每一步模型在想什么(Thought)
  • 它决定做什么(Action)
  • 工具返回了什么(Observation)
  • 以及最后如何用 Finish 给出最终答案

这就是 ReAct 最大的特点:过程透明、可解释、可调试。


七、下一步可以怎么玩?

拿到这个最小可跑版本之后,你可以做一些自己的扩展:

1. 加一个「假装搜索」工具

比如:

def fake_search(query: str) -> str:    if "预习功课" in query:        return "预习可以先看目录、再快速浏览课文、标记不懂的地方……"    return f"目前还不会查 {query},请换个问法。"

然后在 SimpleToolBox 里再注册一个 "Search" 工具,让模型在数学以外的问题上也能「边想边查」。

2. 处理「工具选错」的情况

例如:

  • 模型用 Calculator[百度一下华为最新手机]
  • 你可以在计算器里检测到表达式不是合法数学式,返回“看起来你给的是自然语言而不是算式,请改用 Search 工具。”
  • 再看下一轮模型会不会自动修正 Action

3. 结合 Plan-and-Solve、Reflection

等你对 ReAct 熟悉之后,可以尝试:

  • 用 Plan-and-Solve 先拆解大任务,再在每个子步骤里用 ReAct 调工具
  • 用 Reflection 给 ReAct 的「行动轨迹」做一次批改,看看有没有更优路径

八、小结

这篇文章,我们做了几件事情:

  1. 用「三个同学做题风格」解释了三种经典智能体范式:
  • ReAct:边想边干
  • Plan-and-Solve:先规划再执行
  • Reflection:做完再自我批改
  1. 把 ReAct 的核心脑回路抽象成:Thought → Action → Observation → … → Finish
  2. 在工程上,从 0 写了一个本地可跑的 Mini ReAct Agent
  • SimpleToolBox 管理工具
  • Calculator 工具处理复杂算式
  • MiniReActAgent 实现整个 ReAct 循环
  1. 带你拆解了运行日志,看到智能体真正是如何「边想边干」的。

如果你已经把这段代码跑通,恭喜你: 你不是只会「调 ChatGPT 的 API」,而是开始在真正设计自己的智能体了。

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

在这里插入图片描述

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐