{ "cells": [ { "cell_type": "markdown", "id": "b4151ddd", "metadata": {}, "source": [ "### 多轮对话信息收集助手" ] }, { "cell_type": "code", "execution_count": 1, "id": "549f138d", "metadata": {}, "outputs": [], "source": [ "from openai import OpenAI\n", "from dotenv import load_dotenv \n", "import ipywidgets as widgets\n", "from IPython.display import display, clear_output\n", "import os\n", "load_dotenv()\n", "\n", "client = OpenAI(\n", " base_url=os.getenv(\"BAILIAN_API_BASE_URL\"),\n", " api_key=os.getenv(\"BAILIAN_API_KEY\")\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "30401a75", "metadata": {}, "outputs": [ { "ename": "NotFoundError", "evalue": "Error code: 404", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mNotFoundError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 61\u001b[39m\n\u001b[32m 58\u001b[39m save_user_message(\u001b[33m\"\u001b[39m\u001b[33muser\u001b[39m\u001b[33m\"\u001b[39m, user_message)\n\u001b[32m 60\u001b[39m \u001b[38;5;66;03m# 保存助手的回复\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m61\u001b[39m assistant_message = \u001b[43mget_response\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m)\u001b[49m \n\u001b[32m 62\u001b[39m save_message(\u001b[33m\"\u001b[39m\u001b[33massistant\u001b[39m\u001b[33m\"\u001b[39m, assistant_message)\n\u001b[32m 64\u001b[39m \u001b[38;5;66;03m# 聊天显示区\u001b[39;00m\n", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 47\u001b[39m, in \u001b[36mget_response\u001b[39m\u001b[34m(messages)\u001b[39m\n\u001b[32m 20\u001b[39m system_prompt = \u001b[33mf\u001b[39m\u001b[33m\"\"\"\u001b[39m\n\u001b[32m 21\u001b[39m \u001b[33m你是一个专业的信息收集助手。你的任务是收集用户的姓名、年龄和用户感兴趣的行业。\u001b[39m\n\u001b[32m 22\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 36\u001b[39m \u001b[33m\u001b[39m\u001b[33m\"\u001b[39m\u001b[33m请开始与用户对话,帮助收集所需信息。\u001b[39m\n\u001b[32m 37\u001b[39m \u001b[33m\u001b[39m\u001b[33m\"\"\"\u001b[39m\n\u001b[32m 38\u001b[39m \u001b[38;5;66;03m# response = client.chat.completions.create(\u001b[39;00m\n\u001b[32m 39\u001b[39m \u001b[38;5;66;03m# model=\"qwen3-30b-a3b\",\u001b[39;00m\n\u001b[32m 40\u001b[39m \u001b[38;5;66;03m# messages= [{\"role\": \"system\", \"content\": system_prompt}] + messages,\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 44\u001b[39m \u001b[38;5;66;03m# )\u001b[39;00m\n\u001b[32m 45\u001b[39m \u001b[38;5;66;03m# return response.choices[0].message.content\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m47\u001b[39m response = \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mresponses\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 48\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mqwen3-30b-a3b\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 49\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43m{\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mrole\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43msystem\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcontent\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43msystem_prompt\u001b[49m\u001b[43m}\u001b[49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[43m+\u001b[49m\u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 50\u001b[39m \n\u001b[32m 51\u001b[39m \u001b[43m \u001b[49m\u001b[43mextra_body\u001b[49m\u001b[43m=\u001b[49m\u001b[43m{\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43menable_thinking\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 52\u001b[39m \u001b[43m \u001b[49m\u001b[43mtemperature\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0.7\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 53\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 54\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m response.output_text\n", "\u001b[36mFile \u001b[39m\u001b[32md:\\yusys\\ai_learning\\.venv\\Lib\\site-packages\\openai\\resources\\responses\\responses.py:735\u001b[39m, in \u001b[36mResponses.create\u001b[39m\u001b[34m(self, background, include, input, instructions, max_output_tokens, max_tool_calls, metadata, model, parallel_tool_calls, previous_response_id, prompt, reasoning, service_tier, store, stream, temperature, text, tool_choice, tools, top_logprobs, top_p, truncation, user, extra_headers, extra_query, extra_body, timeout)\u001b[39m\n\u001b[32m 702\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcreate\u001b[39m(\n\u001b[32m 703\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 704\u001b[39m *,\n\u001b[32m (...)\u001b[39m\u001b[32m 733\u001b[39m timeout: \u001b[38;5;28mfloat\u001b[39m | httpx.Timeout | \u001b[38;5;28;01mNone\u001b[39;00m | NotGiven = NOT_GIVEN,\n\u001b[32m 734\u001b[39m ) -> Response | Stream[ResponseStreamEvent]:\n\u001b[32m--> \u001b[39m\u001b[32m735\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_post\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 736\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m/responses\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 737\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmaybe_transform\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 738\u001b[39m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[32m 739\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mbackground\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mbackground\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 740\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43minclude\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43minclude\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 741\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43minput\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 742\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43minstructions\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43minstructions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 743\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmax_output_tokens\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_output_tokens\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 744\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmax_tool_calls\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_tool_calls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 745\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmetadata\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 746\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmodel\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 747\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mparallel_tool_calls\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mparallel_tool_calls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 748\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mprevious_response_id\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mprevious_response_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 749\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mprompt\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 750\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mreasoning\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mreasoning\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 751\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mservice_tier\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mservice_tier\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 752\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstore\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstore\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 753\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstream\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 754\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtemperature\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtemperature\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 755\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtext\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtext\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 756\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtool_choice\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtool_choice\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 757\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtools\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtools\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 758\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtop_logprobs\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtop_logprobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 759\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtop_p\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtop_p\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 760\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtruncation\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtruncation\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 761\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43muser\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43muser\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 762\u001b[39m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 763\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_create_params\u001b[49m\u001b[43m.\u001b[49m\u001b[43mResponseCreateParamsStreaming\u001b[49m\n\u001b[32m 764\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\n\u001b[32m 765\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mresponse_create_params\u001b[49m\u001b[43m.\u001b[49m\u001b[43mResponseCreateParamsNonStreaming\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 766\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 767\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmake_request_options\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 768\u001b[39m \u001b[43m \u001b[49m\u001b[43mextra_headers\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_headers\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_query\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_query\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_body\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\n\u001b[32m 769\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 770\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mResponse\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 771\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 772\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mStream\u001b[49m\u001b[43m[\u001b[49m\u001b[43mResponseStreamEvent\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 773\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32md:\\yusys\\ai_learning\\.venv\\Lib\\site-packages\\openai\\_base_client.py:1249\u001b[39m, in \u001b[36mSyncAPIClient.post\u001b[39m\u001b[34m(self, path, cast_to, body, options, files, stream, stream_cls)\u001b[39m\n\u001b[32m 1235\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mpost\u001b[39m(\n\u001b[32m 1236\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 1237\u001b[39m path: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 1244\u001b[39m stream_cls: \u001b[38;5;28mtype\u001b[39m[_StreamT] | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 1245\u001b[39m ) -> ResponseT | _StreamT:\n\u001b[32m 1246\u001b[39m opts = FinalRequestOptions.construct(\n\u001b[32m 1247\u001b[39m method=\u001b[33m\"\u001b[39m\u001b[33mpost\u001b[39m\u001b[33m\"\u001b[39m, url=path, json_data=body, files=to_httpx_files(files), **options\n\u001b[32m 1248\u001b[39m )\n\u001b[32m-> \u001b[39m\u001b[32m1249\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(ResponseT, \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mopts\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m)\u001b[49m)\n", "\u001b[36mFile \u001b[39m\u001b[32md:\\yusys\\ai_learning\\.venv\\Lib\\site-packages\\openai\\_base_client.py:1037\u001b[39m, in \u001b[36mSyncAPIClient.request\u001b[39m\u001b[34m(self, cast_to, options, stream, stream_cls)\u001b[39m\n\u001b[32m 1034\u001b[39m err.response.read()\n\u001b[32m 1036\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mRe-raising status error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m1037\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m._make_status_error_from_response(err.response) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 1039\u001b[39m \u001b[38;5;28;01mbreak\u001b[39;00m\n\u001b[32m 1041\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m response \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m, \u001b[33m\"\u001b[39m\u001b[33mcould not resolve response (should never happen)\u001b[39m\u001b[33m\"\u001b[39m\n", "\u001b[31mNotFoundError\u001b[39m: Error code: 404" ] } ], "source": [ "# 初始化消息列表\n", "messages = []\n", "\n", "def save_message(role, content):\n", " \"\"\"保存对话消息到消息列表中\"\"\"\n", " messages.append({\"role\": role, \"content\": content})\n", "\n", "def save_user_message(role, content):\n", " \"\"\"保存用户消息\"\"\"\n", " user_message = f\"\"\"\n", " 用户发来新的消息(在<>中提供),如果用户询问一些其他问题时,请礼貌地告诉用户,你是一个信息收集助手,不回答其它不相关问题。\n", " 用户消息:\n", " <{content}>\n", " \"\"\"\n", " messages.append({\"role\": role, \"content\": user_message})\n", "\n", "\n", "# 调用API获取回复\n", "def get_response(messages):\n", " system_prompt = f\"\"\"\n", " 你是一个专业的信息收集助手。你的任务是收集用户的姓名、年龄和用户感兴趣的行业。\n", "\n", " ## 信息收集策略:\n", " 1. 使用开放式问题引导用户提供更多信息\n", " 2. 对模糊的信息进行澄清和确认\n", " 3. 根据上下文,智能地推断和补充相关信息\n", " 4. 保持对话的自然性和连贯性\n", "\n", " ## 对话要求:\n", " 1. 保持友好、专业的语调\n", " 2. 每次回复要简洁明了\n", " 3. 适时总结已收集的信息\n", " 4. 当用户询问一些其他问题时,请礼貌地告诉用户,你是一个信息收集助手,不回答其它不相关问题。提醒用户还没收集完成。\n", "\n", "\n", " \"请开始与用户对话,帮助收集所需信息。\n", " \"\"\"\n", " response = client.chat.completions.create(\n", " model=\"qwen3-30b-a3b\",\n", " messages= [{\"role\": \"system\", \"content\": system_prompt}] + messages,\n", " extra_body={\"enable_thinking\": False},\n", " temperature=0.7,\n", " )\n", " return response.choices[0].message.content\n", "\n", " # response = client.responses.create(\n", " # model=\"qwen3-30b-a3b\",\n", " # input= [{\"role\": \"system\", \"content\": system_prompt}] + messages,\n", " # extra_body={\"enable_thinking\": False},\n", " # temperature=0.7,\n", " # )\n", " # return response.output_text\n", "\n", "# 用户输入的消息\n", "user_message = \"Hello, how are you?\"\n", "save_user_message(\"user\", user_message)\n", "\n", "# 保存助手的回复\n", "assistant_message = get_response(messages) \n", "save_message(\"assistant\", assistant_message)\n", "\n", "# 聊天显示区\n", "chat_area = widgets.Output()\n", "\n", "def refresh_chat():\n", " with chat_area:\n", " clear_output()\n", " for msg in messages:\n", " if msg[\"role\"] == \"user\":\n", " content = msg['content']\n", " if '<' in content and '>' in content:\n", " start = content.find('<')\n", " end = content.find('>')\n", " content = content[start+1:end]\n", " print(f\"用户: {content}\")\n", " continue\n", " print(f\"用户: {content}\")\n", " else:\n", " print(f\"AI助手: {msg['content']}\")\n", "\n", "# 输入框和按钮\n", "input_box = widgets.Text(placeholder=\"请输入您的消息...\")\n", "send_btn = widgets.Button(description=\"发送\", button_style='primary')\n", "\n", "def on_send_clicked(b):\n", " user_msg = input_box.value.strip()\n", " if user_msg:\n", " save_message(\"user\", user_msg)\n", " ai_msg = get_response(messages)\n", " save_message(\"assistant\", ai_msg)\n", " refresh_chat()\n", " input_box.value = \"\"\n", "\n", "send_btn.on_click(on_send_clicked)\n", "\n", "# 初始显示\n", "refresh_chat()\n", "display(chat_area, widgets.HBox([input_box, send_btn]))\n" ] }, { "cell_type": "code", "execution_count": null, "id": "30a0053c", "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 }