{ "cells": [ { "cell_type": "markdown", "id": "ddbc9058", "metadata": {}, "source": [ "## 练习2. 信息收集多轮对话机器人\n", "使用 OpenAI 的预测接口(非 chat API),自己维护 chat hisitory 信息,完成多轮对话,完成一个信息收集助手。\n", "\n", "1. 可以收集用户的姓名、年龄和用户感兴趣的行业\n", "2. 不要存储任何中间状态,只记录对话历史\n", "3. 开始后,\n", " - AI:请输入你的姓名\n", " - User: xxx\n", " - AI: 请输入你的年龄\n", " - User: yyy\n", " - AI: 请输入你感兴趣的行业\n", " - User:zzz\n", " - AI: 收集完成,结果是xxxx\n", "4. 用户中途可以随意输入其他问题,但是 AI 要提醒用户不回答其他问题,然后提醒用户还没收集完成\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "29c715a6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "已设置 OpenAI 客户端,base_url: http://103.154.31.78:20001/compatible-mode/v1/\n" ] } ], "source": [ "import os\n", "from dotenv import load_dotenv\n", "from openai import OpenAI\n", "\n", "def create_client():\n", " load_dotenv()\n", " client = OpenAI(\n", " base_url=os.getenv(\"BAILIAN_API_BASE_URL\"),\n", " api_key=os.getenv(\"BAILIAN_API_KEY\")\n", " )\n", " return client\n", "\n", "client = create_client()\n", "print(f\"已设置 OpenAI 客户端,base_url: {client.base_url}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "4da87a9b", "metadata": {}, "outputs": [], "source": [ "import time\n", "\n", "\n", "questions = {\n", " 'name': '请输入你的姓名',\n", " 'age': '请输入你的年龄',\n", " 'industry': '请输入你感兴趣的行业'\n", "}\n", "\n", "def create_prompt(history, collected_info):\n", " system_prompt = f\"\"\"\n", " 你是一个信息收集助手。你需要依次收集用户的姓名、年龄和感兴趣的行业。\n", " 如果用户输入其他无关内容,请提醒用户需要先完成信息收集。\n", "\n", " 信息收集策略:\n", " 1. 使用开放式问题引导用户提供更多信息\n", " 2. 对模糊的信息进行澄清和确认\n", " 3. 根据上下文,智能地推断和补充相关信息\n", " 4. 保持对话的自然性和连贯性\n", " 5. 务必保证信息的准确性和完整性\n", " 6. 只有当信息符合需要收集的内容的规则时(例如姓名必须是符合姓名规则的,年龄必须是1~100内的数字等等),才将其记录到已收集信息中\n", " 7. 如果用户输入年龄时给出的是出生年份,请帮用户计算实际年龄(今年是2025年)。\n", " 8. 如果用户输入的年龄没有明确的数字,则此输入无效。\n", "\n", " 对话要求:\n", " 1. 保持友好、专业的语调\n", " 2. 每次回复要简洁明了\n", " 3. 每个信息收集成功后,确认用户输入的内容,格式为:“好的,已经收集到您的(此处为收集的项目)是:”,并询问下一个问题。\n", " 4. 当用户询问一些其他问题时,请礼貌地告诉用户,你是一个信息收集助手,不回答其它不相关问题。提醒用户还没收集完成。\n", " 5. 所有问题回答并收集完毕后,请总结用户的所有信息,并告知用户“信息已收集完毕”。\n", " 6. 如果没有对话历史,请先介绍自己,再进行询问。\n", " 7. 如果用户回答与问题无关,请礼貌且友好地提醒用户需要回答相关问题。\n", " 8. 请不要直接将问题内容直接输出,而是要根据用户的回答进行智能化的处理和回复。\n", " \"\"\"\n", "\n", " prompt = system_prompt + \"\\n\\n对话历史:\\n\"\n", " for h in history:\n", " prompt += f\"用户:{h['user']}\\nAI:{h['assistant']}\\n\"\n", " \n", " if 'name' not in collected_info:\n", " prompt += f\"\\n下一个问题:{questions['name']}\"\n", " elif 'age' not in collected_info:\n", " prompt += f\"\\n下一个问题:{questions['age']}\"\n", " elif 'industry' not in collected_info:\n", " prompt += f\"\\n下一个问题:{questions['industry']}\"\n", " else:\n", " prompt += \"\\n所有信息已收集完成\"\n", " \n", " return prompt\n", "\n", "def chat_completion(prompt, model):\n", " response = client.chat.completions.create(\n", " model=model,\n", " messages=prompt,\n", " max_tokens=500,\n", " temperature=0.7,\n", " stop=[\"用户:\"], # 防止模型生成用户的发言\n", " extra_body={\"enable_thinking\": False}\n", " )\n", " return response.choices[0].message.content.strip()\n", "\n", "def information_collection(model):\n", " history = []\n", " collected_info = {}\n", " \n", " # 开始对话\n", " prompt = create_prompt(history, collected_info)\n", " messages = [{\"role\": \"system\", \"content\": prompt}]\n", " response = chat_completion(messages, model)\n", " print(f\"AI: {response}\")\n", " time.sleep(1) # 等待一秒钟,模拟用户思考时间\n", " \n", " while True:\n", " user_input = input(\"用户: \")\n", " if user_input.lower() in ['exit', 'quit']:\n", " print(\"对话结束。\")\n", " break\n", " if not user_input.strip():\n", " print(\"输入不能为空,请重新输入。\")\n", " continue\n", " print(f\"用户: {user_input}\")\n", " \n", " # 记录用户输入\n", " history.append({\"user\": user_input, \"assistant\": \"\"})\n", "\n", " # 生成回复\n", " prompt = create_prompt(history, collected_info)\n", " messages = [{\"role\": \"system\", \"content\": prompt}, {\"role\": \"user\", \"content\": user_input}]\n", " response = chat_completion(messages, model)\n", " if response.startswith(\"好的,已经收集到您的\"):\n", " # 提取已收集的信息\n", " if '姓名' in response:\n", " collected_info['name'] = user_input\n", " elif '年龄' in response:\n", " collected_info['age'] = user_input\n", " elif '行业' in response:\n", " collected_info['industry'] = user_input\n", " print(f\"AI: {response}\")\n", " time.sleep(1)\n", " \n", " # 记录AI回复\n", " history[-1][\"assistant\"] = response\n", " \n", " # 如果所有信息都收集完毕,结束对话\n", " if '收集完毕' in response:\n", " break" ] }, { "cell_type": "code", "execution_count": 37, "id": "808bd704", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "开始进行信息收集...\t使用模型: qwen3-30b-a3b\n", "AI: 您好,我是您的信息收集助手。为了更好地为您提供服务,请您先告诉我您的姓名。\n", "用户: 我是周深\n", "AI: 好的,已经收集到您的姓名是:周深。接下来,请问您的年龄是多少?\n", "用户: 我有点不记得了\n", "AI: 好的,如果您不方便提供年龄,我们可以先进行下一步。请问您感兴趣的行业是什么?\n", "用户: 我感兴趣的行业有很多,我2014年,参加节目《中国好声音第三季》正式出道。 [23]2015年,发行首支个人音乐单曲《玫瑰与小鹿》。 [1]2016年,为动画电影《大鱼海棠》演唱印象曲《大鱼》, [2]并凭该曲斩获多个奖项。 [34-35]2017年,发行首张个人音乐专辑《深的深》。 [4]2019年,在节目《中国梦之声·我们的歌》中夺冠, [112]并举行“C-929星球”全国巡回演唱会。 [13]2020年,作为首发歌手加盟音乐节目《歌手·当打之年》,演唱的歌曲《达拉崩吧》以破亿播放量斩获网易云音乐“云村”播放量第一; [380]同年起,连续两年获腾讯音乐娱乐盛典年度最佳内地男歌手奖。 [346] 2021年,首次登上央视春晚舞台并演唱歌曲《灯火里的中国》; [374]同年,为联合国COP15演唱主题曲《和光同春》。 [312]2022年起,加盟户外竞技真人秀《奔跑吧》担任常驻嘉宾; [431]同年,与最高人民检察院合作推出的单曲《我的答案》获中宣部精神文明建设五个一工程奖。 [501]2023年,携个人单曲《花开忘忧》再度登上央视春晚舞台; [526]同年,获得第30届东方风云榜最佳男歌手奖。 [5]2024年,发行第2张个人音乐专辑《反深代词》, [728]专辑销售额突破6000万; [803]周深9.29Hz巡回演唱会同步启动; [806]同年,应邀前往纽约联合国总部演讲并演唱交响诗《和平颂》。 [676]2025年,开启4大洲5国8城世界巡回演唱会, [812]并参加央视春晚; [822]5月,参与配音的动画电影《时间之子》上映。\n", "AI: 好的,已经收集到您的兴趣行业是:音乐。接下来,请问您的年龄是多少?\n", "用户: 我1992年9月29日出生。\n", "AI: 好的,已经收集到您的出生日期是:1992年9月29日。根据今年是2025年,您的年龄是32岁。信息确认无误吗?\n", "用户: 请问今天天气怎么样?\n", "AI: 抱歉,我是一个信息收集助手,目前需要先完成信息收集。请您回答您感兴趣的行业是什么?\n", "用户: 我不是已经回答过了吗\n", "AI: 是的,您之前提到过您感兴趣的行业是音乐。好的,已经收集到您的兴趣行业是:音乐。信息确认无误吗?\n", "用户: 是的\n", "AI: 好的,已经收集到您的兴趣行业是:音乐。信息确认无误吗?\n", "用户: 是的\n", "AI: 信息已收集完毕。\n" ] } ], "source": [ "model = \"qwen3-30b-a3b\"\n", "print(f\"开始进行信息收集...\\t使用模型: {model}\")\n", "information_collection(model)" ] } ], "metadata": { "kernelspec": { "display_name": "ai-learning", "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 }