2
0

14 Коммитууд 7279110ec2 ... e6885bb64c

Эзэн SHA1 Мессеж Огноо
  iTTsShuu e6885bb64c 合并准备 1 сар өмнө
  iTTsShuu 15a23aa81e 练习2 1 сар өмнө
  iTTsShuu 6c611a1a39 agno练习+转账agent 1 сар өмнө
  iTTsShuu b63e4b4767 多轮对话+agno agent学习实践 1 сар өмнө
  iTTsShuu ef69ea06da 练习情感预测 1 сар өмнө
  iTTsShuu 8d54880344 练习情感预测 1 сар өмнө
  iTTsShuu 9c6192cd82 test1 1 сар өмнө
  iTTsShuu 742178a5d1 练习2 1 сар өмнө
  iTTsShuu 5388e63135 agno练习+转账agent 1 сар өмнө
  iTTsShuu 61d0afb81c agno练习+转账agent 1 сар өмнө
  iTTsShuu 78ef6c7312 多轮对话+agno agent学习实践 1 сар өмнө
  iTTsShuu 9634018ed6 练习情感预测 1 сар өмнө
  iTTsShuu c216ba70bb 练习情感预测 1 сар өмнө
  iTTsShuu 9452f6bc6f test1 1 сар өмнө

+ 2 - 0
README.md

