{ "cells": [ { "cell_type": "code", "id": "938b2e36-f95c-4b0f-8770-335c6bb5bc0e", "metadata": { "ExecuteTime": { "end_time": "2026-01-14T15:56:53.621032679Z", "start_time": "2026-01-14T15:56:53.608893241Z" } }, "source": [ "import requests\n", "import os\n", "import re\n", "from openai import OpenAI\n", "from tavily import TavilyClient\n", "from dotenv import load_dotenv\n", "\n", "# 加载环境变量\n", "load_dotenv()\n", "\n", "# 配置API密钥\n", "API_KEY = os.getenv(\"API_KEY\")\n", "BASE_URL = os.getenv(\"BASE_URL\")\n", "MODEL_ID = os.getenv(\"MODEL_ID\")\n", "TAVILY_API_KEY = os.getenv(\"TAVILY_API_KEY\")\n", "\n", "os.environ['TAVILY_API_KEY'] = TAVILY_API_KEY\n", "\n", "# 系统提示词\n", "AGENT_SYSTEM_PROMPT = \"\"\"\n", "你是一个智能旅行助手。你的任务是分析用户的请求,并使用可用工具一步步地解决问题。\n", "\n", "# 可用工具:\n", "- `get_weather(city: str)`: 查询指定城市的实时天气。\n", "- `get_attraction(city: str, weather: str)`: 根据城市和天气搜索推荐的旅游景点。\n", "\n", "# 行动格式:\n", "你的回答必须严格遵循以下格式。首先是你的思考过程,然后是你要执行的具体行动,每次回复只输出一对Thought-Action:\n", "Thought: [这里是你的思考过程和下一步计划]\n", "Action: 你决定采取的行动,必须是以下格式之一:\n", "- `function_name(arg_name=\"arg_value\")`:调用一个可用工具。\n", "- `Finish[最终答案]`:当你认为已经获得最终答案时。\n", "- 当你收集到足够的信息,能够回答用户的最终问题时,你必须在Action:字段后使用 Finish[最终答案] 来输出最终答案。\n", "\n", "\n", "请开始吧!\n", "\"\"\"" ], "outputs": [], "execution_count": 8 }, { "cell_type": "code", "id": "66d9d404-3c95-42f2-8975-436769b3cb87", "metadata": { "ExecuteTime": { "end_time": "2026-01-14T15:56:54.595070634Z", "start_time": "2026-01-14T15:56:54.532054736Z" } }, "source": [ "def get_weather(city: str) -> str:\n", " \"\"\"\n", " 通过调用 wttr.in API 查询真实的天气信息。\n", " \"\"\"\n", " # API端点,我们请求JSON格式的数据\n", " url = f\"https://wttr.in/{city}?format=j1\"\n", " \n", " try:\n", " # 发起网络请求\n", " response = requests.get(url)\n", " # 检查响应状态码是否为200 (成功)\n", " response.raise_for_status() \n", " # 解析返回的JSON数据\n", " data = response.json()\n", " \n", " # 提取当前天气状况\n", " current_condition = data['current_condition'][0]\n", " weather_desc = current_condition['weatherDesc'][0]['value']\n", " temp_c = current_condition['temp_C']\n", " \n", " # 格式化成自然语言返回\n", " return f\"{city}当前天气:{weather_desc},气温{temp_c}摄氏度\"\n", " \n", " except requests.exceptions.RequestException as e:\n", " # 处理网络错误\n", " return f\"错误:查询天气时遇到网络问题 - {e}\"\n", " except (KeyError, IndexError) as e:\n", " # 处理数据解析错误\n", " return f\"错误:解析天气数据失败,可能是城市名称无效 - {e}\"\n", "\n", "def get_attraction(city: str, weather: str) -> str:\n", " \"\"\"\n", " 根据城市和天气,使用Tavily Search API搜索并返回优化后的景点推荐。\n", " \"\"\"\n", " api_key = os.environ.get(\"TAVILY_API_KEY\")\n", "\n", " if not api_key:\n", " return \"错误:未配置TAVILY_API_KEY。\"\n", "\n", " # 初始化Tavily客户端\n", " tavily = TavilyClient(api_key=api_key)\n", " \n", " # 构造一个精确的查询\n", " query = f\"'{city}' 在'{weather}'天气下最值得去的旅游景点推荐及理由\"\n", " \n", " try:\n", " # 调用API,include_answer=True会返回一个综合性的回答\n", " response = tavily.search(query=query, search_depth=\"basic\", include_answer=True)\n", " \n", " # Tavily返回的结果已经非常干净,可以直接使用\n", " if response.get(\"answer\"):\n", " return response[\"answer\"]\n", " \n", " # 如果没有综合性回答,则格式化原始结果\n", " formatted_results = []\n", " for result in response.get(\"results\", []):\n", " formatted_results.append(f\"- {result['title']}: {result['content']}\")\n", " \n", " if not formatted_results:\n", " return \"抱歉,没有找到相关的旅游景点推荐。\"\n", "\n", " return \"根据搜索,为您找到以下信息:\\n\" + \"\\n\".join(formatted_results)\n", "\n", " except Exception as e:\n", " return f\"错误:执行Tavily搜索时出现问题 - {e}\"\n", "\n", "# 将所有工具函数放入一个字典,方便后续调用\n", "available_tools = {\n", " \"get_weather\": get_weather,\n", " \"get_attraction\": get_attraction,\n", "}\n", "print(\"✅ 工具函数定义完成!\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ 工具函数定义完成!\n" ] } ], "execution_count": 9 }, { "cell_type": "code", "id": "e953fee4-9e3c-4e34-bf48-4ea002c3bb92", "metadata": { "ExecuteTime": { "end_time": "2026-01-14T15:56:55.726641969Z", "start_time": "2026-01-14T15:56:55.671146801Z" } }, "source": [ "class OpenAICompatibleClient:\n", " \"\"\"\n", " 一个用于调用任何兼容OpenAI接口的LLM服务的客户端。\n", " \"\"\"\n", " def __init__(self, model: str, api_key: str, base_url: str):\n", " self.model = model\n", " self.client = OpenAI(api_key=api_key, base_url=base_url)\n", "\n", " def generate(self, prompt: str, system_prompt: str) -> str:\n", " \"\"\"调用LLM API来生成回应。\"\"\"\n", " print(\"正在调用大语言模型...\")\n", " try:\n", " messages = [\n", " {'role': 'system', 'content': system_prompt},\n", " {'role': 'user', 'content': prompt}\n", " ]\n", " response = self.client.chat.completions.create(\n", " model=self.model,\n", " messages=messages,\n", " stream=False\n", " )\n", " answer = response.choices[0].message.content\n", " print(\"大语言模型响应成功。\")\n", " return answer\n", " except Exception as e:\n", " print(f\"调用LLM API时发生错误: {e}\")\n", " return \"错误:调用语言模型服务时出错。\"\n", "\n", "class TravelAssistant:\n", " \"\"\"\n", " 智能旅行助手类\n", " \"\"\"\n", " def __init__(self):\n", " self.llm = OpenAICompatibleClient(\n", " model=MODEL_ID,\n", " api_key=API_KEY,\n", " base_url=BASE_URL\n", " )\n", " self.prompt_history = []\n", " \n", " def reset(self):\n", " \"\"\"重置对话历史\"\"\"\n", " self.prompt_history = []\n", " \n", " def add_user_message(self, message: str):\n", " \"\"\"添加用户消息到历史\"\"\"\n", " self.prompt_history.append(f\"用户请求: {message}\")\n", " \n", " def add_assistant_message(self, message: str):\n", " \"\"\"添加助手消息到历史\"\"\"\n", " self.prompt_history.append(message)\n", " \n", " def add_observation(self, observation: str):\n", " \"\"\"添加观察结果到历史\"\"\"\n", " self.prompt_history.append(f\"Observation: {observation}\")\n", "print(\"✅ 智能助手类定义完成!\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ 智能助手类定义完成!\n" ] } ], "execution_count": 10 }, { "cell_type": "code", "id": "ab5d3142-c119-46ad-a7a1-ec1aa2e79435", "metadata": { "ExecuteTime": { "end_time": "2026-01-14T15:56:56.670907293Z", "start_time": "2026-01-14T15:56:56.608751066Z" } }, "source": [ "\n", "def display_conversation(history):\n", " \"\"\"美观地显示对话历史\"\"\"\n", " print(\"\\n\" + \"=\"*60)\n", " print(\"📝 对话历史\")\n", " print(\"=\"*60)\n", " \n", " for i, message in enumerate(history, 1):\n", " if message.startswith(\"用户请求:\"):\n", " print(f\"\\n👤 用户 [{i}]: {message[5:]}\")\n", " elif message.startswith(\"Thought:\"):\n", " print(f\"\\n🤔 思考 [{i}]: {message[8:].strip()}\")\n", " elif message.startswith(\"Action:\"):\n", " print(f\"🛠️ 行动 [{i}]: {message[7:].strip()}\")\n", " elif message.startswith(\"Observation:\"):\n", " print(f\"📊 观察 [{i}]: {message[12:].strip()}\")\n", " else:\n", " print(f\"💬 消息 [{i}]: {message}\")\n", " \n", " print(\"=\"*60 + \"\\n\")\n", "\n", "def parse_action(action_str):\n", " \"\"\"解析行动字符串\"\"\"\n", " if action_str.startswith(\"Finish\"):\n", " match = re.match(r\"\\w+\\[(.*)\\]\", action_str)\n", " if match:\n", " return \"finish\", {\"answer\": match.group(1)}\n", " return \"finish\", {\"answer\": \"任务完成\"}\n", " \n", " tool_name_match = re.search(r\"(\\w+)\\(\", action_str)\n", " if not tool_name_match:\n", " return None, {}\n", " \n", " tool_name = tool_name_match.group(1)\n", " args_match = re.search(r\"\\((.*)\\)\", action_str)\n", " if args_match:\n", " args_str = args_match.group(1)\n", " kwargs = dict(re.findall(r'(\\w+)=\"([^\"]*)\"', args_str))\n", " else:\n", " kwargs = {}\n", " \n", " return tool_name, kwargs\n", "print(\"✅ 显示函数定义完成!\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ 显示函数定义完成!\n" ] } ], "execution_count": 11 }, { "cell_type": "code", "id": "cc543309-fe16-44a9-9735-bce828b9c7ad", "metadata": { "ExecuteTime": { "end_time": "2026-01-14T15:56:57.497421849Z", "start_time": "2026-01-14T15:56:57.463244826Z" } }, "source": [ "def run_assistant(user_input, max_iterations=5, display=True):\n", " \"\"\"\n", " 运行旅行助手的主函数\n", " \n", " Args:\n", " user_input: 用户输入的问题\n", " max_iterations: 最大循环次数\n", " display: 是否显示对话历史\n", " \n", " Returns:\n", " tuple: (最终答案, 完整的对话历史)\n", " \"\"\"\n", " assistant = TravelAssistant()\n", " assistant.add_user_message(user_input)\n", " \n", " if display:\n", " print(f\"👤 用户输入: {user_input}\")\n", " print(\"=\"*50)\n", " \n", " for i in range(max_iterations):\n", " if display:\n", " print(f\"\\n🔄 循环 {i+1}/{max_iterations}\")\n", " \n", " # 构建完整prompt并调用LLM\n", " full_prompt = \"\\n\".join(assistant.prompt_history)\n", " llm_output = assistant.llm.generate(full_prompt, AGENT_SYSTEM_PROMPT)\n", " # 模型可能会输出多余的Thought-Action,需要截断\n", " match = re.search(r'(Thought:.*?Action:.*?)(?=\\n\\s*(?:Thought:|Action:|Observation:)|\\Z)', llm_output, re.DOTALL)\n", " if match:\n", " truncated = match.group(1).strip()\n", " if truncated != llm_output.strip():\n", " llm_output = truncated\n", " print(\"⚠️ 已截断多余的 Thought-Action 对\")\n", " \n", " assistant.add_assistant_message(llm_output)\n", " \n", " if display:\n", " print(f\"🤖 模型输出:\\n{llm_output}\")\n", " \n", " # 解析行动\n", " action_match = re.search(r\"Action: (.*)\", llm_output, re.DOTALL)\n", " if not action_match:\n", " print(\"❌ 解析错误:模型输出中未找到 Action。\")\n", " break\n", " \n", " action_str = action_match.group(1).strip()\n", " tool_name, kwargs = parse_action(action_str)\n", " \n", " # 处理完成行动\n", " if tool_name == \"finish\":\n", " final_answer = kwargs.get(\"answer\", \"任务完成\")\n", " if display:\n", " print(f\"🎉 任务完成!\")\n", " print(f\"📋 最终答案: {final_answer}\")\n", " return final_answer, assistant.prompt_history\n", " \n", " # 处理工具调用\n", " if tool_name in available_tools:\n", " if display:\n", " print(f\"🛠️ 调用工具: {tool_name}({kwargs})\")\n", " observation = available_tools[tool_name](**kwargs)\n", " else:\n", " observation = f\"错误:未定义的工具 '{tool_name}'\"\n", " \n", " # 记录观察结果\n", " if display:\n", " print(f\"📊 观察结果: {observation}\")\n", " print(\"=\"*50)\n", " \n", " assistant.add_observation(observation)\n", " \n", " # 如果达到最大循环次数仍未完成\n", " timeout_answer = \"抱歉,经过多次尝试仍未完成您的请求。请尝试简化您的问题或稍后重试。\"\n", " if display:\n", " print(f\"⏰ 达到最大循环次数: {timeout_answer}\")\n", " \n", " return timeout_answer, assistant.prompt_history" ], "outputs": [], "execution_count": 12 }, { "cell_type": "code", "id": "3f6e44eb-ff3d-4060-b4c2-ea3e139bf307", "metadata": { "ExecuteTime": { "end_time": "2026-01-14T15:57:56.198306041Z", "start_time": "2026-01-14T15:56:58.506429375Z" } }, "source": [ "# 测试示例\n", "def test_basic_example():\n", " \"\"\"测试北京天气+景点推荐的示例\"\"\"\n", " print(\"🚀 开始测试北京天气+景点推荐示例\")\n", " user_input = \"你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。\"\n", " \n", " final_answer, history = run_assistant(user_input, display=True)\n", " \n", " print(\"\\n\" + \"=\"*60)\n", " print(\"📊 测试完成!\")\n", " print(\"=\"*60)\n", " print(f\"最终答案: {final_answer}\")\n", " \n", " # 显示完整对话历史\n", " display_conversation(history)\n", " \n", " return final_answer, history\n", "\n", "# 运行测试示例\n", "final_answer, history = test_basic_example()" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "🚀 开始测试北京天气+景点推荐示例\n", "👤 用户输入: 你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。\n", "==================================================\n", "\n", "🔄 循环 1/5\n", "正在调用大语言模型...\n", "大语言模型响应成功。\n", "🤖 模型输出:\n", "Thought: 我将先查询今天北京的实时天气,然后根据天气选择合适的景点并给出推荐。\n", "Action: get_weather(city=\"北京\")\n", "🛠️ 调用工具: get_weather({'city': '北京'})\n", "📊 观察结果: 北京当前天气:Clear,气温-1摄氏度\n", "==================================================\n", "\n", "🔄 循环 2/5\n", "正在调用大语言模型...\n", "大语言模型响应成功。\n", "🤖 模型输出:\n", "Thought: 现在北京天气为晴朗且气温-1°C,适合观光但需保暖;接下来根据晴天条件从景点中筛选一个合适的推荐。\n", "\n", "Action: get_attraction(city=\"北京\", weather=\"Clear\")\n", "🛠️ 调用工具: get_attraction({'city': '北京', 'weather': 'Clear'})\n", "📊 观察结果: In clear weather, Beijing's top attractions include the Forbidden City, the Great Wall at Mutianyu, and the Summer Palace. Plan for at least three days to explore major sites.\n", "==================================================\n", "\n", "🔄 循环 3/5\n", "正在调用大语言模型...\n", "大语言模型响应成功。\n", "🤖 模型输出:\n", "Thought: 我将基于当前天气信息,选择一个在 Beijing 今天适合的景点并给出简要理由和出行提示。\n", "\n", "Action: Finish[今天北京的天气是晴(Clear),气温约-1°C。基于当前天气,推荐的景点是颐和园(Summer Palace)。原因:晴朗但寒冷的日子,颐和园的广阔园林和昆明湖景观非常适合观光,且园区内有多处室外赏景点与室内亭榭可提供避寒休憩点。穿着方面请穿厚外套、带帽子和手套,鞋子建议防滑防水。出行建议:尽量乘坐地铁等公共交通前往,出发前可查看开放时间和路线信息。若更倾向室内参观,故宫等室内空间也同样值得一看。]\n", "🎉 任务完成!\n", "📋 最终答案: 今天北京的天气是晴(Clear),气温约-1°C。基于当前天气,推荐的景点是颐和园(Summer Palace)。原因:晴朗但寒冷的日子,颐和园的广阔园林和昆明湖景观非常适合观光,且园区内有多处室外赏景点与室内亭榭可提供避寒休憩点。穿着方面请穿厚外套、带帽子和手套,鞋子建议防滑防水。出行建议:尽量乘坐地铁等公共交通前往,出发前可查看开放时间和路线信息。若更倾向室内参观,故宫等室内空间也同样值得一看。\n", "\n", "============================================================\n", "📊 测试完成!\n", "============================================================\n", "最终答案: 今天北京的天气是晴(Clear),气温约-1°C。基于当前天气,推荐的景点是颐和园(Summer Palace)。原因:晴朗但寒冷的日子,颐和园的广阔园林和昆明湖景观非常适合观光,且园区内有多处室外赏景点与室内亭榭可提供避寒休憩点。穿着方面请穿厚外套、带帽子和手套,鞋子建议防滑防水。出行建议:尽量乘坐地铁等公共交通前往,出发前可查看开放时间和路线信息。若更倾向室内参观,故宫等室内空间也同样值得一看。\n", "\n", "============================================================\n", "📝 对话历史\n", "============================================================\n", "\n", "👤 用户 [1]: 你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。\n", "\n", "🤔 思考 [2]: 我将先查询今天北京的实时天气,然后根据天气选择合适的景点并给出推荐。\n", "Action: get_weather(city=\"北京\")\n", "📊 观察 [3]: 北京当前天气:Clear,气温-1摄氏度\n", "\n", "🤔 思考 [4]: 现在北京天气为晴朗且气温-1°C,适合观光但需保暖;接下来根据晴天条件从景点中筛选一个合适的推荐。\n", "\n", "Action: get_attraction(city=\"北京\", weather=\"Clear\")\n", "📊 观察 [5]: In clear weather, Beijing's top attractions include the Forbidden City, the Great Wall at Mutianyu, and the Summer Palace. Plan for at least three days to explore major sites.\n", "\n", "🤔 思考 [6]: 我将基于当前天气信息,选择一个在 Beijing 今天适合的景点并给出简要理由和出行提示。\n", "\n", "Action: Finish[今天北京的天气是晴(Clear),气温约-1°C。基于当前天气,推荐的景点是颐和园(Summer Palace)。原因:晴朗但寒冷的日子,颐和园的广阔园林和昆明湖景观非常适合观光,且园区内有多处室外赏景点与室内亭榭可提供避寒休憩点。穿着方面请穿厚外套、带帽子和手套,鞋子建议防滑防水。出行建议:尽量乘坐地铁等公共交通前往,出发前可查看开放时间和路线信息。若更倾向室内参观,故宫等室内空间也同样值得一看。]\n", "============================================================\n", "\n" ] } ], "execution_count": 13 }, { "cell_type": "code", "id": "68c735c1-eb3e-40e7-8b70-2be941798187", "metadata": { "ExecuteTime": { "end_time": "2026-01-14T15:58:30.343440202Z", "start_time": "2026-01-14T15:58:30.317379757Z" } }, "source": [ "def interactive_travel_assistant():\n", " \"\"\"\n", " 交互式旅行助手\n", " \"\"\"\n", " print(\"🌍 欢迎使用智能旅行助手!\")\n", " print(\"💡 您可以询问任何城市的天气和旅游景点推荐\")\n", " print(\"❌ 输入 'quit' 或 '退出' 来结束对话\\n\")\n", " \n", " while True:\n", " user_input = input(\"👤 请输入您的问题: \").strip()\n", " \n", " if user_input.lower() in ['quit', '退出', 'exit']:\n", " print(\"👋 感谢使用智能旅行助手,再见!\")\n", " break\n", " \n", " if not user_input:\n", " print(\"⚠️ 请输入有效的问题\")\n", " continue\n", " \n", " print(\"\\n\" + \"=\"*50)\n", " print(\"🔄 正在处理您的请求...\")\n", " \n", " final_answer, history = run_assistant(user_input, display=True)\n", " \n", " print(\"\\n🎯 最终回答:\")\n", " print(\"=\"*30)\n", " print(final_answer)\n", " print(\"=\"*30)\n", " \n", " # 询问是否显示完整对话历史\n", " show_history = input(\"\\n📖 是否显示完整对话历史? (y/n): \").strip().lower()\n", " if show_history in ['y', 'yes', '是']:\n", " display_conversation(history)\n", " \n", " print(\"\\n\" + \"=\"*60)\n", " print(\"🔄 准备接受下一个问题...\\n\")\n", "\n", "# 快速测试函数\n", "def quick_test(city=\"上海\"):\n", " \"\"\"快速测试指定城市的天气和景点\"\"\"\n", " user_input = f\"请帮我查询{city}的天气,并推荐适合的旅游景点\"\n", " print(f\"🚀 快速测试: {user_input}\")\n", " final_answer, _ = run_assistant(user_input, display=True)\n", " return final_answer" ], "outputs": [], "execution_count": 14 }, { "cell_type": "code", "id": "bc58c911-8502-4cf5-aa3f-a9f57a94b679", "metadata": { "ExecuteTime": { "end_time": "2026-01-14T16:02:32.575540116Z", "start_time": "2026-01-14T16:00:39.668510589Z" } }, "source": [ "# 主启动入口\n", "if __name__ == \"__main__\":\n", " # 可以选择直接运行测试示例\n", " print(\"选择运行模式:\")\n", " print(\"1. 运行测试示例 (北京)\")\n", " print(\"2. 交互模式\")\n", " print(\"3. 快速测试其他城市\")\n", " \n", " choice = input(\"请输入选择 (1/2/3): \").strip()\n", " \n", " if choice == \"1\":\n", " test_basic_example()\n", " elif choice == \"2\":\n", " interactive_travel_assistant()\n", " elif choice == \"3\":\n", " city = input(\"请输入要测试的城市: \").strip() or \"上海\"\n", " quick_test(city)\n", " else:\n", " print(\"无效选择,运行测试示例...\")\n", " test_basic_example()" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "选择运行模式:\n", "1. 运行测试示例 (北京)\n", "2. 交互模式\n", "3. 快速测试其他城市\n", "🚀 快速测试: 请帮我查询广州的天气,并推荐适合的旅游景点\n", "👤 用户输入: 请帮我查询广州的天气,并推荐适合的旅游景点\n", "==================================================\n", "\n", "🔄 循环 1/5\n", "正在调用大语言模型...\n", "大语言模型响应成功。\n", "🤖 模型输出:\n", "Thought: Plan to fetch Guangzhou的天气信息作为第一步,然后根据天气来筛选推荐的景点。 \n", "Action: get_weather(city=\"广州\")\n", "🛠️ 调用工具: get_weather({'city': '广州'})\n", "📊 观察结果: 广州当前天气:Clear,气温15摄氏度\n", "==================================================\n", "\n", "🔄 循环 2/5\n", "正在调用大语言模型...\n", "大语言模型响应成功。\n", "🤖 模型输出:\n", "Thought: Guangzhou当前天气为Clear,适合户外活动。我将基于晴天的条件获取推荐的景点列表。 \n", "Action: get_attraction(city=\"广州\", weather=\"Clear\")\n", "🛠️ 调用工具: get_attraction({'city': '广州', 'weather': 'Clear'})\n", "📊 观察结果: 在广州天气晴朗时,最值得去的旅游景点是越秀公园和广州塔。这些地方风景优美,适合观光和休闲。\n", "==================================================\n", "\n", "🔄 循环 3/5\n", "正在调用大语言模型...\n", "大语言模型响应成功。\n", "🤖 模型输出:\n", "Thought: 计划基于广州晴天条件提供景点推荐,先查询符合晴天的景点。\n", "Action: get_attraction(city=\"广州\", weather=\"Clear\")\n", "🛠️ 调用工具: get_attraction({'city': '广州', 'weather': 'Clear'})\n", "📊 观察结果: 在广州天气晴朗时,最值得去的旅游景点是越秀公园和广州塔。这些地方风景优美,适合观光和休闲。\n", "==================================================\n", "\n", "🔄 循环 4/5\n", "正在调用大语言模型...\n", "大语言模型响应成功。\n", "🤖 模型输出:\n", "Thought: 我不能提供内部推理过程,但会直接给出结果。 \n", "Action: Finish[广州天气:晴朗,气温15°C。推荐景点:越秀公园、广州塔。]\n", "🎉 任务完成!\n", "📋 最终答案: 广州天气:晴朗,气温15°C。推荐景点:越秀公园、广州塔。\n" ] } ], "execution_count": 17 }, { "cell_type": "code", "execution_count": null, "id": "b84ad2cf-d240-4322-9e91-5da2af51f53f", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3.11 (hello_agents Environment)", "language": "python", "name": "hello_agents" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.14" } }, "nbformat": 4, "nbformat_minor": 5 }