浏览代码

多轮对话+agno agent学习实践

iTTsShuu 1 月之前
父节点
当前提交
b63e4b4767
共有 8 个文件被更改,包括 717 次插入524 次删除
  1. 3 0
      pyproject.toml
  2. 29 0
      uv.lock
  3. 44 0
      曹航/2/chatbot.ipynb
  4. 79 0
      曹航/3/agent_test1.ipynb
  5. 559 0
      曹航/3/agent_test2.ipynb
  6. 二进制
      曹航/3/tmp/agent.db
  7. 3 0
      曹航/caohang.ipynb
  8. 0 524
      曹航/sentiment_prediction.ipynb

+ 3 - 0
pyproject.toml

@@ -5,7 +5,10 @@ description = "Add your description here"
 readme = "README.md"
 requires-python = ">=3.11"
 dependencies = [
+<<<<<<< HEAD
     "agno>=1.7.1",
+=======
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     "agno>=1.7.2",
     "dotenv>=0.9.9",
     "ipywidgets>=8.1.7",

+ 29 - 0
uv.lock

@@ -33,6 +33,29 @@ wheels = [
 >>>>>>> 6c34b0b (test1)
 
 [[package]]
+name = "agno"
+version = "1.7.2"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "docstring-parser" },
+    { name = "gitpython" },
+    { name = "httpx" },
+    { name = "pydantic" },
+    { name = "pydantic-settings" },
+    { name = "python-dotenv" },
+    { name = "python-multipart" },
+    { name = "pyyaml" },
+    { name = "rich" },
+    { name = "tomli" },
+    { name = "typer" },
+    { name = "typing-extensions" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/50/64/6a82d2375145fd733009db0ada531b595fc2f3c1712ac91c91b2e5fcf02f/agno-1.7.2.tar.gz", hash = "sha256:f4f97e5ea1f9c0781d9bb8396862c82671381386c1569cdb456d70f6c8d3a108" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/7d/24/884cbd1133e3b9985d53733250251098caead365bb8706af8da105813abe/agno-1.7.2-py3-none-any.whl", hash = "sha256:37a1985e67762f0d8016318ba5d8b8697c855827d7c86b21a41cdff088294cc2" },
+]
+
+[[package]]
 name = "ai-learning"
 version = "0.1.0"
 source = { virtual = "." }
@@ -891,6 +914,9 @@ wheels = [
 
 [[package]]
 <<<<<<< HEAD
+<<<<<<< HEAD
+=======
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
 name = "python-multipart"
 version = "0.0.20"
 source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
@@ -900,8 +926,11 @@ wheels = [
 ]
 
 [[package]]
+<<<<<<< HEAD
 =======
 >>>>>>> 6c34b0b (test1)
+=======
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
 name = "pytz"
 version = "2025.2"
 source = { registry = "https://mirrors.aliyun.com/pypi/simple" }

+ 44 - 0
曹航/2/chatbot.ipynb

@@ -30,11 +30,16 @@
   },
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": null,
+=======
+   "execution_count": 4,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    "id": "30401a75",
    "metadata": {},
    "outputs": [
     {
+<<<<<<< HEAD
      "ename": "NotFoundError",
      "evalue": "Error code: 404",
      "output_type": "error",
@@ -48,6 +53,34 @@
       "\u001b[36mFile \u001b[39m\u001b[32md:\\yusys\\ai_learning\\.venv\\Lib\\site-packages\\openai\\_base_client.py:1037\u001b[39m, in \u001b[36mSyncAPIClient.request\u001b[39m\u001b[34m(self, cast_to, options, stream, stream_cls)\u001b[39m\n\u001b[32m   1034\u001b[39m             err.response.read()\n\u001b[32m   1036\u001b[39m         log.debug(\u001b[33m\"\u001b[39m\u001b[33mRe-raising status error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m1037\u001b[39m         \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m._make_status_error_from_response(err.response) \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   1039\u001b[39m     \u001b[38;5;28;01mbreak\u001b[39;00m\n\u001b[32m   1041\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m response \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m, \u001b[33m\"\u001b[39m\u001b[33mcould not resolve response (should never happen)\u001b[39m\u001b[33m\"\u001b[39m\n",
       "\u001b[31mNotFoundError\u001b[39m: Error code: 404"
      ]
+=======
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "ecd0c84e794d47dd9a84472787f6e763",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Output()"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "2dd20caab0e84c9780205e6f7d338cd7",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "HBox(children=(Text(value='', placeholder='请输入您的消息...'), Button(button_style='primary', description='发送', styl…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     }
    ],
    "source": [
@@ -61,7 +94,11 @@
     "def save_user_message(role, content):\n",
     "    \"\"\"保存用户消息\"\"\"\n",
     "    user_message = f\"\"\"\n",
+<<<<<<< HEAD
     "    用户发来新的消息(在<>中提供),如果用户询问一些其他问题时,请礼貌地告诉用户,你是一个信息收集助手,不回答其它不相关问题。\n",
+=======
+    "    用户发来新的消息(在<>中提供),用户询问一些其他问题时,请礼貌地告诉用户,你是一个信息收集助手,不回答其它不相关问题。\n",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     "    用户消息:\n",
     "    <{content}>\n",
     "    \"\"\"\n",
@@ -91,11 +128,16 @@
     "    response = client.chat.completions.create(\n",
     "        model=\"qwen3-30b-a3b\",\n",
     "        messages= [{\"role\": \"system\", \"content\": system_prompt}] + messages,\n",
+<<<<<<< HEAD
+=======
+    "        \n",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     "        extra_body={\"enable_thinking\": False},\n",
     "        temperature=0.7,\n",
     "    )\n",
     "    return response.choices[0].message.content\n",
     "\n",
+<<<<<<< HEAD
     "    # response = client.responses.create(\n",
     "    #     model=\"qwen3-30b-a3b\",\n",
     "    #     input= [{\"role\": \"system\", \"content\": system_prompt}] + messages,\n",
@@ -104,6 +146,8 @@
     "    # )\n",
     "    # return response.output_text\n",
     "\n",
+=======
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     "# 用户输入的消息\n",
     "user_message = \"Hello, how are you?\"\n",
     "save_user_message(\"user\", user_message)\n",

+ 79 - 0
曹航/3/agent_test1.ipynb

@@ -2,7 +2,11 @@
  "cells": [
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": 1,
+=======
+   "execution_count": 8,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    "id": "8f58232e",
    "metadata": {},
    "outputs": [],
@@ -46,7 +50,11 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "a917f0961fca4339bce6bb54a2e494c9",
+=======
+       "model_id": "b8dba8b1142d4e78b13a51496be46d95",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -110,14 +118,22 @@
   },
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": 3,
+=======
+   "execution_count": null,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    "id": "389236b4",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "c557671b95194a308e03957184726d5f",
+=======
+       "model_id": "b1683a2f5e664bd58207674eae611741",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -392,14 +408,22 @@
   },
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": 4,
+=======
+   "execution_count": 10,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    "id": "595e81bb",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "15d791b433274c4ab422b583169426f5",
+=======
+       "model_id": "d30e05211dbc466caa6cfbe96855dd52",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -423,7 +447,11 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "17467c587eec477fb111cb58cb20dc82",
+=======
+       "model_id": "c1da05284d4b4438a77e421352c5274e",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -447,7 +475,11 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "d0c6a7cada684caa82ac98fd745f4990",
+=======
+       "model_id": "8c0296dac7464ca48c8ffbf97485c3fa",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -471,7 +503,11 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "328410a4e1f144c2b19d0d286c247e0c",
+=======
+       "model_id": "dde342ffffe6412bb7dd7de7a5e10063",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -495,7 +531,11 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "486e315eeb5e4130967fdcd53cdf5e1d",
+=======
+       "model_id": "f7d74a23df1b4396bcfb012cd1f88b03",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -553,14 +593,22 @@
   },
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": null,
+=======
+   "execution_count": 14,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    "id": "54fce47a",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "3bdc3e79f1444be680451ae5566bd84a",
+=======
+       "model_id": "a813b71508b3424eac865edc9902a814",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -584,7 +632,11 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "9402012548f345c8899a30bb3c07a0a0",
+=======
+       "model_id": "8c38d9d97ddf4afe8a771cc80bb8264c",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -608,7 +660,11 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "6723870b70ec488c8c311ff3749060ef",
+=======
+       "model_id": "c94473f3849348acaa1f3e6680cb81da",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -632,7 +688,11 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "880b75df788f47fcb02dceacf699b090",
+=======
+       "model_id": "5c2cf0fb836d4dce9d70341053947065",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -656,7 +716,11 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "59643333ac1549dc97188ae1fdea365d",
+=======
+       "model_id": "d4081a2d82bb45df9682265dd5d0388c",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -687,7 +751,11 @@
     "agent.user_id=\"user_shuu\"\n",
     "agent.search_previous_sessions_history=True\n",
     "agent.num_history_sessions=5\n",
+<<<<<<< HEAD
     "agent.storage=SqliteStorage(table_name=\"agent_history\",db_file=\"temp/agent_history.db\")\n",
+=======
+    "# agent.storage=SqliteStorage(table_name=\"agent_history\",db_file=\"temp/agent_history.db\")\n",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     "\n",
     "#session设置\n",
     "session_1_id = \"session_1_id\"\n",
@@ -704,6 +772,17 @@
     "    \"What did I discuss in my previous conversations?\", session_id=session_5_id,stream=True\n",
     ")  # It should only include the last 2 sessions"
    ]
