HelloAgents 进阶篇 task00,task01

这一部分主要进行了Agent有关环境的配置以及ReAct、Plan-and-Solve、Reflection三种智能体架构范式的实现。

一、环境配置

在进行架构实现之前,需要先进行环境的配置。

1.虚拟环境创建

为了进行环境隔离,推荐使用虚拟环境的方式进行环境配置,我使用的是python方式进行虚拟环境创建。

bash 复制代码
# 进入项目目录
cd "hello-agents"

# 创建虚拟环境
python -m venv venv

# 激活虚拟环境
# Windows:
venv\Scripts\activate

同样,也可以使用conda的方式进行环境创建。

2.依赖安装

虚拟环境创建好之后下面进行依赖包的安装。

bash 复制代码
# 安装核心依赖
pip install requests>=2.31.0
pip install tavily-python>=0.3.0
pip install openai>=1.0.0

# 可选:安装其他常用包
pip install python-dotenv>=1.0.0

3.环境变量配置

为了便于API等配置的调用,通过使用.env文件对一些常用变量进行配置。

bash 复制代码
# Tavily API 配置
TAVILY_API_KEY=

# 大语言模型 API 配置(选择其中一种)
# 选项一:AIHubmix
OPENAI_API_KEY=your_aihubmix_api_key
OPENAI_BASE_URL=https://aihubmix.com/v1
MODEL_NAME=xxxx

# ============================================================================
# HelloAgents 统一环境变量配置文件
# ============================================================================
# 复制此文件为 .env 并填入你的API密钥
# 系统要求:Python 3.10+ (必需)

# ============================================================================
# 🚀 统一配置格式(推荐)- 框架自动检测provider
# ============================================================================
# 只需配置以下4个通用环境变量,框架会自动识别LLM提供商:

# 模型名称
LLM_MODEL_ID=deepseek-chat

# API密钥
LLM_API_KEY=
# 服务地址
LLM_BASE_URL=

# 超时时间(可选,默认60秒)
LLM_TIMEOUT=60

# ============================================================================
# 🛠️ 工具配置(可选)
# ============================================================================

# Tavily搜索(推荐)- 获取API密钥:https://tavily.com/
# TAVILY_API_KEY=
# SerpApi搜索(备选)- 获取API密钥:https://serpapi.com/
SERPAPI_API_KEY=

4.搭建第一个Agent

在环境配置好之后就可以开始搭建第一个Agent,接下来以一个天气景点搜索Agent为例来进行搭建。

首先需要先配置我们要使用的大语言模型,我使用过MiniMax2.7和DeepseekV3.2这两个模型,对比下来,使用DeepSeekV3.2这个非思考模型的准确性较高,同时token价格相对较低,因此后面我决定使用Deepseek来作为智能体的基座模型。

除了基座模型的选择,还需要配置Tavily Search API用来让大模型可以搜索相关信息。

有了这些配置之后,就可以开始着手构建智能体。

python 复制代码
AGENT_SYSTEM_PROMPT = """
你是一个智能旅行助手。你的任务是分析用户的请求,并使用可用工具一步步地解决问题。

# 可用工具:
- `get_weather(city: str)`: 查询指定城市的实时天气。
- `get_attraction(city: str, weather: str)`: 根据城市和天气搜索推荐的旅游景点。

# 输出格式要求:
你的每次回复必须严格遵循以下格式,包含一对Thought和Action:

Thought: [你的思考过程和下一步计划]
Action: [你要执行的具体行动]

Action的格式必须是以下之一:
1. 调用工具:function_name(arg_name="arg_value")
2. 结束任务:Finish[最终答案]

# 重要提示:
- 每次只输出一对Thought-Action
- Action必须在同一行,不要换行
- 当收集到足够信息可以回答用户问题时,必须使用 Action: Finish[最终答案] 格式结束

请开始吧!
"""


import requests

def get_weather(city: str) -> str:
    """
    通过调用 wttr.in API 查询真实的天气信息。
    """
    # API端点,我们请求JSON格式的数据
    url = f"https://wttr.in/{city}?format=j1"
    
    try:
        # 发起网络请求
        response = requests.get(url)
        # 检查响应状态码是否为200 (成功)
        response.raise_for_status() 
        # 解析返回的JSON数据
        data = response.json()
        
        # 提取当前天气状况
        current_condition = data['current_condition'][0]
        weather_desc = current_condition['weatherDesc'][0]['value']
        temp_c = current_condition['temp_C']
        
        # 格式化成自然语言返回
        return f"{city}当前天气:{weather_desc},气温{temp_c}摄氏度"
        
    except requests.exceptions.RequestException as e:
        # 处理网络错误
        return f"错误:查询天气时遇到网络问题 - {e}"
    except (KeyError, IndexError) as e:
        # 处理数据解析错误
        return f"错误:解析天气数据失败,可能是城市名称无效 - {e}"



import os
from tavily import TavilyClient

def get_attraction(city: str, weather: str) -> str:
    """
    根据城市和天气,使用Tavily Search API搜索并返回优化后的景点推荐。
    """

    # 从环境变量或主程序配置中获取API密钥
    api_key = os.environ.get("TAVILY_API_KEY") # 推荐方式
    # 或者,我们可以在主循环中传入,如此处代码所示

    if not api_key:
        return "错误:未配置TAVILY_API_KEY。"

    # 2. 初始化Tavily客户端
    tavily = TavilyClient(api_key=api_key)
    
    # 3. 构造一个精确的查询
    query = f"'{city}' 在'{weather}'天气下最值得去的旅游景点推荐及理由"
    
    try:
        # 4. 调用API,include_answer=True会返回一个综合性的回答
        response = tavily.search(query=query, search_depth="basic", include_answer=True)
        
        # 5. Tavily返回的结果已经非常干净,可以直接使用
        # response['answer'] 是一个基于所有搜索结果的总结性回答
        if response.get("answer"):
            return response["answer"]
        
        # 如果没有综合性回答,则格式化原始结果
        formatted_results = []
        for result in response.get("results", []):
            formatted_results.append(f"- {result['title']}: {result['content']}")
        
        if not formatted_results:
             return "抱歉,没有找到相关的旅游景点推荐。"

        return "根据搜索,为您找到以下信息:\n" + "\n".join(formatted_results)

    except Exception as e:
        return f"错误:执行Tavily搜索时出现问题 - {e}"


# 将所有工具函数放入一个字典,方便后续调用
available_tools = {
    "get_weather": get_weather,
    "get_attraction": get_attraction,
}

from openai import OpenAI

class OpenAICompatibleClient:
    """
    一个用于调用任何兼容OpenAI接口的LLM服务的客户端。
    """
    def __init__(self, model: str, api_key: str, base_url: str):
        self.model = model
        self.client = OpenAI(api_key=api_key, base_url=base_url)

    def generate(self, prompt: str, system_prompt: str) -> str:
        """调用LLM API来生成回应。"""
        print("正在调用大语言模型...")
        try:
            messages = [
                {'role': 'system', 'content': system_prompt},
                {'role': 'user', 'content': prompt}
            ]
            response = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                stream=False
            )
            answer = response.choices[0].message.content
            print("大语言模型响应成功。")
            return answer
        except Exception as e:
            print(f"调用LLM API时发生错误: {e}")
            return "错误:调用语言模型服务时出错。"

