Browse Source

gemini版的ipynb

张宸旭 7 months ago
parent
commit
7c610a398f
1 changed files with 1359 additions and 0 deletions
  1. 1359 0
      code/chapter1/chapter1.ipynb

+ 1359 - 0
code/chapter1/chapter1.ipynb

@@ -0,0 +1,1359 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "id": "938b2e36-f95c-4b0f-8770-335c6bb5bc0e",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "API 配置完成!\n"
+     ]
+    }
+   ],
+   "source": [
+    "import google.generativeai as genai\n",
+    "import requests\n",
+    "import json\n",
+    "import os\n",
+    "import re\n",
+    "from tavily import TavilyClient\n",
+    "from IPython.display import display, Markdown, HTML, clear_output\n",
+    "import time\n",
+    "\n",
+    "# 配置 API 密钥\n",
+    "GEMINI_API_KEY = \"AIzaSyBYXm6uWt5-wDi9wXQ1oBhHhsMTWAH8kbo\"\n",
+    "TAVILY_API_KEY = \"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\"\n",
+    "MODEL_NAME = \"gemini-2.5-flash\"  # 如果2.5不可用,使用1.5\n",
+    "\n",
+    "# 配置 Gemini\n",
+    "genai.configure(api_key=GEMINI_API_KEY)\n",
+    "\n",
+    "# 配置 Tavily\n",
+    "os.environ['TAVILY_API_KEY'] = TAVILY_API_KEY\n",
+    "\n",
+    "print(\"API 配置完成!\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "id": "66d9d404-3c95-42f2-8975-436769b3cb87",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "✅ 工具函数定义完成!\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 单元块 2: 定义工具函数\n",
+    "def get_weather(city: str) -> str:\n",
+    "    \"\"\"查询城市天气\"\"\"\n",
+    "    url = f\"https://wttr.in/{city}?format=j1\"\n",
+    "    \n",
+    "    try:\n",
+    "        response = requests.get(url)\n",
+    "        response.raise_for_status()\n",
+    "        data = response.json()\n",
+    "        \n",
+    "        current_condition = data['current_condition'][0]\n",
+    "        weather_desc = current_condition['weatherDesc'][0]['value']\n",
+    "        temp_c = current_condition['temp_C']\n",
+    "        humidity = current_condition['humidity']\n",
+    "        wind_speed = current_condition['windspeedKmph']\n",
+    "        \n",
+    "        return f\"{city}当前天气:{weather_desc},气温{temp_c}°C,湿度{humidity}%,风速{wind_speed}km/h\"\n",
+    "        \n",
+    "    except Exception as e:\n",
+    "        return f\"错误:查询天气时遇到问题 - {e}\"\n",
+    "\n",
+    "def get_attraction(city: str, weather: str) -> str:\n",
+    "    \"\"\"查询景点推荐\"\"\"\n",
+    "    try:\n",
+    "        tavily = TavilyClient(api_key=os.environ['TAVILY_API_KEY'])\n",
+    "        query = f\"'{city}' 在'{weather}'天气下最值得去的旅游景点推荐及理由\"\n",
+    "        \n",
+    "        response = tavily.search(query=query, search_depth=\"basic\", include_answer=True)\n",
+    "        \n",
+    "        if response.get(\"answer\"):\n",
+    "            return response[\"answer\"]\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\"错误:执行搜索时出现问题 - {e}\"\n",
+    "\n",
+    "print(\"✅ 工具函数定义完成!\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "id": "e953fee4-9e3c-4e34-bf48-4ea002c3bb92",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "✅ 智能助手类定义完成!\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 单元块 3: 定义智能助手类\n",
+    "class NotebookTravelAssistant:\n",
+    "    def __init__(self, model_name=\"gemini-1.5-flash\"):\n",
+    "        # 初始化模型\n",
+    "        self.model_name = model_name\n",
+    "        try:\n",
+    "            self.model = genai.GenerativeModel(model_name)\n",
+    "        except:\n",
+    "            print(f\"⚠️ 模型 {model_name} 不可用,使用 gemini-1.5-flash 替代\")\n",
+    "            self.model = genai.GenerativeModel(\"gemini-1.5-flash\")\n",
+    "        \n",
+    "        # 定义工具\n",
+    "        self.available_tools = {\n",
+    "            \"get_weather\": get_weather,\n",
+    "            \"get_attraction\": get_attraction,\n",
+    "        }\n",
+    "        \n",
+    "        # 系统提示词\n",
+    "        self.system_prompt = \"\"\"\n",
+    "你是一个智能旅行助手。你的任务是分析用户的请求,并使用可用工具一步步地解决问题。\n",
+    "\n",
+    "# 可用工具:\n",
+    "- `get_weather(city: str)`: 查询指定城市的实时天气。\n",
+    "- `get_attraction(city: str, weather: str)`: 根据城市和天气搜索推荐的旅游景点。\n",
+    "\n",
+    "# 行动格式:\n",
+    "你的回答必须严格遵循以下格式。首先是你的思考过程,然后是你要执行的具体行动。\n",
+    "Thought: [这里是你的思考过程和下一步计划]\n",
+    "Action: [这里是你要调用的工具,格式为 function_name(arg_name=\"arg_value\")]\n",
+    "\n",
+    "# 任务完成:\n",
+    "当你收集到足够的信息,能够回答用户的最终问题时,你必须使用 `finish(answer=\"...\")` 来输出最终答案。\n",
+    "\n",
+    "请开始吧!\n",
+    "\"\"\"\n",
+    "    \n",
+    "    def generate_response(self, prompt: str) -> str:\n",
+    "        \"\"\"调用Gemini生成回应\"\"\"\n",
+    "        full_prompt = f\"{self.system_prompt}\\n\\n用户请求: {prompt}\"\n",
+    "        response = self.model.generate_content(full_prompt)\n",
+    "        return response.text\n",
+    "    \n",
+    "    def parse_action(self, text: str):\n",
+    "        \"\"\"解析行动指令\"\"\"\n",
+    "        action_match = re.search(r\"Action: (.*)\", text, re.DOTALL)\n",
+    "        if not action_match:\n",
+    "            return None, None\n",
+    "        \n",
+    "        action_str = action_match.group(1).strip()\n",
+    "        \n",
+    "        if action_str.startswith(\"finish\"):\n",
+    "            final_answer_match = re.search(r'finish\\(answer=\"(.*)\"\\)', action_str)\n",
+    "            if final_answer_match:\n",
+    "                return \"finish\", final_answer_match.group(1)\n",
+    "            return \"finish\", \"抱歉,我无法提供完整的答案。\"\n",
+    "        \n",
+    "        tool_match = re.search(r\"(\\w+)\\((.*)\\)\", action_str)\n",
+    "        if not tool_match:\n",
+    "            return None, None\n",
+    "            \n",
+    "        tool_name = tool_match.group(1)\n",
+    "        args_str = tool_match.group(2)\n",
+    "        \n",
+    "        kwargs = {}\n",
+    "        if args_str:\n",
+    "            arg_matches = re.findall(r'(\\w+)=\"([^\"]*)\"', args_str)\n",
+    "            kwargs = dict(arg_matches)\n",
+    "        \n",
+    "        return tool_name, kwargs\n",
+    "\n",
+    "print(\"✅ 智能助手类定义完成!\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "id": "ab5d3142-c119-46ad-a7a1-ec1aa2e79435",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "✅ 显示函数定义完成!\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 单元块 4: 定义显示函数\n",
+    "def display_user_input(user_input):\n",
+    "    \"\"\"显示用户输入\"\"\"\n",
+    "    display(HTML(f\"\"\"\n",
+    "    <div style=\"background: #f0f7ff; border-left: 4px solid #4dabf7; padding: 12px 16px; margin: 10px 0; border-radius: 4px;\">\n",
+    "        <div style=\"font-weight: bold; color: #1971c2; margin-bottom: 4px;\">👤 用户:</div>\n",
+    "        <div>{user_input}</div>\n",
+    "    </div>\n",
+    "    \"\"\"))\n",
+    "\n",
+    "def display_cycle_header(cycle_num):\n",
+    "    \"\"\"显示循环标题\"\"\"\n",
+    "    display(HTML(f\"\"\"\n",
+    "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+    "        <strong>🔄 循环 {cycle_num}:</strong>\n",
+    "    </div>\n",
+    "    \"\"\"))\n",
+    "\n",
+    "def display_thought(thought_text):\n",
+    "    \"\"\"显示思考过程\"\"\"\n",
+    "    display(HTML(f\"\"\"\n",
+    "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+    "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+    "        <div><strong>Thought:</strong> {thought_text}</div>\n",
+    "    </div>\n",
+    "    \"\"\"))\n",
+    "\n",
+    "def display_action(tool_name, args):\n",
+    "    \"\"\"显示行动\"\"\"\n",
+    "    display(HTML(f\"\"\"\n",
+    "    <div style=\"background: #fff9db; border-left: 4px solid #f59f00; padding: 8px 12px; margin: 8px 0; border-radius: 4px;\">\n",
+    "        <strong>⚡ 执行工具:</strong> {tool_name}({', '.join([f'{k}=\"{v}\"' for k, v in args.items()])})\n",
+    "    </div>\n",
+    "    \"\"\"))\n",
+    "\n",
+    "def display_observation(observation):\n",
+    "    \"\"\"显示观察结果\"\"\"\n",
+    "    display(HTML(f\"\"\"\n",
+    "    <div style=\"background: #f8f9fa; border-left: 4px solid #adb5bd; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+    "        <div style=\"font-weight: bold; color: #495057; margin-bottom: 4px;\">👁️ 观察结果:</div>\n",
+    "        <div>{observation}</div>\n",
+    "    </div>\n",
+    "    \"\"\"))\n",
+    "\n",
+    "def display_final_result(result):\n",
+    "    \"\"\"显示最终结果\"\"\"\n",
+    "    display(HTML(f\"\"\"\n",
+    "    <div style=\"background: #d3f9d8; border: 2px solid #40c057; padding: 16px 20px; margin: 16px 0; border-radius: 8px;\">\n",
+    "        <div style=\"font-weight: bold; color: #2b8a3e; font-size: 18px; margin-bottom: 8px;\">✅ 任务完成!</div>\n",
+    "        <div style=\"font-size: 16px; line-height: 1.5;\">{result}</div>\n",
+    "    </div>\n",
+    "    \"\"\"))\n",
+    "\n",
+    "print(\"✅ 显示函数定义完成!\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "id": "cc543309-fe16-44a9-9735-bce828b9c7ad",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "✅ 主运行函数定义完成!\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 单元块 5: 定义主运行函数\n",
+    "def run_assistant(user_input, max_iterations=5):\n",
+    "    \"\"\"运行智能助手\"\"\"\n",
+    "    # 创建助手实例\n",
+    "    assistant = NotebookTravelAssistant(model_name=MODEL_NAME)\n",
+    "    \n",
+    "    # 显示用户输入\n",
+    "    display_user_input(user_input)\n",
+    "    \n",
+    "    prompt_history = [f\"用户请求: {user_input}\"]\n",
+    "    \n",
+    "    for i in range(max_iterations):\n",
+    "        # 显示循环标题\n",
+    "        display_cycle_header(i+1)\n",
+    "        \n",
+    "        # 调用模型\n",
+    "        full_prompt = \"\\n\".join(prompt_history)\n",
+    "        llm_output = assistant.generate_response(full_prompt)\n",
+    "        \n",
+    "        # 提取思考过程\n",
+    "        thought_match = re.search(r\"Thought: (.*?)(?=Action:|$)\", llm_output, re.DOTALL)\n",
+    "        thought_text = thought_match.group(1).strip() if thought_match else \"思考过程未明确显示\"\n",
+    "        \n",
+    "        # 显示思考过程\n",
+    "        display_thought(thought_text)\n",
+    "        \n",
+    "        # 解析并执行行动\n",
+    "        tool_name, args = assistant.parse_action(llm_output)\n",
+    "        \n",
+    "        if tool_name == \"finish\":\n",
+    "            # 显示最终结果\n",
+    "            display_final_result(args)\n",
+    "            return args\n",
+    "        \n",
+    "        elif tool_name in assistant.available_tools:\n",
+    "            # 显示行动\n",
+    "            display_action(tool_name, args)\n",
+    "            \n",
+    "            # 执行工具\n",
+    "            observation = assistant.available_tools[tool_name](**args)\n",
+    "            \n",
+    "            # 显示观察结果\n",
+    "            display_observation(observation)\n",
+    "            \n",
+    "            # 更新历史\n",
+    "            prompt_history.append(llm_output)\n",
+    "            prompt_history.append(f\"Observation: {observation}\")\n",
+    "            \n",
+    "            # 添加短暂延迟,使输出更易读\n",
+    "            time.sleep(1)\n",
+    "        else:\n",
+    "            display(HTML(f\"<div style='color: red; padding: 10px;'>❌ 无法解析行动: {tool_name}</div>\"))\n",
+    "            break\n",
+    "    \n",
+    "    return \"抱歉,我无法完成这个请求。请尝试更具体的查询。\"\n",
+    "\n",
+    "print(\"✅ 主运行函数定义完成!\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "id": "3f6e44eb-ff3d-4060-b4c2-ea3e139bf307",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f0f7ff; border-left: 4px solid #4dabf7; padding: 12px 16px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #1971c2; margin-bottom: 4px;\">👤 用户:</div>\n",
+       "        <div>你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 1:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 用户首先要求查询北京的天气,然后根据天气推荐旅游景点。我需要先调用 `get_weather` 工具来获取北京的天气信息。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff9db; border-left: 4px solid #f59f00; padding: 8px 12px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <strong>⚡ 执行工具:</strong> get_weather(city=\"北京\")\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f8f9fa; border-left: 4px solid #adb5bd; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #495057; margin-bottom: 4px;\">👁️ 观察结果:</div>\n",
+       "        <div>北京当前天气:Mist,气温8°C,湿度100%,风速8km/h</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 2:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 我已经获取了北京的天气信息是 \"Mist\"。现在我需要根据这个天气信息来推荐一个合适的旅游景点。我将使用 `get_attraction` 工具,将城市设置为 \"北京\",天气设置为 \"Mist\"。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff9db; border-left: 4px solid #f59f00; padding: 8px 12px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <strong>⚡ 执行工具:</strong> get_attraction(city=\"北京\", weather=\"Mist\")\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f8f9fa; border-left: 4px solid #adb5bd; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #495057; margin-bottom: 4px;\">👁️ 观察结果:</div>\n",
+       "        <div>In mist weather, Beijing's Forbidden City, Temple of Heaven, and Summer Palace are best for sightseeing. These sites offer indoor attractions and clear views despite weather.</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 3:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 我已经获取了北京的天气信息是 \"Mist\",并且根据这个天气推荐了景点:故宫、天坛和颐和园。现在我拥有了回答用户请求的所有信息。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #d3f9d8; border: 2px solid #40c057; padding: 16px 20px; margin: 16px 0; border-radius: 8px;\">\n",
+       "        <div style=\"font-weight: bold; color: #2b8a3e; font-size: 18px; margin-bottom: 8px;\">✅ 任务完成!</div>\n",
+       "        <div style=\"font-size: 16px; line-height: 1.5;\">您好!今天北京的天气是:有薄雾(Mist),气温8°C。根据薄雾天气,推荐您去故宫、天坛和颐和园游览,这些景点即使在薄雾天气下也能提供室内景点或清晰的视野。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# 单元块 6: 运行示例\n",
+    "user_input = \"你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点\"\n",
+    "result = run_assistant(user_input)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "id": "68c735c1-eb3e-40e7-8b70-2be941798187",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "✅ 交互式对话功能已加载!\n",
+      "运行 'interactive_travel_assistant()' 开始对话\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 单元块 7: 实现交互式对话功能\n",
+    "def interactive_travel_assistant():\n",
+    "    \"\"\"交互式旅行助手\"\"\"\n",
+    "    print(\"🌍 欢迎使用智能旅行助手!\")\n",
+    "    print(\"=\" * 50)\n",
+    "    print(\"我可以帮您查询任何城市的天气,并根据天气推荐合适的旅游景点。\")\n",
+    "    print(\"您只需输入城市名称,我将为您提供完整的旅行建议。\")\n",
+    "    print(\"输入 '退出'、'quit' 或 'exit' 可以结束对话。\")\n",
+    "    print(\"=\" * 50)\n",
+    "    \n",
+    "    conversation_count = 0\n",
+    "    \n",
+    "    while True:\n",
+    "        # 获取用户输入\n",
+    "        user_input = input(f\"\\n🏙️  请输入城市名称 (对话 {conversation_count + 1}): \").strip()\n",
+    "        \n",
+    "        # 检查退出条件\n",
+    "        if user_input.lower() in ['退出', 'quit', 'exit']:\n",
+    "            print(\"\\n\" + \"=\" * 50)\n",
+    "            print(\"👋 感谢使用智能旅行助手,期待下次为您服务!\")\n",
+    "            print(\"=\" * 50)\n",
+    "            break\n",
+    "            \n",
+    "        # 检查空输入\n",
+    "        if not user_input:\n",
+    "            print(\"⚠️  请输入有效的城市名称。\")\n",
+    "            continue\n",
+    "        \n",
+    "        # 构建查询\n",
+    "        query = f\"请帮我查询{user_input}的天气,然后根据天气推荐合适的旅游景点\"\n",
+    "        \n",
+    "        print(f\"\\n📡 处理您的请求: {query}\")\n",
+    "        print(\"-\" * 50)\n",
+    "        \n",
+    "        # 运行助手\n",
+    "        result = run_assistant(query)\n",
+    "        \n",
+    "        # 增加对话计数\n",
+    "        conversation_count += 1\n",
+    "        \n",
+    "        print(\"\\n\" + \"=\" * 50)\n",
+    "        print(f\"💫 已完成 {conversation_count} 次对话\")\n",
+    "        print(\"=\" * 50)\n",
+    "\n",
+    "# 启动交互式助手\n",
+    "print(\"✅ 交互式对话功能已加载!\")\n",
+    "print(\"运行 'interactive_travel_assistant()' 开始对话\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "id": "bc58c911-8502-4cf5-aa3f-a9f57a94b679",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "🌍 欢迎使用智能旅行助手!\n",
+      "==================================================\n",
+      "我可以帮您查询任何城市的天气,并根据天气推荐合适的旅游景点。\n",
+      "您只需输入城市名称,我将为您提供完整的旅行建议。\n",
+      "输入 '退出'、'quit' 或 'exit' 可以结束对话。\n",
+      "==================================================\n"
+     ]
+    },
+    {
+     "name": "stdin",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "🏙️  请输入城市名称 (对话 1):  伦敦\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "📡 处理您的请求: 请帮我查询伦敦的天气,然后根据天气推荐合适的旅游景点\n",
+      "--------------------------------------------------\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f0f7ff; border-left: 4px solid #4dabf7; padding: 12px 16px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #1971c2; margin-bottom: 4px;\">👤 用户:</div>\n",
+       "        <div>请帮我查询伦敦的天气,然后根据天气推荐合适的旅游景点</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 1:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 用户请求查询伦敦的天气,并根据天气推荐景点。第一步是获取伦敦的天气。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff9db; border-left: 4px solid #f59f00; padding: 8px 12px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <strong>⚡ 执行工具:</strong> get_weather(city=\"伦敦\")\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f8f9fa; border-left: 4px solid #adb5bd; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #495057; margin-bottom: 4px;\">👁️ 观察结果:</div>\n",
+       "        <div>伦敦当前天气:Clear,气温9°C,湿度93%,风速12km/h</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 2:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 我已经查询到伦敦的天气是\"Clear\"。现在我需要根据这个天气信息来推荐伦敦的旅游景点。我可以使用 `get_attraction` 工具,将城市设置为\"伦敦\",天气设置为\"Clear\"。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff9db; border-left: 4px solid #f59f00; padding: 8px 12px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <strong>⚡ 执行工具:</strong> get_attraction(city=\"伦敦\", weather=\"Clear\")\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f8f9fa; border-left: 4px solid #adb5bd; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #495057; margin-bottom: 4px;\">👁️ 观察结果:</div>\n",
+       "        <div>在伦敦天气晴朗时,乘船游览泰晤士河是最佳选择,欣赏国会大厦和伦敦眼。白天参观西敏寺和大本钟。格林威治天文台也是不错的景点。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 3:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 我已经查询到伦敦的天气信息,并且根据晴朗的天气推荐了合适的旅游景点。现在我拥有了所有必要的信息来回答用户的请求。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #d3f9d8; border: 2px solid #40c057; padding: 16px 20px; margin: 16px 0; border-radius: 8px;\">\n",
+       "        <div style=\"font-weight: bold; color: #2b8a3e; font-size: 18px; margin-bottom: 8px;\">✅ 任务完成!</div>\n",
+       "        <div style=\"font-size: 16px; line-height: 1.5;\">伦敦目前天气晴朗,气温9°C。在伦敦天气晴朗时,乘船游览泰晤士河是最佳选择,可以欣赏国会大厦和伦敦眼。白天还可以参观西敏寺、大本钟和格林威治天文台。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "==================================================\n",
+      "💫 已完成 1 次对话\n",
+      "==================================================\n"
+     ]
+    },
+    {
+     "name": "stdin",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "🏙️  请输入城市名称 (对话 2):  郑州\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "📡 处理您的请求: 请帮我查询郑州的天气,然后根据天气推荐合适的旅游景点\n",
+      "--------------------------------------------------\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f0f7ff; border-left: 4px solid #4dabf7; padding: 12px 16px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #1971c2; margin-bottom: 4px;\">👤 用户:</div>\n",
+       "        <div>请帮我查询郑州的天气,然后根据天气推荐合适的旅游景点</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 1:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 用户请求包含两个步骤:首先查询郑州的天气,然后根据天气推荐景点。我需要先调用 `get_weather` 工具获取郑州的天气信息。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff9db; border-left: 4px solid #f59f00; padding: 8px 12px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <strong>⚡ 执行工具:</strong> get_weather(city=\"郑州\")\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f8f9fa; border-left: 4px solid #adb5bd; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #495057; margin-bottom: 4px;\">👁️ 观察结果:</div>\n",
+       "        <div>郑州当前天气:Mist,气温10°C,湿度94%,风速4km/h</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 2:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 我已经查询到了郑州的天气是 \"Mist\"。现在我需要根据这个天气信息,调用 `get_attraction` 工具来推荐旅游景点。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff9db; border-left: 4px solid #f59f00; padding: 8px 12px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <strong>⚡ 执行工具:</strong> get_attraction(city=\"郑州\", weather=\"Mist\")\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f8f9fa; border-left: 4px solid #adb5bd; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #495057; margin-bottom: 4px;\">👁️ 观察结果:</div>\n",
+       "        <div>在雾霾天气下,郑州的二七纪念塔和新稀伏羲山景区是最值得去的旅游景点。这些地方空气质量较好,景色优美。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 3:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 我已经获取了郑州的天气信息和根据该天气推荐的旅游景点。现在我可以将这些信息整合起来,回答用户的请求。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #d3f9d8; border: 2px solid #40c057; padding: 16px 20px; margin: 16px 0; border-radius: 8px;\">\n",
+       "        <div style=\"font-weight: bold; color: #2b8a3e; font-size: 18px; margin-bottom: 8px;\">✅ 任务完成!</div>\n",
+       "        <div style=\"font-size: 16px; line-height: 1.5;\">郑州当前天气:Mist,气温10°C,湿度94%,风速4km/h。根据当前雾蒙蒙的天气,推荐您前往二七纪念塔和新稀伏羲山景区,这些地方空气质量较好,景色优美。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "==================================================\n",
+      "💫 已完成 2 次对话\n",
+      "==================================================\n"
+     ]
+    },
+    {
+     "name": "stdin",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "🏙️  请输入城市名称 (对话 3):  莆田\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "📡 处理您的请求: 请帮我查询莆田的天气,然后根据天气推荐合适的旅游景点\n",
+      "--------------------------------------------------\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f0f7ff; border-left: 4px solid #4dabf7; padding: 12px 16px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #1971c2; margin-bottom: 4px;\">👤 用户:</div>\n",
+       "        <div>请帮我查询莆田的天气,然后根据天气推荐合适的旅游景点</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 1:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 用户请求包含两个步骤:首先查询莆田的天气,然后根据天气推荐景点。我需要先使用 `get_weather` 工具获取莆田的天气信息。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff9db; border-left: 4px solid #f59f00; padding: 8px 12px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <strong>⚡ 执行工具:</strong> get_weather(city=\"莆田\")\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f8f9fa; border-left: 4px solid #adb5bd; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #495057; margin-bottom: 4px;\">👁️ 观察结果:</div>\n",
+       "        <div>莆田当前天气:Partly cloudy,气温19°C,湿度77%,风速10km/h</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 2:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 我已经获取了莆田的天气信息是 \"Partly cloudy\"。现在我需要根据这个天气信息,使用 `get_attraction` 工具来推荐合适的旅游景点。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff9db; border-left: 4px solid #f59f00; padding: 8px 12px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <strong>⚡ 执行工具:</strong> get_attraction(city=\"莆田\", weather=\"Partly cloudy\")\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #f8f9fa; border-left: 4px solid #adb5bd; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #495057; margin-bottom: 4px;\">👁️ 观察结果:</div>\n",
+       "        <div>莆田在多云天气下,莆田市博物馆和莆田古城是最值得去的景点。这些地方风景宜人,适合观光。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #fff3bf; border-left: 4px solid #fcc419; padding: 8px 12px; margin: 10px 0; border-radius: 4px;\">\n",
+       "        <strong>🔄 循环 3:</strong>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #e6fcf5; border-left: 4px solid #20c997; padding: 12px 16px; margin: 8px 0; border-radius: 4px;\">\n",
+       "        <div style=\"font-weight: bold; color: #087f5b; margin-bottom: 4px;\">🧠 智能体响应:</div>\n",
+       "        <div><strong>Thought:</strong> 我已经获取了莆田的天气信息和根据天气推荐的旅游景点。现在我可以将这些信息整合成最终答案。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    <div style=\"background: #d3f9d8; border: 2px solid #40c057; padding: 16px 20px; margin: 16px 0; border-radius: 8px;\">\n",
+       "        <div style=\"font-weight: bold; color: #2b8a3e; font-size: 18px; margin-bottom: 8px;\">✅ 任务完成!</div>\n",
+       "        <div style=\"font-size: 16px; line-height: 1.5;\">莆田当前天气:Partly cloudy,气温19°C,湿度77%,风速10km/h。在多云天气下,莆田市博物馆和莆田古城是最值得去的景点,这些地方风景宜人,适合观光。</div>\n",
+       "    </div>\n",
+       "    "
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "==================================================\n",
+      "💫 已完成 3 次对话\n",
+      "==================================================\n"
+     ]
+    },
+    {
+     "ename": "KeyboardInterrupt",
+     "evalue": "Interrupted by user",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
+      "\u001b[31mKeyboardInterrupt\u001b[39m                         Traceback (most recent call last)",
+      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[41]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m      1\u001b[39m \u001b[38;5;66;03m# 启动交互式对话\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m \u001b[43minteractive_travel_assistant\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
+      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[40]\u001b[39m\u001b[32m, line 15\u001b[39m, in \u001b[36minteractive_travel_assistant\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m     11\u001b[39m conversation_count = \u001b[32m0\u001b[39m\n\u001b[32m     13\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[32m     14\u001b[39m     \u001b[38;5;66;03m# 获取用户输入\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m     user_input = \u001b[38;5;28;43minput\u001b[39;49m\u001b[43m(\u001b[49m\u001b[33;43mf\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[38;5;130;43;01m\\n\u001b[39;49;00m\u001b[33;43m🏙️  请输入城市名称 (对话 \u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mconversation_count\u001b[49m\u001b[38;5;250;43m \u001b[39;49m\u001b[43m+\u001b[49m\u001b[38;5;250;43m \u001b[39;49m\u001b[32;43m1\u001b[39;49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[33;43m): \u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m.strip()\n\u001b[32m     17\u001b[39m     \u001b[38;5;66;03m# 检查退出条件\u001b[39;00m\n\u001b[32m     18\u001b[39m     \u001b[38;5;28;01mif\u001b[39;00m user_input.lower() \u001b[38;5;129;01min\u001b[39;00m [\u001b[33m'\u001b[39m\u001b[33m退出\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mquit\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mexit\u001b[39m\u001b[33m'\u001b[39m]:\n",
+      "\u001b[36mFile \u001b[39m\u001b[32mD:\\Anaconda\\envs\\hello_agents\\Lib\\site-packages\\ipykernel\\kernelbase.py:1275\u001b[39m, in \u001b[36mKernel.raw_input\u001b[39m\u001b[34m(self, prompt)\u001b[39m\n\u001b[32m   1273\u001b[39m     msg = \u001b[33m\"\u001b[39m\u001b[33mraw_input was called, but this frontend does not support input requests.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m   1274\u001b[39m     \u001b[38;5;28;01mraise\u001b[39;00m StdinNotImplementedError(msg)\n\u001b[32m-> \u001b[39m\u001b[32m1275\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_input_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m   1276\u001b[39m \u001b[43m    \u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   1277\u001b[39m \u001b[43m    \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_parent_ident\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mshell\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   1278\u001b[39m \u001b[43m    \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_parent\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mshell\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m   1279\u001b[39m \u001b[43m    \u001b[49m\u001b[43mpassword\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m   1280\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
+      "\u001b[36mFile \u001b[39m\u001b[32mD:\\Anaconda\\envs\\hello_agents\\Lib\\site-packages\\ipykernel\\kernelbase.py:1320\u001b[39m, in \u001b[36mKernel._input_request\u001b[39m\u001b[34m(self, prompt, ident, parent, password)\u001b[39m\n\u001b[32m   1317\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m:\n\u001b[32m   1318\u001b[39m     \u001b[38;5;66;03m# re-raise KeyboardInterrupt, to truncate traceback\u001b[39;00m\n\u001b[32m   1319\u001b[39m     msg = \u001b[33m\"\u001b[39m\u001b[33mInterrupted by user\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m-> \u001b[39m\u001b[32m1320\u001b[39m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m(msg) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m   1321\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n\u001b[32m   1322\u001b[39m     \u001b[38;5;28mself\u001b[39m.log.warning(\u001b[33m\"\u001b[39m\u001b[33mInvalid Message:\u001b[39m\u001b[33m\"\u001b[39m, exc_info=\u001b[38;5;28;01mTrue\u001b[39;00m)\n",
+      "\u001b[31mKeyboardInterrupt\u001b[39m: Interrupted by user"
+     ]
+    }
+   ],
+   "source": [
+    "# 启动交互式对话\n",
+    "interactive_travel_assistant()"
+   ]
+  },
+  {
+   "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
+}