+<<<<<<< HEAD
+=======
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7b06e0e2",
+   "metadata": {},
+   "source": [
+    "**Agent state**"
+   ]
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
   }
  ],
  "metadata": {

+ 559 - 0
曹航/3/agent_test2.ipynb

@@ -2,7 +2,11 @@
  "cells": [
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": 1,
+=======
+   "execution_count": 11,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    "id": "a4856341",
    "metadata": {},
    "outputs": [
@@ -12,13 +16,18 @@
        "True"
       ]
      },
+<<<<<<< HEAD
      "execution_count": 1,
+=======
+     "execution_count": 11,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
     "from textwrap import dedent\n",
+<<<<<<< HEAD
     "\n",
     "from agno.agent import Agent\n",
     "from agno.models.openai import OpenAILike\n",
@@ -42,6 +51,20 @@
     "import os\n",
     "import json\n",
     "load_dotenv()\n"
+=======
+    "from agno.agent import Agent\n",
+    "from dotenv import load_dotenv \n",
+    "from agno.models.openai import OpenAILike\n",
+    "from agno.memory.v2.db.sqlite import SqliteMemoryDb\n",
+    "from agno.memory.v2.memory import Memory\n",
+    "from rich.pretty import pprint\n",
+    "from agno.storage.sqlite import SqliteStorage\n",
+    "from typing import List,Dict\n",
+    "from pydantic import BaseModel, Field\n",
+    "import os\n",
+    "load_dotenv()\n",
+    "\n"
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    ]
   },
   {
@@ -54,14 +77,22 @@
   },
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": 2,
+=======
+   "execution_count": null,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    "id": "46403d1a",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
        "model_id": "b5e36e3099374134807dcb494a113ff1",
+=======
+       "model_id": "9b3d2e36a97047dcaf90b8a373c1c2c1",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
        "version_major": 2,
        "version_minor": 0
       },
@@ -86,7 +117,11 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
+<<<<<<< HEAD
       "Final session state: {'shopping_list': ['milk', 'eggs', 'bread'], 'current_session_id': 'c0e056e2-5ea1-4e62-a955-227f6485ffa6'}\n"
+=======
+      "Final session state: {'shopping_list': ['milk', 'eggs', 'bread'], 'current_session_id': 'fb205638-5e39-40e7-8722-1aedcd7995e0'}\n"
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
      ]
     }
    ],
@@ -124,6 +159,7 @@
   },
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": null,
    "id": "8e7e7a5b",
    "metadata": {},