import re
from llm_client import HelloAgentsLLM

# --- 1. 配置LLM客户端 ---
# 请根据您使用的服务,将这里替换成对应的凭证和地址
API_KEY = ""
BASE_URL = ""
MODEL_ID = "deepseek-chat"
os.environ['TAVILY_API_KEY'] = ""

llm = OpenAICompatibleClient(
    model=MODEL_ID,
    api_key=API_KEY,
    base_url=BASE_URL
)

# --- 2. 初始化 ---
user_prompt = "你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。"
prompt_history = [f"用户请求: {user_prompt}"]

print(f"用户输入: {user_prompt}\n" + "="*40)

# --- 3. 运行主循环 ---
for i in range(5): # 设置最大循环次数
    print(f"--- 循环 {i+1} ---\n")
    
    # 3.1. 构建Prompt
    full_prompt = "\n".join(prompt_history)
    
    # 3.2. 调用LLM进行思考
    llm_output = llm.generate(full_prompt, system_prompt=AGENT_SYSTEM_PROMPT)
    # 模型可能会输出多余的Thought-Action,需要截断
    match = re.search(r'(Thought:.*?Action:.*?)(?=\n\s*(?:Thought:|Action:|Observation:)|\Z)', llm_output, re.DOTALL)
    if match:
        truncated = match.group(1).strip()
        if truncated != llm_output.strip():
            llm_output = truncated
            print("已截断多余的 Thought-Action 对")
    print(f"模型输出:\n{llm_output}\n")
    prompt_history.append(llm_output)
    
    # 3.3. 解析并执行行动
    action_match = re.search(r"Action: (.*)", llm_output, re.DOTALL)
    if not action_match:
        observation = "错误: 未能解析到 Action 字段。请确保你的回复严格遵循 'Thought: ... Action: ...' 的格式。"
        observation_str = f"Observation: {observation}"
        print(f"{observation_str}\n" + "="*40)
        prompt_history.append(observation_str)
        continue
    action_str = action_match.group(1).strip()

    if action_str.startswith("Finish"):
        final_answer = re.match(r"Finish\[(.*)\]", action_str).group(1)
        print(f"任务完成,最终答案: {final_answer}")
        break
    
    tool_name = re.search(r"(\w+)\(", action_str).group(1)
    args_str = re.search(r"\((.*)\)", action_str).group(1)
    kwargs = dict(re.findall(r'(\w+)="([^"]*)"', args_str))

    if tool_name in available_tools:
        observation = available_tools[tool_name](**kwargs)
    else:
        observation = f"错误:未定义的工具 '{tool_name}'"

    # 3.4. 记录观察结果
    observation_str = f"Observation: {observation}"
    print(f"{observation_str}\n" + "="*40)
    prompt_history.append(observation_str)

运行结果如下:

bash 复制代码
用户输入: 你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。
========================================
--- 循环 1 ---

正在调用大语言模型...
大语言模型响应成功。
模型输出:
Thought: 用户想查询北京的天气,然后根据天气推荐合适的旅游景点。我需要先调用get_weather获取北京今天的天气信息。
Action: get_weather(city="北京")

Observation: 北京当前天气:Sunny,气温21摄氏度
========================================
--- 循环 2 ---

正在调用大语言模型...
大语言模型响应成功。
已截断多余的 Thought-Action 对
模型输出:
Thought: 现在我知道了北京的天气是晴朗,气温21度。接下来我需要根据这个天气信息来推荐一个合适的旅游景点。应该调用get_attraction工具,传入城市和天气信息。
Action: get_attraction(city="北京", weather="Sunny")

Observation: 在晴天,北京的颐和园和长城是最值得去的旅游景点。颐和园是皇家园林,长城展现壮观景象。
========================================
--- 循环 3 ---

正在调用大语言模型...
大语言模型响应成功。
模型输出:
Thought: 我已经获取了北京的天气信息(晴朗,21摄氏度)和基于这个天气的景点推荐。现在我有足够的信息来回答用户的问题,可以给出最终答案了。
Action: Finish[根据查询结果,北京今天天气晴朗,气温21摄氏度。在这样晴朗的天气里,推荐您去颐和园或长城游玩。颐和园是美丽的皇家园林,而长城则能展现壮观的景象,都是非常适合晴天游览的景点。]     

任务完成,最终答案: 根据查询结果,北京今天天气晴朗,气温21摄氏度。在这样晴朗的天气里,推荐您去颐和园或长城游玩。颐和园是美丽的皇家园林,而长城则能展现壮观的景象,都是非常适合晴天游览的景点。

二、智能体经典范式

1.ReAct

ReAct通过思考指导行动,而行动的结果又反过来修正思考这一固定轨迹来引导模型:

  • Thought (思考): 这是智能体的"内心独白"。它会分析当前情况、分解任务、制定下一步计划,或者反思上一步的结果。
  • Action (行动): 这是智能体决定采取的具体动作,通常是调用一个外部工具,例如 Search['华为最新款手机']
  • Observation (观察): 这是执行Action后从外部工具返回的结果,例如搜索结果的摘要或API的返回值。

这一范式适合以下几个场景:

  • 需要外部知识的任务:如查询实时信息(天气、新闻、股价)、搜索专业领域的知识等。
  • 需要精确计算的任务:将数学问题交给计算器工具,避免LLM的计算错误。
  • 需要与API交互的任务:如操作数据库、调用某个服务的API来完成特定功能。

因为我们需要使用到外部工具,所以首先构建一个工具类。

python 复制代码
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()

import os
from serpapi import Client
from typing import Dict, Any

def search(query: str) -> str:
    """
    一个基于SerpApi的实战网页搜索引擎工具。
    它会智能地解析搜索结果,优先返回直接答案或知识图谱信息。
    """
    print(f"🔍 正在执行 [SerpApi] 网页搜索: {query}")
    try:
        api_key = os.getenv("SERPAPI_API_KEY")
        if not api_key:
            return "错误:SERPAPI_API_KEY 未在 .env 文件中配置。"

        params = {
            "engine": "google",
            "q": query,
            "api_key": api_key,
            "gl": "cn",  # 国家代码
            "hl": "zh-cn", # 语言代码
        }
        
        client = Client(api_key=api_key)
        # client = Client(params)
        results = client.search(params)
        
        # 智能解析:优先寻找最直接的答案
        if "answer_box_list" in results:
            return "\n".join(results["answer_box_list"])
        if "answer_box" in results and "answer" in results["answer_box"]:
            return results["answer_box"]["answer"]
        if "knowledge_graph" in results and "description" in results["knowledge_graph"]:
            return results["knowledge_graph"]["description"]
        if "organic_results" in results and results["organic_results"]:
            # 如果没有直接答案,则返回前三个有机结果的摘要
            snippets = [
                f"[{i+1}] {res.get('title', '')}\n{res.get('snippet', '')}"
                for i, res in enumerate(results["organic_results"][:3])
            ]
            return "\n\n".join(snippets)
        
        return f"对不起,没有找到关于 '{query}' 的信息。"

    except Exception as e:
        return f"搜索时发生错误: {e}"
    
