一文入门 agent:从理论到代码实战

Agent(智能体)比较权威的定义出自 Stuart Russell 与 Peter Norvig 的《Artificial Intelligence: A Modern Approach》(1995, 《人工智能:一种现代方法》)。

An agent is anything that can be viewed as perceiving its environment through sensors and acting upon that environment through actuators.

通常指一个能够自主感知环境、决策并执行动作以完成特定目标的智能系统 。

简单来说,它就像是一个智能代理 ,可以接受我们的指令,在一定程度上自己想办法去完成任务,而不仅仅是被动响应

举个日常类比:可以把 Agent 想象成自己的 AI 助手或员工,给出任务,它会自己想如何去做,必要时查资料、调用工具,最后给出结果。

发展历史

人工智能领域的「Agent」概念经历了漫长的发展演变:

规则驱动的系统与专家系统(1950 - 1990年):

早期的 AI 系统多是基于手工编写规则的。这类系统按照预设的 if-then 规则集工作,缺乏灵活性但在特定领域表现不错。

典型代表是专家系统,例如 1970s 的医学诊断专家系统 MYCIN 和更早的 DENDRAL 。专家系统通过将人类专家的知识转化为规则库,能在狭窄领域模拟出专家级推理 。

比如 MYCIN 系统包含数百条治疗传染病的规则,可以根据患者症状给出诊断和治疗建议。它甚至能用一定的自然语言与用户交互并解释自己的推理过程 。

然而,这类系统的局限在于:知识获取成本高(需要专家手工编码大量规则),不具备自我学习,遇到规则覆盖不到的情况就束手无策。

强化学习 Agent(1990 - 2020年)

随着机器学习兴起,Agent 的智能决策开始由学习而非死板规则产生。

强化学习(Reinforcement Learning, RL)提供了一种让 Agent 通过试错与环境交互、自主学习策略的框架。

经典的 RL 设定中,Agent 不断感知环境状态,采取动作,根据环境给的奖励/惩罚调整策略。经过无数轮训练,Agent 学会在环境中达到奖励最大化的行动序列。

1990 - 2000 年代,RL 被用于机器人控制、游戏等领域,但真正让大众震撼的是 2010 年代的深度强化学习:例如 2016 年 DeepMind 的 AlphaGo 通过深度神经网络结合强化学习,在围棋上击败了人类世界冠军,展示了 Agent 在复杂环境下惊人的决策能力。

这一时期的 Agent 多数是在模拟/游戏环境里训练出的「智能体」(如学会玩雅达利游戏、下棋等),它们能自行探索出有效策略。

然而,RL Agent 通常需要明确的奖励函数和大量训练样本,在现实开放任务上应用受限。此外,训练得到的策略往往专门针对某一任务,缺乏通用性。

大语言模型时代的 Agent(2020年代)

进入 2020 年,AI 出现了一个新拐点:大型语言模型(LLM)的崛起。

像 GPT-3、GPT-4 这样的模型在海量文本上预训练,掌握了丰富的世界知识和推理能力。

研究者们很快意识到,可以把 LLM 当作通用「大脑」来赋予 Agent 智慧,而不必像过去那样为每个任务单独训练模型。

2022年,提出了链式思考(Chain-of-Thought, CoT)提示方法,让语言模型学会在输出最终答案前先生成逐步的思考过程。这使模型在复杂推理题上表现大幅提升 。

紧接着,研究者开始探索如何让 LLM 不仅会「想」也会「做」,于是出现了将推理和行动交织的架构(后面详述的 ReAct 等),赋予模型调用工具、与外界交互的能力 。

Autonomous Agent(自主代理)的概念在 2023 年引爆开源社区:比如 AutoGPT 和 BabyAGI 等项目火遍全网 。这些系统基于 GPT-4 等强大 LLM,围绕「让AI自主完成复杂任务」展开实验。

例如 AutoGPT 可以在给定一个高阶目标后,自己拆解子任务、通过互联网搜索信息、执行代码等,一系列操作循环,直到完成目标。

虽然早期的 AutoGPT 暂未表现出可靠实用的效果,但它标志着一种全新的 Agent 形态:完全由 LLM 驱动的自治智能体。

同时,LangChain 等开发框架崛起,为构建此类 LLM Agent 提供了便利工具库。