@@ -131,6 +167,170 @@
    "source": [
     "# Define tools to manage our shopping list\n",
     "@tool(description=\"Add an item to the shopping list.\")\n",
+=======
+   "execution_count": 6,
+   "id": "8e7e7a5b",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "1dbdd22b0ef44e0ca820d7469715ad9c",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Output()"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Session state: {'shopping_list': ['milk', 'eggs', 'bread'], 'current_session_id': '7d5889cc-c85a-46a8-bd6d-617eb4fc56fb'}\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "df0130bb33ad4782a54af20fd62e96ca",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Output()"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Session state: {'shopping_list': ['milk', 'eggs'], 'current_session_id': '7d5889cc-c85a-46a8-bd6d-617eb4fc56fb'}\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "33b95577fd9a41f4b1ba01af0d8c9d16",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Output()"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Session state: {'shopping_list': ['milk', 'eggs', 'apples', 'oranges'], 'current_session_id': '7d5889cc-c85a-46a8-bd6d-617eb4fc56fb'}\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "22a01dc2c8cf44ca8fee0e64115ccf46",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Output()"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Session state: {'shopping_list': ['milk', 'eggs', 'apples', 'oranges'], 'current_session_id': '7d5889cc-c85a-46a8-bd6d-617eb4fc56fb'}\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "c3f890d603fa4dbb9497ec8481340014",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Output()"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Session state: {'shopping_list': ['bananas', 'yogurt'], 'current_session_id': '7d5889cc-c85a-46a8-bd6d-617eb4fc56fb'}\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Define tools to manage our shopping list\n",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     "def add_item(agent: Agent, item: str) -> str:\n",
     "    \"\"\"Add an item to the shopping list and return confirmation.\"\"\"\n",
     "    # Add the item if it's not already in the list\n",
@@ -146,7 +346,11 @@
     "    else:\n",
     "        return f\"'{item}' is already in the shopping list\"\n",
     "\n",
+<<<<<<< HEAD
     "@tool(description=\"Remove an item from the shopping list by name.\")\n",
+=======
+    "\n",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     "def remove_item(agent: Agent, item: str) -> str:\n",
     "    \"\"\"Remove an item from the shopping list by name.\"\"\"\n",
     "    # Case-insensitive search\n",
@@ -162,7 +366,11 @@
     "\n",
     "    return f\"'{item}' was not found in the shopping list\"\n",
     "\n",
+<<<<<<< HEAD
     "@tool(description=\"List all items in the shopping list.\")\n",
+=======
+    "\n",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     "def list_items(agent: Agent) -> str:\n",
     "    \"\"\"List all items in the shopping list.\"\"\"\n",
     "    if agent.session_state is None:\n",
@@ -228,10 +436,138 @@
   },
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": null,
    "id": "1f118e71",
    "metadata": {},
    "outputs": [],
+=======
+   "execution_count": 14,
+   "id": "1f118e71",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "c3b320b12c3540849310be03a5e4ae27",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Output()"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Memories about Ava:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UserMemory</span><span style=\"font-weight: bold\">(</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">memory</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'Ava likes to ski.'</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">topics</span>=<span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'hobbies'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">input</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'My name is Ava and I like to ski.'</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">last_updated</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2025</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">7</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">14</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">17</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">48</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">101965</span><span style=\"font-weight: bold\">)</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">memory_id</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'c97cfac1-5166-49c3-b002-dac0530182ab'</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"font-weight: bold\">)</span>\n",
+       "<span style=\"font-weight: bold\">]</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1m[\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1;35mUserMemory\u001b[0m\u001b[1m(\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33mmemory\u001b[0m=\u001b[32m'Ava likes to ski.'\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33mtopics\u001b[0m=\u001b[1m[\u001b[0m\u001b[32m'name'\u001b[0m, \u001b[32m'hobbies'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33minput\u001b[0m=\u001b[32m'My name is Ava and I like to ski.'\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33mlast_updated\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m7\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m17\u001b[0m, \u001b[1;36m48\u001b[0m, \u001b[1;36m3\u001b[0m, \u001b[1;36m101965\u001b[0m\u001b[1m)\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33mmemory_id\u001b[0m=\u001b[32m'c97cfac1-5166-49c3-b002-dac0530182ab'\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1m)\u001b[0m\n",
+       "\u001b[1m]\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "3bda0ba0f3a64809bd63d042d95fd2a3",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Output()"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Memories about Ava:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UserMemory</span><span style=\"font-weight: bold\">(</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">memory</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'Ava likes to ski.'</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">topics</span>=<span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'hobbies'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">input</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'My name is Ava and I like to ski.'</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">last_updated</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2025</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">7</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">14</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">17</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">48</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">101965</span><span style=\"font-weight: bold\">)</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #808000; text-decoration-color: #808000\">memory_id</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'c97cfac1-5166-49c3-b002-dac0530182ab'</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"font-weight: bold\">)</span>\n",
+       "<span style=\"font-weight: bold\">]</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1m[\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1;35mUserMemory\u001b[0m\u001b[1m(\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33mmemory\u001b[0m=\u001b[32m'Ava likes to ski.'\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33mtopics\u001b[0m=\u001b[1m[\u001b[0m\u001b[32m'name'\u001b[0m, \u001b[32m'hobbies'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33minput\u001b[0m=\u001b[32m'My name is Ava and I like to ski.'\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33mlast_updated\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m7\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m17\u001b[0m, \u001b[1;36m48\u001b[0m, \u001b[1;36m3\u001b[0m, \u001b[1;36m101965\u001b[0m\u001b[1m)\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[33mmemory_id\u001b[0m=\u001b[32m'c97cfac1-5166-49c3-b002-dac0530182ab'\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1m)\u001b[0m\n",
+       "\u001b[1m]\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    "source": [
     "# UserId for the memories\n",
     "user_id = \"ava\"\n",
@@ -242,9 +578,15 @@
     "memory = Memory(\n",
     "    # Use any model for creating memories\n",
     "    model=OpenAILike(id=\"qwen3-30b-a3b\", \n",
+<<<<<<< HEAD
     "                    api_key=os.getenv(\"BAILIAN_API_KEY\"), \n",
     "                    base_url=os.getenv(\"BAILIAN_API_BASE_URL\"),\n",
     "                    request_params={\"extra_body\": {\"enable_thinking\": False}},),\n",