from typing import Dict, Any

class ToolExecutor:
    """
    一个工具执行器,负责管理和执行工具。
    """
    def __init__(self):
        self.tools: Dict[str, Dict[str, Any]] = {}

    def registerTool(self, name: str, description: str, func: callable):
        """
        向工具箱中注册一个新工具。
        """
        if name in self.tools:
            print(f"警告:工具 '{name}' 已存在,将被覆盖。")
        
        self.tools[name] = {"description": description, "func": func}
        print(f"工具 '{name}' 已注册。")

    def getTool(self, name: str) -> callable:
        """
        根据名称获取一个工具的执行函数。
        """
        return self.tools.get(name, {}).get("func")

    def getAvailableTools(self) -> str:
        """
        获取所有可用工具的格式化描述字符串。
        """
        return "\n".join([
            f"- {name}: {info['description']}" 
            for name, info in self.tools.items()
        ])


# --- 工具初始化与使用示例 ---
if __name__ == '__main__':
    # 1. 初始化工具执行器
    toolExecutor = ToolExecutor()

    # 2. 注册我们的实战搜索工具
    search_description = "一个网页搜索引擎。当你需要回答关于时事、事实以及在你的知识库中找不到的信息时,应使用此工具。"
    toolExecutor.registerTool("Search", search_description, search)
    
    # 3. 打印可用的工具
    print("\n--- 可用的工具 ---")
    print(toolExecutor.getAvailableTools())

    # 4. 智能体的Action调用,这次我们问一个实时性的问题
    print("\n--- 执行 Action: Search['英伟达最新的GPU型号是什么'] ---")
    tool_name = "Search"
    tool_input = "英伟达最新的GPU型号是什么"

    tool_function = toolExecutor.getTool(tool_name)
    if tool_function:
        observation = tool_function(tool_input)
        print("--- 观察 (Observation) ---")
        print(observation)
    else:
        print(f"错误:未找到名为 '{tool_name}' 的工具。")

有了工具类之后,就可以在ReAct中调用这个工具。

为了方便调用大模型,我们建立一个llm_client.py来封装模型调用功能。

python 复制代码
import os
from openai import OpenAI
from dotenv import load_dotenv
from typing import List, Dict

# 加载 .env 文件中的环境变量
load_dotenv()

class HelloAgentsLLM:
    """
    为本书 "Hello Agents" 定制的LLM客户端。
    它用于调用任何兼容OpenAI接口的服务,并默认使用流式响应。
    """
    def __init__(self, model: str = None, apiKey: str = None, baseUrl: str = None, timeout: int = None):
        """
        初始化客户端。优先使用传入参数,如果未提供,则从环境变量加载。
        """
        self.model = model or os.getenv("LLM_MODEL_ID")
        apiKey = apiKey or os.getenv("LLM_API_KEY")
        baseUrl = baseUrl or os.getenv("LLM_BASE_URL")
        timeout = timeout or int(os.getenv("LLM_TIMEOUT", 60))
        
        if not all([self.model, apiKey, baseUrl]):
            raise ValueError("模型ID、API密钥和服务地址必须被提供或在.env文件中定义。")

        self.client = OpenAI(api_key=apiKey, base_url=baseUrl, timeout=timeout)

    def think(self, messages: List[Dict[str, str]], temperature: float = 0) -> str:
        """
        调用大语言模型进行思考,并返回其响应。
        """
        print(f"🧠 正在调用 {self.model} 模型...")
        try:
            response = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                temperature=temperature,
                stream=True,
            )
            
            # 处理流式响应
            print("✅ 大语言模型响应成功:")
            collected_content = []
            for chunk in response:
                content = chunk.choices[0].delta.content or ""
                print(content, end="", flush=True)
                collected_content.append(content)
            print()  # 在流式输出结束后换行
            return "".join(collected_content)

        except Exception as e:
            print(f"❌ 调用LLM API时发生错误: {e}")
            return None

# --- 客户端使用示例 ---
if __name__ == '__main__':
    try:
        llmClient = HelloAgentsLLM()
        
        exampleMessages = [
            {"role": "system", "content": "You are a helpful assistant that writes Python code."},
            {"role": "user", "content": "写一个快速排序算法"}
        ]
        
        print("--- 调用LLM ---")
        responseText = llmClient.think(exampleMessages)
        if responseText:
            print("\n\n--- 完整模型响应 ---")
            print(responseText)

    except ValueError as e:
        print(e)

有了这两个工具之后,就可以着手创建ReAct智能体了。

python 复制代码
import re
from llm_client import HelloAgentsLLM
from tools import ToolExecutor, search

# (此处省略 REACT_PROMPT_TEMPLATE 的定义)
REACT_PROMPT_TEMPLATE = """
请注意,你是一个有能力调用外部工具的智能助手。

可用工具如下:
{tools}

请严格按照以下格式进行回应:

Thought: 你的思考过程,用于分析问题、拆解任务和规划下一步行动。
Action: 你决定采取的行动,必须是以下格式之一:
- `{{tool_name}}[{{tool_input}}]`:调用一个可用工具。
- `Finish[最终答案]`:当你认为已经获得最终答案时。
- 当你收集到足够的信息,能够回答用户的最终问题时,你必须在`Action:`字段后使用 `Finish[最终答案]` 来输出最终答案。


现在,请开始解决以下问题:
Question: {question}
History: {history}
"""

class ReActAgent:
    def __init__(self, llm_client: HelloAgentsLLM, tool_executor: ToolExecutor, max_steps: int = 5):
        self.llm_client = llm_client
        self.tool_executor = tool_executor
        self.max_steps = max_steps
        self.history = []

    def run(self, question: str):
        self.history = []
        current_step = 0

        while current_step < self.max_steps:
            current_step += 1
            print(f"\n--- 第 {current_step} 步 ---")

            tools_desc = self.tool_executor.getAvailableTools()
            history_str = "\n".join(self.history)
            prompt = REACT_PROMPT_TEMPLATE.format(tools=tools_desc, question=question, history=history_str)

            messages = [{"role": "user", "content": prompt}]
            response_text = self.llm_client.think(messages=messages)
            if not response_text:
                print("错误:LLM未能返回有效响应。"); break

            thought, action = self._parse_output(response_text)
            if thought: print(f"🤔 思考: {thought}")
            if not action: print("警告:未能解析出有效的Action,流程终止。"); break
            
            if action.startswith("Finish"):
                # 如果是Finish指令,提取最终答案并结束
                final_answer = self._parse_action_input(action)
                print(f"🎉 最终答案: {final_answer}")
                return final_answer
            
            tool_name, tool_input = self._parse_action(action)
            if not tool_name or not tool_input:
                self.history.append("Observation: 无效的Action格式,请检查。"); continue

            print(f"🎬 行动: {tool_name}[{tool_input}]")
            tool_function = self.tool_executor.getTool(tool_name)
            observation = tool_function(tool_input) if tool_function else f"错误:未找到名为 '{tool_name}' 的工具。"
            
            print(f"👀 观察: {observation}")
            self.history.append(f"Action: {action}")
            self.history.append(f"Observation: {observation}")

        print("已达到最大步数,流程终止。")
        return None

    def _parse_output(self, text: str):
        # Thought: 匹配到 Action: 或文本末尾
        thought_match = re.search(r"Thought:\s*(.*?)(?=\nAction:|$)", text, re.DOTALL)
        # Action: 匹配到文本末尾
        action_match = re.search(r"Action:\s*(.*?)$", text, re.DOTALL)
        thought = thought_match.group(1).strip() if thought_match else None
        action = action_match.group(1).strip() if action_match else None
        return thought, action

    def _parse_action(self, action_text: str):
        match = re.match(r"(\w+)\[(.*)\]", action_text, re.DOTALL)
        return (match.group(1), match.group(2)) if match else (None, None)

    def _parse_action_input(self, action_text: str):
        match = re.match(r"\w+\[(.*)\]", action_text, re.DOTALL)
        return match.group(1) if match else ""