总的来说,LLM时代的 Agent 相比以往有几个显著特点:无需专项训练即可通用(依赖预训练知识),以自然语言为接口(决策过程和人类可读的计划融为一体),以及能够调用开放工具和知识源(如网络、数据库),从而显著拓展了 AI 解决现实任务的能力。

LLM agent

回到目前爆火的大语言模型(LLM) agent。业界逐渐探索出多种架构范式,其中有两种典型模式:一种是 ReAct (Reason + Act) 推理-行动交替模式,另一种是 Plan-and-Execute 先规划再执行的模式。

ReAct

ReAct 是 Reasoning and Acting 的缩写,顾名思义,它的核心思想是在 Agent 内部将「思考(Reason)」和「行动(Act)」交替进行 。这一范式最早由 2022 年谷歌大脑团队的论文「ReAct: Synergizing Reasoning and Acting in Language Models」提出 。

简单来说,ReAct 让 LLM 在解决任务时模拟人类的思考过程:想一步,做一步,再根据结果调整思考,再行动......如此循环,直到得出最终答案。

ReAct Agent 的典型工作流程如下:

  1. Thought(思考):Agent(LLM)对当前问题或状态进行分析,在内部生成一段思考/推理。这一步类似人脑的自言自语,可能涉及分解问题、制定子目标、假设下一步需要的信息等。

    例如面对一个复杂提问,Agent 可能产生内部思考:「要回答这个问题,我需要先查找相关统计数据」。

  2. Action(行动) :基于上一步的思考结论,Agent 决定采取一个具体行动 。在LLM Agent中,这通常体现为模型输出一个特殊格式的指令,如调用某个工具。举例:"Action: Search[关于X的统计数据]"。

    这里的工具可以是预先注入 Agent 的函数,比如网络搜索、计算器、数据库查询等。ReAct 提示模板通常要求模型按照「Thought: ... \n Action: ... \n Action Input: ...」格式输出 ,以明确指示要用的工具及输入 。

  3. Observation(观察):一旦 Agent 发出了 Action 指令,外部环境(或我们预先设置的执行器)就会执行这个动作,并将结果返回给 Agent 。

    比如当 Action 是搜索查询时,Observation 可能是一段搜索结果摘要。当 Action 是调用计算器,Observation 则是计算结果的值。这个观察结果相当于 Agent 在环境中获取到的新信息

  4. 循环迭代:Agent 将 Observation 纳入自己的上下文,再次进入 Thought 阶段进行推理,总结新获取的信息,与之前的目标对比,决定下一步怎么做 。它可能修正原先思路或提出新的子任务。

    如果任务还没完成就继续 Thought → Action → Observation 循环。如此反复,Agent 不断交替"思考-行动",逐步推进任务。

  5. Final Answer(最终答案) :当 Agent 判断已经收集了足够信息或完成了目标,就会在最后一次 Thought 后输出最终答案而不是新行动指令 。这标志着 ReAct 流程的终止,Agent 向用户给出结果。

用一个具体例子说明:假设用户问题是"中国的人口是多少的两倍?"。一个 ReAct Agent 可能这样运作:

  • 初始 Thought:"用户在问中国人口的两倍,这需要先查中国人口是多少"。
  • Action:"Search[中国人口]"。
  • Observation:"搜索结果显示:中国 2023 年人口约 14.1 亿"。
  • Thought:"好的,中国人口约 14.1 亿,问题要两倍,那计算一下 2×14.1 亿"。
  • Action:"Calculator[ 2 * 14.1 亿]"。(注:Agent可能将14.1亿转成数字再计算)
  • Observation:"结果=28.2 亿"。
  • Thought:"已经得到答案,可以作答"。
  • Final Answer:"约 28.2 亿"。

ReAct 模式以其直观明了的循环成为LLM Agent的基础范式之一。

它通过交替的「思想」和「行动」赋予 Agent 如同人类一般的解题风格,能逐步推理、调用工具获取实时信息以降低幻觉,并通过思维外显便于调试,通用性强。

但它效率较低、缺乏全局规划且依赖工具,因而更适合交互性强、步骤较少、需要实时查询或轻量推理的任务场景。

Plan-and-Execute 模式:先计划后执行

当任务变得更加复杂、步骤繁多时,另一种「规划-执行」架构开始展现威力。

这种模式将 Agent 的流程明确分为两个阶段:先规划(Plan),再执行(Execute) 先让 Agent 想出一整套方案,然后按照方案逐步落实。

与 ReAct 不同,Plan-and-Execute 会强制 LLM 做全局思考。它通常涉及两个子 Agent 或子模块:一个 Planner(规划者)和一个Executor(执行者)。两者分工如下:

  • Planner :由一个 LLM 来承担,它的任务是分析目标,产出详细的执行计划 。Planner 会接收用户的最终任务描述,然后以列表形式生成需要完成的子任务序列

    Planner 在这一步可以充分利用 LLM 的链式思考能力,将模糊的目标细化为可执行的步骤,并考虑步骤间的依赖、先后顺序等 。

  • Executor(s) :执行者负责按照 Planner 给出的每个子任务,逐条执行 。Executor 本质上也是一个 Agent,可以针对不同子任务切换工具或 API,也可以调用一个内部 ReAct Agent 来完成。

    Executor 会读取任务清单的某一条,比如「第1步:搜索 X 信息」,然后实际调用对应的工具完成它,将结果记录下来,再执行下一步。

Plan-and-Execute 模式的运行过程可以概括如下:

  1. 任务规划(Planning) :接收用户请求后,首先调用 Planner (LLM) 来生成完整计划。Planner 输出的计划通常是有序列表形式的步骤1、步骤2... 。

    例如用户让 Agent 「写一份关于某课题的调研报告」,Planner 可能输出:1. 搜集背景资料;2. 分析资料;3. 撰写报告初稿;4. 定稿并输出报告。

    Planner 提示词通常会明示模型:「先理解问题并制定计划,然后我们再逐步执行」。这一阶段,LLM 会尽量细化步骤直到每一步可以由工具或简单操作完成。

  2. 任务执行(Execution) :拿到 Planner 给出的任务清单后,进入执行环节。Executor 会逐步读取每条子任务并执行之 。执行时可能再次用到LLM,尤其当需要处理任务中的自然语言逻辑时。

    例如 LangChain 实现中,每一步的执行其实可以调用一个内部 ReAct Agent 来完成 (因为子任务本身也许需要检索或计算,多步才能得出结果)。

    但重要的是,Executor 聚焦于当前子任务的完成,不用操心全局流程。执行一个步骤后,把结果保存到共享状态中(相当于黑板或内存,记录目前有哪些信息、子任务完成情况) 。

  3. 计划调整(Replan,可选):理想情况下,按照初始计划顺利执行完所有步骤,就可以结束了。然而现实中,有时初始计划并不完美:可能遗漏了一些步骤,或者某步结果出乎意料、需要增加新的步骤。

    Plan-and-Execute 架构因此通常允许一个反馈回路:当执行到一定阶段后,Agent 可以启动 Planner 进行重新规划 (Replan) 。此时 Planner 会参考当前已完成的任务状态,增补或修改后续计划。这个规划-执行循环可以进行多轮,直到 Agent 确信任务完成。

  4. 生成最终答案:所有必要的子任务都执行完毕,Agent 最后汇总状态中的信息,由 LLM 编写最终交付结果,并返回给用户 (比如完整的报告文本) 。

Plan-and-Execute 的核心优势在于结构化地解决复杂任务,但也带来额外成本。

相比 ReAct,它通过 Planner 和 Executor 分工来保证任务分解、执行更有条理,适合多步骤、长程、高精度和跨工具的任务。

但缺点在于:实现复杂、误差传递、上下文管理压力大、执行耗时

因此,它更适合在复杂问题分解、长程规划、精度要求高或需要跨工具协调的场景下使用,而在简单任务或即时反应的场合,ReAct 往往更高效。

代码实战

零框架实现 ReAct

核心是两点:

  • 通过 prompt 控制大模型的输出格式
  • 解析大模型的输出,手动调用工具

直接 Cursor 生成代码就好:

忘了让 AI 用 ollama,再让它改一下:

核心就是一个不停的调用大模型的循环,期间拆解动作,执行动作,循环往复:

python 复制代码
def solve(self, question: str, verbose: bool = True) -> str:
        """
        使用 ReAct 模式解决问题
        
        Args:
            question: 用户问题
            verbose: 是否显示详细过程
            
        Returns:
            最终答案
        """
        messages = [
            {"role": "system", "content": self._get_system_prompt()},
            {"role": "user", "content": question}
        ]
        
        for step in range(self.max_steps):
            if verbose:
                print(f"\\n=== 步骤 {step + 1} ===")
                
            # 获取模型响应
            try:
                assistant_message = self._call_llm(messages)
                if verbose:
                    print(f"Assistant: {assistant_message}")
                    
                messages.append({"role": "assistant", "content": assistant_message})
                
                # 检查是否包含最终答案
                if "Final Answer:" in assistant_message:
                    final_answer = assistant_message.split("Final Answer:")[-1].strip()
                    if verbose:
                        print(f"\\n🎉 找到答案: {final_answer}")
                    return final_answer
                
                # 解析并执行行动
                action_result = self._parse_action(assistant_message)
                if action_result:
                    tool_name, params = action_result
                    observation = self._execute_tool(tool_name, params)
                    
                    if verbose:
                        print(f"🔧 执行工具: {tool_name}")
                        print(f"📋 参数: {params}")
                        print(f"👁️ 观察结果: {observation}")
                    
                    # 添加观察结果到对话历史
                    messages.append({
                        "role": "user", 
                        "content": f"Observation: {observation}"
                    })
                else:
                    # 如果没有找到有效的行动,继续下一轮
                    if verbose:
                        print("⚠️ 未找到有效的行动,继续思考...")
                        
            except Exception as e:
                error_msg = f"API 调用错误: {str(e)}"
                if verbose:
                    print(f"❌ {error_msg}")
                return error_msg
                
        return "达到最大步数限制,未能找到答案。"

拆解一下:

一个循环的框架:

python 复制代码
def solve(self, question: str, verbose: bool = True) -> str:
        """
        使用 ReAct 模式解决问题
        
        Args:
            question: 用户问题
            verbose: 是否显示详细过程
            
        Returns:
            最终答案
        """
        messages = [
            {"role": "system", "content": self._get_system_prompt()},
            {"role": "user", "content": question}
        ]
        
        for step in range(self.max_steps):
           ...
            except Exception as e:
                error_msg = f"API 调用错误: {str(e)}"
                if verbose:
                    print(f"❌ {error_msg}")
                return error_msg
                
        return "达到最大步数限制,未能找到答案。"

_get_system_prompt 返回提示词:

python 复制代码
def _get_system_prompt(self) -> str:
        """获取系统提示词"""
        tools_desc = "\\n".join([
            f"- {name}: {desc}" 
            for name, desc in self.tool_descriptions.items()
        ])
        
        return f"""你是一个智能助手,使用 ReAct(Reasoning and Acting)模式来解决问题。

可用工具:
{tools_desc}

工作流程:
1. Thought: 分析问题,制定计划
2. Action: 选择并执行工具
3. Observation: 观察结果
4. 重复直到找到答案

格式要求:
- 用 "Thought:" 开始你的思考
- 用 "Action:" 开始行动,格式为 Action: tool_name(parameters)
- 我会提供 "Observation:" 显示行动结果
- 用 "Final Answer:" 给出最终答案

示例:
Thought: 我需要计算 25 + 17 的结果
Action: calculator(25 + 17)
Observation: 42
Final Answer: 25 + 17 = 42

现在开始解决用户的问题。"""

其中的可用工具,需要提前实现:

yaml 复制代码
可用工具:
	•	calculator: 计算数学表达式,支持基本运算和常用数学函数(sqrt, sin, cos, tan, log)
	•	web_search: 搜索网络信息,获取实时数据和知识
	•	web_scraper: 抓取指定网页的文本内容
	•	read_file: 文件操作工具,支持读取、写入文件和列出目录内容
	•	write_file: 写入内容到文件
	•	list_directory: 列出目录内容
	•	get_weather: 获取指定城市的天气信息

接着是循环里边,将用户问题和提示词传给大模型:

python 复制代码
def solve(self, question: str, verbose: bool = True) -> str:
        """
        使用 ReAct 模式解决问题
        
        Args:
            question: 用户问题
            verbose: 是否显示详细过程
            
        Returns:
            最终答案
        """
        messages = [
            {"role": "system", "content": self._get_system_prompt()},
            {"role": "user", "content": question}
        ]
        
        for step in range(self.max_steps):
            if verbose:
                print(f"\\n=== 步骤 {step + 1} ===")
                
            # 获取模型响应
            try:
                assistant_message = self._call_llm(messages)
                if verbose:
                    print(f"Assistant: {assistant_message}")
                    
                messages.append({"role": "assistant", "content": assistant_message})
                
                # 检查是否包含最终答案
                if "Final Answer:" in assistant_message:
                    final_answer = assistant_message.split("Final Answer:")[-1].strip()
                    if verbose:
                        print(f"\\n🎉 找到答案: {final_answer}")
                    return final_answer
                
                ...
                        
            except Exception as e:
                error_msg = f"API 调用错误: {str(e)}"
                if verbose:
                    print(f"❌ {error_msg}")
                return error_msg
                
        return "达到最大步数限制,未能找到答案。"

因为 prompt 中要求了大模型用 「Final Answer:」给出最终答案,因此循环终点就是判断是否有 「Final Answer」。

接着再解析 大模型返回的Action ,来手动调用提前实现好的工具:

python 复制代码
def solve(self, question: str, verbose: bool = True) -> str:
        """
        使用 ReAct 模式解决问题
        
        Args:
            question: 用户问题
            verbose: 是否显示详细过程
            
        Returns:
            最终答案
        """
        messages = [
            {"role": "system", "content": self._get_system_prompt()},
            {"role": "user", "content": question}
        ]
        
        for step in range(self.max_steps):
            if verbose:
                print(f"\\n=== 步骤 {step + 1} ===")
                
            # 获取模型响应
            try:
                assistant_message = self._call_llm(messages)
                if verbose:
                    print(f"Assistant: {assistant_message}")
                    
                messages.append({"role": "assistant", "content": assistant_message})
                
                # 检查是否包含最终答案
                if "Final Answer:" in assistant_message:
                    final_answer = assistant_message.split("Final Answer:")[-1].strip()
                    if verbose:
                        print(f"\\n🎉 找到答案: {final_answer}")
                    return final_answer
                
                # 解析并执行行动
                action_result = self._parse_action(assistant_message)
                if action_result:
                    tool_name, params = action_result
                    observation = self._execute_tool(tool_name, params)
                    
                    if verbose:
                        print(f"🔧 执行工具: {tool_name}")
                        print(f"📋 参数: {params}")
                        print(f"👁️ 观察结果: {observation}")
                    
                    # 添加观察结果到对话历史
                    messages.append({
                        "role": "user", 
                        "content": f"Observation: {observation}"
                    })
                else:
                    # 如果没有找到有效的行动,继续下一轮
                    if verbose:
                        print("⚠️ 未找到有效的行动,继续思考...")
                        
            except Exception as e:
                error_msg = f"API 调用错误: {str(e)}"
                if verbose:
                    print(f"❌ {error_msg}")
                return error_msg
                
        return "达到最大步数限制,未能找到答案。"

其中 _parse_action 就是解析 prompt 中说的 用 "Action:" 开始行动,格式为 Action: tool_name(parameters)

python 复制代码
def _parse_action(self, text: str) -> Optional[tuple]:
        """
        解析行动文本,提取工具名称和参数
        
        Args:
            text: 包含行动的文本
            
        Returns:
            (tool_name, parameters) 或 None
        """
        # 查找 Action: 行
        action_pattern = r"Action:\s*(\w+)\((.*?)\)"
        match = re.search(action_pattern, text, re.DOTALL)
        
        if match:
            tool_name = match.group(1)
            params_str = match.group(2).strip()
            
            if tool_name in self.tools:
                # 尝试解析参数
                try:
                    # 简单的参数解析(可以根据需要改进)
                    if params_str:
                        # 如果参数看起来像 JSON,尝试解析
                        if params_str.startswith('{') and params_str.endswith('}'):
                            params = json.loads(params_str)
                        else:
                            params = params_str
                    else:
                        params = None
                    return tool_name, params
                except json.JSONDecodeError:
                    return tool_name, params_str
                    
        return None

先正则解析出 Action 的内容 r"Action:\s*(\w+)\((.*?)\)" ,接着拿到 tool_name(工具名)和 params_str(入参)返回。

拿到之后去调用函数:

python 复制代码
 action_result = self._parse_action(assistant_message)
if action_result:
    tool_name, params = action_result
    observation = self._execute_tool(tool_name, params)
    
def _execute_tool(self, tool_name: str, params: Any) -> str:
        """
        执行工具函数
        
        Args:
            tool_name: 工具名称
            params: 工具参数
            
        Returns:
            工具执行结果
        """
        try:
            tool_func = self.tools[tool_name]
            if params is None:
                result = tool_func()
            elif isinstance(params, dict):
                result = tool_func(**params)
            else:
                result = tool_func(params)
            return str(result)
        except Exception as e:
            return f"工具执行错误: {str(e)}"

拿到对应的函数,然后将参数传入即可。

最后将工具返回的结果追加到对话列表中下一次循环即可:

python 复制代码
observation = self._execute_tool(tool_name, params)

                  if verbose:
                      print(f"🔧 执行工具: {tool_name}")
                      print(f"📋 参数: {params}")
                      print(f"👁️ 观察结果: {observation}")

                  # 添加观察结果到对话历史
                  messages.append({
                      "role": "user", 
                      "content": f"Observation: {observation}"
                  })

看下运行效果:

直接调用一次 Action: calculator(9 * 8 - 2)

调用两次 Action,web_search("中国当前人口数")calculator(1400000000 * 2)

LangChain 实现 Plan-and-Execute

用 LangChain 的话,我们只需要提供 Tools,提示词、agent、记忆管理全部内置了,代码会简单很多:

python 复制代码
from langchain_community.llms import Ollama
from langchain.agents import Tool
from langchain_experimental.plan_and_execute import PlanAndExecute, load_agent_executor, load_chat_planner
from duckduckgo_search import DDGS

# 初始化LLM模型(Ollama qwen2.5:7b)
llm = Ollama(model="qwen2.5:7b", temperature=0)

# 定义一个DuckDuckGo搜索工具
def ddg_search(query: str) -> str:
    """使用DuckDuckGo进行搜索,返回前几条结果摘要。"""
    results = []
    with DDGS() as ddgs:  # 使用duckduckgo_search库
        for r in ddgs.text(query, max_results=3):  # 取前三条结果
            results.append(f"{r['title']}: {r['body']}")
    return "\n".join(results)

search_tool = Tool(
    name="WebSearch",
    func=ddg_search,
    description="用于在互联网上搜索信息的工具。输入查询,返回相关简要结果。"
)

tools = [search_tool]

# 加载 Planner 和 Executor
planner = load_chat_planner(llm)                   # 规划阶段使用同一LLM
executor = load_agent_executor(llm, tools, verbose=True)  # 执行阶段Agent(允许调用搜索工具)
agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)

# 运行 Agent 执行任务
task = "调查气候变化对北极熊种群的影响,并给出一份总结报告。"
result = agent.run(task)

print("最终汇总报告:\n", result)

调用 load_agent_executor 就可以得到一个 ReAct 的 Agent,调用 load_chat_planner 就得到了可以 planner 的 Agent。

问一个相对复杂的问题 「调查气候变化对北极熊种群的影响,并给出一份总结报告。」,最开始是生成了步骤,然后一步一步得出了结论:

js 复制代码
Entering new PlanAndExecute chain...

steps=[Step(value='确定气候变化的主要影响因素。'), Step(value='分析这些因素如何具体影响北极熊的生存环境和行为模式。'), Step(value='收集并分析相关科学研究数据,了解北极熊种群数量变化趋势。'), Step(value='总结气候变化对北极熊种群的具体影响,并提出保护建议。\n\n')]

> Entering new AgentExecutor chain...
Action:
```
{
  "action": "WebSearch",
  "action_input": "确定气候变化的主要影响因素"
}
```

/Users/windliang/my-project/agent-demo/plan.py:13: RuntimeWarning: This package (`duckduckgo_search`) has been renamed to `ddgs`! Use `pip install ddgs` instead.
  with DDGS() as ddgs:  # 使用duckduckgo_search库