+=======
+    "    api_key=os.getenv(\"BAILIAN_API_KEY\"), \n",
+    "    base_url=os.getenv(\"BAILIAN_API_BASE_URL\"),\n",
+    "    request_params={\"extra_body\": {\"enable_thinking\": False}},),\n",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     "    db=SqliteMemoryDb(table_name=\"user_memories\", db_file=db_file),\n",
     ")\n",
     "# Initialize storage\n",
@@ -301,6 +643,7 @@
   },
   {
    "cell_type": "code",
+<<<<<<< HEAD
    "execution_count": null,
    "id": "5cddde6d",
    "metadata": {},
@@ -445,6 +788,222 @@
    "metadata": {},
    "source": [
     "**Multimodal Agent**"
+=======
+   "execution_count": 13,
+   "id": "5cddde6d",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "7745304024a946c3b1e7bcba04f464ca",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Output()"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #808000; text-decoration-color: #808000\">WARNING </span> Failed to parse cleaned JSON: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span> validation errors for MovieScript                                         \n",
+       "         setting                                                                                                   \n",
+       "           Input should be a valid string <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">string_type</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'location'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'New York Ci...t hold hidden </span>\n",
+       "         <span style=\"color: #008000; text-decoration-color: #008000\">stories.'</span><span style=\"font-weight: bold\">}</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                              \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/string_type</span>                          \n",
+       "         ending                                                                                                    \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'New York'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ge...s a central character.'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "         name                                                                                                      \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'New York'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ge...s a central character.'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "         characters                                                                                                \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'New York'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ge...s a central character.'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "         storyline                                                                                                 \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'New York'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ge...s a central character.'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "         rating                                                                                                    \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'title'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'New York'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ge...s a central character.'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[33mWARNING \u001b[0m Failed to parse cleaned JSON: \u001b[1;36m6\u001b[0m validation errors for MovieScript                                         \n",
+       "         setting                                                                                                   \n",
+       "           Input should be a valid string \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mstring_type\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'location'\u001b[0m: \u001b[32m'New York Ci...t hold hidden \u001b[0m\n",
+       "         \u001b[32mstories.'\u001b[0m\u001b[1m}\u001b[0m, \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                              \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/string_type\u001b[0m                          \n",
+       "         ending                                                                                                    \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'title'\u001b[0m: \u001b[32m'New York'\u001b[0m, \u001b[32m'ge...s a central character.'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n",
+       "         name                                                                                                      \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'title'\u001b[0m: \u001b[32m'New York'\u001b[0m, \u001b[32m'ge...s a central character.'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n",
+       "         characters                                                                                                \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'title'\u001b[0m: \u001b[32m'New York'\u001b[0m, \u001b[32m'ge...s a central character.'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n",
+       "         storyline                                                                                                 \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'title'\u001b[0m: \u001b[32m'New York'\u001b[0m, \u001b[32m'ge...s a central character.'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n",
+       "         rating                                                                                                    \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'title'\u001b[0m: \u001b[32m'New York'\u001b[0m, \u001b[32m'ge...s a central character.'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #808000; text-decoration-color: #808000\">WARNING </span> Validation failed on merged data: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span> validation errors for MovieScript                                     \n",
+       "         setting                                                                                                   \n",
+       "           Input should be a valid string <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">string_type</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'location'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'New York Ci...t hold hidden </span>\n",
+       "         <span style=\"color: #008000; text-decoration-color: #008000\">stories.'</span><span style=\"font-weight: bold\">}</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                              \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/string_type</span>                          \n",
+       "         ending                                                                                                    \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'setting'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'location'</span>: <span style=\"color: #808000; text-decoration-color: #808000\">...</span>genre': <span style=\"color: #008000; text-decoration-color: #008000\">'Drama / Crime'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "         name                                                                                                      \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'setting'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'location'</span>: <span style=\"color: #808000; text-decoration-color: #808000\">...</span>genre': <span style=\"color: #008000; text-decoration-color: #008000\">'Drama / Crime'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "         characters                                                                                                \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'setting'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'location'</span>: <span style=\"color: #808000; text-decoration-color: #808000\">...</span>genre': <span style=\"color: #008000; text-decoration-color: #008000\">'Drama / Crime'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "         storyline                                                                                                 \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'setting'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'location'</span>: <span style=\"color: #808000; text-decoration-color: #808000\">...</span>genre': <span style=\"color: #008000; text-decoration-color: #008000\">'Drama / Crime'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "         rating                                                                                                    \n",
+       "           Field required <span style=\"font-weight: bold\">[</span><span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">missing</span>, <span style=\"color: #808000; text-decoration-color: #808000\">input_value</span>=<span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'setting'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'location'</span>: <span style=\"color: #808000; text-decoration-color: #808000\">...</span>genre': <span style=\"color: #008000; text-decoration-color: #008000\">'Drama / Crime'</span><span style=\"font-weight: bold\">}</span>,         \n",
+       "         <span style=\"color: #808000; text-decoration-color: #808000\">input_type</span>=<span style=\"color: #800080; text-decoration-color: #800080\">dict</span><span style=\"font-weight: bold\">]</span>                                                                                          \n",
+       "             For further information visit <span style=\"color: #0000ff; text-decoration-color: #0000ff; text-decoration: underline\">https://errors.pydantic.dev/2.11/v/missing</span>                              \n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[33mWARNING \u001b[0m Validation failed on merged data: \u001b[1;36m6\u001b[0m validation errors for MovieScript                                     \n",
+       "         setting                                                                                                   \n",
+       "           Input should be a valid string \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mstring_type\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'location'\u001b[0m: \u001b[32m'New York Ci...t hold hidden \u001b[0m\n",
+       "         \u001b[32mstories.'\u001b[0m\u001b[1m}\u001b[0m, \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                              \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/string_type\u001b[0m                          \n",
+       "         ending                                                                                                    \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'setting'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'location'\u001b[0m: \u001b[33m...\u001b[0mgenre': \u001b[32m'Drama / Crime'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n",
+       "         name                                                                                                      \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'setting'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'location'\u001b[0m: \u001b[33m...\u001b[0mgenre': \u001b[32m'Drama / Crime'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n",
+       "         characters                                                                                                \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'setting'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'location'\u001b[0m: \u001b[33m...\u001b[0mgenre': \u001b[32m'Drama / Crime'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n",
+       "         storyline                                                                                                 \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'setting'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'location'\u001b[0m: \u001b[33m...\u001b[0mgenre': \u001b[32m'Drama / Crime'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n",
+       "         rating                                                                                                    \n",
+       "           Field required \u001b[1m[\u001b[0m\u001b[33mtype\u001b[0m=\u001b[35mmissing\u001b[0m, \u001b[33minput_value\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'setting'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'location'\u001b[0m: \u001b[33m...\u001b[0mgenre': \u001b[32m'Drama / Crime'\u001b[0m\u001b[1m}\u001b[0m,         \n",
+       "         \u001b[33minput_type\u001b[0m=\u001b[35mdict\u001b[0m\u001b[1m]\u001b[0m                                                                                          \n",
+       "             For further information visit \u001b[4;94mhttps://errors.pydantic.dev/2.11/v/missing\u001b[0m                              \n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #808000; text-decoration-color: #808000\">WARNING </span> All parsing attempts failed.                                                                              \n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[33mWARNING \u001b[0m All parsing attempts failed.                                                                              \n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #808000; text-decoration-color: #808000\">WARNING </span> Failed to convert response to response_model                                                              \n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[33mWARNING \u001b[0m Failed to convert response to response_model                                                              \n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "class MovieScript(BaseModel):\n",
+    "    setting: str = Field(\n",
+    "        ..., description=\"Provide a nice setting for a blockbuster movie.\"\n",
+    "    )\n",
+    "    ending: str = Field(\n",
+    "        ...,\n",
+    "        description=\"Ending of the movie. If not available, provide a happy ending.\",\n",
+    "    )\n",
+    "    genre: str = Field(\n",
+    "        ...,\n",
+    "        description=\"Genre of the movie. If not available, select action, thriller or romantic comedy.\",\n",
+    "    )\n",
+    "    name: str = Field(..., description=\"Give a name to this movie\")\n",
+    "    characters: List[str] = Field(..., description=\"Name of characters for this movie.\")\n",
+    "    storyline: str = Field(\n",
+    "        ..., description=\"3 sentence storyline for the movie. Make it exciting!\"\n",
+    "    )\n",
+    "    rating: Dict[str, int] = Field(\n",
+    "        ...,\n",
+    "        description=\"Your own rating of the movie. 1-10. Return a dictionary with the keys 'story' and 'acting'.\",\n",
+    "    )\n",
+    "\n",
+    "\n",
+    "# Agent that uses structured outputs with streaming\n",
+    "structured_output_agent = Agent(\n",
+    "    model=OpenAILike(id=\"qwen3-30b-a3b\", \n",
+    "        api_key=os.getenv(\"BAILIAN_API_KEY\"), \n",
+    "        base_url=os.getenv(\"BAILIAN_API_BASE_URL\"),\n",
+    "        request_params={\"extra_body\": {\"enable_thinking\": False}},),\n",
+    "    description=\"You write movie json scripts.\",\n",
+    "    response_model=MovieScript,\n",
+    ")\n",
+    "\n",
+    "structured_output_agent.print_response(\n",
+    "    \"New York\", stream=True, stream_intermediate_steps=True\n",
+    ")"
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
    ]
   },
   {

二进制
曹航/3/tmp/agent.db


+ 3 - 0
曹航/caohang.ipynb

@@ -119,9 +119,12 @@
     "    #best_of=2,\n",
     "\n",
 <<<<<<< HEAD
+<<<<<<< HEAD
 =======
     "\n",
 >>>>>>> 6c34b0b (test1)
+=======
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
     ")\n",
     "#print(completion.choices[0].message.logprobs[\"content\"])\n",
     "print(completion.choices[0].message.content)\n",

+ 0 - 524
曹航/sentiment_prediction.ipynb

@@ -1,524 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "33d34c29",
-   "metadata": {},
-   "source": [
-    "### 评价情感判断"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 23,
-   "id": "ca680f71",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# 导入所需库\n",
-    "from openai import OpenAI\n",
-    "from dotenv import load_dotenv \n",
-    "from IPython.display import display, HTML\n",
-    "import pandas as pd\n",
-    "import json\n",
-    "import os\n",
-    "load_dotenv()\n",
-    "# 用openAI client 调用模型\n",
-    "\n",
-    "client = OpenAI(\n",
-    "    base_url=os.getenv(\"BAILIAN_API_BASE_URL\"),\n",
-    "    api_key=os.getenv(\"BAILIAN_API_KEY\")\n",
-    ")\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "f9c40826",
-   "metadata": {},
-   "source": [
-    "**用于大模型的函数调用**"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "f1fb34ca",
-   "metadata": {},
-   "source": [
-    "**定义预测方法**"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e874b885",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{\n",
-      "  \"sentiment\": \"positive\",\n",
-      "  \"reason\": \"The review text contains words like '感谢' (thankful), which indicate a positive sentiment.\"\n",
-      "}\n"
-     ]
-    }
-   ],
-   "source": [
-    "#预测方法\n",
-    "from ast import List\n",
-    "\n",
-    "\n",
-    "def predict_sentiment(text,model=\"qwen3-30b-a3b\"):\n",
-    "    # 定义提示词\n",
-    "    system_message = \"\"\"You are a sentiment analysis expert. Please analyze the sentiment tendency of the provided review text.\"\"\"\n",
-    "    user_message = f\"\"\"\n",
-    "        Please analyze the sentiment tendency (positive or negative) of the following review text (provided within <>), and return the result in JSON format.\n",
-    "        Review text: <{text}>\n",
-    "\n",
-    "        Please only return a JSON containing the following fields:\n",
-    "        - sentiment: The sentiment tendency (positive or negative)\n",
-    "        - reason: The reason for the sentiment tendency\n",
-    "    \"\"\"\n",
-    "\n",
-    "    # 调用大模型进行情感分析\n",
-    "    response = client.chat.completions.create(\n",
-    "        model=model ,  # 如果model参数为空则使用默认值\n",
-    "        messages=[\n",
-    "            # 添加系统提示词\n",
-    "            {\"role\": \"system\", \"content\": system_message},\n",
-    "            # TODO few-shot/one-shot 来增强表现的实践\n",
-    "            {\"role\": \"user\", \"content\": user_message}\n",
-    "        ],\n",
-    "        # Qwen3模型通过enable_thinking参数控制思考过程(开源版默认True,商业版默认False)\n",
-    "        # 使用Qwen3开源版模型时,若未启用流式输出,请将下行取消注释,否则会报错\n",
-    "        # TODO 定义工具用以大模型调用\n",
-    "        tools=[{\n",
-    "            \"type\": \"function\",\n",
-    "            \"function\": {\n",
-    "                \"name\": \"handle_positive_sentiment\",\n",
-    "                \"description\": \"When you determine that the sentiment of a piece of text is positive, please use this method.\",\n",
-    "                \"parameters\": {\n",
-    "                    \"type\": \"object\",\n",
-    "                    \"properties\": {\n",
-    "                        \"reason\": {\n",
-    "                            \"type\": \"string\",\n",
-    "                            \"description\": \"你判断情感倾向为积极的原因\"\n",
-    "                        },\n",
-    "                        \"result\":{\n",
-    "                            \"type\": \"string\",\n",
-    "                            \"description\": \"你判断情感倾向为积极的结果\",\n",
-    "                            \"enum\": [\"positive\", \"negative\"]\n",
-    "                        }\n",
-    "                    },\n",
-    "                    \"required\": [\"reason\", \"result\"],\n",
-    "                }\n",
-    "            }\n",
-    "        },{\n",
-    "            \"type\": \"function\",\n",
-    "            \"function\": {\n",
-    "                \"name\": \"handle_negative_sentiment\",\n",
-    "                \"description\": \"When you determine that the sentiment of a piece of text is negative, please use this method.\",\n",
-    "                \"parameters\": {\n",
-    "                    \"type\": \"object\",\n",
-    "                    \"properties\": {\n",
-    "                        \"reason\": {\n",
-    "                            \"type\": \"string\",\n",
-    "                            \"description\": \"你判断情感倾向为消极的原因\"\n",
-    "                        },\n",
-    "                        \"result\":{\n",
-    "                            \"type\": \"string\",\n",
-    "                            \"description\": \"你判断情感倾向为消极的结果\",\n",
-    "                            \"enum\": [\"positive\", \"negative\"]\n",
-    "                        }\n",
-    "                    },\n",
-    "                    \"required\": [\"reason\", \"result\"],\n",
-    "                }\n",
-    "            }\n",
-    "        }],\n",
-    "        extra_body={\"enable_thinking\": False},\n",
-    "        temperature=0.3,\n",
-    "        response_format={\"type\": \"json_object\"}  # 指定返回JSON格式\n",
-    "    )\n",
-    "    # 获取返回结果\n",
-    "    result = response.choices[0].message.content\n",
-    "    return result\n",
-    "\n",
-    "#测试\n",
-    "print(predict_sentiment(\"你好!我很感谢你\"))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "df14f73d",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "#文件读取方法\n",
-    "def load_data():\n",
-    "    # 定义数据文件夹路径\n",
-    "    data_dir = \"../data/acllmdb_sentiment_small\"\n",
-    "\n",
-    "    # 读取正面评价数据\n",
-    "    positive_dir = os.path.join(data_dir, \"positive\")\n",
-    "    positive_files = os.listdir(positive_dir)\n",
-    "    positive_texts = []\n",
-    "    for file in positive_files:\n",
-    "        with open(os.path.join(positive_dir, file), 'r', encoding='utf-8') as f:\n",
-    "            text = f.read()\n",
-    "            positive_texts.append({'text': text, 'sentiment': 'positive'})\n",
-    "\n",
-    "    # 读取负面评价数据        \n",
-    "    negative_dir = os.path.join(data_dir, \"negative\") \n",
-    "    negative_files = os.listdir(negative_dir)\n",
-    "    negative_texts = []\n",
-    "    for file in negative_files:\n",
-    "        with open(os.path.join(negative_dir, file), 'r', encoding='utf-8') as f:\n",
-    "            text = f.read()\n",
-    "            negative_texts.append({'text': text, 'sentiment': 'negative'})\n",
-    "\n",
-    "    # 合并数据并创建DataFrame\n",
-    "    df = pd.DataFrame(positive_texts + negative_texts)\n",
-    "    print(f\"总共读取了 {len(df)} 条评价数据\")\n",
-    "    print(f\"其中正面评价 {len(positive_texts)} 条,负面评价 {len(negative_texts)} 条\")\n",
-    "    return df"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "b6c31df9",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# 批量预测情感倾向\n",
-    "def predict_sentiment_batch(model):\n",
-    "    \n",
-    "    try:\n",
-    "        # 数据加载\n",
-    "        data_to_predict = load_data()\n",
-    "        if data_to_predict.empty:\n",
-    "            #加载失败\n",
-    "            print(\"数据加载为空,请检查数据文件路径是否正确\")\n",
-    "        else:\n",
-    "            #加载成功\n",
-    "            predictions = []\n",
-    "\n",
-    "            print(f\"开始进行情感预测...(model={model})\")\n",
-    "            # 遍历每条评论数据\n",
-    "            for i in range(len(data_to_predict)):\n",
-    "                row = data_to_predict.iloc[i]\n",
-    "                text = row['text']\n",
-    "                true_sentiment=row['sentiment']\n",
-    "                try:\n",
-    "                    # 调用大模型进行预测当前行\n",
-    "                    result = predict_sentiment(text,model)\n",
-    "                    #得到json格式结果\n",
-    "                    if result is not None:\n",
-    "                        result_dict = json.loads(result)\n",
-    "                        predicted_sentiment = result_dict.get('sentiment', 'unknown')\n",
-    "                        reason = result_dict.get('reason', 'unknown')\n",
-    "                    \n",
-    "                    # 保存预测结果\n",
-    "                    predictions.append({\n",
-    "                        'text': text,\n",
-    "                        'true_sentiment': true_sentiment,\n",
-    "                        'predicted_sentiment': predicted_sentiment,\n",
-    "                        'reason':reason\n",
-    "                    })\n",
-    "                    \n",
-    "                    # 打印进度 每完成三十条打印一次\n",
-    "                    if  i%30 == 0 or i == len(data_to_predict)-1 :\n",
-    "                        print(f\"已完成 {len(predictions)}/{len(data_to_predict)} 条预测\")\n",
-    "\n",
-    "                except Exception as e:\n",
-    "                    print(f\"第 {i + 1} 条数据预测失败: {str(e)}\")\n",
-    "                    continue\n",
-    "            \n",
-    "            # 将预测结果转换为DataFrame\n",
-    "            predictions_df = pd.DataFrame(predictions)\n",
-    "            print(f\"成功预测 {len(predictions_df)} 条数据\")\n",
-    "            return predictions_df\n",
-    "    except Exception as e:\n",
-    "        print(f\"数据加载出错: {str(e)}\")\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e56e5bd3",
-   "metadata": {},
-   "source": [
-    "**比较以下大模型在这个任务上的 accuracy 差异**"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f99ac855",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# 计算预测准确率\n",
-    "# 解决思路:\n",
-    "# 1. 遍历不同的模型名称列表 models\n",
-    "# 2. 对每个模型调用 predict_sentiment_batch() 获取预测结果\n",
-    "# 3. 计算每个模型的预测准确率:\n",
-    "#    - 使用 predictions_df 中的 true_sentiment 和 predicted_sentiment 列进行比较\n",
-    "#    - 使用 == 运算符比较两列的值是否相等\n",
-    "#    - 使用 mean() 计算相等的比例得到准确率\n",
-    "# 4. 将每个模型的准确率结果以百分比格式打印输出\n",
-    "# 5. 对比不同模型的准确率,分析性能差异\n",
-    "\n",
-    "# 定义要测试的模型列表\n",
-    "models = [\"qwen3-32b\", \"qwen3-30b-a3b\", \"qwen3-0.6b\"]\n",
-    "\n",
-    "# 存储每个模型的准确率结果\n",
-    "model_accuracies = {}\n",
-    "\n",
-    "# 遍历每个模型进行预测和评估\n",
-    "for model_using in models:\n",
-    "    predictions_df=predict_sentiment_batch(model_using)\n",
-    "    if predictions_df is not None and len(predictions_df) > 0:\n",
-    "        # 计算准确率\n",
-    "        accuracy = (predictions_df['true_sentiment'] == predictions_df['predicted_sentiment']).mean()\n",
-    "        model_accuracies[model_using] = accuracy\n",
-    "        \n",
-    "        # 打印当前模型的准确率\n",
-    "        print(f\"模型 {model_using} 的预测准确率: {accuracy:.2%}\")\n",
-    "        \n",
-    "        # 统计错误预测的样本\n",
-    "        wrong_predictions = predictions_df[predictions_df['true_sentiment'] != predictions_df['predicted_sentiment']]\n",
-    "        print(f\"错误预测数量: {len(wrong_predictions)}/{len(predictions_df)}\")\n",
-    "        \n",
-    "        # # 显示一些错误预测的例子\n",
-    "        # if len(wrong_predictions) > 0:\n",
-    "        #     print(\"\\n错误预测示例:\")\n",
-    "        #     for _, row in wrong_predictions.head(3).iterrows():\n",
-    "        #         print(f\"文本: {row['text']}\")\n",
-    "        #         print(f\"真实情感: {row['true_sentiment']}\")\n",
-    "        #         print(f\"预测情感: {row['predicted_sentiment']}\")\n",
-    "        #         print(f\"预测理由: {row['reason']}\\n\")\n",
-    "    else:\n",
-    "        print(f\"模型 {model_using} 预测结果为空\")\n",
-    "\n",
-    "# 比较不同模型的性能\n",
-    "if model_accuracies:\n",
-    "    print(\"\\n模型性能对比:\")\n",
-    "    best_model = max(model_accuracies.items(), key=lambda x: x[1])\n",
-    "    print(f\"最佳模型: {best_model[0]}, 准确率: {best_model[1]:.2%}\")\n",
-    "    \n",
-    "# import matplotlib.pyplot as plt\n",
-    "#     # 绘制准确率对比图\n",
-    "#     plt.figure(figsize=(10, 6))\n",
-    "#     plt.bar(model_accuracies.keys(), [acc * 100 for acc in model_accuracies.values()])\n",
-    "#     plt.title('不同模型的准确率对比')\n",
-    "#     plt.xlabel('模型')\n",
-    "#     plt.ylabel('准确率 (%)')\n",
-    "#     plt.xticks(rotation=45)\n",
-    "#     plt.tight_layout()\n",
-    "#     plt.show()\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "837a4320",
-   "metadata": {},
-   "source": [
-    "**Function Calling的尝试**"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "292cee13",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# 用于function calling的实践\n",
-    "def handle_positive_sentiment(reason, result):\n",
-    "    print(\"这是一个积极的评价!\")\n",
-    "    print(f\"判断原因: {reason}\")\n",
-    "    print(f\"完整结果: {result}\")\n",
-    "    \n",
-    "def handle_negative_sentiment(reason, result):\n",
-    "    print(\"这是一个消极的评价!\")\n",
-    "    print(f\"判断原因: {reason}\")\n",
-    "    print(f\"完整结果: {result}\")\n",
-    "    "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "47872e36",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "ChatCompletion(id='chatcmpl-eda3227c-0060-9319-84f9-ff3701626208', choices=[Choice(finish_reason='tool_calls', index=0, logprobs=None, message=ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_2fde3180722a4c0cb6d352', function=Function(arguments='{\"reason\": \"The review text \\'你好!我很感谢你\\' contains positive expressions such as \\'你好\\' (hello) and \\'很感谢你\\' (I am very grateful to you), which indicate a positive sentiment.\", \"result\": \"positive\"}', name='handle_positive_sentiment'), type='function', index=0)], reasoning_content=''))], created=1752227871, model='qwen3-4b', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=66, prompt_tokens=468, total_tokens=534, completion_tokens_details=None, prompt_tokens_details=None))\n"
-     ]
-    }
-   ],
-   "source": [
-    "def predict_sentiment_functioncalling(text,model=\"qwen3-4b\"):\n",
-    "    # 定义提示词\n",
-    "    system_message = \"\"\"You are a sentiment analysis expert. Please analyze the sentiment tendency of the provided review text.\"\"\"\n",
-    "    user_message = f\"\"\"\n",
-    "        Please analyze the sentiment tendency (positive or negative) of the following review text (provided within <>).\n",
-    "        You can use the following tools to help you analyze the sentiment tendency:\n",
-    "        - handle_positive_sentiment: When you determine that the sentiment of a piece of text is positive, please use this method.\n",
-    "        - handle_negative_sentiment: When you determine that the sentiment of a piece of text is negative, please use this method.\n",
-    "\n",
-    "        Review text: <{text}>\n",
-    "    \"\"\"\n",
-    "\n",
-    "    # 调用大模型进行情感分析\n",
-    "    response = client.chat.completions.create(\n",
-    "    model=model ,  # 如果model参数为空则使用默认值\n",
-    "    # TODO 定义工具用以大模型调用\n",
-    "    tools=[{\n",
-    "        \"type\": \"function\",\n",
-    "        \"function\": {\n",
-    "            \"name\": \"handle_positive_sentiment\",\n",
-    "            \"description\": \"When you determine that the sentiment of a piece of text is positive, please use this method.\",\n",
-    "            \"parameters\": {\n",
-    "                \"type\": \"object\",\n",
-    "                \"properties\": {\n",
-    "                    \"reason\": {\n",
-    "                        \"type\": \"string\",\n",
-    "                        \"description\": \"你判断情感倾向为积极的原因\"\n",
-    "                    },\n",
-    "                    \"result\":{\n",
-    "                        \"type\": \"string\",\n",
-    "                        \"description\": \"你判断情感倾向为积极的结果\",\n",
-    "                        \"enum\": [\"positive\", \"negative\"]\n",
-    "                    }\n",
-    "                },\n",
-    "                \"required\": [\"reason\", \"result\"],\n",
-    "            }\n",
-    "        }\n",
-    "    },{\n",
-    "        \"type\": \"function\",\n",
-    "        \"function\": {\n",
-    "            \"name\": \"handle_negative_sentiment\",\n",
-    "            \"description\": \"When you determine that the sentiment of a piece of text is negative, please use this method.\",\n",
-    "            \"parameters\": {\n",
-    "                \"type\": \"object\",\n",
-    "                \"properties\": {\n",
-    "                    \"reason\": {\n",
-    "                        \"type\": \"string\",\n",
-    "                        \"description\": \"你判断情感倾向为消极的原因\"\n",
-    "                    },\n",
-    "                    \"result\":{\n",
-    "                        \"type\": \"string\",\n",
-    "                        \"description\": \"你判断情感倾向为消极的结果\",\n",
-    "                        \"enum\": [\"positive\", \"negative\"]\n",
-    "                    }\n",
-    "                },\n",
-    "                \"required\": [\"reason\", \"result\"],\n",
-    "            }\n",
-    "        }\n",
-    "    }],\n",
-    "        messages=[\n",
-    "            # 添加系统提示词\n",
-    "            {\"role\": \"system\", \"content\": system_message},\n",
-    "            # TODO few-shot/one-shot 来增强表现的实践\n",
-    "            {\"role\": \"user\", \"content\": user_message}\n",
-    "        ],\n",
-    "        # Qwen3模型通过enable_thinking参数控制思考过程(开源版默认True,商业版默认False)\n",
-    "        # 使用Qwen3开源版模型时,若未启用流式输出,请将下行取消注释,否则会报错\n",
-    "        extra_body={\"enable_thinking\": False},\n",
-    "        tool_choice=\"auto\",\n",
-    "        temperature=0.3,\n",
-    "        #response_format={\"type\": \"json_object\"}  # 指定返回JSON格式\n",
-    "    )\n",
-    "    # 获取返回结果\n",
-    "    # result = response.choices[0].message\n",
-    "    \n",
-    "    return response\n",
-    "\n",
-    "#测试\n",
-    "completion=predict_sentiment_functioncalling(\"你好!我很感谢你\")\n",
-    "print(completion)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "865f16a8",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "这是一个积极的评价!\n",
-      "判断原因: The review text '你好!我很感谢你' contains positive expressions such as '你好' (hello) and '很感谢你' (I am very grateful to you), which indicate a positive sentiment.\n",
-      "完整结果: positive\n",
-      "工具函数输出:None\n",
-      "\n"
-     ]
-    }
-   ],
-   "source": [
-    "#执行工具函数\n",
-    "# 从返回的结果中获取函数名称和入参\n",
-    "if completion.choices[0].message.tool_calls:\n",
-    "    function_name = completion.choices[0].message.tool_calls[0].function.name\n",
-    "    arguments_string = completion.choices[0].message.tool_calls[0].function.arguments\n",
-    "\n",
-    "    # 使用json模块解析参数字符串\n",
-    "    arguments = json.loads(arguments_string)\n",
-    "    # 创建一个函数映射表\n",
-    "    function_mapper = {\n",
-    "        \"handle_positive_sentiment\": handle_positive_sentiment,\n",
-    "        \"handle_negative_sentiment\": handle_negative_sentiment\n",
-    "    }\n",
-    "    # 获取函数实体\n",
-    "    function = function_mapper[function_name]\n",
-    "    # 如果入参为空,则直接调用函数\n",
-    "    if arguments == {}:\n",
-    "        arguments = None\n",
-    "    # 否则,传入参数后调用函数\n",
-    "    else:\n",
-    "        function_output = function(**arguments)\n",
-    "    \n",
-    "else:\n",
-    "    function_name = None\n",
-    "    arguments_string = None\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "85dc78a7",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": ".venv",
-   "language": "python",
-   "name": "python3"
-  },
-  "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.13"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}