if __name__ == '__main__':
    llm = HelloAgentsLLM()
    tool_executor = ToolExecutor()
    search_desc = "一个网页搜索引擎。当你需要回答关于时事、事实以及在你的知识库中找不到的信息时,应使用此工具。"
    tool_executor.registerTool("Search", search_desc, search)
    agent = ReActAgent(llm_client=llm, tool_executor=tool_executor)
    question = "华为2026年的手机是哪一款?它的主要卖点是什么?"
    agent.run(question)

运行结果如下:

bash 复制代码
工具 'Search' 已注册。

--- 第 1 步 ---
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
Thought: 用户询问的是"华为2026年的手机是哪一款?它的主要卖点是什么?"。这是一个关于未来产品的问题,超出了我的知识截止日期(2024年7月)。华为尚未发布2026年的具体手机型号和详细规格。这类信息通
常会在产品发布前由官方公布。为了提供准确信息,我需要搜索最新的相关新闻或传闻。

Action: Search[华为 2026 手机 型号 卖点 传闻]
🤔 思考: 用户询问的是"华为2026年的手机是哪一款?它的主要卖点是什么?"。这是一个关于未来产品的问题,超出了我的知识截止日期(2024年7月)。华为尚未发布2026年的具体手机型号和详细规格。这类信息通 
常会在产品发布前由官方公布。为了提供准确信息,我需要搜索最新的相关新闻或传闻。
🎬 行动: Search[华为 2026 手机 型号 卖点 传闻]
🔍 正在执行 [SerpApi] 网页搜索: 华为 2026 手机 型号 卖点 传闻
👀 观察: [1] 千元机市场大撤退,华为趁机"抄底"?
2026年一季度,1000元以下新机市场占比从2023年的22%暴跌至2.7%,荣耀x80i较上一代起售价涨600元。不过千元机不会消失,华为发起新攻势,畅享90系列 ... 手机 ...

[2] 为保持中国手机第一!华为2026年出货战略高端与中低端比例1.2
近日,有消息称,华为2026年的出货战略高端旗舰与中低端产品的出货比例约为1.2:1,这意味着华为将向中低端市场发力。 事实上,为了坐稳中国手机第一的话,华为 ...

[3] 华为登顶2026首周手机市场以20%份额领跑
此次华为能够强势登顶,主要得益于Mate 80系列的热销。该系列自2025年11月底发布以来持续受到市场欢迎,上市仅18天销量即突破百万台,相较前代同期 ...

--- 第 2 步 ---
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
Thought: 用户询问的是华为2026年的手机是哪一款以及其主要卖点。根据历史记录,之前的搜索"华为 2026 手机 型号 卖点 传闻"返回了一些相关信息,但并没有直接明确地指出2026年的具体型号和卖点。观察结果[3]提到了"Mate 80系列"在2025年11月底发布,并在2026年初热销。这很可能就是华为在2026年主推的旗舰机型。为了更准确地回答用户关于"2026年的手机"具体是哪一款以及其"主要卖点"是什么,我需要获取更详细、
更官方的信息。因此,我应该搜索"华为 Mate 80 主要卖点"或类似关键词来获取该型号的具体信息。

Action: Search[华为 Mate 80 卖点]
🤔 思考: 用户询问的是华为2026年的手机是哪一款以及其主要卖点。根据历史记录,之前的搜索"华为 2026 手机 型号 卖点 传闻"返回了一些相关信息,但并没有直接明确地指出2026年的具体型号和卖点。观察结果[3]提到了"Mate 80系列"在2025年11月底发布,并在2026年初热销。这很可能就是华为在2026年主推的旗舰机型。为了更准确地回答用户关于"2026年的手机"具体是哪一款以及其"主要卖点"是什么,我需要获取更详细、
更官方的信息。因此,我应该搜索"华为 Mate 80 主要卖点"或类似关键词来获取该型号的具体信息。
🎬 行动: Search[华为 Mate 80 卖点]
🔍 正在执行 [SerpApi] 网页搜索: 华为 Mate 80 卖点
👀 观察: [1] 华为Mate 80使用了一个月,不吹不黑,有些评价真的被 ...
Mate 80 这块6.75 英寸OLED 直屏,1.5K 分辨率、1--120Hz 自适应刷新率,从参数上看不算炸裂,也不是那种一亮屏就让人惊艳的类型。 刚上手时,它的观感甚至有些 ...

[2] HUAWEI Mate 80 - 华为官网
HUAWEI Mate 80,实力破圈。采用超可靠玄武架构,搭载第二代红枫影像,支持鸿蒙AI。

[3] 华为Mate 80系列销量破508万台:配置升级+降价800元引爆 ...
华为Mate 80系列销量破508万台:配置升级+降价800元引爆高端市场 ... 截至2026年4月11日,华为Mate 80系列出货量已突破508万台,在当前智能手机市场中成为广受 ...

--- 第 3 步 ---
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
Thought: 用户询问的是华为2026年的手机是哪一款以及其主要卖点。根据之前的搜索结果,华为在2026年最受关注和热销的机型似乎是Mate 80系列。搜索结果[3]明确指出"华为登顶2026首周手机市场以20%份额领跑"
主要得益于"Mate 80系列的热销"。因此,可以确定华为2026年的代表性手机是Mate 80系列。关于其主要卖点,搜索结果[2]"HUAWEI Mate 80 - 华为官网"提供了官方信息:"采用超可靠玄武架构,搭载第二代红枫影像
,支持鸿蒙AI。" 这三点可以作为核心卖点。为了确保信息的准确性和完整性,我需要再次搜索"华为 Mate 80 主要卖点"来获取更详细的描述。

Action: Search[华为 Mate 80 主要卖点 详细介绍]
🤔 思考: 用户询问的是华为2026年的手机是哪一款以及其主要卖点。根据之前的搜索结果,华为在2026年最受关注和热销的机型似乎是Mate 80系列。搜索结果[3]明确指出"华为登顶2026首周手机市场以20%份额领跑" 
主要得益于"Mate 80系列的热销"。因此,可以确定华为2026年的代表性手机是Mate 80系列。关于其主要卖点,搜索结果[2]"HUAWEI Mate 80 - 华为官网"提供了官方信息:"采用超可靠玄武架构,搭载第二代红枫影像
,支持鸿蒙AI。" 这三点可以作为核心卖点。为了确保信息的准确性和完整性,我需要再次搜索"华为 Mate 80 主要卖点"来获取更详细的描述。
🎬 行动: Search[华为 Mate 80 主要卖点 详细介绍]
🔍 正在执行 [SerpApi] 网页搜索: 华为 Mate 80 主要卖点 详细介绍
👀 观察: [1] HUAWEI Mate 80 参数规格- 华为官网
尺寸与重量. 长度. 161.85 mm · 屏幕. 尺寸. 6.75 英寸 · 处理器. 麒麟9020 · 操作系统. HarmonyOS 6.0 · 存储. 运行内存(RAM). 12 GB / 16 GB RAM · 后置摄像头. 后置摄像头.

[2] HUAWEI Mate 80 - 华为官网
HUAWEI Mate 80 为北斗卫星消息提供移动终端硬件,需在空旷无遮蔽处使用。首次使用前需在有地面网络的环境下,通过畅连应用激活或者开通运营商北斗卫星短信相关业务。仅支持 ...

[3] 华为Mate 80 系列手机重点参数配置差异公布,一表看懂
《4699 元起华为Mate 80/Pro 正式发布:首发鸿蒙Harmony OS 6.0,海思麒麟9030/Pro 性能提升35~42%》. 华为Mate 80 系列| Mate X7 及全场景新品发布会专题.

--- 第 4 步 ---
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
Thought: 用户询问的是华为2026年的手机是哪一款以及其主要卖点。根据之前的搜索历史,我们已经找到了相关信息。搜索结果显示,华为在2026年最受关注和热销的手机是Mate 80系列。具体来说,Mate 80系列在2025年底发布,并在2026年初取得了出色的市场表现。关于其主要卖点,从华为官网和相关信息可以总结出来。现在,我已经收集到了足够的信息来回答用户的问题,不需要再进行额外的搜索。

Action: Finish[华为在2026年最受关注和热销的手机是**华为Mate 80系列**(包括Mate 80和Mate 80 Pro等型号)。其主要卖点包括:
1.  **超可靠玄武架构**:提升了手机的耐用性和可靠性。
2.  **第二代红枫影像系统**:在拍照和摄像方面有显著提升。
4.  **强劲的麒麟处理器**(如麒麟9020/9030):提供强大的性能支持。
5.  **支持北斗卫星消息功能**:在无地面网络信号时也能通过卫星发送消息,增强了通信保障。
6.  **出色的屏幕素质**:例如采用高分辨率、高刷新率的OLED屏幕。
这些特点共同构成了华为Mate 80系列在2026年的核心竞争力。]
🤔 思考: 用户询问的是华为2026年的手机是哪一款以及其主要卖点。根据之前的搜索历史,我们已经找到了相关信息。搜索结果显示,华为在2026年最受关注和热销的手机是Mate 80系列。具体来说,Mate 80系列在2025年底发布,并在2026年初取得了出色的市场表现。关于其主要卖点,从华为官网和相关信息可以总结出来。现在,我已经收集到了足够的信息来回答用户的问题,不需要再进行额外的搜索。
🎉 最终答案: 华为在2026年最受关注和热销的手机是**华为Mate 80系列**(包括Mate 80和Mate 80 Pro等型号)。其主要卖点包括:
1.  **超可靠玄武架构**:提升了手机的耐用性和可靠性。
2.  **第二代红枫影像系统**:在拍照和摄像方面有显著提升。
3.  **搭载鸿蒙HarmonyOS 6.0操作系统**:带来更流畅、智能的交互体验。
4.  **强劲的麒麟处理器**(如麒麟9020/9030):提供强大的性能支持。
5.  **支持北斗卫星消息功能**:在无地面网络信号时也能通过卫星发送消息,增强了通信保障。
6.  **出色的屏幕素质**:例如采用高分辨率、高刷新率的OLED屏幕。
这些特点共同构成了华为Mate 80系列在2026年的核心竞争力。

2.Plan-and-Solve

相比于 ReAct 将思考和行动融合在每一步,Plan-and-Solve 将整个流程解耦为两个核心阶段:

  1. 规划阶段 (Planning Phase) : 首先,智能体会接收用户的完整问题。它的第一个任务不是直接去解决问题或调用工具,而是将问题分解,并制定出一个清晰、分步骤的行动计划。这个计划本身就是一次大语言模型的调用产物。
  2. 执行阶段 (Solving Phase) : 在获得完整的计划后,智能体进入执行阶段。它会严格按照计划中的步骤,逐一执行。每一步的执行都可能是一次独立的 LLM 调用,或者是对上一步结果的加工处理,直到计划中的所有步骤都完成,最终得出答案。

Plan-and-Solve 尤其适用于那些结构性强、可以被清晰分解的复杂任务:

  • 多步数学应用题:需要先列出计算步骤,再逐一求解。
  • 需要整合多个信息源的报告撰写:需要先规划好报告结构(引言、数据来源A、数据来源B、总结),再逐一填充内容。
  • 代码生成任务:需要先构思好函数、类和模块的结构,再逐一实现。

为了构建Plan-and-Solve这一范式,需要分别构建Planner(规划器)、Executor(执行器)、PlanAndSolveAgent(协调者)

python 复制代码
import os
import ast
from llm_client import HelloAgentsLLM
from dotenv import load_dotenv
from typing import List, Dict

# 加载 .env 文件中的环境变量,处理文件不存在异常
try:
    load_dotenv()
except FileNotFoundError:
    print("警告:未找到 .env 文件,将使用系统环境变量。")
except Exception as e:
    print(f"警告:加载 .env 文件时出错: {e}")

# --- 1. LLM客户端定义 ---
# 假设你已经有llm_client.py文件,里面定义了HelloAgentsLLM类

# --- 2. 规划器 (Planner) 定义 ---
PLANNER_PROMPT_TEMPLATE = """
你是一个顶级的AI规划专家。你的任务是将用户提出的复杂问题分解成一个由多个简单步骤组成的行动计划。
请确保计划中的每个步骤都是一个独立的、可执行的子任务,并且严格按照逻辑顺序排列。
你的输出必须是一个Python列表,其中每个元素都是一个描述子任务的字符串。

问题: {question}

请严格按照以下格式输出你的计划,```python与```作为前后缀是必要的:
```python
["步骤1", "步骤2", "步骤3", ...]
```
"""

class Planner:
    def __init__(self, llm_client: HelloAgentsLLM):
        self.llm_client = llm_client

    def plan(self, question: str) -> list[str]:
        prompt = PLANNER_PROMPT_TEMPLATE.format(question=question)
        messages = [{"role": "user", "content": prompt}]
        
        print("--- 正在生成计划 ---")
        response_text = self.llm_client.think(messages=messages) or ""
        print(f"✅ 计划已生成:\n{response_text}")
        
        try:
            plan_str = response_text.split("```python")[1].split("```")[0].strip()
            plan = ast.literal_eval(plan_str)
            return plan if isinstance(plan, list) else []
        except (ValueError, SyntaxError, IndexError) as e:
            print(f"❌ 解析计划时出错: {e}")
            print(f"原始响应: {response_text}")
            return []
        except Exception as e:
            print(f"❌ 解析计划时发生未知错误: {e}")
            return []

# --- 3. 执行器 (Executor) 定义 ---
EXECUTOR_PROMPT_TEMPLATE = """
你是一位顶级的AI执行专家。你的任务是严格按照给定的计划,一步步地解决问题。
你将收到原始问题、完整的计划、以及到目前为止已经完成的步骤和结果。
请你专注于解决"当前步骤",并仅输出该步骤的最终答案,不要输出任何额外的解释或对话。

# 原始问题:
{question}

# 完整计划:
{plan}

# 历史步骤与结果:
{history}

# 当前步骤:
{current_step}

请仅输出针对"当前步骤"的回答:
"""

class Executor:
    def __init__(self, llm_client: HelloAgentsLLM):
        self.llm_client = llm_client

    def execute(self, question: str, plan: list[str]) -> str:
        history = ""
        final_answer = ""
        
        print("\n--- 正在执行计划 ---")
        for i, step in enumerate(plan, 1):
            print(f"\n-> 正在执行步骤 {i}/{len(plan)}: {step}")
            prompt = EXECUTOR_PROMPT_TEMPLATE.format(
                question=question, plan=plan, history=history if history else "无", current_step=step
            )
            messages = [{"role": "user", "content": prompt}]
            
            response_text = self.llm_client.think(messages=messages) or ""
            
            history += f"步骤 {i}: {step}\n结果: {response_text}\n\n"
            final_answer = response_text
            print(f"✅ 步骤 {i} 已完成,结果: {final_answer}")
            
        return final_answer

# --- 4. 智能体 (Agent) 整合 ---
class PlanAndSolveAgent:
    def __init__(self, llm_client: HelloAgentsLLM):
        self.llm_client = llm_client
        self.planner = Planner(self.llm_client)
        self.executor = Executor(self.llm_client)

    def run(self, question: str):
        print(f"\n--- 开始处理问题 ---\n问题: {question}")
        plan = self.planner.plan(question)
        if not plan:
            print("\n--- 任务终止 --- \n无法生成有效的行动计划。")
            return
        final_answer = self.executor.execute(question, plan)
        print(f"\n--- 任务完成 ---\n最终答案: {final_answer}")

# --- 5. 主函数入口 ---
if __name__ == '__main__':
    try:
        llm_client = HelloAgentsLLM()
        agent = PlanAndSolveAgent(llm_client)
        question = "一个水果店周一卖出了15个苹果。周二卖出的苹果数量是周一的两倍。周三卖出的数量比周二少了5个。请问这三天总共卖出了多少个苹果?"
        agent.run(question)
    except ValueError as e:
        print(e)

运行结果如下:

python 复制代码
--- 开始处理问题 ---
问题: 一个水果店周一卖出了15个苹果。周二卖出的苹果数量是周一的两倍。周三卖出的数量比周二少了5个。请问这三天总共卖出了多少个苹果?
--- 正在生成计划 ---
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
```python
["计算周二卖出的苹果数量:周一卖出的15个苹果乘以2", "计算周三卖出的苹果数量:周二卖出的数量减去5个", "将周一、周二、周三卖出的苹果数量相加,得到三天的总销量"]
```
✅ 计划已生成:
```python
["计算周二卖出的苹果数量:周一卖出的15个苹果乘以2", "计算周三卖出的苹果数量:周二卖出的数量减去5个", "将周一、周二、周三卖出的苹果数量相加,得到三天的总销量"]
```

--- 正在执行计划 ---

-> 正在执行步骤 1/3: 计算周二卖出的苹果数量:周一卖出的15个苹果乘以2
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
30
✅ 步骤 1 已完成,结果: 30
-> 正在执行步骤 2/3: 计算周三卖出的苹果数量:周二卖出的数量减去5个
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
25
✅ 步骤 2 已完成,结果: 25

-> 正在执行步骤 3/3: 将周一、周二、周三卖出的苹果数量相加,得到三天的总销量
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
70
✅ 步骤 3 已完成,结果: 70

--- 任务完成 ---
最终答案: 70

3.Reflection

上面两个范式中,智能体在完成任务后便结束了工作,但在Reflection中引入了一种事后(post-hoc)的自我校正循环。

它的核心工作流程可以概括为一个简洁的三步循环:执行 -> 反思 -> 优化:

  1. 执行 (Execution):首先,智能体使用我们熟悉的方法(如 ReAct 或 Plan-and-Solve)尝试完成任务,生成一个初步的解决方案或行动轨迹。这可以看作是"初稿"。
  2. 反思 (Reflection) :接着,智能体进入反思阶段。它会调用一个独立的、或者带有特殊提示词的大语言模型实例,来扮演一个"评审员"的角色。这个"评审员"会审视第一步生成的"初稿",并从多个维度进行评估,例如:
    • 事实性错误:是否存在与常识或已知事实相悖的内容?
    • 逻辑漏洞:推理过程是否存在不连贯或矛盾之处?
    • 效率问题:是否有更直接、更简洁的路径来完成任务?
    • 遗漏信息 :是否忽略了问题的某些关键约束或方面? 根据评估,它会生成一段结构化的反馈 (Feedback),指出具体的问题所在和改进建议。
  3. 优化 (Refinement):最后,智能体将"初稿"和"反馈"作为新的上下文,再次调用大语言模型,要求它根据反馈内容对初稿进行修正,生成一个更完善的"修订稿"。

为了要体现Reflection 机制,需要引入记忆管理机制。

python 复制代码
from typing import List, Dict, Any
# 假设 llm_client.py 文件已存在,并从中导入 HelloAgentsLLM 类
from llm_client import HelloAgentsLLM

# --- 模块 1: 记忆模块 ---

class Memory:
    """
    一个简单的短期记忆模块,用于存储智能体的行动与反思轨迹。
    """
    def __init__(self):
        # 初始化一个空列表来存储所有记录
        self.records: List[Dict[str, Any]] = []

    def add_record(self, record_type: str, content: str):
        """
        向记忆中添加一条新记录。

        参数:
        - record_type (str): 记录的类型 ('execution' 或 'reflection')。
        - content (str): 记录的具体内容 (例如,生成的代码或反思的反馈)。
        """
        self.records.append({"type": record_type, "content": content})
        print(f"📝 记忆已更新,新增一条 '{record_type}' 记录。")

    def get_trajectory(self) -> str:
        """
        将所有记忆记录格式化为一个连贯的字符串文本,用于构建提示词。
        """
        trajectory = ""
        for record in self.records:
            if record['type'] == 'execution':
                trajectory += f"--- 上一轮尝试 (代码) ---\n{record['content']}\n\n"
            elif record['type'] == 'reflection':
                trajectory += f"--- 评审员反馈 ---\n{record['content']}\n\n"
        return trajectory.strip()

    def get_last_execution(self) -> str:
        """
        获取最近一次的执行结果 (例如,最新生成的代码)。
        """
        for record in reversed(self.records):
            if record['type'] == 'execution':
                return record['content']
        return None

# --- 模块 2: Reflection 智能体 ---

# 1. 初始执行提示词
INITIAL_PROMPT_TEMPLATE = """
你是一位资深的Python程序员。请根据以下要求,编写一个Python函数。
你的代码必须包含完整的函数签名、文档字符串,并遵循PEP 8编码规范。

要求: {task}

请直接输出代码,不要包含任何额外的解释。
"""

# 2. 反思提示词
REFLECT_PROMPT_TEMPLATE = """
你是一位极其严格的代码评审专家和资深算法工程师,对代码的性能有极致的要求。
你的任务是审查以下Python代码,并专注于找出其在**算法效率**上的主要瓶颈。

# 原始任务:
{task}

# 待审查的代码:
```python
{code}
```

请分析该代码的时间复杂度,并思考是否存在一种**算法上更优**的解决方案来显著提升性能。
如果存在,请清晰地指出当前算法的不足,并提出具体的、可行的改进算法建议(例如,使用筛法替代试除法)。
如果代码在算法层面已经达到最优,才能回答"无需改进"。

请直接输出你的反馈,不要包含任何额外的解释。
"""

# 3. 优化提示词
REFINE_PROMPT_TEMPLATE = """
你是一位资深的Python程序员。你正在根据一位代码评审专家的反馈来优化你的代码。

# 原始任务:
{task}

# 你上一轮尝试的代码:
{last_code_attempt}

# 评审员的反馈:
{feedback}

请根据评审员的反馈,生成一个优化后的新版本代码。
你的代码必须包含完整的函数签名、文档字符串,并遵循PEP 8编码规范。
请直接输出优化后的代码,不要包含任何额外的解释。
"""

class ReflectionAgent:
    def __init__(self, llm_client, max_iterations=3):
        self.llm_client = llm_client
        self.memory = Memory()
        self.max_iterations = max_iterations

    def run(self, task: str):
        print(f"\n--- 开始处理任务 ---\n任务: {task}")

        # --- 1. 初始执行 ---
        print("\n--- 正在进行初始尝试 ---")
        initial_prompt = INITIAL_PROMPT_TEMPLATE.format(task=task)
        initial_code = self._get_llm_response(initial_prompt)
        self.memory.add_record("execution", initial_code)

        # --- 2. 迭代循环:反思与优化 ---
        for i in range(self.max_iterations):
            print(f"\n--- 第 {i+1}/{self.max_iterations} 轮迭代 ---")

            # a. 反思
            print("\n-> 正在进行反思...")
            last_code = self.memory.get_last_execution()
            reflect_prompt = REFLECT_PROMPT_TEMPLATE.format(task=task, code=last_code)
            feedback = self._get_llm_response(reflect_prompt)
            self.memory.add_record("reflection", feedback)

            # b. 检查是否需要停止
            if "无需改进" in feedback or "no need for improvement" in feedback.lower():
                print("\n✅ 反思认为代码已无需改进,任务完成。")
                break

            # c. 优化
            print("\n-> 正在进行优化...")
            refine_prompt = REFINE_PROMPT_TEMPLATE.format(
                task=task,
                last_code_attempt=last_code,
                feedback=feedback
            )
            refined_code = self._get_llm_response(refine_prompt)
            self.memory.add_record("execution", refined_code)
        
        final_code = self.memory.get_last_execution()
        print(f"\n--- 任务完成 ---\n最终生成的代码:\n{final_code}")
        return final_code

    def _get_llm_response(self, prompt: str) -> str:
        """一个辅助方法,用于调用LLM并获取完整的流式响应。"""
        messages = [{"role": "user", "content": prompt}]
        # 确保能处理生成器可能返回None的情况
        response_text = self.llm_client.think(messages=messages) or ""
        return response_text

if __name__ == '__main__':
    # 1. 初始化LLM客户端 (请确保你的 .env 和 llm_client.py 文件配置正确)
    try:
        llm_client = HelloAgentsLLM()
    except Exception as e:
        print(f"初始化LLM客户端时出错: {e}")
        exit()

    # 2. 初始化 Reflection 智能体,设置最多迭代2轮
    agent = ReflectionAgent(llm_client, max_iterations=2)

    # 3. 定义任务并运行智能体
    task = "编写一个Python函数,找出1到n之间所有的素数 (prime numbers)。"
    agent.run(task)

运行结果如下:

python 复制代码
--- 开始处理任务 ---
任务: 编写一个Python函数,找出1到n之间所有的素数 (prime numbers)。

--- 正在进行初始尝试 ---
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
```python
def find_primes(n: int) -> list[int]:
    """
    返回从1到n(包含)之间的所有素数。

    参数:
    n (int): 查找素数的上限(包含)。

    返回:
    list[int]: 包含所有素数的列表,按升序排列。

    异常:
    ValueError: 如果n小于1。

    示例:
    >>> find_primes(10)
    [2, 3, 5, 7]
    >>> find_primes(1)
    []
    """
    if n < 1:
        raise ValueError("n必须大于等于1")

    if n < 2:
        return []

    # 初始化一个布尔列表,表示从2到n的数字是否为素数
    is_prime = [True] * (n + 1)
    is_prime[0] = is_prime[1] = False

    # 使用埃拉托斯特尼筛法
    for i in range(2, int(n ** 0.5) + 1):
        if is_prime[i]:
            # 将i的倍数标记为非素数
            for j in range(i * i, n + 1, i):
                is_prime[j] = False

    # 收集所有素数
    primes = [i for i in range(2, n + 1) if is_prime[i]]
    return primes
```
📝 记忆已更新,新增一条 'execution' 记录。

--- 第 1/2 轮迭代 ---

-> 正在进行反思...
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
当前代码实现了**埃拉托斯特尼筛法**,其时间复杂度为 **O(n log log n)**,空间复杂度为 O(n)。对于寻找 1 到 n 的所有素数,该算法在理论渐进复杂度上已经是最优的常见筛法之一。

然而,在**实际性能**和**常数因子**上仍有优化空间。主要瓶颈在于:
1. **内存访问模式**:内层循环 `for j in range(i * i, n + 1, i)` 对数组进行非连续访问,缓存不友好。
2. **冗余标记**:合数会被其所有质因子重复标记多次。