Observation: 
Thought:Action:
```
{
  "action": "WebSearch",
  "action_input": "确定气候变化的主要影响因素"
}
```/Users/windliang/my-project/agent-demo/plan.py:13: RuntimeWarning: This package (`duckduckgo_search`) has been renamed to `ddgs`! Use `pip install ddgs` instead.
  with DDGS() as ddgs:  # 使用duckduckgo_search库

Observation: Butantã (district of São Paulo) - Wikipedia: Butantã (Portuguese pronunciation: [butɐ̃ˈtɐ̃], from the tupi for "crushed soil") is a district of the city of São Paulo, Brazil. It is part of the homonymous subprefecture, located on the west bank of the ...
Home - Subprefeitura - Butantã - Prefeitura: Confira informações atualizadas sobre a cidade de São Paulo!
Bairro do Butantã: 5 passeios para fazer por lá! - Visite São Paulo: Mar 21, 2024 · Explore o bairro do Butantã, com passeios cheios de diversidade, cultura e história. Descubra locais incríveis localizados no bairro!
Thought:Action:
```
{
  "action": "WebSearch",
  "action_input": "确定气候变化的主要影响因素"
}
```/Users/windliang/my-project/agent-demo/plan.py:13: RuntimeWarning: This package (`duckduckgo_search`) has been renamed to `ddgs`! Use `pip install ddgs` instead.
  with DDGS() as ddgs:  # 使用duckduckgo_search库

Observation: YouTube: Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
YouTube on the App Store: Get the official YouTube app on iPhones and iPads. See what the world is watching -- from the hottest music videos to what's popular in gaming, fashion, beauty, news, learning and more.
YouTube -- Apps on Google Play: Get the official YouTube app on Android phones and tablets. See what the world is watching -- from the hottest music videos to what's popular in gaming, fashion, beauty, news, learning and ...
Thought:Action: 


... 此处省略中间


```
{
  "action": "WebSearch",
  "action_input": "北极熊种群数量变化趋势 科学研究"
}
```/Users/windliang/my-project/agent-demo/plan.py:13: RuntimeWarning: This package (`duckduckgo_search`) has been renamed to `ddgs`! Use `pip install ddgs` instead.
  with DDGS() as ddgs:  # 使用duckduckgo_search库

Observation: 新研究将北极熊数量下降与气候变化联系起来 - TUN: Jan 31, 2025 · 多伦多大学士嘉堡分校的研究人员得出了一个令人警醒的结论,他们证实了气候变化导致的海冰萎缩与哈德逊湾西部北极熊种群数量下降之间存在直接联系。
在快速变化的北极地区建立北极熊预测模型的增量演化,Ecological ...: 在这里,我们回顾了预测全球北极熊 ( Ursus maritimus ) 种群状况变化的前两代贝叶斯网络概率模型,并根据最新的研究结果和新气候模型的海冰预测提供了当代更新。
北极熊灭绝的科学预测和模型 - Sigma Earth: 在过去的几十年里,科学预测和模型越来越多地警告说,如果目前的气候变化趋势持续下去,北极熊可能会灭绝。 本文探讨了这些预测背后的技术以及对北极熊种群的结论和影响。
Thought:Action:
```
{
  "action": "WebSearch",
  "action_input": "北极熊种群数量变化趋势 科学研究"
}
```/Users/windliang/my-project/agent-demo/plan.py:13: RuntimeWarning: This package (`duckduckgo_search`) has been renamed to `ddgs`! Use `pip install ddgs` instead.
  with DDGS() as ddgs:  # 使用duckduckgo_search库

Observation: 
Thought:Action:
```
{
  "action": "WebSearch",
  "action_input": "北极熊种群数量变化趋势 科学研究"
}
```/Users/windliang/my-project/agent-demo/plan.py:13: RuntimeWarning: This package (`duckduckgo_search`) has been renamed to `ddgs`! Use `pip install ddgs` instead.
  with DDGS() as ddgs:  # 使用duckduckgo_search库

Observation: 
Thought:Action:
```
{
  "action": "Final Answer",
  "action_input": "根据科学研究,气候变化导致的海冰萎缩是影响北极熊种群数量下降的主要因素之一。多伦多大学士嘉堡分校的研究人员证实了这一点,并指出哈德逊湾西部的北极熊种群数量已经因为海冰减少而有所下降。此外,预测模型表明,如果不采取措施减缓气候变化,北极熊可能会面临灭绝的风险。"
}
```

