|
@@ -0,0 +1,527 @@
|
|
|
|
|
+{
|
|
|
|
|
+ "cells": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "2e73bc46",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "# ========================================\n",
|
|
|
|
|
+ "# 情感分析助手\n",
|
|
|
|
|
+ "# ========================================"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "f0e5a740",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": []
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "9040c93c",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "from hello_agents import SimpleAgent, HelloAgentsLLM, ToolRegistry\n",
|
|
|
|
|
+ "from hello_agents.tools import Tool, ToolParameter, ToolRegistry\n",
|
|
|
|
|
+ "from typing import Dict, Any, List\n",
|
|
|
|
|
+ "from paddlenlp import Taskflow\n",
|
|
|
|
|
+ "import ast\n",
|
|
|
|
|
+ "import os\n",
|
|
|
|
|
+ "import pandas as pd\n",
|
|
|
|
|
+ "import re\n"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "fd38aa87",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ "os.environ[\"LLM_MODEL_ID\"] = \"Qwen/Qwen3-8B\"\n",
|
|
|
|
|
+ "os.environ[\"LLM_API_KEY\"] = \"\" # 你自己的\n",
|
|
|
|
|
+ "os.environ[\"LLM_BASE_URL\"] = \"https://api-inference.modelscope.cn/v1\"\n",
|
|
|
|
|
+ "os.environ[\"LLM_TIMEOUT\"] = \"60\"\n"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "d53dad4d",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "# ========================================\n",
|
|
|
|
|
+ "# 1. 定义代码分析工具\n",
|
|
|
|
|
+ "# ========================================"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "5b5ee68c",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "文本清洗"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "ee7f97e7",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "class ProcessChatHistoryTool(Tool):\n",
|
|
|
|
|
+ " \"\"\"\n",
|
|
|
|
|
+ " 导入并清洗微信或QQ的文本聊天记录\n",
|
|
|
|
|
+ " 继承 Tool 抽象类,实现 run、get_parameters 方法\n",
|
|
|
|
|
+ " \"\"\"\n",
|
|
|
|
|
+ " def __init__(self):\n",
|
|
|
|
|
+ " super().__init__(\n",
|
|
|
|
|
+ " name=\"process_chat_history\",\n",
|
|
|
|
|
+ " description=\"读取微信/QQ聊天记录TXT文件,自动清洗,返回结构化DataFrame\"\n",
|
|
|
|
|
+ " )\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " def run(self, parameters: Dict[str, Any]) -> pd.DataFrame:\n",
|
|
|
|
|
+ " \"\"\"\n",
|
|
|
|
|
+ " 工具执行入口\n",
|
|
|
|
|
+ " :param parameters: 外部传入参数 file_path, chat_type\n",
|
|
|
|
|
+ " :return: 清洗后的 DataFrame\n",
|
|
|
|
|
+ " \"\"\"\n",
|
|
|
|
|
+ " # 从参数中获取值\n",
|
|
|
|
|
+ " file_path = parameters.get(\"file_path\", \"\")\n",
|
|
|
|
|
+ " chat_type = parameters.get(\"chat_type\", \"wechat\")\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " messages = []\n",
|
|
|
|
|
+ " pattern = re.compile(r'(\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2})\\s+(.+?):\\s+(.+)')\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " try:\n",
|
|
|
|
|
+ " with open(file_path, 'r', encoding='utf-8') as f:\n",
|
|
|
|
|
+ " for line in f:\n",
|
|
|
|
|
+ " line = line.strip()\n",
|
|
|
|
|
+ " match = pattern.match(line)\n",
|
|
|
|
|
+ " if match:\n",
|
|
|
|
|
+ " time, sender, content = match.groups()\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " # 过滤系统消息\n",
|
|
|
|
|
+ " if any(keyword in content for keyword in ['[图片]', '[视频]', '撤回了一条消息', '拍了拍']):\n",
|
|
|
|
|
+ " continue\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " messages.append({\n",
|
|
|
|
|
+ " 'time': time,\n",
|
|
|
|
|
+ " 'sender': sender,\n",
|
|
|
|
|
+ " 'content': content\n",
|
|
|
|
|
+ " })\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " df = pd.DataFrame(messages)\n",
|
|
|
|
|
+ " print(f\"✅ 成功导入 {len(df)} 条有效聊天记录!\")\n",
|
|
|
|
|
+ " return df\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " except Exception as e:\n",
|
|
|
|
|
+ " print(f\"❌ 读取文件失败:{str(e)}\")\n",
|
|
|
|
|
+ " return pd.DataFrame()\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " def get_parameters(self) -> List[ToolParameter]:\n",
|
|
|
|
|
+ " \"\"\"\n",
|
|
|
|
|
+ " 定义工具参数\n",
|
|
|
|
|
+ " \"\"\"\n",
|
|
|
|
|
+ " return [\n",
|
|
|
|
|
+ " ToolParameter(\n",
|
|
|
|
|
+ " name=\"file_path\",\n",
|
|
|
|
|
+ " type=\"string\",\n",
|
|
|
|
|
+ " description=\"聊天记录txt文件路径\",\n",
|
|
|
|
|
+ " required=True\n",
|
|
|
|
|
+ " ),\n",
|
|
|
|
|
+ " ToolParameter(\n",
|
|
|
|
|
+ " name=\"chat_type\",\n",
|
|
|
|
|
+ " type=\"string\",\n",
|
|
|
|
|
+ " description=\"聊天类型:wechat 或 qq\",\n",
|
|
|
|
|
+ " required=False\n",
|
|
|
|
|
+ " )\n",
|
|
|
|
|
+ " ]"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "61e13b03",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "情感分析"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "463c84b4",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "class AnalyzeSentimentAndMoodTool(Tool):\n",
|
|
|
|
|
+ " \"\"\"使用SKEP-ERNIE模型分析聊天记录情感与心情\"\"\"\n",
|
|
|
|
|
+ " \n",
|
|
|
|
|
+ " def __init__(self):\n",
|
|
|
|
|
+ " super().__init__(\n",
|
|
|
|
|
+ " name=\"analyze_sentiment_and_mood\",\n",
|
|
|
|
|
+ " description=\"分析聊天记录的情感倾向(正面/负面)与心情(开心/生气/平淡)\"\n",
|
|
|
|
|
+ " )\n",
|
|
|
|
|
+ " # 初始化模型(只加载一次)\n",
|
|
|
|
|
+ " self.sentiment_analyzer = Taskflow(\n",
|
|
|
|
|
+ " \"sentiment_analysis\", \n",
|
|
|
|
|
+ " model=\"skep_ernie_1.0_large_ch\",\n",
|
|
|
|
|
+ " )\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " def run(self, parameters: Dict[str, Any]) -> pd.DataFrame:\n",
|
|
|
|
|
+ " df = parameters.get(\"df\", pd.DataFrame())\n",
|
|
|
|
|
+ " \n",
|
|
|
|
|
+ " if df.empty:\n",
|
|
|
|
|
+ " return df\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " contents = df['content'].tolist()\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " try:\n",
|
|
|
|
|
+ " results = self.sentiment_analyzer(contents)\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " sentiments = [res['sentiment_key'] for res in results]\n",
|
|
|
|
|
+ " confidence = [\n",
|
|
|
|
|
+ " res['positive_probs'] if res['sentiment_key'] == 'positive' \n",
|
|
|
|
|
+ " else 1 - res['positive_probs'] \n",
|
|
|
|
|
+ " for res in results\n",
|
|
|
|
|
+ " ]\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " moods = []\n",
|
|
|
|
|
+ " for res in results:\n",
|
|
|
|
|
+ " if res['sentiment_key'] == 'positive':\n",
|
|
|
|
|
+ " moods.append('开心/认可')\n",
|
|
|
|
|
+ " else:\n",
|
|
|
|
|
+ " neg_prob = 1 - res['positive_probs']\n",
|
|
|
|
|
+ " if neg_prob > 0.8:\n",
|
|
|
|
|
+ " moods.append('生气/难过')\n",
|
|
|
|
|
+ " else:\n",
|
|
|
|
|
+ " moods.append('无奈/平淡')\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " df['sentiment'] = sentiments\n",
|
|
|
|
|
+ " df['mood'] = moods\n",
|
|
|
|
|
+ " df['confidence'] = confidence\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " print(\"✅ 情感与心情分析完成!\")\n",
|
|
|
|
|
+ " return df\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " except Exception as e:\n",
|
|
|
|
|
+ " print(f\"❌ 情感分析出错:{e}\")\n",
|
|
|
|
|
+ " return df\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " def get_parameters(self) -> List[ToolParameter]:\n",
|
|
|
|
|
+ " return [\n",
|
|
|
|
|
+ " ToolParameter(\n",
|
|
|
|
|
+ " name=\"df\",\n",
|
|
|
|
|
+ " type=\"object\",\n",
|
|
|
|
|
+ " description=\"清洗后的聊天记录DataFrame\",\n",
|
|
|
|
|
+ " required=True\n",
|
|
|
|
|
+ " )\n",
|
|
|
|
|
+ " ]"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "fb9b10e6",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "情感统计"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "2bf65900",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "class SummarizeEmotionStatsTool(Tool):\n",
|
|
|
|
|
+ " \"\"\"统计聊天情感数据,生成报告与结构化结果\"\"\"\n",
|
|
|
|
|
+ " \n",
|
|
|
|
|
+ " def __init__(self):\n",
|
|
|
|
|
+ " super().__init__(\n",
|
|
|
|
|
+ " name=\"summarize_emotion_stats\",\n",
|
|
|
|
|
+ " description=\"统计情感分析结果,计算开心/生气数量与占比,返回报告字典\"\n",
|
|
|
|
|
+ " )\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " def run(self, parameters: Dict[str, Any]) -> dict:\n",
|
|
|
|
|
+ " df = parameters.get(\"df\", pd.DataFrame())\n",
|
|
|
|
|
+ " sender_name = parameters.get(\"sender_name\", None)\n",
|
|
|
|
|
+ " \n",
|
|
|
|
|
+ " if df.empty or 'sentiment' not in df.columns:\n",
|
|
|
|
|
+ " print(\"❌ 数据为空或尚未进行情感分析,请先运行前两个工具!\")\n",
|
|
|
|
|
+ " return {}\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " if sender_name:\n",
|
|
|
|
|
+ " analysis_df = df[df['sender'] == sender_name].copy()\n",
|
|
|
|
|
+ " if analysis_df.empty:\n",
|
|
|
|
|
+ " print(f\"⚠️ 未找到 {sender_name} 的聊天记录\")\n",
|
|
|
|
|
+ " return {}\n",
|
|
|
|
|
+ " print(f\"🔍 正在统计 {sender_name} 的情感数据...\")\n",
|
|
|
|
|
+ " else:\n",
|
|
|
|
|
+ " analysis_df = df.copy()\n",
|
|
|
|
|
+ " print(\"🔍 正在统计全员的情感数据...\")\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " total_messages = len(analysis_df)\n",
|
|
|
|
|
+ " happy_count = len(analysis_df[analysis_df['sentiment'] == 'positive'])\n",
|
|
|
|
|
+ " angry_count = len(analysis_df[analysis_df['sentiment'] == 'negative'])\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " happy_ratio = round((happy_count / total_messages) * 100, 2) if total_messages > 0 else 0.0\n",
|
|
|
|
|
+ " angry_ratio = round((angry_count / total_messages) * 100, 2) if total_messages > 0 else 0.0\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " print(\"\\n\" + \"=\"*30)\n",
|
|
|
|
|
+ " print(f\"📊 【情感统计报告】\")\n",
|
|
|
|
|
+ " print(f\"总有效发言数: {total_messages} 条\")\n",
|
|
|
|
|
+ " print(f\"😄 开心/认可: {happy_count} 条 (占比 {happy_ratio}%)\")\n",
|
|
|
|
|
+ " print(f\"😡 生气/难过: {angry_count} 条 (占比 {angry_ratio}%)\")\n",
|
|
|
|
|
+ " print(f\"😐 中性/其他: {total_messages - happy_count - angry_count} 条\")\n",
|
|
|
|
|
+ " print(\"=\"*30 + \"\\n\")\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " return {\n",
|
|
|
|
|
+ " 'total_messages': total_messages,\n",
|
|
|
|
|
+ " 'happy_count': happy_count,\n",
|
|
|
|
|
+ " 'angry_count': angry_count,\n",
|
|
|
|
|
+ " 'happy_ratio': happy_ratio,\n",
|
|
|
|
|
+ " 'angry_ratio': angry_ratio\n",
|
|
|
|
|
+ " }\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " def get_parameters(self) -> List[ToolParameter]:\n",
|
|
|
|
|
+ " return [\n",
|
|
|
|
|
+ " ToolParameter(\n",
|
|
|
|
|
+ " name=\"df\",\n",
|
|
|
|
|
+ " type=\"object\",\n",
|
|
|
|
|
+ " description=\"已完成情感分析的 DataFrame\",\n",
|
|
|
|
|
+ " required=True\n",
|
|
|
|
|
+ " ),\n",
|
|
|
|
|
+ " ToolParameter(\n",
|
|
|
|
|
+ " name=\"sender_name\",\n",
|
|
|
|
|
+ " type=\"string\",\n",
|
|
|
|
|
+ " description=\"可选,指定发言者名称\",\n",
|
|
|
|
|
+ " required=False\n",
|
|
|
|
|
+ " )\n",
|
|
|
|
|
+ " ]"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "99ca0b30",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "class PlotEmotionChartTool(Tool):\n",
|
|
|
|
|
+ " \"\"\"将情感统计结果绘制成柱状图\"\"\"\n",
|
|
|
|
|
+ " \n",
|
|
|
|
|
+ " def __init__(self):\n",
|
|
|
|
|
+ " super().__init__(\n",
|
|
|
|
|
+ " name=\"plot_emotion_chart\",\n",
|
|
|
|
|
+ " description=\"根据情感统计字典绘制可视化柱状图\"\n",
|
|
|
|
|
+ " )\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " def run(self, parameters: Dict[str, Any]) -> str:\n",
|
|
|
|
|
+ " stats = parameters.get(\"stats\", {})\n",
|
|
|
|
|
+ " \n",
|
|
|
|
|
+ " if not stats:\n",
|
|
|
|
|
+ " return \"⚠️ 无统计数据,无法生成图表\"\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " # 设置中文字体\n",
|
|
|
|
|
+ " plt.rcParams['font.sans-serif'] = ['SimHei']\n",
|
|
|
|
|
+ " plt.rcParams['axes.unicode_minus'] = False\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " labels = ['开心/认可', '生气/难过']\n",
|
|
|
|
|
+ " counts = [stats['happy_count'], stats['angry_count']]\n",
|
|
|
|
|
+ " colors = ['#FF9999', '#66B2FF']\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " plt.figure(figsize=(8, 5))\n",
|
|
|
|
|
+ " bars = plt.bar(labels, counts, color=colors)\n",
|
|
|
|
|
+ " plt.title(f\"情感分布统计 (总数: {stats['total_messages']}条)\", fontsize=15)\n",
|
|
|
|
|
+ " plt.ylabel('发言条数', fontsize=12)\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " # 显示数值\n",
|
|
|
|
|
+ " for bar in bars:\n",
|
|
|
|
|
+ " yval = bar.get_height()\n",
|
|
|
|
|
+ " plt.text(bar.get_x() + bar.get_width()/2, yval + 0.5, int(yval), ha='center', va='bottom', fontsize=12)\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " plt.show()\n",
|
|
|
|
|
+ " return \"✅ 图表已成功绘制!\"\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ " def get_parameters(self) -> List[ToolParameter]:\n",
|
|
|
|
|
+ " return [\n",
|
|
|
|
|
+ " ToolParameter(\n",
|
|
|
|
|
+ " name=\"stats\",\n",
|
|
|
|
|
+ " type=\"object\",\n",
|
|
|
|
|
+ " description=\"summarize_emotion_stats 函数返回的统计字典\",\n",
|
|
|
|
|
+ " required=True\n",
|
|
|
|
|
+ " )\n",
|
|
|
|
|
+ " ]"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "45ed2cab",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "# ========================================\n",
|
|
|
|
|
+ "# 2. 创建工具注册表和智能体\n",
|
|
|
|
|
+ "# ========================================"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "57b0eb34",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "tool_registry = ToolRegistry()\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ "tool_registry.register_tool(ProcessChatHistoryTool())\n",
|
|
|
|
|
+ "tool_registry.register_tool(AnalyzeSentimentAndMoodTool())\n",
|
|
|
|
|
+ "tool_registry.register_tool(SummarizeEmotionStatsTool())\n",
|
|
|
|
|
+ "tool_registry.register_tool(PlotEmotionChartTool())\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ "print(\"✅ 所有情感分析工具注册成功!\")"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "31bf419b",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "# ========================================\n",
|
|
|
|
|
+ "# 3.初始化大模型\n",
|
|
|
|
|
+ "# ========================================"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "3a7783f9",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "print(\">>> 实际读取到的 Base URL 是:\", repr(os.getenv(\"LLM_BASE_URL\")))\n",
|
|
|
|
|
+ "\tllm = HelloAgentsLLM(\n",
|
|
|
|
|
+ " model=\"Qwen/Qwen3-8B\",\n",
|
|
|
|
|
+ " base_url=\"https://api-inference.modelscope.cn/v1\",\n",
|
|
|
|
|
+ " api_key=\"YOUR API KEY\",\n",
|
|
|
|
|
+ " timeout=60\n",
|
|
|
|
|
+ ")"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "1960a4e9",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "# ========================================\n",
|
|
|
|
|
+ "# 4. 定义系统提示词\n",
|
|
|
|
|
+ "# ========================================"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "e07c6c3a",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "system_prompt = \"\"\"你是一位拥有10年经验的亲密关系心理学专家,同时也是一位高情商沟通教练。你的任务是深入分析用户提供的聊天记录,并提供极具洞察力的情感分析报告。\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ "请严格按照以下步骤执行:\n",
|
|
|
|
|
+ "1. **语境理解**:结合上下文,精准识别对话双方的关系阶段(如暧昧期、热恋期、冷战期)。\n",
|
|
|
|
|
+ "2. **潜台词挖掘**:不要只看表面文字,要深度解读对方话语背后的真实情绪、需求和未说出口的潜台词。\n",
|
|
|
|
|
+ "3. **情感量化**:基于对话的亲密度、回应速度和情绪价值,给出一个0-100分的“心动指数”。\n",
|
|
|
|
|
+ "4. **回复建议**:针对当前的对话僵局或话题,提供3种不同风格(如:幽默风趣、深情走心、推拉试探)的高情商回复话术。\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ "请以Markdown格式输出报告,报告结构必须包含:\n",
|
|
|
|
|
+ "- **心动指数**:(给出具体分数及简短评语)\n",
|
|
|
|
|
+ "- **深度解读**:(分析对方的心理状态和潜在意图)\n",
|
|
|
|
|
+ "- **潜台词翻译**:(挑选1-2句关键对话进行“翻译”)\n",
|
|
|
|
|
+ "- **高情商回复**:(提供3个具体的回复选项)\n",
|
|
|
|
|
+ "\"\"\""
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "a72bdc22",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "# ========================================\n",
|
|
|
|
|
+ "# 5.生成智能体\n",
|
|
|
|
|
+ "# ========================================"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "15c0c181",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "agent = SimpleAgent(\n",
|
|
|
|
|
+ "name=\"情感分析助手\",\n",
|
|
|
|
|
+ "llm=llm,\n",
|
|
|
|
|
+ "system_prompt=system_prompt,\n",
|
|
|
|
|
+ "tool_registry=tool_registry\n",
|
|
|
|
|
+ ")"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "markdown",
|
|
|
|
|
+ "id": "ae6d3c6d",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "# ========================================\n",
|
|
|
|
|
+ "# 6. 运行示例\n",
|
|
|
|
|
+ "# ========================================"
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "cell_type": "code",
|
|
|
|
|
+ "execution_count": null,
|
|
|
|
|
+ "id": "c515a480",
|
|
|
|
|
+ "metadata": {},
|
|
|
|
|
+ "outputs": [],
|
|
|
|
|
+ "source": [
|
|
|
|
|
+ "with open(\"data/1.txt\",\"r\",encoding=\"utf-8\") as f:\n",
|
|
|
|
|
+ " talktxt=f.read()\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ "print('---------------聊天记录---------------')\n",
|
|
|
|
|
+ "print(talktxt)\n",
|
|
|
|
|
+ "\n",
|
|
|
|
|
+ "print('--------------开始分析记录--------------')\n",
|
|
|
|
|
+ "print(\"当前 LLM_BASE_URL:\", repr(os.environ[\"LLM_BASE_URL\"]))\n",
|
|
|
|
|
+ "result=agent.run(talktxt)\n",
|
|
|
|
|
+ "print(result)\n",
|
|
|
|
|
+ "print('---------------保存结果---------------')\n",
|
|
|
|
|
+ "with open(\"outputs/review_report.md\", \"w\", encoding=\"utf-8\") as f:\n",
|
|
|
|
|
+ " f.write(result)\n",
|
|
|
|
|
+ "print(\"\\n审查报告已保存到 outputs/review_report.md\")"
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "metadata": {
|
|
|
|
|
+ "kernelspec": {
|
|
|
|
|
+ "display_name": "Python 3",
|
|
|
|
|
+ "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.9"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ "nbformat": 4,
|
|
|
|
|
+ "nbformat_minor": 5
|
|
|
|
|
+}
|