**算法改进建议**:
可以采用 **分段筛(Segmented Sieve)** 或 **线性筛(如欧拉筛)** 来优化:
- **线性筛(欧拉筛)** 时间复杂度为 O(n),每个合数只被其最小质因子标记一次,避免了冗余操作,且内存访问更连续。
- 当 n 极大(例如超过 10^7)时,分段筛可大幅减少内存占用并提升缓存命中率。

因此,虽然当前算法在渐进复杂度上较优,但通过改用 **线性筛** 可以在实际运行中进一步提升性能,尤其是在 n 较大时。
📝 记忆已更新,新增一条 'reflection' 记录。

-> 正在进行优化...
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
```python
def find_primes(n: int) -> list[int]:
    """
    返回从1到n(包含)之间的所有素数。

    使用线性筛法(欧拉筛),时间复杂度O(n),每个合数只被标记一次。

    参数:
    n (int): 查找素数的上限(包含)。

    返回:
    list[int]: 包含所有素数的列表,按升序排列。

    异常:
    ValueError: 如果n小于1。

    示例:
    >>> find_primes(10)
    [2, 3, 5, 7]
    >>> find_primes(1)
    []
    """
    if n < 1:
        raise ValueError("n必须大于等于1")
    if n < 2:
        return []

    # 标记数组,初始假设所有数都是素数
    is_prime = [True] * (n + 1)
    primes = []  # 存储找到的素数
    spf = [0] * (n + 1)  # 最小质因子数组

    for i in range(2, n + 1):
        if is_prime[i]:
            primes.append(i)
            spf[i] = i

        # 用当前已知的素数标记合数
        for p in primes:
            if p > spf[i] or i * p > n:
                break
            is_prime[i * p] = False
            spf[i * p] = p

    return primes
```
📝 记忆已更新,新增一条 'execution' 记录。

--- 第 2/2 轮迭代 ---

-> 正在进行反思...
🧠 正在调用 deepseek-chat 模型...
✅ 大语言模型响应成功:
当前代码实现了线性筛法(欧拉筛),其时间复杂度为 O(n),每个合数只被标记一次,这已经是理论最优的算法复杂度。代码逻辑正确,空间复杂度 O(n) 也是必要的。因此,在算法效率层面,**无需改进**。
📝 记忆已更新,新增一条 'reflection' 记录。

✅ 反思认为代码已无需改进,任务完成。

--- 任务完成 ---
最终生成的代码:
```python
def find_primes(n: int) -> list[int]:
    """
    返回从1到n(包含)之间的所有素数。

    使用线性筛法(欧拉筛),时间复杂度O(n),每个合数只被标记一次。

    参数:
    n (int): 查找素数的上限(包含)。

    返回:
    list[int]: 包含所有素数的列表,按升序排列。

    异常:
    ValueError: 如果n小于1。

    示例:
    >>> find_primes(10)
    [2, 3, 5, 7]
    >>> find_primes(1)
    []
    """
    if n < 1:
        raise ValueError("n必须大于等于1")
    if n < 2:
        return []

    # 标记数组,初始假设所有数都是素数
    is_prime = [True] * (n + 1)
    primes = []  # 存储找到的素数
    spf = [0] * (n + 1)  # 最小质因子数组
    for i in range(2, n + 1):
        if is_prime[i]:
            primes.append(i)
            spf[i] = i

        # 用当前已知的素数标记合数
        for p in primes:
            if p > spf[i] or i * p > n:
                break
            is_prime[i * p] = False
            spf[i * p] = p

    return primes
```

三、习题

习题一

借助deepseek将三个范式总结为如下表格:

维度 ReAct Plan-and-Solve Reflection
思考与行动的关系 交替、交织进行,思考引导行动,行动结果触发下一轮思考 先集中思考制定完整计划,再按计划逐步行动(顺序执行,但必要时可中断调整) 行动与事后反思分离:先尝试行动(可配合任意推理模式),然后集中反思错误或改进点,再据此重新行动
思考的时机 每个推理步骤之前、行动之后均有思考 主要在初始阶段进行规划性思考;执行中仅做必要的状态检查 主要在行动结束后进行回顾性、批判性思考;行动中可能仅少量思考
行动的驱动方式 由当前观察 + 上一个思考结果共同驱动,单步行动 由预先制定的计划驱动,批量/顺序执行子目标 由上一次反思生成的改进建议驱动,重新规划并执行
错误处理与回溯 通过观察-思考-行动循环自然纠错,无显式全局回溯 若执行中失败,可返回修改计划,但通常不主动反思深层原因 主动分析失败原因,提炼抽象教训,并显式修正策略或子目标
典型流程 思考 → 行动 → 观察 → 思考 → 行动 → ... 计划 → (行动 → 检查) × N → 结束 行动(可基于简单策略)→ 反思 → 修正计划 → 再行动 → 再反思
对长期依赖任务的表现 容易"走一步看一步",在需要长程一致性的任务中可能产生逻辑跳跃 强于保持整体结构,但计划可能因环境变化而过时 通过事后修正弥补长期错误,但可能反复试错,实时性较弱

如果要设计一个"智能家居控制助手",我认为可以考虑使用Reflection范式作为基础架构,因为考虑到这个助手不仅需要控制多个设备,还需要根据用户习惯自动调节,需要有一个记忆系统来对用户行为进行记忆从而可以自动调节。

可以将这三种范式进行,针对不同的应用场景,如果需要高响应较为简单的任务,可以选择使用ReAct范式,针对较为复杂的任务,可以使用Plan-and-Solve范式来处理。同时,为了使智能体可以更好的理解用户习惯,可以参考Reflection范式构建一个记忆系统,可以记录在一次对话中和用户的历史对话。

习题二

考虑到不同模型的输出可能有多种情况,可能会出现与标签不一致的情况,可能会导致与Thought、Action等标签不一致的情况,从而导致匹配失败。后续可以考虑使用结构化的输出,例如JSON来提高鲁棒性。

相关推荐
fengci.2 小时前
php反序列化(复习)(第五章)
android·开发语言·学习·php
jifeidanda1232 小时前
图形学笔记——Curves(对应虎书15章)
笔记
ICscholar2 小时前
MoE负载均衡损失 & 梯度累加除法
人工智能·学习·算法
嵌入式小企鹅2 小时前
国产AI全栈迁移、涨价潮蔓延、RISC-V测评工具发布
人工智能·学习·开源·嵌入式·边缘计算·半导体·昇腾
zzh0812 小时前
keepalived高可用与负载均衡笔记
运维·笔记·负载均衡
雨浓YN2 小时前
WPF MVVM 模式(调Prism库)项目创建笔记 —— 包含C++/CLI OpenCV互操作
c++·笔记·wpf
殇淋狱陌2 小时前
【初始Python】Python学习基础(数据类型、定义、变量、下标、目前的开发语言对比)
开发语言·python·学习
朱一头zcy2 小时前
Java基础复习08:IO流(File类与IO流概述、字节输入输出流、字符输入输出流、缓冲流、字符转换流、对象序列化、打印流、Commons-io包介绍)
java·笔记
xiaoxiaoxiaolll2 小时前
数据驱动下的人工电磁材料逆向设计与智能优化研究
人工智能·学习