> Finished chain.
*****

Step: 收集并分析相关科学研究数据,了解北极熊种群数量变化趋势。

Response: 根据科学研究,气候变化导致的海冰萎缩是影响北极熊种群数量下降的主要因素之一。多伦多大学士嘉堡分校的研究人员证实了这一点,并指出哈德逊湾西部的北极熊种群数量已经因为海冰减少而有所下降。此外,预测模型表明,如果不采取措施减缓气候变化,北极熊可能会面临灭绝的风险。

> Entering new AgentExecutor chain...
Action:
```
{
  "action": "Final Answer",
  "action_input": "气候变化通过减少栖息地和狩猎范围、增加能量消耗以及导致繁殖困难等途径,对北极熊的生存环境和行为模式产生了显著影响。这些因素共同作用下,北极熊种群数量正在下降,并且有灭绝的风险。为了保护北极熊,建议采取以下措施:1. 减少温室气体排放;2. 保护森林资源;3. 加强国际合作,共同应对气候变化问题;4. 建立保护区,为北极熊提供安全的栖息地;5. 开展科学研究,监测北极熊种群数量变化趋势。"
}
```

> Finished chain.
*****

Step: 总结气候变化对北极熊种群的具体影响,并提出保护建议。



Response: 气候变化通过减少栖息地和狩猎范围、增加能量消耗以及导致繁殖困难等途径,对北极熊的生存环境和行为模式产生了显著影响。这些因素共同作用下,北极熊种群数量正在下降,并且有灭绝的风险。为了保护北极熊,建议采取以下措施:1. 减少温室气体排放;2. 保护森林资源;3. 加强国际合作,共同应对气候变化问题;4. 建立保护区,为北极熊提供安全的栖息地;5. 开展科学研究,监测北极熊种群数量变化趋势。
> Finished chain.
最终汇总报告:
 气候变化通过减少栖息地和狩猎范围、增加能量消耗以及导致繁殖困难等途径,对北极熊的生存环境和行为模式产生了显著影响。这些因素共同作用下,北极熊种群数量正在下降,并且有灭绝的风险。为了保护北极熊,建议采取以下措施:1. 减少温室气体排放;2. 保护森林资源;3. 加强国际合作,共同应对气候变化问题;4. 建立保护区,为北极熊提供安全的栖息地;5. 开展科学研究,监测北极熊种群数量变化趋势。

大模型是一个聪明的大脑,但它不会主动做什么,需要我们通过 prompt 指挥,然后它需要干什么我们帮它去做,循环往复,结合起来就变成了一个 agent。

Prompt 控制 / 模块化设计、规划策略、工具调度 / 使用、记忆机制、控制流与反馈、Agent 协同架构、以及工具库可扩展性 / 安全性,这些共同决定了一个 agent 表现的好坏,也诞生了现在各种各样的 agent 应用。

相关推荐
一枚前端小能手2 小时前
🔥 字符串处理又踩坑了?JavaScript字符串方法全攻略,这些技巧让你效率翻倍
前端·javascript
4z332 小时前
Jetpack Compose重组原理(一):快照系统如何精准追踪状态变化
前端·android jetpack
三十_2 小时前
私有 npm 仓库实践:Verdaccio 保姆级搭建教程与最佳实践
前端·npm
CoovallyAIHub2 小时前
华为发布开源超节点架构,以开放战略叩响AI算力生态变局
算法·架构·github
叫我詹躲躲2 小时前
别再手写正则了!20 + 证件 / 手机号 / 邮箱验证函数,直接复制能用
前端·javascript·正则表达式
猪哥帅过吴彦祖2 小时前
第 4 篇:赋予表面生命 - WebGL 纹理贴图
前端·javascript·webgl
猪哥帅过吴彦祖2 小时前
Flutter 系列教程:核心概念 - StatelessWidget vs. StatefulWidget
前端·javascript·flutter
郝学胜-神的一滴2 小时前
解析前端框架 Axios 的设计理念与源码
开发语言·前端·javascript·设计模式·前端框架·软件工程
aixfe2 小时前
Ant Design V5 Token 体系颜色处理最佳实践
前端