@@ -32,6 +32,8 @@
    ```bash
    # 激活虚拟环境
    source .venv/bin/activate
+   #Windows用户 
+   .venv/Scripts/activate
    
    # 或者使用 uv run 来直接在虚拟环境中运行命令
    uv run python your_script.py

+ 9 - 0
pyproject.toml

@@ -5,14 +5,23 @@ 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",
     "openai>=1.93.0",
+<<<<<<< HEAD
     "duckduckgo-search>=6.0.0",
     "pandas",
     "yfinance>=0.2.65",
     "ipywidgets",
     "sqlalchemy"
+=======
+>>>>>>> 6c34b0b (test1)
+    "pandas>=2.3.1",
 ]
 
 [dependency-groups]

+ 480 - 52
uv.lock

@@ -1,14 +1,70 @@
 version = 1
 revision = 2
 requires-python = ">=3.11"
+resolution-markers = [
+    "python_full_version >= '3.12'",
+    "python_full_version < '3.12'",
+]
+<<<<<<< HEAD
+
+[[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" },
+]
+=======
+>>>>>>> 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 = "." }
 dependencies = [
+    { name = "agno" },
     { name = "dotenv" },
+    { name = "ipywidgets" },
     { name = "openai" },
+    { name = "pandas" },
 ]
 
 [package.dev-dependencies]
@@ -18,8 +74,11 @@ dev = [
 
 [package.metadata]
 requires-dist = [
+    { name = "agno", specifier = ">=1.7.2" },
     { name = "dotenv", specifier = ">=0.9.9" },
+    { name = "ipywidgets", specifier = ">=8.1.7" },
     { name = "openai", specifier = ">=1.93.0" },
+    { name = "pandas", specifier = ">=2.3.1" },
 ]
 
 [package.metadata.requires-dev]
@@ -28,7 +87,7 @@ dev = [{ name = "ipykernel", specifier = ">=6.29.5" }]
 [[package]]
 name = "annotated-types"
 version = "0.7.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53" },
@@ -37,7 +96,7 @@ wheels = [
 [[package]]
 name = "anyio"
 version = "4.9.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "idna" },
     { name = "sniffio" },
@@ -51,7 +110,7 @@ wheels = [
 [[package]]
 name = "appnope"
 version = "0.1.4"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c" },
@@ -60,7 +119,7 @@ wheels = [
 [[package]]
 name = "asttokens"
 version = "3.0.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2" },
@@ -69,7 +128,7 @@ wheels = [
 [[package]]
 name = "certifi"
 version = "2025.6.15"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057" },
@@ -78,7 +137,7 @@ wheels = [
 [[package]]
 name = "cffi"
 version = "1.17.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "pycparser" },
 ]
@@ -121,9 +180,21 @@ wheels = [
 ]
 
 [[package]]
+name = "click"
+version = "8.2.1"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "colorama", marker = "sys_platform == 'win32'" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b" },
+]
+
+[[package]]
 name = "colorama"
 version = "0.4.6"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" },
@@ -132,7 +203,7 @@ wheels = [
 [[package]]
 name = "comm"
 version = "0.2.2"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "traitlets" },
 ]
@@ -144,7 +215,7 @@ wheels = [
 [[package]]
 name = "debugpy"
 version = "1.8.14"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/bd/75/087fe07d40f490a78782ff3b0a30e3968936854105487decdb33446d4b0e/debugpy-1.8.14.tar.gz", hash = "sha256:7cd287184318416850aa8b60ac90105837bb1e59531898c07569d197d2ed5322" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/67/e8/57fe0c86915671fd6a3d2d8746e40485fd55e8d9e682388fbb3a3d42b86f/debugpy-1.8.14-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:1b2ac8c13b2645e0b1eaf30e816404990fbdb168e193322be8f545e8c01644a9" },
@@ -165,7 +236,7 @@ wheels = [
 [[package]]
 name = "decorator"
 version = "5.2.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a" },
@@ -174,16 +245,25 @@ wheels = [
 [[package]]
 name = "distro"
 version = "1.9.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2" },
 ]
 
 [[package]]
+name = "docstring-parser"
+version = "0.16"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/08/12/9c22a58c0b1e29271051222d8906257616da84135af9ed167c9e28f85cb3/docstring_parser-0.16.tar.gz", hash = "sha256:538beabd0af1e2db0146b6bd3caa526c35a34d61af9fd2887f3a8a27a739aa6e" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/d5/7c/e9fcff7623954d86bdc17782036cbf715ecab1bec4847c008557affe1ca8/docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637" },
+]
+
+[[package]]
 name = "dotenv"
 version = "0.9.9"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "python-dotenv" },
 ]
@@ -194,16 +274,40 @@ wheels = [
 [[package]]
 name = "executing"
 version = "2.2.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa" },
 ]
 
 [[package]]
+name = "gitdb"
+version = "4.0.12"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "smmap" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf" },
+]
+
+[[package]]
+name = "gitpython"
+version = "3.1.44"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "gitdb" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c0/89/37df0b71473153574a5cdef8f242de422a0f5d26d7a9e231e6f169b4ad14/gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/1d/9a/4114a9057db2f1462d5c8f8390ab7383925fe1ac012eaa42402ad65c2963/GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110" },
+]
+
+[[package]]
 name = "h11"
 version = "0.16.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86" },
@@ -212,7 +316,7 @@ wheels = [
 [[package]]
 name = "httpcore"
 version = "1.0.9"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "certifi" },
     { name = "h11" },
@@ -225,7 +329,7 @@ wheels = [
 [[package]]
 name = "httpx"
 version = "0.28.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "anyio" },
     { name = "certifi" },
@@ -240,7 +344,7 @@ wheels = [
 [[package]]
 name = "idna"
 version = "3.10"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" },
@@ -249,7 +353,7 @@ wheels = [
 [[package]]
 name = "ipykernel"
 version = "6.29.5"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "appnope", marker = "sys_platform == 'darwin'" },
     { name = "comm" },
@@ -273,7 +377,7 @@ wheels = [
 [[package]]
 name = "ipython"
 version = "9.4.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "colorama", marker = "sys_platform == 'win32'" },
     { name = "decorator" },
@@ -295,7 +399,7 @@ wheels = [
 [[package]]
 name = "ipython-pygments-lexers"
 version = "1.1.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "pygments" },
 ]
@@ -305,9 +409,25 @@ wheels = [
 ]
 
 [[package]]
+name = "ipywidgets"
+version = "8.1.7"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "comm" },
+    { name = "ipython" },
+    { name = "jupyterlab-widgets" },
+    { name = "traitlets" },
+    { name = "widgetsnbextension" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/3e/48/d3dbac45c2814cb73812f98dd6b38bbcc957a4e7bb31d6ea9c03bf94ed87/ipywidgets-8.1.7.tar.gz", hash = "sha256:15f1ac050b9ccbefd45dccfbb2ef6bed0029d8278682d569d71b8dd96bee0376" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/58/6a/9166369a2f092bd286d24e6307de555d63616e8ddb373ebad2b5635ca4cd/ipywidgets-8.1.7-py3-none-any.whl", hash = "sha256:764f2602d25471c213919b8a1997df04bef869251db4ca8efba1b76b1bd9f7bb" },
+]
+
+[[package]]
 name = "jedi"
 version = "0.19.2"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "parso" },
 ]
@@ -319,7 +439,7 @@ wheels = [
 [[package]]
 name = "jiter"
 version = "0.10.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ee/9d/ae7ddb4b8ab3fb1b51faf4deb36cb48a4fbbd7cb36bad6a5fca4741306f7/jiter-0.10.0.tar.gz", hash = "sha256:07a7142c38aacc85194391108dc91b5b57093c978a9932bd86a36862759d9500" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/1b/dd/6cefc6bd68b1c3c979cecfa7029ab582b57690a31cd2f346c4d0ce7951b6/jiter-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3bebe0c558e19902c96e99217e0b8e8b17d570906e72ed8a87170bc290b1e978" },
@@ -379,7 +499,7 @@ wheels = [
 [[package]]
 name = "jupyter-client"
 version = "8.6.3"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "jupyter-core" },
     { name = "python-dateutil" },
@@ -395,7 +515,7 @@ wheels = [
 [[package]]
 name = "jupyter-core"
 version = "5.8.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "platformdirs" },
     { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" },
@@ -407,9 +527,30 @@ wheels = [
 ]
 
 [[package]]
+name = "jupyterlab-widgets"
+version = "3.0.15"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b9/7d/160595ca88ee87ac6ba95d82177d29ec60aaa63821d3077babb22ce031a5/jupyterlab_widgets-3.0.15.tar.gz", hash = "sha256:2920888a0c2922351a9202817957a68c07d99673504d6cd37345299e971bb08b" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/43/6a/ca128561b22b60bd5a0c4ea26649e68c8556b82bc70a0c396eebc977fe86/jupyterlab_widgets-3.0.15-py3-none-any.whl", hash = "sha256:d59023d7d7ef71400d51e6fee9a88867f6e65e10a4201605d2d7f3e8f012a31c" },
+]
+
+[[package]]
+name = "markdown-it-py"
+version = "3.0.0"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "mdurl" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1" },
+]
+
+[[package]]
 name = "matplotlib-inline"
 version = "0.1.7"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "traitlets" },
 ]
@@ -419,18 +560,85 @@ wheels = [
 ]
 
 [[package]]
+name = "mdurl"
+version = "0.1.2"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8" },
+]
+
+[[package]]
 name = "nest-asyncio"
 version = "1.6.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c" },
 ]
 
 [[package]]
+name = "numpy"
+version = "2.3.1"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/2e/19/d7c972dfe90a353dbd3efbbe1d14a5951de80c99c9dc1b93cd998d51dc0f/numpy-2.3.1.tar.gz", hash = "sha256:1ec9ae20a4226da374362cca3c62cd753faf2f951440b0e3b98e93c235441d2b" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/b0/c7/87c64d7ab426156530676000c94784ef55676df2f13b2796f97722464124/numpy-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6ea9e48336a402551f52cd8f593343699003d2353daa4b72ce8d34f66b722070" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/58/0e/0966c2f44beeac12af8d836e5b5f826a407cf34c45cb73ddcdfce9f5960b/numpy-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ccb7336eaf0e77c1635b232c141846493a588ec9ea777a7c24d7166bb8533ae" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/7d/31/6e35a247acb1bfc19226791dfc7d4c30002cd4e620e11e58b0ddf836fe52/numpy-2.3.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0bb3a4a61e1d327e035275d2a993c96fa786e4913aa089843e6a2d9dd205c66a" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/b0/25/93b621219bb6f5a2d4e713a824522c69ab1f06a57cd571cda70e2e31af44/numpy-2.3.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:e344eb79dab01f1e838ebb67aab09965fb271d6da6b00adda26328ac27d4a66e" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ef/60/6b06ed98d11fb32e27fb59468b42383f3877146d3ee639f733776b6ac596/numpy-2.3.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:467db865b392168ceb1ef1ffa6f5a86e62468c43e0cfb4ab6da667ede10e58db" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/75/c9/9bec03675192077467a9c7c2bdd1f2e922bd01d3a69b15c3a0fdcd8548f6/numpy-2.3.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:afed2ce4a84f6b0fc6c1ce734ff368cbf5a5e24e8954a338f3bdffa0718adffb" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/6a/e2/5756a00cabcf50a3f527a0c968b2b4881c62b1379223931853114fa04cda/numpy-2.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0025048b3c1557a20bc80d06fdeb8cc7fc193721484cca82b2cfa072fec71a93" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ff/86/a471f65f0a86f1ca62dcc90b9fa46174dd48f50214e5446bc16a775646c5/numpy-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5ee121b60aa509679b682819c602579e1df14a5b07fe95671c8849aad8f2115" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/43/a6/482a53e469b32be6500aaf61cfafd1de7a0b0d484babf679209c3298852e/numpy-2.3.1-cp311-cp311-win32.whl", hash = "sha256:a8b740f5579ae4585831b3cf0e3b0425c667274f82a484866d2adf9570539369" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/6b/fb/bb613f4122c310a13ec67585c70e14b03bfc7ebabd24f4d5138b97371d7c/numpy-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4580adadc53311b163444f877e0789f1c8861e2698f6b2a4ca852fda154f3ff" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/51/58/2d842825af9a0c041aca246dc92eb725e1bc5e1c9ac89712625db0c4e11c/numpy-2.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:ec0bdafa906f95adc9a0c6f26a4871fa753f25caaa0e032578a30457bff0af6a" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c6/56/71ad5022e2f63cfe0ca93559403d0edef14aea70a841d640bd13cdba578e/numpy-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2959d8f268f3d8ee402b04a9ec4bb7604555aeacf78b360dc4ec27f1d508177d" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/25/65/2db52ba049813670f7f987cc5db6dac9be7cd95e923cc6832b3d32d87cef/numpy-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:762e0c0c6b56bdedfef9a8e1d4538556438288c4276901ea008ae44091954e29" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/57/dd/28fa3c17b0e751047ac928c1e1b6990238faad76e9b147e585b573d9d1bd/numpy-2.3.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:867ef172a0976aaa1f1d1b63cf2090de8b636a7674607d514505fb7276ab08fc" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c9/fc/84ea0cba8e760c4644b708b6819d91784c290288c27aca916115e3311d17/numpy-2.3.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:4e602e1b8682c2b833af89ba641ad4176053aaa50f5cacda1a27004352dde943" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/61/b2/512b0c2ddec985ad1e496b0bd853eeb572315c0f07cd6997473ced8f15e2/numpy-2.3.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:8e333040d069eba1652fb08962ec5b76af7f2c7bce1df7e1418c8055cf776f25" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/6e/45/c51cb248e679a6c6ab14b7a8e3ead3f4a3fe7425fc7a6f98b3f147bec532/numpy-2.3.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e7cbf5a5eafd8d230a3ce356d892512185230e4781a361229bd902ff403bc660" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/e4/ff/feb4be2e5c09a3da161b412019caf47183099cbea1132fd98061808c2df2/numpy-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f1b8f26d1086835f442286c1d9b64bb3974b0b1e41bb105358fd07d20872952" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/bc/6d/ceafe87587101e9ab0d370e4f6e5f3f3a85b9a697f2318738e5e7e176ce3/numpy-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ee8340cb48c9b7a5899d1149eece41ca535513a9698098edbade2a8e7a84da77" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/2b/19/0fb49a3ea088be691f040c9bf1817e4669a339d6e98579f91859b902c636/numpy-2.3.1-cp312-cp312-win32.whl", hash = "sha256:e772dda20a6002ef7061713dc1e2585bc1b534e7909b2030b5a46dae8ff077ab" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/b1/3e/e28f4c1dd9e042eb57a3eb652f200225e311b608632bc727ae378623d4f8/numpy-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:cfecc7822543abdea6de08758091da655ea2210b8ffa1faf116b940693d3df76" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/04/a8/8a5e9079dc722acf53522b8f8842e79541ea81835e9b5483388701421073/numpy-2.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:7be91b2239af2658653c5bb6f1b8bccafaf08226a258caf78ce44710a0160d30" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/d4/bd/35ad97006d8abff8631293f8ea6adf07b0108ce6fec68da3c3fcca1197f2/numpy-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25a1992b0a3fdcdaec9f552ef10d8103186f5397ab45e2d25f8ac51b1a6b97e8" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/f1/4f/df5923874d8095b6062495b39729178eef4a922119cee32a12ee1bd4664c/numpy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dea630156d39b02a63c18f508f85010230409db5b2927ba59c8ba4ab3e8272e" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/8c/0f/a1f269b125806212a876f7efb049b06c6f8772cf0121139f97774cd95626/numpy-2.3.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bada6058dd886061f10ea15f230ccf7dfff40572e99fef440a4a857c8728c9c0" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/6d/63/a7f7fd5f375b0361682f6ffbf686787e82b7bbd561268e4f30afad2bb3c0/numpy-2.3.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:a894f3816eb17b29e4783e5873f92faf55b710c2519e5c351767c51f79d8526d" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/bf/0d/1854a4121af895aab383f4aa233748f1df4671ef331d898e32426756a8a6/numpy-2.3.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:18703df6c4a4fee55fd3d6e5a253d01c5d33a295409b03fda0c86b3ca2ff41a1" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/50/30/af1b277b443f2fb08acf1c55ce9d68ee540043f158630d62cef012750f9f/numpy-2.3.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5902660491bd7a48b2ec16c23ccb9124b8abfd9583c5fdfa123fe6b421e03de1" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/6e/ec/3b68220c277e463095342d254c61be8144c31208db18d3fd8ef02712bcd6/numpy-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:36890eb9e9d2081137bd78d29050ba63b8dab95dff7912eadf1185e80074b2a0" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/77/2b/4014f2bcc4404484021c74d4c5ee8eb3de7e3f7ac75f06672f8dcf85140a/numpy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a780033466159c2270531e2b8ac063704592a0bc62ec4a1b991c7c40705eb0e8" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/40/8d/2ddd6c9b30fcf920837b8672f6c65590c7d92e43084c25fc65edc22e93ca/numpy-2.3.1-cp313-cp313-win32.whl", hash = "sha256:39bff12c076812595c3a306f22bfe49919c5513aa1e0e70fac756a0be7c2a2b8" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/dd/c8/beaba449925988d415efccb45bf977ff8327a02f655090627318f6398c7b/numpy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d5ee6eec45f08ce507a6570e06f2f879b374a552087a4179ea7838edbcbfa42" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/0b/c3/5c0c575d7ec78c1126998071f58facfc124006635da75b090805e642c62e/numpy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:0c4d9e0a8368db90f93bd192bfa771ace63137c3488d198ee21dfb8e7771916e" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ea/19/a029cd335cf72f79d2644dcfc22d90f09caa86265cbbde3b5702ccef6890/numpy-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b0b5397374f32ec0649dd98c652a1798192042e715df918c20672c62fb52d4b8" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/25/91/8ea8894406209107d9ce19b66314194675d31761fe2cb3c84fe2eeae2f37/numpy-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c5bdf2015ccfcee8253fb8be695516ac4457c743473a43290fd36eba6a1777eb" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/a6/7f/06187b0066eefc9e7ce77d5f2ddb4e314a55220ad62dd0bfc9f2c44bac14/numpy-2.3.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d70f20df7f08b90a2062c1f07737dd340adccf2068d0f1b9b3d56e2038979fee" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/e8/ec/a926c293c605fa75e9cfb09f1e4840098ed46d2edaa6e2152ee35dc01ed3/numpy-2.3.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:2fb86b7e58f9ac50e1e9dd1290154107e47d1eef23a0ae9145ded06ea606f992" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/e3/62/d68e52fb6fde5586650d4c0ce0b05ff3a48ad4df4ffd1b8866479d1d671d/numpy-2.3.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:23ab05b2d241f76cb883ce8b9a93a680752fbfcbd51c50eff0b88b979e471d8c" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/fc/ec/b74d3f2430960044bdad6900d9f5edc2dc0fb8bf5a0be0f65287bf2cbe27/numpy-2.3.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ce2ce9e5de4703a673e705183f64fd5da5bf36e7beddcb63a25ee2286e71ca48" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/0d/15/def96774b9d7eb198ddadfcbd20281b20ebb510580419197e225f5c55c3e/numpy-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c4913079974eeb5c16ccfd2b1f09354b8fed7e0d6f2cab933104a09a6419b1ee" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/2b/57/c3203974762a759540c6ae71d0ea2341c1fa41d84e4971a8e76d7141678a/numpy-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:010ce9b4f00d5c036053ca684c77441f2f2c934fd23bee058b4d6f196efd8280" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/22/8a/ccdf201457ed8ac6245187850aff4ca56a79edbea4829f4e9f14d46fa9a5/numpy-2.3.1-cp313-cp313t-win32.whl", hash = "sha256:6269b9edfe32912584ec496d91b00b6d34282ca1d07eb10e82dfc780907d6c2e" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/f1/7e/7f431d8bd8eb7e03d79294aed238b1b0b174b3148570d03a8a8a8f6a0da9/numpy-2.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2a809637460e88a113e186e87f228d74ae2852a2e0c44de275263376f17b5bdc" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/d4/ca/af82bf0fad4c3e573c6930ed743b5308492ff19917c7caaf2f9b6f9e2e98/numpy-2.3.1-cp313-cp313t-win_arm64.whl", hash = "sha256:eccb9a159db9aed60800187bc47a6d3451553f0e1b08b068d8b277ddfbb9b244" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/e8/34/facc13b9b42ddca30498fc51f7f73c3d0f2be179943a4b4da8686e259740/numpy-2.3.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ad506d4b09e684394c42c966ec1527f6ebc25da7f4da4b1b056606ffe446b8a3" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/65/b6/41b705d9dbae04649b529fc9bd3387664c3281c7cd78b404a4efe73dcc45/numpy-2.3.1-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:ebb8603d45bc86bbd5edb0d63e52c5fd9e7945d3a503b77e486bd88dde67a19b" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/7a/b4/fe3ac1902bff7a4934a22d49e1c9d71a623204d654d4cc43c6e8fe337fcb/numpy-2.3.1-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:15aa4c392ac396e2ad3d0a2680c0f0dee420f9fed14eef09bdb9450ee6dcb7b7" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ae/ee/89bedf69c36ace1ac8f59e97811c1f5031e179a37e4821c3a230bf750142/numpy-2.3.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c6e0bf9d1a2f50d2b65a7cf56db37c095af17b59f6c132396f7c6d5dd76484df" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/15/08/e00e7070ede29b2b176165eba18d6f9784d5349be3c0c1218338e79c27fd/numpy-2.3.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eabd7e8740d494ce2b4ea0ff05afa1b7b291e978c0ae075487c51e8bd93c0c68" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/48/6b/1c6b515a83d5564b1698a61efa245727c8feecf308f4091f565988519d20/numpy-2.3.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e610832418a2bc09d974cc9fecebfa51e9532d6190223bc5ef6a7402ebf3b5cb" },
+]
+
+[[package]]
 name = "openai"
 version = "1.93.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "anyio" },
     { name = "distro" },
@@ -449,16 +657,57 @@ wheels = [
 [[package]]
 name = "packaging"
 version = "25.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484" },
 ]
 
 [[package]]
+name = "pandas"
+version = "2.3.1"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "numpy" },
+    { name = "python-dateutil" },
+    { name = "pytz" },
+    { name = "tzdata" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d1/6f/75aa71f8a14267117adeeed5d21b204770189c0a0025acbdc03c337b28fc/pandas-2.3.1.tar.gz", hash = "sha256:0a95b9ac964fe83ce317827f80304d37388ea77616b1425f0ae41c9d2d0d7bb2" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/76/1c/ccf70029e927e473a4476c00e0d5b32e623bff27f0402d0a92b7fc29bb9f/pandas-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2b0540963d83431f5ce8870ea02a7430adca100cec8a050f0811f8e31035541b" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ec/d3/3c37cb724d76a841f14b8f5fe57e5e3645207cc67370e4f84717e8bb7657/pandas-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fe7317f578c6a153912bd2292f02e40c1d8f253e93c599e82620c7f69755c74f" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/8a/4c/367c98854a1251940edf54a4df0826dcacfb987f9068abf3e3064081a382/pandas-2.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6723a27ad7b244c0c79d8e7007092d7c8f0f11305770e2f4cd778b3ad5f9f85" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/07/5f/63760ff107bcf5146eee41b38b3985f9055e710a72fdd637b791dea3495c/pandas-2.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3462c3735fe19f2638f2c3a40bd94ec2dc5ba13abbb032dd2fa1f540a075509d" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/15/53/f31a9b4dfe73fe4711c3a609bd8e60238022f48eacedc257cd13ae9327a7/pandas-2.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:98bcc8b5bf7afed22cc753a28bc4d9e26e078e777066bc53fac7904ddef9a678" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/e0/94/6fce6bf85b5056d065e0a7933cba2616dcb48596f7ba3c6341ec4bcc529d/pandas-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d544806b485ddf29e52d75b1f559142514e60ef58a832f74fb38e48d757b299" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c8/7b/bdcb1ed8fccb63d04bdb7635161d0ec26596d92c9d7a6cce964e7876b6c1/pandas-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:b3cd4273d3cb3707b6fffd217204c52ed92859533e31dc03b7c5008aa933aaab" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/46/de/b8445e0f5d217a99fe0eeb2f4988070908979bec3587c0633e5428ab596c/pandas-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:689968e841136f9e542020698ee1c4fbe9caa2ed2213ae2388dc7b81721510d3" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/1e/e0/801cdb3564e65a5ac041ab99ea6f1d802a6c325bb6e58c79c06a3f1cd010/pandas-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:025e92411c16cbe5bb2a4abc99732a6b132f439b8aab23a59fa593eb00704232" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/51/a5/c76a8311833c24ae61a376dbf360eb1b1c9247a5d9c1e8b356563b31b80c/pandas-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b7ff55f31c4fcb3e316e8f7fa194566b286d6ac430afec0d461163312c5841e" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/da/01/e383018feba0a1ead6cf5fe8728e5d767fee02f06a3d800e82c489e5daaf/pandas-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dcb79bf373a47d2a40cf7232928eb7540155abbc460925c2c96d2d30b006eb4" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/5b/14/cec7760d7c9507f11c97d64f29022e12a6cc4fc03ac694535e89f88ad2ec/pandas-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56a342b231e8862c96bdb6ab97170e203ce511f4d0429589c8ede1ee8ece48b8" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/50/b9/6e2d2c6728ed29fb3d4d4d302504fb66f1a543e37eb2e43f352a86365cdf/pandas-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ca7ed14832bce68baef331f4d7f294411bed8efd032f8109d690df45e00c4679" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/80/a5/3a92893e7399a691bad7664d977cb5e7c81cf666c81f89ea76ba2bff483d/pandas-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ac942bfd0aca577bef61f2bc8da8147c4ef6879965ef883d8e8d5d2dc3e744b8" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/32/ed/ff0a67a2c5505e1854e6715586ac6693dd860fbf52ef9f81edee200266e7/pandas-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9026bd4a80108fac2239294a15ef9003c4ee191a0f64b90f170b40cfb7cf2d22" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c7/db/d8f24a7cc9fb0972adab0cc80b6817e8bef888cfd0024eeb5a21c0bb5c4a/pandas-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6de8547d4fdb12421e2d047a2c446c623ff4c11f47fddb6b9169eb98ffba485a" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/0f/b0/80f6ec783313f1e2356b28b4fd8d2148c378370045da918c73145e6aab50/pandas-2.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:782647ddc63c83133b2506912cc6b108140a38a37292102aaa19c81c83db2928" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/e9/e2/20a317688435470872885e7fc8f95109ae9683dec7c50be29b56911515a5/pandas-2.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ba6aff74075311fc88504b1db890187a3cd0f887a5b10f5525f8e2ef55bfdb9" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/55/79/20d746b0a96c67203a5bee5fb4e00ac49c3e8009a39e1f78de264ecc5729/pandas-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e5635178b387bd2ba4ac040f82bc2ef6e6b500483975c4ebacd34bec945fda12" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/7c/0f/145c8b41e48dbf03dd18fdd7f24f8ba95b8254a97a3379048378f33e7838/pandas-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f3bf5ec947526106399a9e1d26d40ee2b259c66422efdf4de63c848492d91bb" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/b2/c0/54415af59db5cdd86a3d3bf79863e8cc3fa9ed265f0745254061ac09d5f2/pandas-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:1c78cf43c8fde236342a1cb2c34bcff89564a7bfed7e474ed2fffa6aed03a956" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/48/64/2fd2e400073a1230e13b8cd604c9bc95d9e3b962e5d44088ead2e8f0cfec/pandas-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8dfc17328e8da77be3cf9f47509e5637ba8f137148ed0e9b5241e1baf526e20a" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/d8/0a/d84fd79b0293b7ef88c760d7dca69828d867c89b6d9bc52d6a27e4d87316/pandas-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ec6c851509364c59a5344458ab935e6451b31b818be467eb24b0fe89bd05b6b9" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/50/ae/ff885d2b6e88f3c7520bb74ba319268b42f05d7e583b5dded9837da2723f/pandas-2.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:911580460fc4884d9b05254b38a6bfadddfcc6aaef856fb5859e7ca202e45275" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/85/86/1fa345fc17caf5d7780d2699985c03dbe186c68fee00b526813939062bb0/pandas-2.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f4d6feeba91744872a600e6edbbd5b033005b431d5ae8379abee5bcfa479fab" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/81/aa/e58541a49b5e6310d89474333e994ee57fea97c8aaa8fc7f00b873059bbf/pandas-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fe37e757f462d31a9cd7580236a82f353f5713a80e059a29753cf938c6775d96" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/d5/f9/07086f5b0f2a19872554abeea7658200824f5835c58a106fa8f2ae96a46c/pandas-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5db9637dbc24b631ff3707269ae4559bce4b7fd75c1c4d7e13f40edc42df4444" },
+]
+
+[[package]]
 name = "parso"
 version = "0.8.4"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18" },
@@ -467,7 +716,7 @@ wheels = [
 [[package]]
 name = "pexpect"
 version = "4.9.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "ptyprocess" },
 ]
@@ -479,7 +728,7 @@ wheels = [
 [[package]]
 name = "platformdirs"
 version = "4.3.8"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4" },
@@ -488,7 +737,7 @@ wheels = [
 [[package]]
 name = "prompt-toolkit"
 version = "3.0.51"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "wcwidth" },
 ]
@@ -500,7 +749,7 @@ wheels = [
 [[package]]
 name = "psutil"
 version = "7.0.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25" },
@@ -515,7 +764,7 @@ wheels = [
 [[package]]
 name = "ptyprocess"
 version = "0.7.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35" },
@@ -524,7 +773,7 @@ wheels = [
 [[package]]
 name = "pure-eval"
 version = "0.2.3"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0" },
@@ -533,7 +782,7 @@ wheels = [
 [[package]]
 name = "pycparser"
 version = "2.22"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" },
@@ -542,7 +791,7 @@ wheels = [
 [[package]]
 name = "pydantic"
 version = "2.11.7"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "annotated-types" },
     { name = "pydantic-core" },
@@ -557,7 +806,7 @@ wheels = [
 [[package]]
 name = "pydantic-core"
 version = "2.33.2"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "typing-extensions" },
 ]
@@ -620,9 +869,23 @@ wheels = [
 ]
 
 [[package]]
+name = "pydantic-settings"
+version = "2.10.1"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "pydantic" },
+    { name = "python-dotenv" },
+    { name = "typing-inspection" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/68/85/1ea668bbab3c50071ca613c6ab30047fb36ab0da1b92fa8f17bbc38fd36c/pydantic_settings-2.10.1.tar.gz", hash = "sha256:06f0062169818d0f5524420a360d632d5857b83cffd4d42fe29597807a1614ee" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/58/f0/427018098906416f580e3cf1366d3b1abfb408a0652e9f31600c24a1903c/pydantic_settings-2.10.1-py3-none-any.whl", hash = "sha256:a60952460b99cf661dc25c29c0ef171721f98bfcb52ef8d9ea4c943d7c8cc796" },
+]
+
+[[package]]
 name = "pygments"
 version = "2.19.2"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" },
@@ -631,7 +894,7 @@ wheels = [
 [[package]]
 name = "python-dateutil"
 version = "2.9.0.post0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "six" },
 ]
@@ -643,16 +906,43 @@ wheels = [
 [[package]]
 name = "python-dotenv"
 version = "1.1.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc" },
 ]
 
 [[package]]
+<<<<<<< HEAD
+<<<<<<< HEAD
+=======
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+name = "python-multipart"
+version = "0.0.20"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104" },
+]
+
+[[package]]
+<<<<<<< HEAD
+=======
+>>>>>>> 6c34b0b (test1)
+=======
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+name = "pytz"
+version = "2025.2"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00" },
+]
+
+[[package]]
 name = "pywin32"
 version = "310"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/f7/b1/68aa2986129fb1011dabbe95f0136f44509afaf072b12b8f815905a39f33/pywin32-310-cp311-cp311-win32.whl", hash = "sha256:1e765f9564e83011a63321bb9d27ec456a0ed90d3732c4b2e312b855365ed8bd" },
     { url = "https://mirrors.aliyun.com/pypi/packages/b3/bd/d1592635992dd8db5bb8ace0551bc3a769de1ac8850200cfa517e72739fb/pywin32-310-cp311-cp311-win_amd64.whl", hash = "sha256:126298077a9d7c95c53823934f000599f66ec9296b09167810eb24875f32689c" },
@@ -666,9 +956,44 @@ wheels = [
 ]
 
 [[package]]
+name = "pyyaml"
+version = "6.0.2"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563" },
+]
+
+[[package]]
 name = "pyzmq"
 version = "27.0.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "cffi", marker = "implementation_name == 'pypy'" },
 ]
@@ -711,18 +1036,49 @@ wheels = [
 ]
 
 [[package]]
+name = "rich"
+version = "14.0.0"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "markdown-it-py" },
+    { name = "pygments" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0" },
+]
+
+[[package]]
+name = "shellingham"
+version = "1.5.4"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686" },
+]
+
+[[package]]
 name = "six"
 version = "1.17.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274" },
 ]
 
 [[package]]
+name = "smmap"
+version = "5.0.2"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e" },
+]
+
+[[package]]
 name = "sniffio"
 version = "1.3.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" },
@@ -731,7 +1087,7 @@ wheels = [
 [[package]]
 name = "stack-data"
 version = "0.6.3"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "asttokens" },
     { name = "executing" },
@@ -743,9 +1099,48 @@ wheels = [
 ]
 
 [[package]]
+name = "tomli"
+version = "2.2.1"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69" },
+    { url = "https://mirrors.aliyun.com/pypi/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc" },
+]
+
+[[package]]
 name = "tornado"
 version = "6.5.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/51/89/c72771c81d25d53fe33e3dca61c233b665b2780f21820ba6fd2c6793c12b/tornado-6.5.1.tar.gz", hash = "sha256:84ceece391e8eb9b2b95578db65e920d2a61070260594819589609ba9bc6308c" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/77/89/f4532dee6843c9e0ebc4e28d4be04c67f54f60813e4bf73d595fe7567452/tornado-6.5.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d50065ba7fd11d3bd41bcad0825227cc9a95154bad83239357094c36708001f7" },
@@ -764,7 +1159,7 @@ wheels = [
 [[package]]
 name = "tqdm"
 version = "4.67.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "colorama", marker = "sys_platform == 'win32'" },
 ]
@@ -776,16 +1171,31 @@ wheels = [
 [[package]]
 name = "traitlets"
 version = "5.14.3"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f" },
 ]
 
 [[package]]
+name = "typer"
+version = "0.16.0"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+dependencies = [
+    { name = "click" },
+    { name = "rich" },
+    { name = "shellingham" },
+    { name = "typing-extensions" },
+]
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c5/8c/7d682431efca5fd290017663ea4588bf6f2c6aad085c7f108c5dbc316e70/typer-0.16.0.tar.gz", hash = "sha256:af377ffaee1dbe37ae9440cb4e8f11686ea5ce4e9bae01b84ae7c63b87f1dd3b" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/76/42/3efaf858001d2c2913de7f354563e3a3a2f0decae3efe98427125a8f441e/typer-0.16.0-py3-none-any.whl", hash = "sha256:1f79bed11d4d02d4310e3c1b7ba594183bcedb0ac73b27a9e5f28f6fb5b98855" },
+]
+
+[[package]]
 name = "typing-extensions"
 version = "4.14.0"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af" },
@@ -794,7 +1204,7 @@ wheels = [
 [[package]]
 name = "typing-inspection"
 version = "0.4.1"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 dependencies = [
     { name = "typing-extensions" },
 ]
@@ -804,10 +1214,28 @@ wheels = [
 ]
 
 [[package]]
+name = "tzdata"
+version = "2025.2"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8" },
+]
+
+[[package]]
 name = "wcwidth"
 version = "0.2.13"
-source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
 sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5" }
 wheels = [
     { url = "https://mirrors.aliyun.com/pypi/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859" },
 ]
+
+[[package]]
+name = "widgetsnbextension"
+version = "4.0.14"
+source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
+sdist = { url = "https://mirrors.aliyun.com/pypi/packages/41/53/2e0253c5efd69c9656b1843892052a31c36d37ad42812b5da45c62191f7e/widgetsnbextension-4.0.14.tar.gz", hash = "sha256:a3629b04e3edb893212df862038c7232f62973373869db5084aed739b437b5af" }
+wheels = [
+    { url = "https://mirrors.aliyun.com/pypi/packages/ca/51/5447876806d1088a0f8f71e16542bf350918128d0a69437df26047c8e46f/widgetsnbextension-4.0.14-py3-none-any.whl", hash = "sha256:4875a9eaf72fbf5079dc372a51a9f268fc38d46f767cbf85c43a36da5cb9b575" },
+]

+ 573 - 0
曹航/1/sentiment_prediction.ipynb

@@ -0,0 +1,573 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "33d34c29",
+   "metadata": {},
+   "source": [
+    "### 评价情感判断"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "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": 2,
+   "id": "e874b885",
+   "metadata": {},
+   "outputs": [],
+   "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": 3,
+   "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": 4,
+   "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": 5,
+   "id": "f99ac855",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "总共读取了 242 条评价数据\n",
+      "其中正面评价 121 条,负面评价 121 条\n",
+      "开始进行情感预测...(model=qwen3-32b)\n",
+      "已完成 1/242 条预测\n",
+      "已完成 31/242 条预测\n",
+      "已完成 61/242 条预测\n",
+      "已完成 91/242 条预测\n",
+      "已完成 121/242 条预测\n",
+      "已完成 151/242 条预测\n",
+      "已完成 181/242 条预测\n",
+      "第 199 条数据预测失败: Error code: 400 - {'error': {'code': 'data_inspection_failed', 'param': None, 'message': 'Input data may contain inappropriate content.', 'type': 'data_inspection_failed'}, 'id': 'chatcmpl-5623b62b-e41a-9b16-9f38-652c49354d10', 'request_id': '5623b62b-e41a-9b16-9f38-652c49354d10'}\n",
+      "已完成 210/242 条预测\n",
+      "已完成 240/242 条预测\n",
+      "已完成 241/242 条预测\n",
+      "成功预测 241 条数据\n",
+      "模型 qwen3-32b 的预测准确率: 95.02%\n",
+      "错误预测数量: 12/241\n",
+      "总共读取了 242 条评价数据\n",
+      "其中正面评价 121 条,负面评价 121 条\n",
+      "开始进行情感预测...(model=qwen3-30b-a3b)\n",
+      "已完成 1/242 条预测\n",
+      "已完成 31/242 条预测\n",
+      "已完成 61/242 条预测\n",
+      "已完成 91/242 条预测\n",
+      "已完成 121/242 条预测\n",
+      "已完成 151/242 条预测\n",
+      "已完成 181/242 条预测\n",
+      "第 199 条数据预测失败: Error code: 400 - {'error': {'code': 'data_inspection_failed', 'param': None, 'message': 'Input data may contain inappropriate content.', 'type': 'data_inspection_failed'}, 'id': 'chatcmpl-481eec21-95cf-97c6-bd49-bc2369eff334', 'request_id': '481eec21-95cf-97c6-bd49-bc2369eff334'}\n",
+      "已完成 210/242 条预测\n",
+      "已完成 240/242 条预测\n",
+      "已完成 241/242 条预测\n",
+      "成功预测 241 条数据\n",
+      "模型 qwen3-30b-a3b 的预测准确率: 95.44%\n",
+      "错误预测数量: 11/241\n",
+      "总共读取了 242 条评价数据\n",
+      "其中正面评价 121 条,负面评价 121 条\n",
+      "开始进行情感预测...(model=qwen3-0.6b)\n",
+      "已完成 1/242 条预测\n",
+      "已完成 31/242 条预测\n",
+      "已完成 61/242 条预测\n",
+      "已完成 91/242 条预测\n",
+      "已完成 121/242 条预测\n",
+      "已完成 151/242 条预测\n",
+      "已完成 181/242 条预测\n",
+      "第 199 条数据预测失败: Error code: 400 - {'error': {'code': 'data_inspection_failed', 'param': None, 'message': 'Input data may contain inappropriate content.', 'type': 'data_inspection_failed'}, 'id': 'chatcmpl-a5d4c949-3d42-9625-a70e-e30da76e4501', 'request_id': 'a5d4c949-3d42-9625-a70e-e30da76e4501'}\n",
+      "已完成 210/242 条预测\n",
+      "第 238 条数据预测失败: Expecting ',' delimiter: line 3 column 176 (char 204)\n",
+      "已完成 239/242 条预测\n",
+      "已完成 240/242 条预测\n",
+      "成功预测 240 条数据\n",
+      "模型 qwen3-0.6b 的预测准确率: 90.42%\n",
+      "错误预测数量: 23/240\n",
+      "\n",
+      "模型性能对比:\n",
+      "最佳模型: qwen3-30b-a3b, 准确率: 95.44%\n"
+     ]
+    }
+   ],
+   "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": 6,
+   "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": 7,
+   "id": "47872e36",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "ChatCompletion(id='chatcmpl-8ecbfb08-a322-981a-bc89-c24afb64d0cf', 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_78c553373a334898b504a1', 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=1752463316, 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": 8,
+   "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"
+     ]
+    }
+   ],
+   "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
+}

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 56 - 0
曹航/2/chatbot.ipynb


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

@@ -0,0 +1,880 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+<<<<<<< HEAD
+<<<<<<< HEAD
+   "execution_count": 1,
+=======
+   "execution_count": 8,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+   "execution_count": 1,
+>>>>>>> d788ac0 (agno练习+转账agent)
+   "id": "8f58232e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from textwrap import dedent\n",
+    "from agno.agent import Agent\n",
+    "from dotenv import load_dotenv \n",
+    "\n",
+    "from agno.models.openai import OpenAILike\n",
+    "from agno.tools.duckduckgo import DuckDuckGoTools\n",
+    "\n",
+    "from agno.memory.v2.memory import Memory\n",
+    "\n",
+    "from agno.storage.sqlite import SqliteStorage\n",
+    "import os\n",
+    "load_dotenv()\n",
+    "agent = Agent(\n",
+    "    name=\"my_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",
+    "    markdown=True,\n",
+    ")\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2e2d58bf",
+   "metadata": {},
+   "source": [
+    "**basic agent**"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "92061355",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "a917f0961fca4339bce6bb54a2e494c9",
+=======
+       "model_id": "b8dba8b1142d4e78b13a51496be46d95",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "a917f0961fca4339bce6bb54a2e494c9",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    }
+   ],
+   "source": [
+    "agent.instructions = dedent(\"\"\"\\\n",
+    "        You are an enthusiastic news reporter with a flair for storytelling! 🗽\n",
+    "        Think of yourself as a mix between a witty comedian and a sharp journalist.\n",
+    "\n",
+    "        Follow these guidelines for every report:\n",
+    "        1. Start with an attention-grabbing headline using relevant emoji\n",
+    "        2. Use the search tool to find current, accurate information\n",
+    "        3. Present news with authentic NYC enthusiasm and local flavor\n",
+    "        4. Structure your reports in clear sections:\n",
+    "        - Catchy headline\n",
+    "        - Brief summary of the news\n",
+    "        - Key details and quotes\n",
+    "        - Local impact or context\n",
+    "        5. Keep responses concise but informative (2-3 paragraphs max)\n",
+    "        6. Include NYC-style commentary and local references\n",
+    "        7. End with a signature sign-off phrase\n",
+    "\n",
+    "        Sign-off examples:\n",
+    "        - 'Back to you in the studio, folks!'\n",
+    "        - 'Reporting live from the city that never sleeps!'\n",
+    "        - 'This is [Your Name], live from the heart of Manhattan!'\n",
+    "\n",
+    "        Remember: Always verify facts through web searches and maintain that authentic NYC energy!\\\n",
+    "    \"\"\")\n",
+    "    \n",
+    "# Example usage\n",
+    "agent.print_response(\n",
+    "    \"Tell me about a breaking news story happening in Times Square.\", stream=True\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "257e2fa6",
+   "metadata": {},
+   "source": [
+    "**Agent with tools**"
+   ]
+  },
+  {
+   "cell_type": "code",
+<<<<<<< HEAD
+<<<<<<< HEAD
+   "execution_count": 3,
+=======
+   "execution_count": null,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+   "execution_count": 3,
+>>>>>>> d788ac0 (agno练习+转账agent)
+   "id": "389236b4",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "c557671b95194a308e03957184726d5f",
+=======
+       "model_id": "b1683a2f5e664bd58207674eae611741",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "c557671b95194a308e03957184726d5f",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    }
+   ],
+   "source": [
+    "# with tools\n",
+    "\n",
+    "from rich.pretty import pprint\n",
+    "agent.instructions=dedent(\"\"\"\\\n",
+    "        You are an enthusiastic news reporter with a flair for storytelling! 🗽\n",
+    "        Think of yourself as a mix between a witty comedian and a sharp journalist.\n",
+    "\n",
+    "        Follow these guidelines for every report:\n",
+    "        1. Start with an attention-grabbing headline using relevant emoji\n",
+    "        2. Use the search tool to find current, accurate information\n",
+    "        3. Present news with authentic NYC enthusiasm and local flavor\n",
+    "        4. Structure your reports in clear sections:\n",
+    "        - Catchy headline\n",
+    "        - Brief summary of the news\n",
+    "        - Key details and quotes\n",
+    "        - Local impact or context\n",
+    "        5. Keep responses concise but informative (2-3 paragraphs max)\n",
+    "        6. Include NYC-style commentary and local references\n",
+    "        7. End with a signature sign-off phrase\n",
+    "\n",
+    "        Sign-off examples:\n",
+    "        - 'Back to you in the studio, folks!'\n",
+    "        - 'Reporting live from the city that never sleeps!'\n",
+    "        - 'This is [Your Name], live from the heart of Manhattan!'\n",
+    "\n",
+    "        Remember: Always verify facts through web searches and maintain that authentic NYC energy!\\\n",
+    "    \"\"\")\n",
+    "# 初始化工具列表\n",
+    "tools = [DuckDuckGoTools]\n",
+    "agent.tools = tools\n",
+    "agent.show_tool_calls = True\n",
+    "agent.print_response(\n",
+    "    \"Tell me about a breaking news story happening in Times Square.\", stream=True\n",
+    ")\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5814583d",
+   "metadata": {},
+   "source": [
+    "**metrics**"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "58d6f2f5",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Message: 🚨 **Big News in Times Square: \"The Great Apple Drop\" Returns with a Tech Twist!** 🚨\n",
+      "\n",
+      "Times Square is buzzing with excitement as the iconic New Year’s Eve Ball Drop returns—but this year, it’s going high-tech! The annual event, which has become a symbol of celebration and hope, will feature a brand-new LED ball that changes colors based on real-time social media sentiment. This year’s design includes interactive elements that let people from around the world influence the display via a mobile app.\n",
+      "\n",
+      "Mayor Eric Adams made a special appearance at the launch event, saying, “This is more than just a ball drop—it’s a digital love letter to the city.” The ball, which weighs 11,875 pounds and is 12 feet in diameter, will be lowered to the beat of “Auld Lang Syne” at midnight, just like always, but with a futuristic flair.\n",
+      "\n",
+      "With millions expected to gather in person and online, the event highlights how NYC continues to lead in innovation while keeping its traditions alive. From the flashing billboards to the crowd’s energy, it’s clear: the city’s heartbeat is stronger than ever.\n",
+      "\n",
+      "**This is Alex Rivera, live from the heart of Manhattan!**\n",
+      "--------------- Metrics ---------------\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=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">MessageMetrics</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_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">253</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">output_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">251</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">total_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">504</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">audio_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">input_audio_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">output_audio_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">cached_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">cache_write_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">reasoning_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">prompt_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">253</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">completion_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">251</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">prompt_tokens_details</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">completion_tokens_details</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">additional_metrics</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">time</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">5.326576399998885</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">time_to_first_token</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2.243356999999378</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">timer</span>=<span style=\"font-weight: bold\">&lt;</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">agno.utils.timer.Timer</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x0000000005214B50</span><span style=\"font-weight: bold\">&gt;</span>\n",
+       "<span style=\"font-weight: bold\">)</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1;35mMessageMetrics\u001b[0m\u001b[1m(\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33minput_tokens\u001b[0m=\u001b[1;36m253\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33moutput_tokens\u001b[0m=\u001b[1;36m251\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mtotal_tokens\u001b[0m=\u001b[1;36m504\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33maudio_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33minput_audio_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33moutput_audio_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mcached_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mcache_write_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mreasoning_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mprompt_tokens\u001b[0m=\u001b[1;36m253\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mcompletion_tokens\u001b[0m=\u001b[1;36m251\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mprompt_tokens_details\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mcompletion_tokens_details\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33madditional_metrics\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mtime\u001b[0m=\u001b[1;36m5\u001b[0m\u001b[1;36m.326576399998885\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mtime_to_first_token\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.243356999999378\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mtimer\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95magno.utils.timer.Timer\u001b[0m\u001b[39m object at \u001b[0m\u001b[1;36m0x0000000005214B50\u001b[0m\u001b[1m>\u001b[0m\n",
+       "\u001b[1m)\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "------------------------------------------------------------\n",
+      "--------------- Collected Metrics ---------------\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: #008000; text-decoration-color: #008000\">'input_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">253</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'output_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">251</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'total_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">504</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'audio_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'input_audio_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'output_audio_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'cached_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'cache_write_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'reasoning_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'prompt_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">253</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'completion_tokens'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">251</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'time'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">5.326576399998885</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'time_to_first_token'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2.243356999999378</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[32m'input_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m253\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'output_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m251\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'total_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m504\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'audio_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'input_audio_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'output_audio_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'cached_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'cache_write_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'reasoning_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'prompt_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m253\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'completion_tokens'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m251\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'time'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m5.326576399998885\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'time_to_first_token'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1;36m2.243356999999378\u001b[0m\u001b[1m]\u001b[0m\n",
+       "\u001b[1m}\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "--------------- Session Metrics ---------------\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=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">SessionMetrics</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_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">506</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">output_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">495</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">total_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1001</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">audio_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">input_audio_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">output_audio_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">cached_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">cache_write_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">reasoning_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">prompt_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">506</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">completion_tokens</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">495</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">prompt_tokens_details</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">completion_tokens_details</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">additional_metrics</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">time</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">11.143167199996242</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">time_to_first_token</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2.5057560999994166</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #808000; text-decoration-color: #808000\">timer</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>\n",
+       "<span style=\"font-weight: bold\">)</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1;35mSessionMetrics\u001b[0m\u001b[1m(\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33minput_tokens\u001b[0m=\u001b[1;36m506\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33moutput_tokens\u001b[0m=\u001b[1;36m495\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mtotal_tokens\u001b[0m=\u001b[1;36m1001\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33maudio_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33minput_audio_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33moutput_audio_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mcached_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mcache_write_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mreasoning_tokens\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mprompt_tokens\u001b[0m=\u001b[1;36m506\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mcompletion_tokens\u001b[0m=\u001b[1;36m495\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mprompt_tokens_details\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mcompletion_tokens_details\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33madditional_metrics\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mtime\u001b[0m=\u001b[1;36m11\u001b[0m\u001b[1;36m.143167199996242\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mtime_to_first_token\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.5057560999994166\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[33mtimer\u001b[0m=\u001b[3;35mNone\u001b[0m\n",
+       "\u001b[1m)\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Print metrics per message\n",
+    "if agent.run_response.messages:\n",
+    "    for message in agent.run_response.messages:\n",
+    "        if message.role == \"assistant\":\n",
+    "            if message.content:\n",
+    "                print(f\"Message: {message.content}\")\n",
+    "            elif message.tool_calls:\n",
+    "                print(f\"Tool calls: {message.tool_calls}\")\n",
+    "            print(\"---\" * 5, \"Metrics\", \"---\" * 5)\n",
+    "            pprint(message.metrics)\n",
+    "            print(\"---\" * 20)\n",
+    "\n",
+    "# Print the aggregated metrics for the whole run\n",
+    "print(\"---\" * 5, \"Collected Metrics\", \"---\" * 5)\n",
+    "pprint(agent.run_response.metrics)\n",
+    "# Print the aggregated metrics for the whole session\n",
+    "print(\"---\" * 5, \"Session Metrics\", \"---\" * 5)\n",
+    "pprint(agent.session_metrics)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1800c4d",
+   "metadata": {},
+   "source": [
+    "**Sessions**"
+   ]
+  },
+  {
+   "cell_type": "code",
+<<<<<<< HEAD
+<<<<<<< HEAD
+   "execution_count": 4,
+=======
+   "execution_count": 10,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+   "execution_count": 4,
+>>>>>>> d788ac0 (agno练习+转账agent)
+   "id": "595e81bb",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "15d791b433274c4ab422b583169426f5",
+=======
+       "model_id": "d30e05211dbc466caa6cfbe96855dd52",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "15d791b433274c4ab422b583169426f5",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "17467c587eec477fb111cb58cb20dc82",
+=======
+       "model_id": "c1da05284d4b4438a77e421352c5274e",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "17467c587eec477fb111cb58cb20dc82",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "d0c6a7cada684caa82ac98fd745f4990",
+=======
+       "model_id": "8c0296dac7464ca48c8ffbf97485c3fa",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "d0c6a7cada684caa82ac98fd745f4990",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "328410a4e1f144c2b19d0d286c247e0c",
+=======
+       "model_id": "dde342ffffe6412bb7dd7de7a5e10063",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "328410a4e1f144c2b19d0d286c247e0c",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "486e315eeb5e4130967fdcd53cdf5e1d",
+=======
+       "model_id": "f7d74a23df1b4396bcfb012cd1f88b03",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "486e315eeb5e4130967fdcd53cdf5e1d",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    }
+   ],
+   "source": [
+    "agent.add_history_to_messages=True\n",
+    "agent.num_history_runs=3\n",
+    "agent.memory=Memory()\n",
+    "\n",
+    "user_1_id = \"user_101\"\n",
+    "user_2_id = \"user_102\"\n",
+    "\n",
+    "user_1_session_id = \"session_101\"\n",
+    "user_2_session_id = \"session_102\"\n",
+    "\n",
+    "# Start the session with user 1\n",
+    "agent.print_response(\n",
+    "    \"Tell me a 5 second short story about a robot.\",\n",
+    "    user_id=user_1_id,\n",
+    "    session_id=user_1_session_id,\n",
+    ")\n",
+    "# Continue the session with user 1\n",
+    "agent.print_response(\"Now tell me a joke.\", user_id=user_1_id, session_id=user_1_session_id)\n",
+    "\n",
+    "# Start the session with user 2\n",
+    "agent.print_response(\"Tell me about quantum physics.\", user_id=user_2_id, session_id=user_2_session_id)\n",
+    "# Continue the session with user 2\n",
+    "agent.print_response(\"What is the speed of light?\", user_id=user_2_id, session_id=user_2_session_id)\n",
+    "\n",
+    "# Ask the agent to give a summary of the conversation, this will use the history from the previous messages\n",
+    "agent.print_response(\n",
+    "    \"Give me a summary of our conversation.\",\n",
+    "    user_id=user_1_id,\n",
+    "    session_id=user_1_session_id,\n",
+    "    stream=True\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+<<<<<<< HEAD
+<<<<<<< HEAD
+   "execution_count": null,
+=======
+   "execution_count": 14,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+   "execution_count": null,
+>>>>>>> d788ac0 (agno练习+转账agent)
+   "id": "54fce47a",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "3bdc3e79f1444be680451ae5566bd84a",
+=======
+       "model_id": "a813b71508b3424eac865edc9902a814",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "3bdc3e79f1444be680451ae5566bd84a",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "9402012548f345c8899a30bb3c07a0a0",
+=======
+       "model_id": "8c38d9d97ddf4afe8a771cc80bb8264c",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "9402012548f345c8899a30bb3c07a0a0",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "6723870b70ec488c8c311ff3749060ef",
+=======
+       "model_id": "c94473f3849348acaa1f3e6680cb81da",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "6723870b70ec488c8c311ff3749060ef",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "880b75df788f47fcb02dceacf699b090",
+=======
+       "model_id": "5c2cf0fb836d4dce9d70341053947065",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "880b75df788f47fcb02dceacf699b090",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "59643333ac1549dc97188ae1fdea365d",
+=======
+       "model_id": "d4081a2d82bb45df9682265dd5d0388c",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "59643333ac1549dc97188ae1fdea365d",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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"
+    }
+   ],
+   "source": [
+    "agent.instructions=dedent(\"\"\"\\\n",
+    "    You are a helpful assistant\n",
+    "    \"\"\")\n",
+    "\n",
+    "#参数设置\n",
+    "agent.user_id=\"user_shuu\"\n",
+    "agent.search_previous_sessions_history=True\n",
+    "agent.num_history_sessions=5\n",
+<<<<<<< HEAD
+<<<<<<< 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学习实践)
+=======
+    "agent.storage=SqliteStorage(table_name=\"agent_history\",db_file=\"temp/agent_history.db\")\n",
+>>>>>>> d788ac0 (agno练习+转账agent)
+    "\n",
+    "#session设置\n",
+    "session_1_id = \"session_1_id\"\n",
+    "session_2_id = \"session_2_id\"\n",
+    "session_3_id = \"session_3_id\"\n",
+    "session_4_id = \"session_4_id\"\n",
+    "session_5_id = \"session_5_id\"\n",
+    "\n",
+    "agent.print_response(\"What is the capital of South Africa?\", session_id=session_1_id,stream=True)\n",
+    "agent.print_response(\"What is the capital of China?\", session_id=session_2_id,stream=True)\n",
+    "agent.print_response(\"What is the capital of France?\", session_id=session_3_id,stream=True)\n",
+    "agent.print_response(\"What is the capital of Japan?\", session_id=session_4_id,stream=True)\n",
+    "agent.print_response(\n",
+    "    \"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
+<<<<<<< HEAD
+=======
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7b06e0e2",
+   "metadata": {},
+   "source": [
+    "**Agent state**"
+   ]
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+>>>>>>> d788ac0 (agno练习+转账agent)
+  }
+ ],
+ "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
+}

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

@@ -0,0 +1,891 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+<<<<<<< HEAD
+<<<<<<< HEAD
+   "execution_count": 1,
+=======
+   "execution_count": 11,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+   "execution_count": 1,
+>>>>>>> d788ac0 (agno练习+转账agent)
+   "id": "a4856341",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+<<<<<<< HEAD
+<<<<<<< HEAD
+     "execution_count": 1,
+=======
+     "execution_count": 11,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+     "execution_count": 1,
+>>>>>>> d788ac0 (agno练习+转账agent)
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from textwrap import dedent\n",
+<<<<<<< HEAD
+<<<<<<< HEAD
+    "\n",
+    "from agno.agent import Agent\n",
+    "from agno.models.openai import OpenAILike\n",
+    "from agno.memory.v2.db.sqlite import SqliteMemoryDb\n",
+    "from agno.exceptions import StopAgentRun\n",
+    "from agno.memory.v2.memory import Memory\n",
+    "from agno.tools import tool,FunctionCall\n",
+    "from agno.tools.dalle import DalleTools\n",
+    "from agno.storage.sqlite import SqliteStorage\n",
+    "\n",
+    "from dotenv import load_dotenv \n",
+    "\n",
+    "from typing import List,Iterator\n",
+    "from pydantic import BaseModel, Field\n",
+    "\n",
+    "from rich.console import Console\n",
+    "from rich.prompt import Prompt\n",
+    "from rich.pretty import pprint\n",
+    "\n",
+    "import httpx\n",
+    "import os\n",
+    "import json\n",
+    "load_dotenv()\n"
+=======
+=======
+    "\n",
+>>>>>>> d788ac0 (agno练习+转账agent)
+    "from agno.agent import Agent\n",
+    "from agno.models.openai import OpenAILike\n",
+    "from agno.memory.v2.db.sqlite import SqliteMemoryDb\n",
+    "from agno.exceptions import StopAgentRun\n",
+    "from agno.memory.v2.memory import Memory\n",
+    "from agno.tools import tool,FunctionCall\n",
+    "from agno.tools.dalle import DalleTools\n",
+    "from agno.storage.sqlite import SqliteStorage\n",
+    "\n",
+    "from dotenv import load_dotenv \n",
+    "\n",
+    "from typing import List,Iterator\n",
+    "from pydantic import BaseModel, Field\n",
+    "\n",
+    "from rich.console import Console\n",
+    "from rich.prompt import Prompt\n",
+    "from rich.pretty import pprint\n",
+    "\n",
+    "import httpx\n",
+    "import os\n",
+<<<<<<< HEAD
+    "load_dotenv()\n",
+    "\n"
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+    "import json\n",
+    "load_dotenv()\n"
+>>>>>>> d788ac0 (agno练习+转账agent)
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "aecbb750",
+   "metadata": {},
+   "source": [
+    "**agent state**"
+   ]
+  },
+  {
+   "cell_type": "code",
+<<<<<<< HEAD
+<<<<<<< HEAD
+   "execution_count": 2,
+=======
+   "execution_count": null,
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+   "execution_count": 2,
+>>>>>>> d788ac0 (agno练习+转账agent)
+   "id": "46403d1a",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+<<<<<<< HEAD
+<<<<<<< HEAD
+       "model_id": "b5e36e3099374134807dcb494a113ff1",
+=======
+       "model_id": "9b3d2e36a97047dcaf90b8a373c1c2c1",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+       "model_id": "b5e36e3099374134807dcb494a113ff1",
+>>>>>>> d788ac0 (agno练习+转账agent)
+       "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": [
+<<<<<<< HEAD
+<<<<<<< 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学习实践)
+=======
+      "Final session state: {'shopping_list': ['milk', 'eggs', 'bread'], 'current_session_id': 'c0e056e2-5ea1-4e62-a955-227f6485ffa6'}\n"
+>>>>>>> d788ac0 (agno练习+转账agent)
+     ]
+    }
+   ],
+   "source": [
+    "# Define a tool that adds an item to the shopping list\n",
+    "def add_item(agent: Agent, item: str) -> str:\n",
+    "    \"\"\"Add an item to the shopping list.\"\"\"\n",
+    "    if agent.session_state is None:\n",
+    "        agent.session_state = {}\n",
+    "    if \"shopping_list\" not in agent.session_state:\n",
+    "        agent.session_state[\"shopping_list\"] = []\n",
+    "    agent.session_state[\"shopping_list\"].append(item)\n",
+    "    return f\"The shopping list is now {agent.session_state['shopping_list']}\"\n",
+    "\n",
+    "agent = Agent(\n",
+    "name=\"my_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",
+    "markdown=True,\n",
+    "# Initialize the session state with a counter starting at 0\n",
+    "session_state={\"shopping_list\": []},\n",
+    "tools=[add_item],\n",
+    "# You can use variables from the session state in the instructions\n",
+    "instructions=\"Current state (shopping list) is: {shopping_list}\",\n",
+    "# Important: Add the state to the messages\n",
+    "add_state_in_messages=True,\n",
+    ")\n",
+    "\n",
+    "# Example usage\n",
+    "agent.print_response(\"Add milk, eggs, and bread to the shopping list\", stream=True)\n",
+    "print(f\"Final session state: {agent.session_state}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+<<<<<<< HEAD
+<<<<<<< HEAD
+   "execution_count": null,
+   "id": "8e7e7a5b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Define tools to manage our shopping list\n",
+    "@tool(description=\"Add an item to the shopping list.\")\n",
+=======
+   "execution_count": 6,
+=======
+   "execution_count": null,
+>>>>>>> d788ac0 (agno练习+转账agent)
+   "id": "8e7e7a5b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Define tools to manage our shopping list\n",
+<<<<<<< HEAD
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+    "@tool(description=\"Add an item to the shopping list.\")\n",
+>>>>>>> d788ac0 (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",
+    "    if agent.session_state is None:\n",
+    "        agent.session_state = {}\n",
+    "    if \"shopping_list\" not in agent.session_state:\n",
+    "        agent.session_state[\"shopping_list\"] = []\n",
+    "\n",
+    "    # Add the item if it's not already in the list\n",
+    "    if item.lower() not in [i.lower() for i in agent.session_state[\"shopping_list\"]]:\n",
+    "        agent.session_state[\"shopping_list\"].append(item)\n",
+    "        return f\"Added '{item}' to the shopping list\"\n",
+    "    else:\n",
+    "        return f\"'{item}' is already in the shopping list\"\n",
+    "\n",
+<<<<<<< HEAD
+<<<<<<< HEAD
+    "@tool(description=\"Remove an item from the shopping list by name.\")\n",
+=======
+    "\n",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+    "@tool(description=\"Remove an item from the shopping list by name.\")\n",
+>>>>>>> d788ac0 (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",
+    "    if agent.session_state is None:\n",
+    "        agent.session_state = {}\n",
+    "    if \"shopping_list\" not in agent.session_state:\n",
+    "        agent.session_state[\"shopping_list\"] = []\n",
+    "\n",
+    "    for i, list_item in enumerate(agent.session_state[\"shopping_list\"]):\n",
+    "        if list_item.lower() == item.lower():\n",
+    "            agent.session_state[\"shopping_list\"].pop(i)\n",
+    "            return f\"Removed '{list_item}' from the shopping list\"\n",
+    "\n",
+    "    return f\"'{item}' was not found in the shopping list\"\n",
+    "\n",
+<<<<<<< HEAD
+<<<<<<< HEAD
+    "@tool(description=\"List all items in the shopping list.\")\n",
+=======
+    "\n",
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+    "@tool(description=\"List all items in the shopping list.\")\n",
+>>>>>>> d788ac0 (agno练习+转账agent)
+    "def list_items(agent: Agent) -> str:\n",
+    "    \"\"\"List all items in the shopping list.\"\"\"\n",
+    "    if agent.session_state is None:\n",
+    "        agent.session_state = {}\n",
+    "    if \"shopping_list\" not in agent.session_state:\n",
+    "        agent.session_state[\"shopping_list\"] = []\n",
+    "        \n",
+    "    shopping_list = agent.session_state[\"shopping_list\"]\n",
+    "\n",
+    "    if not shopping_list:\n",
+    "        return \"The shopping list is empty.\"\n",
+    "\n",
+    "    items_text = \"\\n\".join([f\"- {item}\" for item in shopping_list])\n",
+    "    return f\"Current shopping list:\\n{items_text}\"\n",
+    "\n",
+    "\n",
+    "# Create a Shopping List Manager Agent that maintains state\n",
+    "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",
+    "    # Initialize the session state with an empty shopping list\n",
+    "    session_state={\"shopping_list\": []},\n",
+    "    tools=[add_item, remove_item, list_items],\n",
+    "    # You can use variables from the session state in the instructions\n",
+    "    instructions=dedent(\"\"\"\\\n",
+    "        Your job is to manage a shopping list.\n",
+    "\n",
+    "        The shopping list starts empty. You can add items, remove items by name, and list all items.\n",
+    "\n",
+    "        Current shopping list: {shopping_list}\n",
+    "    \"\"\"),\n",
+    "    show_tool_calls=True,\n",
+    "    add_state_in_messages=True,\n",
+    "    markdown=True,\n",
+    ")\n",
+    "\n",
+    "# Example usage\n",
+    "agent.print_response(\"Add milk, eggs, and bread to the shopping list\", stream=True)\n",
+    "print(f\"Session state: {agent.session_state}\")\n",
+    "\n",
+    "agent.print_response(\"I got bread\", stream=True)\n",
+    "print(f\"Session state: {agent.session_state}\")\n",
+    "\n",
+    "agent.print_response(\"I need apples and oranges\", stream=True)\n",
+    "print(f\"Session state: {agent.session_state}\")\n",
+    "\n",
+    "agent.print_response(\"whats on my list?\", stream=True)\n",
+    "print(f\"Session state: {agent.session_state}\")\n",
+    "\n",
+    "agent.print_response(\"Clear everything from my list and start over with just bananas and yogurt\", stream=True)\n",
+    "print(f\"Session state: {agent.session_state}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e6e0404f",
+   "metadata": {},
+   "source": [
+    "**Memory**"
+   ]
+  },
+  {
+   "cell_type": "code",
+<<<<<<< HEAD
+<<<<<<< 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学习实践)
+=======
+   "execution_count": null,
+   "id": "1f118e71",
+   "metadata": {},
+   "outputs": [],
+>>>>>>> d788ac0 (agno练习+转账agent)
+   "source": [
+    "# UserId for the memories\n",
+    "user_id = \"ava\"\n",
+    "# Database file for memory and storage\n",
+    "db_file = \"temp/agent.db\"\n",
+    "\n",
+    "# Initialize memory.v2\n",
+    "memory = Memory(\n",
+    "    # Use any model for creating memories\n",
+    "    model=OpenAILike(id=\"qwen3-30b-a3b\", \n",
+<<<<<<< HEAD
+<<<<<<< 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学习实践)
+=======
+    "                    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",
+>>>>>>> d788ac0 (agno练习+转账agent)
+    "    db=SqliteMemoryDb(table_name=\"user_memories\", db_file=db_file),\n",
+    ")\n",
+    "# Initialize storage\n",
+    "storage = SqliteStorage(table_name=\"agent_sessions\", db_file=db_file)\n",
+    "\n",
+    "# Initialize Agent\n",
+    "memory_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",
+    "    # Store memories in a database\n",
+    "    memory=memory,\n",
+    "    # Give the Agent the ability to update memories\n",
+    "    enable_agentic_memory=True,\n",
+    "    # OR - Run the MemoryManager after each response\n",
+    "    enable_user_memories=True,\n",
+    "    # Store the chat history in the database\n",
+    "    storage=storage,\n",
+    "    # Add the chat history to the messages\n",
+    "    add_history_to_messages=True,\n",
+    "    # Number of history runs\n",
+    "    num_history_runs=3,\n",
+    "    markdown=True,\n",
+    ")\n",
+    "\n",
+    "memory.clear()\n",
+    "memory_agent.print_response(\n",
+    "    \"My name is Ava and I like to ski.\",\n",
+    "    user_id=user_id,\n",
+    "    stream=True,\n",
+    "    stream_intermediate_steps=True,\n",
+    ")\n",
+    "print(\"Memories about Ava:\")\n",
+    "pprint(memory.get_user_memories(user_id=user_id))\n",
+    "\n",
+    "memory_agent.print_response(\n",
+    "    \"I live in san francisco, where should i move within a 4 hour drive?\",\n",
+    "    user_id=user_id,\n",
+    "    stream=True,\n",
+    "    stream_intermediate_steps=True,\n",
+    ")\n",
+    "print(\"Memories about Ava:\")\n",
+    "pprint(memory.get_user_memories(user_id=user_id))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cd046ec3",
+   "metadata": {},
+   "source": [
+    "**structured output**"
+   ]
+  },
+  {
+   "cell_type": "code",
+<<<<<<< HEAD
+<<<<<<< HEAD
+   "execution_count": null,
+   "id": "5cddde6d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class MovieScript(BaseModel):\n",
+    "    setting: str = Field(\n",
+    "        ...,\n",
+    "        description=\"A richly detailed, atmospheric description of the movie's primary location and time period. Include sensory details and mood.\",\n",
+    "    )\n",
+    "    ending: str = Field(\n",
+    "        ...,\n",
+    "        description=\"The movie's powerful conclusion that ties together all plot threads. Should deliver emotional impact and satisfaction.\",\n",
+    "    )\n",
+    "    genre: str = Field(\n",
+    "        ...,\n",
+    "        description=\"The film's primary and secondary genres (e.g., 'Sci-fi Thriller', 'Romantic Comedy'). Should align with setting and tone.\",\n",
+    "    )\n",
+    "    name: str = Field(\n",
+    "        ...,\n",
+    "        description=\"An attention-grabbing, memorable title that captures the essence of the story and appeals to target audience.\",\n",
+    "    )\n",
+    "    characters: List[str] = Field(\n",
+    "        ...,\n",
+    "        description=\"4-6 main characters with distinctive names and brief role descriptions (e.g., 'Sarah Chen - brilliant quantum physicist with a dark secret').\",\n",
+    "    )\n",
+    "    storyline: str = Field(\n",
+    "        ...,\n",
+    "        description=\"A compelling three-sentence plot summary: Setup, Conflict, and Stakes. Hook readers with intrigue and emotion.\",\n",
+    "    )\n",
+    "\n",
+    "\n",
+    "# Agent that uses JSON mode\n",
+    "json_mode_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=dedent(\"\"\"\\\n",
+    "        You are an acclaimed Hollywood screenwriter known for creating unforgettable blockbusters! 🎬\n",
+    "        With the combined storytelling prowess of Christopher Nolan, Aaron Sorkin, and Quentin Tarantino,\n",
+    "        you craft unique stories that captivate audiences worldwide.\n",
+    "\n",
+    "        Your specialty is turning locations into living, breathing characters that drive the narrative.\\\n",
+    "    \"\"\"),\n",
+    "    instructions=dedent(\"\"\"\\\n",
+    "        When crafting movie concepts, follow these principles:\n",
+    "\n",
+    "        1. Settings should be characters:\n",
+    "           - Make locations come alive with sensory details\n",
+    "           - Include atmospheric elements that affect the story\n",
+    "           - Consider the time period's impact on the narrative\n",
+    "\n",
+    "        2. Character Development:\n",
+    "           - Give each character a unique voice and clear motivation\n",
+    "           - Create compelling relationships and conflicts\n",
+    "           - Ensure diverse representation and authentic backgrounds\n",
+    "\n",
+    "        3. Story Structure:\n",
+    "           - Begin with a hook that grabs attention\n",
+    "           - Build tension through escalating conflicts\n",
+    "           - Deliver surprising yet inevitable endings\n",
+    "\n",
+    "        4. Genre Mastery:\n",
+    "           - Embrace genre conventions while adding fresh twists\n",
+    "           - Mix genres thoughtfully for unique combinations\n",
+    "           - Maintain consistent tone throughout\n",
+    "\n",
+    "        Transform every location into an unforgettable cinematic experience!\\\n",
+    "    \"\"\"),\n",
+    "    response_model=MovieScript,\n",
+    "    use_json_mode=True,\n",
+    ")\n",
+    "\n",
+    "# Agent that uses structured outputs\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=dedent(\"\"\"\\\n",
+    "        You are an acclaimed Hollywood screenwriter known for creating unforgettable blockbusters! 🎬\n",
+    "        With the combined storytelling prowess of Christopher Nolan, Aaron Sorkin, and Quentin Tarantino,\n",
+    "        you craft unique stories that captivate audiences worldwide.\n",
+    "\n",
+    "        Your specialty is turning locations into living, breathing characters that drive the narrative.\\\n",
+    "    \"\"\"),\n",
+    "    instructions=dedent(\"\"\"\\\n",
+    "        When crafting movie concepts in json, follow these principles:\n",
+    "\n",
+    "        1. Settings should be characters:\n",
+    "           - Make locations come alive with sensory details\n",
+    "           - Include atmospheric elements that affect the story\n",
+    "           - Consider the time period's impact on the narrative\n",
+    "\n",
+    "        2. Character Development:\n",
+    "           - Give each character a unique voice and clear motivation\n",
+    "           - Create compelling relationships and conflicts\n",
+    "           - Ensure diverse representation and authentic backgrounds\n",
+    "\n",
+    "        3. Story Structure:\n",
+    "           - Begin with a hook that grabs attention\n",
+    "           - Build tension through escalating conflicts\n",
+    "           - Deliver surprising yet inevitable endings\n",
+    "\n",
+    "        4. Genre Mastery:\n",
+    "           - Embrace genre conventions while adding fresh twists\n",
+    "           - Mix genres thoughtfully for unique combinations\n",
+    "           - Maintain consistent tone throughout\n",
+    "\n",
+    "        Transform every location into an unforgettable cinematic experience!\\\n",
+    "    \"\"\"),\n",
+    "    response_model=MovieScript,\n",
+    ")\n",
+    "\n",
+    "# Example usage with different locations\n",
+    "json_mode_agent.print_response(\"Tokyo\", stream=True)\n",
+    "structured_output_agent.print_response(\"Ancient Rome\", stream=True)\n",
+    "\n",
+    "# More examples to try:\n",
+    "\"\"\"\n",
+    "Creative location prompts to explore:\n",
+    "1. \"Underwater Research Station\" - For a claustrophobic sci-fi thriller\n",
+    "2. \"Victorian London\" - For a gothic mystery\n",
+    "3. \"Dubai 2050\" - For a futuristic heist movie\n",
+    "4. \"Antarctic Research Base\" - For a survival horror story\n",
+    "5. \"Caribbean Island\" - For a tropical adventure romance\n",
+    "\"\"\"\n",
+    "\n",
+    "# To get the response in a variable:\n",
+    "# from rich.pretty import pprint\n",
+    "\n",
+    "# json_mode_response: RunResponse = json_mode_agent.run(\"New York\")\n",
+    "# pprint(json_mode_response.content)\n",
+    "# structured_output_response: RunResponse = structured_output_agent.run(\"New York\")\n",
+    "# pprint(structured_output_response.content)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "80d94c56",
+   "metadata": {},
+   "source": [
+    "**Multimodal Agent**"
+=======
+   "execution_count": 13,
+=======
+   "execution_count": null,
+>>>>>>> d788ac0 (agno练习+转账agent)
+   "id": "5cddde6d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class MovieScript(BaseModel):\n",
+    "    setting: str = Field(\n",
+    "        ...,\n",
+    "        description=\"A richly detailed, atmospheric description of the movie's primary location and time period. Include sensory details and mood.\",\n",
+    "    )\n",
+    "    ending: str = Field(\n",
+    "        ...,\n",
+    "        description=\"The movie's powerful conclusion that ties together all plot threads. Should deliver emotional impact and satisfaction.\",\n",
+    "    )\n",
+    "    genre: str = Field(\n",
+    "        ...,\n",
+    "        description=\"The film's primary and secondary genres (e.g., 'Sci-fi Thriller', 'Romantic Comedy'). Should align with setting and tone.\",\n",
+    "    )\n",
+    "    name: str = Field(\n",
+    "        ...,\n",
+    "        description=\"An attention-grabbing, memorable title that captures the essence of the story and appeals to target audience.\",\n",
+    "    )\n",
+    "    characters: List[str] = Field(\n",
+    "        ...,\n",
+    "        description=\"4-6 main characters with distinctive names and brief role descriptions (e.g., 'Sarah Chen - brilliant quantum physicist with a dark secret').\",\n",
+    "    )\n",
+    "    storyline: str = Field(\n",
+    "        ...,\n",
+    "        description=\"A compelling three-sentence plot summary: Setup, Conflict, and Stakes. Hook readers with intrigue and emotion.\",\n",
+    "    )\n",
+    "\n",
+    "\n",
+    "# Agent that uses JSON mode\n",
+    "json_mode_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=dedent(\"\"\"\\\n",
+    "        You are an acclaimed Hollywood screenwriter known for creating unforgettable blockbusters! 🎬\n",
+    "        With the combined storytelling prowess of Christopher Nolan, Aaron Sorkin, and Quentin Tarantino,\n",
+    "        you craft unique stories that captivate audiences worldwide.\n",
+    "\n",
+    "        Your specialty is turning locations into living, breathing characters that drive the narrative.\\\n",
+    "    \"\"\"),\n",
+    "    instructions=dedent(\"\"\"\\\n",
+    "        When crafting movie concepts, follow these principles:\n",
+    "\n",
+    "        1. Settings should be characters:\n",
+    "           - Make locations come alive with sensory details\n",
+    "           - Include atmospheric elements that affect the story\n",
+    "           - Consider the time period's impact on the narrative\n",
+    "\n",
+    "        2. Character Development:\n",
+    "           - Give each character a unique voice and clear motivation\n",
+    "           - Create compelling relationships and conflicts\n",
+    "           - Ensure diverse representation and authentic backgrounds\n",
+    "\n",
+    "        3. Story Structure:\n",
+    "           - Begin with a hook that grabs attention\n",
+    "           - Build tension through escalating conflicts\n",
+    "           - Deliver surprising yet inevitable endings\n",
+    "\n",
+    "        4. Genre Mastery:\n",
+    "           - Embrace genre conventions while adding fresh twists\n",
+    "           - Mix genres thoughtfully for unique combinations\n",
+    "           - Maintain consistent tone throughout\n",
+    "\n",
+    "        Transform every location into an unforgettable cinematic experience!\\\n",
+    "    \"\"\"),\n",
+    "    response_model=MovieScript,\n",
+    "    use_json_mode=True,\n",
+    ")\n",
+    "\n",
+    "# Agent that uses structured outputs\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=dedent(\"\"\"\\\n",
+    "        You are an acclaimed Hollywood screenwriter known for creating unforgettable blockbusters! 🎬\n",
+    "        With the combined storytelling prowess of Christopher Nolan, Aaron Sorkin, and Quentin Tarantino,\n",
+    "        you craft unique stories that captivate audiences worldwide.\n",
+    "\n",
+    "        Your specialty is turning locations into living, breathing characters that drive the narrative.\\\n",
+    "    \"\"\"),\n",
+    "    instructions=dedent(\"\"\"\\\n",
+    "        When crafting movie concepts in json, follow these principles:\n",
+    "\n",
+    "        1. Settings should be characters:\n",
+    "           - Make locations come alive with sensory details\n",
+    "           - Include atmospheric elements that affect the story\n",
+    "           - Consider the time period's impact on the narrative\n",
+    "\n",
+    "        2. Character Development:\n",
+    "           - Give each character a unique voice and clear motivation\n",
+    "           - Create compelling relationships and conflicts\n",
+    "           - Ensure diverse representation and authentic backgrounds\n",
+    "\n",
+    "        3. Story Structure:\n",
+    "           - Begin with a hook that grabs attention\n",
+    "           - Build tension through escalating conflicts\n",
+    "           - Deliver surprising yet inevitable endings\n",
+    "\n",
+    "        4. Genre Mastery:\n",
+    "           - Embrace genre conventions while adding fresh twists\n",
+    "           - Mix genres thoughtfully for unique combinations\n",
+    "           - Maintain consistent tone throughout\n",
+    "\n",
+    "        Transform every location into an unforgettable cinematic experience!\\\n",
+    "    \"\"\"),\n",
+    "    response_model=MovieScript,\n",
+    ")\n",
+    "\n",
+<<<<<<< HEAD
+    "structured_output_agent.print_response(\n",
+    "    \"New York\", stream=True, stream_intermediate_steps=True\n",
+    ")"
+>>>>>>> bad0e67 (多轮对话+agno agent学习实践)
+=======
+    "# Example usage with different locations\n",
+    "json_mode_agent.print_response(\"Tokyo\", stream=True)\n",
+    "structured_output_agent.print_response(\"Ancient Rome\", stream=True)\n",
+    "\n",
+    "# More examples to try:\n",
+    "\"\"\"\n",
+    "Creative location prompts to explore:\n",
+    "1. \"Underwater Research Station\" - For a claustrophobic sci-fi thriller\n",
+    "2. \"Victorian London\" - For a gothic mystery\n",
+    "3. \"Dubai 2050\" - For a futuristic heist movie\n",
+    "4. \"Antarctic Research Base\" - For a survival horror story\n",
+    "5. \"Caribbean Island\" - For a tropical adventure romance\n",
+    "\"\"\"\n",
+    "\n",
+    "# To get the response in a variable:\n",
+    "# from rich.pretty import pprint\n",
+    "\n",
+    "# json_mode_response: RunResponse = json_mode_agent.run(\"New York\")\n",
+    "# pprint(json_mode_response.content)\n",
+    "# structured_output_response: RunResponse = structured_output_agent.run(\"New York\")\n",
+    "# pprint(structured_output_response.content)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "80d94c56",
+   "metadata": {},
+   "source": [
+    "**Multimodal Agent**"
+>>>>>>> d788ac0 (agno练习+转账agent)
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "accc8ac2",
+   "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
+}

+ 332 - 0
曹航/3/agent_test3.ipynb

@@ -0,0 +1,332 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "b4617320",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from textwrap import dedent\n",
+    "\n",
+    "from agno.agent import Agent\n",
+    "from agno.models.openai import OpenAILike\n",
+    "from agno.exceptions import StopAgentRun\n",
+    "from agno.tools import tool,FunctionCall\n",
+    "from agno.tools.function import UserInputField\n",
+    "from agno.utils import pprint\n",
+    "\n",
+    "from dotenv import load_dotenv \n",
+    "\n",
+    "from typing import Iterator,List\n",
+    "\n",
+    "from rich.console import Console\n",
+    "from rich.prompt import Prompt\n",
+    "\n",
+    "import httpx\n",
+    "import os\n",
+    "import json\n",
+    "load_dotenv()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "72dce64b",
+   "metadata": {},
+   "source": [
+    "**User Control Flows(Human in loop)**"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "cb6ea5c6",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "26ccd24ca6fa453490acd99692ca1ba6",
+       "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"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
+       "About to run <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">get_top_hackernews_stories</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\n",
+       "About to run \u001b[1;34mget_top_hackernews_stories\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\">Do you want to continue? <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">[y/n]</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">(y)</span>: </pre>\n"
+      ],
+      "text/plain": [
+       "Do you want to continue? \u001b[1;35m[y/n]\u001b[0m \u001b[1;36m(y)\u001b[0m: "
+      ]
+     },
+     "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": [
+    "# This is the console instance used by the print_response method\n",
+    "# We can use this to stop and restart the live display and ask for user confirmation\n",
+    "console = Console()\n",
+    "\n",
+    "\n",
+    "def pre_hook(fc: FunctionCall):\n",
+    "    # Get the live display instance from the console\n",
+    "    live = console._live\n",
+    "\n",
+    "    # Stop the live display temporarily so we can ask for user confirmation\n",
+    "    live.stop()  # type: ignore\n",
+    "\n",
+    "    # Ask for confirmation\n",
+    "    console.print(f\"\\nAbout to run [bold blue]{fc.function.name}[/]\")\n",
+    "    message = (\n",
+    "        Prompt.ask(\"Do you want to continue?\", choices=[\"y\", \"n\"], default=\"y\")\n",
+    "        .strip()\n",
+    "        .lower()\n",
+    "    )\n",
+    "\n",
+    "    # Restart the live display\n",
+    "    live.start()  # type: ignore\n",
+    "\n",
+    "    # If the user does not want to continue, raise a StopExecution exception\n",
+    "    if message != \"y\":\n",
+    "        raise StopAgentRun(\n",
+    "            \"Tool call cancelled by user\",  \n",
+    "            agent_message=\"Stopping execution as permission was not granted.\",\n",
+    "        )\n",
+    "\n",
+    "\n",
+    "@tool(pre_hook=pre_hook)\n",
+    "def get_top_hackernews_stories(num_stories: int) -> Iterator[str]:\n",
+    "    \"\"\"Fetch top stories from Hacker News after user confirmation.\n",
+    "\n",
+    "    Args:\n",
+    "        num_stories (int): Number of stories to retrieve\n",
+    "\n",
+    "    Returns:\n",
+    "        str: JSON string containing story details\n",
+    "    \"\"\"\n",
+    "    # Fetch top story IDs\n",
+    "    response = httpx.get(\"https://hacker-news.firebaseio.com/v0/topstories.json\")\n",
+    "    story_ids = response.json()\n",
+    "\n",
+    "    # Yield story details\n",
+    "    for story_id in story_ids[:num_stories]:\n",
+    "        story_response = httpx.get(\n",
+    "            f\"https://hacker-news.firebaseio.com/v0/item/{story_id}.json\"\n",
+    "        )\n",
+    "        story = story_response.json()\n",
+    "        if \"text\" in story:\n",
+    "            story.pop(\"text\", None)\n",
+    "        yield json.dumps(story)\n",
+    "\n",
+    "\n",
+    "# Initialize the agent with a tech-savvy personality and clear instructions\n",
+    "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=\"A Tech News Assistant that fetches and summarizes Hacker News stories\",\n",
+    "    instructions=dedent(\"\"\"\\\n",
+    "        You are an enthusiastic Tech Reporter\n",
+    "\n",
+    "        Your responsibilities:\n",
+    "        - Present Hacker News stories in an engaging and informative way\n",
+    "        - Provide clear summaries of the information you gather\n",
+    "\n",
+    "        Style guide:\n",
+    "        - Use emoji to make your responses more engaging\n",
+    "        - Keep your summaries concise but informative\n",
+    "        - End with a friendly tech-themed sign-off\\\n",
+    "    \"\"\"),\n",
+    "    tools=[get_top_hackernews_stories],\n",
+    "    show_tool_calls=True,\n",
+    "    markdown=True,\n",
+    ")\n",
+    "\n",
+    "# Example questions to try:\n",
+    "# - \"What are the top 3 HN stories right now?\"\n",
+    "# - \"Show me the most recent story from Hacker News\"\n",
+    "# - \"Get the top 5 stories (you can try accepting and declining the confirmation)\"\n",
+    "agent.print_response(\n",
+    "    \"What are the top 2 hackernews stories?\", stream=True, console=console\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "9485bd62",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "Field: subject\n",
+      "Description: The subject of the email.\n",
+      "Type: <class 'str'>\n",
+      "\n",
+      "Field: body\n",
+      "Description: The body of the email.\n",
+      "Type: <class 'str'>\n",
+      "Value: Hello, world!\n",
+      "\n",
+      "Field: to_address\n",
+      "Description: The address to send the email to.\n",
+      "Type: <class 'str'>\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=\"color: #000080; text-decoration-color: #000080\">╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
+       "<span style=\"color: #000080; text-decoration-color: #000080\">│</span> The email with the body \"Hello, world!\" has been successfully sent. Let me know if there's anything else I can  <span style=\"color: #000080; text-decoration-color: #000080\">│</span>\n",
+       "<span style=\"color: #000080; text-decoration-color: #000080\">│</span> assist you with!                                                                                                <span style=\"color: #000080; text-decoration-color: #000080\">│</span>\n",
+       "<span style=\"color: #000080; text-decoration-color: #000080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[34m╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮\u001b[0m\n",
+       "\u001b[34m│\u001b[0m The email with the body \"Hello, world!\" has been successfully sent. Let me know if there's anything else I can  \u001b[34m│\u001b[0m\n",
+       "\u001b[34m│\u001b[0m assist you with!                                                                                                \u001b[34m│\u001b[0m\n",
+       "\u001b[34m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# You can either specify the user_input_fields leave empty for all fields to be provided by the user\n",
+    "@tool(requires_user_input=True, user_input_fields=[\"subject\", \"to_address\"])\n",
+    "def send_email(subject: str, body: str, to_address: str) -> str:\n",
+    "    \"\"\"\n",
+    "    Send an email.\n",
+    "\n",
+    "    Args:\n",
+    "        subject (str): The subject of the email.\n",
+    "        body (str): The body of the email.\n",
+    "        to_address (str): The address to send the email to.\n",
+    "    \"\"\"\n",
+    "    return f\"Sent email to {to_address} with subject {subject} and body {body}\"\n",
+    "\n",
+    "agent = Agent(\n",
+    "    model=OpenAILike(id=\"qwen3-32b\", \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",
+    "    tools=[send_email],\n",
+    "    show_tool_calls=True,\n",
+    "    markdown=True,\n",
+    ")\n",
+    "\n",
+    "agent.run(\"Send an email with the body 'Hello, world!'\")\n",
+    "if agent.is_paused and agent.run_response:\n",
+    "    for tool in agent.run_response.tools_requiring_user_input:\n",
+    "        if tool.user_input_schema:\n",
+    "            input_schema: List[UserInputField] = tool.user_input_schema\n",
+    "\n",
+    "        for field in input_schema:\n",
+    "            # Display field information to the user\n",
+    "            print(f\"\\nField: {field.name}\")\n",
+    "            print(f\"Description: {field.description}\")\n",
+    "            print(f\"Type: {field.field_type}\")\n",
+    "\n",
+    "            # Get user input\n",
+    "            if field.value is None:\n",
+    "                user_value = input(f\"Please enter a value for {field.name}: \")\n",
+    "                # Update the field value\n",
+    "                field.value = user_value\n",
+    "            else:\n",
+    "                print(f\"Value: {field.value}\")\n",
+    "\n",
+    "    run_response = agent.continue_run()\n",
+    "    pprint.pprint_run_response(run_response)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fd9fbd3d",
+   "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
+}

+ 148 - 0
曹航/3/agno_transfer_agent.py

@@ -0,0 +1,148 @@
+from logging import log
+from textwrap import dedent
+
+from agno.agent import Agent
+from agno.models.openai import OpenAILike
+from agno.playground import Playground
+from agno.storage.sqlite import SqliteStorage
+from agno.tools.yfinance import YFinanceTools
+from agno.tools import tool
+
+import os
+from agno.utils.log import log_info
+from dotenv import load_dotenv
+load_dotenv()
+#数据存储位置
+agent_storage: str = "./曹航/3/transfer/tmp/agents.db"
+
+
+
+#测试
+finance_agent = Agent(
+    name="Finance Agent",
+    model=OpenAILike(id="qwen3-32b",
+                    api_key=os.getenv("BAILIAN_API_KEY"), 
+                    base_url=os.getenv("BAILIAN_API_BASE_URL"),
+                    request_params={"extra_body": {"enable_thinking": False}},),
+    tools=[YFinanceTools(stock_price=True, analyst_recommendations=True, company_info=True, company_news=True)],
+    instructions=["Always use tables to display data"],
+    storage=SqliteStorage(table_name="finance_agent", db_file=agent_storage),
+    add_datetime_to_instructions=True,
+    add_history_to_messages=True,
+    num_history_responses=5,
+    markdown=True,
+)
+# 从transfer/prompt目录读取prompt文件
+# with open("transfer/prompt/prompt.txt", "r", encoding="utf-8") as f:
+#     prompt_text = f.read()
+
+prompt_text="""
+    ## 背景与目标
+    你是一个金融助手 Agent,使用 Qwen3-32B 模型驱动,负责协助用户完成向他人账户转账的流程。/
+    当用户提问你其它与转账不相关的问题时,你应该时刻提醒并保持礼貌。/
+    你将通过自然语言与用户对话,收集必要信息,确认并调用转账接口完成操作。
+    请根据以下流程与规则进行对话与操作。
+
+    ## 任务流程
+
+    ### 进行信息收集
+    请通过对话与用户交互,依次确认并记录以下三项转账信息:
+
+    1. 通过对方姓名查询账户是否存在(`get_contact`)
+    2. 确认转账金额是否大于账户余额(`get_balance`)
+    3. 余额不足时,请重新向用户收集信息,继续转账(`replay_to_user`)
+
+    > 请在用户表达不清或信息缺失时,请通过方法 `replay_to_user` 发起澄清。
+
+    ### 执行转账
+    确认收集信息后,请总结信息,并请发起转账(`transfer`)
+
+"""
+# 创建用户列表
+users = [
+    {"name": "张三","phone": "13800138000","amount": 1000.0},
+    {"name": "李四","phone": "13800138001","amount": 500.0},
+]
+
+# 定义转账相关的工具函数
+def get_contact(user_name: str) -> bool:
+    """
+    检查账户是否存在
+    Args:
+        account_number: 账号
+    Returns:
+        bool: 账户是否存在
+    """
+    # 这里模拟账户检查逻辑
+    if user_name == "张三":
+        return True
+    else:
+        return False
+
+def get_balance() -> float:
+    """
+    查询账户余额
+    Returns:
+        float: 账户余额
+    """
+    balance=users[1]["amount"]
+    return balance
+
+#TODO 做用户确认
+# @tool(requires_user_input=True,user_input_fields=["amount"])
+def transfer(user_name, phone: str, amount: float) -> bool:
+    """
+    执行转账操作
+    Args:
+        to_account: 转入账号 
+        amount: 转账金额
+    Returns:
+        bool: 转账是否成功
+    """
+    # 这里模拟转账逻辑
+    users[0]["amount"] += amount
+    print(f"向{user_name}转账{amount}元成功")
+    return True
+
+def replay_to_user(message: str)->str:
+    """
+    当前步骤需要用户输入时,请通过此方法向用户提问
+    向用户提问获取信息,并记录到log
+    Args:
+        message: 提问内容
+    
+    """
+    # 这里实现向用户提问的逻辑
+    #只是记录log
+    log_info(message)
+    return "请等待用户回答"
+
+transfer_agent = Agent(
+    name="Transfer Agent",
+    model=OpenAILike(id="qwen3-32b",
+                    api_key=os.getenv("BAILIAN_API_KEY"), 
+                    base_url=os.getenv("BAILIAN_API_BASE_URL"),
+                    request_params={"extra_body": {"enable_thinking": False}},),
+    tools=[get_contact,get_balance,transfer,replay_to_user],
+    #TODO memory记忆
+    # memory=SqliteStorage(table_name="transfer_agent", db_file=agent_storage),
+    instructions=dedent(prompt_text),
+    # Store the agent sessions in a sqlite database
+    storage=SqliteStorage(table_name="transfer_agent_session", db_file=agent_storage),
+    show_tool_calls=True,
+    # Adds the current date and time to the instructions
+    add_datetime_to_instructions=True,
+    # Adds the history of the conversation to the messages
+    add_history_to_messages=True,
+    # Number of history responses to add to the messages
+    num_history_responses=5,
+    # Adds markdown formatting to the messages
+    markdown=True,
+)
+
+# 启动playground-server
+playground = Playground(agents=[transfer_agent, finance_agent])
+app = playground.get_app()
+
+if __name__ == "__main__":
+    playground.serve("agno_transfer_agent:app", reload=True)

BIN
曹航/3/temp/agent.db


BIN
曹航/3/temp/agent_history.db


+ 18 - 0
曹航/3/transfer/prompt/prompt.txt

@@ -0,0 +1,18 @@
+# Agent 任务定义:协助用户完成转账操作
+
+## 背景与目标
+你是一个金融助手 Agent,使用 Qwen3-32B 模型驱动,负责协助用户完成向他人账户转账的流程。你将通过自然语言与用户对话,收集必要信息,确认并调用转账接口完成操作。请根据以下流程与规则进行对话与操作。
+
+## 任务流程
+
+### 第一步:信息收集
+请通过对话与用户交互,依次确认并记录以下三项转账信息:
+
+1. 对方姓名(`recipient_name`)
+2. 对方卡号(`recipient_account_number`)
+3. 转账金额(`transfer_amount`)
+
+> 请在用户表达不清或信息缺失时调用 `clarify(question: str)` 方法发起澄清。
+
+### 第二步:执行转账
+信息收集完毕后,调用以下方法发起转账操作:

BIN
曹航/3/transfer/tmp/agents.db


+ 175 - 0
曹航/caohang.ipynb

@@ -0,0 +1,175 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 简单实践"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from openai import OpenAI\n",
+    "from dotenv import load_dotenv \n",
+    "import os\n",
+    "load_dotenv()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# # 免费api的尝试\n",
+    "# chatanywhere_client = OpenAI(\n",
+    "#     base_url=os.getenv(\"CHATANYWHERE_API_BASE_URL\"),\n",
+    "#     api_key=os.getenv(\"CHATANYWHERE_API_KEY\")\n",
+    "# )\n",
+    "# completion = chatanywhere_client.chat.completions.create(\n",
+    "#     model=\"gpt-3.5-turbo\",\n",
+    "#     messages=[\n",
+    "#         {\"role\": \"user\", \"content\": \"你是谁?\"},\n",
+    "#     ],\n",
+    "# )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### openAI文档内容实践\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "我最爱的城市是杭州,  \n",
+      "湖光山色美如画。\n",
+      "我爱杭州,风景如画,  \n",
+      "西湖美景,令人心。\n",
+      "我爱杭州,风景如画,  \n",
+      "西湖美景,心神啊。\n"
+     ]
+    }
+   ],
+   "source": [
+    "# simple example\n",
+    "client = OpenAI(\n",
+    "    base_url=os.getenv(\"BAILIAN_API_BASE_URL\"),\n",
+    "    api_key=os.getenv(\"BAILIAN_API_KEY\")\n",
+    ")\n",
+    "\n",
+    "system_message = \"\"\"你是一个很有用的AI助手.\n",
+    "                使用中文来回答每次用户的问题.\n",
+    "                并且每次回答都要求押韵\"\"\"\n",
+    "\n",
+    "completion = client.chat.completions.create(\n",
+    "    # 模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models\n",
+    "    model=\"qwen3-30b-a3b\",\n",
+    "    messages=[\n",
+    "        {\"role\": \"system\", \"content\": system_message},\n",
+    "        {\"role\": \"user\", \"content\": \"你最喜欢的城市是什么?请用简洁明了的语言回答我的问题。\"},\n",
+    "    ],\n",
+    "    # Qwen3模型通过enable_thinking参数控制思考过程(开源版默认True,商业版默认False)\n",
+    "    # 使用Qwen3开源版模型时,若未启用流式输出,请将下行取消注释,否则会报错\n",
+    "    extra_body={\"enable_thinking\": False},\n",
+    "\n",
+    "    # 返回可能的下一个token的log概率\n",
+    "    # logprobs=True,\n",
+    "    # top_logprobs=5\n",
+    "\n",
+    "    #控制随机和多样\n",
+    "    # temperature=0.1,\n",
+    "    # top_p=0.95,\n",
+    "\n",
+    "    # 控制token的生成概率\n",
+    "    # logit_bias={\n",
+    "    #     \"151377\": -100,\n",
+    "    #     \"151378\": -100,\n",
+    "    # }\n",
+    "\n",
+    "    #使文本生成过程更具有确定性\n",
+    "    #seed=2048,\n",
+    "\n",
+    "    #控制响应生成数量\n",
+    "    #n=3,\n",
+    "    #返回得分最高的n个响应\n",
+    "    #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",
+    "# print(completion.choices[1].message.content)\n",
+<<<<<<< HEAD
+    "# print(completion.choices[2].message.content)"
+   ]
+=======
+    "# print(completion.choices[2].message.content)\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+>>>>>>> 6c34b0b (test1)
+  }
+ ],
+ "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": 2
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно