Backup before system reinstall

This commit is contained in:
llama-research
2025-09-06 07:37:16 +00:00
parent f9856c31e5
commit e78aefac88
66 changed files with 16347 additions and 1917 deletions

View File

@@ -0,0 +1,295 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
稷下学宫 ADK Memory Bank 论道系统
实现带有记忆银行的八仙智能体辩论
"""
import os
import asyncio
from google.adk import Agent, Runner
from google.adk.sessions import InMemorySessionService
from google.adk.memory import VertexAiMemoryBankService
from google.adk.memory.memory_entry import MemoryEntry
from google.genai import types
import json
from datetime import datetime
from typing import Dict, List, Optional
class BaxianMemoryManager:
"""八仙记忆管理器"""
def __init__(self):
self.memory_services: Dict[str, VertexAiMemoryBankService] = {}
self.agents: Dict[str, Agent] = {}
async def initialize_baxian_agents(self):
"""初始化八仙智能体及其记忆银行"""
# 从环境变量获取项目ID和位置
project_id = os.getenv('GOOGLE_CLOUD_PROJECT_ID')
location = os.getenv('GOOGLE_CLOUD_LOCATION', 'us-central1')
if not project_id:
raise ValueError("未设置 GOOGLE_CLOUD_PROJECT_ID 环境变量")
# 八仙角色配置
baxian_config = {
"铁拐李": {
"instruction": "你是铁拐李,八仙中的逆向思维专家。你善于从批判和质疑的角度看问题,总是能发现事物的另一面。你会从你的记忆中回忆相关的逆向投资案例和失败教训。",
"memory_context": "逆向投资案例、市场泡沫警告、风险识别经验"
},
"吕洞宾": {
"instruction": "你是吕洞宾,八仙中的理性分析者。你善于平衡各方观点,用理性和逻辑来分析问题。你会从记忆中调用技术分析的成功案例和理论知识。",
"memory_context": "技术分析理论、成功预测案例、市场趋势分析"
},
"何仙姑": {
"instruction": "你是何仙姑,八仙中的风险控制专家。你总是从风险管理的角度思考问题,善于发现潜在危险。你会回忆历史上的重大风险事件。",
"memory_context": "风险管理案例、黑天鹅事件、危机预警经验"
},
"张果老": {
"instruction": "你是张果老,八仙中的历史智慧者。你善于从历史数据中寻找规律和智慧,总是能提供长期视角。你会从记忆中调用历史数据和长期趋势。",
"memory_context": "历史市场数据、长期投资趋势、周期性规律"
}
}
# 为每个仙人创建智能体和记忆服务
for name, config in baxian_config.items():
# 创建记忆服务
memory_service = VertexAiMemoryBankService(
project=project_id,
location=location
)
# 初始化记忆内容
await self._initialize_agent_memory(memory_service, name, config['memory_context'])
# 创建智能体
agent = Agent(
name=name,
model="gemini-2.5-flash",
instruction=f"{config['instruction']} 在回答时,请先从你的记忆银行中检索相关信息,然后结合当前话题给出回应。",
memory_service=memory_service
)
self.memory_services[name] = memory_service
self.agents[name] = agent
print(f"✅ 已初始化 {len(self.agents)} 个八仙智能体及其记忆服务")
async def _initialize_agent_memory(self, memory_service: VertexAiMemoryBankService, agent_name: str, context: str):
"""为智能体初始化记忆内容"""
# 根据角色添加初始记忆
initial_memories = {
"铁拐李": [
"2000年互联网泡沫破裂许多高估值科技股暴跌90%以上",
"2008年金融危机前房地产市场过度繁荣逆向思维者提前撤离",
"比特币从2万美元跌到3千美元提醒我们任何资产都可能大幅回调",
"巴菲特说过:别人贪婪时我恐惧,别人恐惧时我贪婪"
],
"吕洞宾": [
"移动平均线交叉是经典的技术分析信号",
"RSI指标超过70通常表示超买低于30表示超卖",
"支撑位和阻力位是技术分析的核心概念",
"成功的技术分析需要结合多个指标综合判断"
],
"何仙姑": [
"2008年雷曼兄弟倒闭引发全球金融危机",
"长期资本管理公司(LTCM)的失败说明了风险管理的重要性",
"分散投资是降低风险的基本原则",
"黑天鹅事件虽然罕见但影响巨大,需要提前准备"
],
"张果老": [
"股市存在7-10年的长期周期",
"康德拉季耶夫长波理论描述了50-60年的经济周期",
"历史上每次重大技术革命都带来新的投资机会",
"长期来看,优质资产总是向上的"
]
}
memories = initial_memories.get(agent_name, [])
for memory_text in memories:
memory_entry = MemoryEntry(
content=memory_text,
metadata={
"agent": agent_name,
"type": "historical_knowledge",
"timestamp": datetime.now().isoformat()
}
)
# 注意VertexAiMemoryBankService 的 add_memory 方法可能需要不同的参数
# 这里假设它有一个类似的方法
await memory_service.add_memory(memory_entry)
async def add_debate_memory(self, agent_name: str, content: str, topic: str):
"""为智能体添加辩论记忆"""
if agent_name in self.memory_services:
memory_entry = MemoryEntry(
content=content,
metadata={
"agent": agent_name,
"type": "debate_history",
"topic": topic,
"timestamp": datetime.now().isoformat()
}
)
# 注意VertexAiMemoryBankService 的 add_memory 方法可能需要不同的参数
# 这里假设它有一个类似的方法
await self.memory_services[agent_name].add_memory(memory_entry)
async def retrieve_relevant_memories(self, agent_name: str, query: str, limit: int = 3) -> List[str]:
"""检索智能体的相关记忆"""
if agent_name not in self.memory_services:
return []
try:
# 注意VertexAiMemoryBankService 的 search 方法可能需要不同的参数
# 这里假设它有一个类似的方法
memories = await self.memory_services[agent_name].search(query, limit=limit)
return [memory.content for memory in memories]
except Exception as e:
print(f"⚠️ 记忆检索失败 ({agent_name}): {e}")
return []
class MemoryEnhancedDebate:
"""带记忆增强的辩论系统"""
def __init__(self):
self.memory_manager = BaxianMemoryManager()
self.session_service = InMemorySessionService()
self.runners: Dict[str, Runner] = {}
async def initialize(self):
"""初始化辩论系统"""
await self.memory_manager.initialize_baxian_agents()
# 创建会话
self.session = await self.session_service.create_session(
state={},
app_name="稷下学宫记忆增强论道系统",
user_id="memory_debate_user"
)
# 为每个智能体创建Runner
for name, agent in self.memory_manager.agents.items():
runner = Runner(
app_name="稷下学宫记忆增强论道系统",
agent=agent,
session_service=self.session_service
)
self.runners[name] = runner
async def conduct_memory_debate(self, topic: str, participants: List[str] = None):
"""进行带记忆的辩论"""
if participants is None:
participants = ["铁拐李", "吕洞宾", "何仙姑", "张果老"]
print(f"\n🎭 稷下学宫记忆增强论道开始...")
print(f"📋 论道主题: {topic}")
print(f"🎯 参与仙人: {', '.join(participants)}")
debate_history = []
for round_num in range(2): # 进行2轮辩论
print(f"\n🔄 第 {round_num + 1} 轮论道:")
for participant in participants:
if participant not in self.runners:
continue
print(f"\n🗣️ {participant} 发言:")
# 检索相关记忆
relevant_memories = await self.memory_manager.retrieve_relevant_memories(
participant, topic, limit=2
)
# 构建包含记忆的提示
memory_context = ""
if relevant_memories:
memory_context = f"\n从你的记忆中回忆到:\n" + "\n".join([f"- {memory}" for memory in relevant_memories])
# 构建辩论历史上下文
history_context = ""
if debate_history:
recent_history = debate_history[-3:] # 最近3条发言
history_context = f"\n最近的论道内容:\n" + "\n".join([f"- {h}" for h in recent_history])
prompt = f"关于'{topic}'这个话题{memory_context}{history_context}\n\n请结合你的记忆和当前讨论从你的角色特点出发发表观点。请控制在150字以内。"
# 发送消息并获取回复
content = types.Content(role='user', parts=[types.Part(text=prompt)])
response = self.runners[participant].run_async(
user_id=self.session.user_id,
session_id=self.session.id,
new_message=content
)
# 收集回复
reply = ""
async for event in response:
if hasattr(event, 'content') and event.content:
if hasattr(event.content, 'parts') and event.content.parts:
for part in event.content.parts:
if hasattr(part, 'text') and part.text:
reply += str(part.text)
if reply.strip():
clean_reply = reply.strip()
print(f" {clean_reply}")
# 记录到辩论历史
debate_entry = f"{participant}: {clean_reply}"
debate_history.append(debate_entry)
# 添加到记忆银行
await self.memory_manager.add_debate_memory(
participant, clean_reply, topic
)
await asyncio.sleep(1) # 避免API调用过快
print(f"\n🎉 记忆增强论道完成!")
print(f"📝 本次论道共产生 {len(debate_history)} 条发言,已存储到各仙人的记忆银行中。")
return debate_history
async def close(self):
"""关闭资源"""
for runner in self.runners.values():
await runner.close()
async def main():
"""主函数"""
print("🚀 稷下学宫 ADK Memory Bank 论道系统")
# 检查API密钥
api_key = os.getenv('GOOGLE_API_KEY')
if not api_key:
print("❌ 未找到 GOOGLE_API_KEY 环境变量")
print("请使用: doppler run -- python src/jixia/debates/adk_memory_debate.py")
return
print(f"✅ API密钥已配置")
# 创建并初始化辩论系统
debate_system = MemoryEnhancedDebate()
try:
await debate_system.initialize()
# 进行辩论
await debate_system.conduct_memory_debate(
topic="人工智能对投资市场的影响",
participants=["铁拐李", "吕洞宾", "何仙姑", "张果老"]
)
except Exception as e:
print(f"❌ 运行失败: {e}")
import traceback
traceback.print_exc()
finally:
await debate_system.close()
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,290 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
稷下学宫 八仙论道系统
实现八仙四对矛盾的对角线辩论:男女、老少、富贫、贵贱
基于先天八卦的智慧对话系统
"""
import os
import asyncio
from google.adk import Agent, Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
import re
import sys
from contextlib import contextmanager
def create_baxian_agents():
"""创建八仙智能体 - 四对矛盾"""
# 男女对立吕洞宾vs 何仙姑(女)
lu_dong_bin = Agent(
name="吕洞宾",
model="gemini-2.5-flash",
instruction="你是吕洞宾八仙中的男性代表理性分析者。你代表男性视角善于逻辑思辨注重理性和秩序。你的发言风格温和而深刻总是能找到问题的核心。每次发言控制在80字以内。"
)
he_xian_gu = Agent(
name="何仙姑",
model="gemini-2.5-flash",
instruction="你是何仙姑八仙中的女性代表感性智慧者。你代表女性视角善于直觉洞察注重情感和和谐。你的发言风格柔和而犀利总是能看到事物的另一面。每次发言控制在80字以内。"
)
# 老少对立张果老vs 韩湘子(少)
zhang_guo_lao = Agent(
name="张果老",
model="gemini-2.5-flash",
instruction="你是张果老八仙中的长者代表经验智慧者。你代表老年视角善于从历史经验出发注重传统和稳重。你的发言风格深沉而睿智总是能从历史中汲取教训。每次发言控制在80字以内。"
)
han_xiang_zi = Agent(
name="韩湘子",
model="gemini-2.5-flash",
instruction="你是韩湘子八仙中的青年代表创新思维者。你代表年轻视角善于创新思考注重变革和进步。你的发言风格活泼而敏锐总是能提出新颖的观点。每次发言控制在80字以内。"
)
# 富贫对立汉钟离vs 蓝采和(贫)
han_zhong_li = Agent(
name="汉钟离",
model="gemini-2.5-flash",
instruction="你是汉钟离八仙中的富贵代表资源掌控者。你代表富有阶层视角善于从资源配置角度思考注重效率和投资回报。你的发言风格稳重而务实总是能看到经济利益。每次发言控制在80字以内。"
)
lan_cai_he = Agent(
name="蓝采和",
model="gemini-2.5-flash",
instruction="你是蓝采和八仙中的贫困代表民生关怀者。你代表普通民众视角善于从底层角度思考注重公平和民生。你的发言风格朴实而真诚总是能关注到弱势群体。每次发言控制在80字以内。"
)
# 贵贱对立曹国舅vs 铁拐李(贱)
cao_guo_jiu = Agent(
name="曹国舅",
model="gemini-2.5-flash",
instruction="你是曹国舅八仙中的贵族代表权力思考者。你代表上层社会视角善于从权力结构角度分析注重秩序和等级。你的发言风格优雅而权威总是能看到政治层面。每次发言控制在80字以内。"
)
tie_guai_li = Agent(
name="铁拐李",
model="gemini-2.5-flash",
instruction="你是铁拐李八仙中的底层代表逆向思维者。你代表社会底层视角善于从批判角度质疑注重真实和反叛。你的发言风格直接而犀利总是能揭示问题本质。每次发言控制在80字以内。"
)
return {
'male_female': (lu_dong_bin, he_xian_gu),
'old_young': (zhang_guo_lao, han_xiang_zi),
'rich_poor': (han_zhong_li, lan_cai_he),
'noble_humble': (cao_guo_jiu, tie_guai_li)
}
@contextmanager
def suppress_stdout():
"""抑制标准输出"""
with open(os.devnull, "w") as devnull:
old_stdout = sys.stdout
sys.stdout = devnull
try:
yield
finally:
sys.stdout = old_stdout
def clean_debug_output(text):
"""清理调试输出"""
if not text:
return ""
# 移除调试信息,但保留实际内容
lines = text.split('\n')
cleaned_lines = []
for line in lines:
line = line.strip()
# 只过滤明确的调试信息,保留实际回复内容
if any(debug_pattern in line for debug_pattern in
['Event from', 'API_KEY', 'Both GOOGLE_API_KEY', 'Using GOOGLE_API_KEY']):
continue
if line and not line.startswith('DEBUG') and not line.startswith('INFO'):
cleaned_lines.append(line)
result = ' '.join(cleaned_lines)
return result if result.strip() else text.strip()
async def conduct_diagonal_debate(agent1, agent2, topic, perspective1, perspective2, round_num):
"""进行对角线辩论"""
print(f"\n🎯 第{round_num}轮对角线辩论:{agent1.name} vs {agent2.name}")
print(f"📋 辩论视角:{perspective1} vs {perspective2}")
# 设置环境变量以抑制ADK调试输出
os.environ['GRPC_VERBOSITY'] = 'ERROR'
os.environ['GRPC_TRACE'] = ''
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import warnings
warnings.filterwarnings('ignore')
# 创建会话服务和运行器
session_service = InMemorySessionService()
# 创建会话
session = await session_service.create_session(
state={},
app_name="稷下学宫八仙论道系统",
user_id="baxian_debate_user"
)
# 创建Runner实例
runner1 = Runner(agent=agent1, session_service=session_service, app_name="稷下学宫八仙论道系统")
runner2 = Runner(agent=agent2, session_service=session_service, app_name="稷下学宫八仙论道系统")
try:
# 第一轮agent1 发起
prompt1 = f"请从{perspective1}的角度,对'{topic}'发表你的观点。要求:观点鲜明,论证有力,体现{perspective1}的特色。"
content1 = types.Content(role='user', parts=[types.Part(text=prompt1)])
response1 = runner1.run_async(
user_id=session.user_id,
session_id=session.id,
new_message=content1
)
# 提取回复内容
agent1_reply = ""
async for event in response1:
# 只处理包含实际文本内容的事件,过滤调试信息
if hasattr(event, 'content') and event.content:
if hasattr(event.content, 'parts') and event.content.parts:
for part in event.content.parts:
if hasattr(part, 'text') and part.text and part.text.strip():
text_content = str(part.text).strip()
# 过滤掉调试信息和系统消息
if not text_content.startswith('Event from') and not 'API_KEY' in text_content:
agent1_reply += text_content
elif hasattr(event, 'text') and event.text:
text_content = str(event.text).strip()
if not text_content.startswith('Event from') and not 'API_KEY' in text_content:
agent1_reply += text_content
print(f"\n🗣️ {agent1.name}{perspective1}")
print(f" {agent1_reply}")
# 第二轮agent2 回应
prompt2 = f"针对{agent1.name}刚才的观点:'{agent1_reply}',请从{perspective2}的角度进行回应和反驳。要求:有理有据,体现{perspective2}的独特视角。"
content2 = types.Content(role='user', parts=[types.Part(text=prompt2)])
response2 = runner2.run_async(
user_id=session.user_id,
session_id=session.id,
new_message=content2
)
agent2_reply = ""
async for event in response2:
# 只处理包含实际文本内容的事件,过滤调试信息
if hasattr(event, 'content') and event.content:
if hasattr(event.content, 'parts') and event.content.parts:
for part in event.content.parts:
if hasattr(part, 'text') and part.text and part.text.strip():
text_content = str(part.text).strip()
# 过滤掉调试信息和系统消息
if not text_content.startswith('Event from') and not 'API_KEY' in text_content:
agent2_reply += text_content
elif hasattr(event, 'text') and event.text:
text_content = str(event.text).strip()
if not text_content.startswith('Event from') and not 'API_KEY' in text_content:
agent2_reply += text_content
print(f"\n🗣️ {agent2.name}{perspective2}")
print(f" {agent2_reply}")
# 第三轮agent1 再次回应
prompt3 = f"听了{agent2.name}的观点:'{agent2_reply}',请从{perspective1}的角度进行最后的总结和回应。"
content3 = types.Content(role='user', parts=[types.Part(text=prompt3)])
response3 = runner1.run_async(
user_id=session.user_id,
session_id=session.id,
new_message=content3
)
agent1_final = ""
async for event in response3:
# 只处理包含实际文本内容的事件,过滤调试信息
if hasattr(event, 'content') and event.content:
if hasattr(event.content, 'parts') and event.content.parts:
for part in event.content.parts:
if hasattr(part, 'text') and part.text and part.text.strip():
text_content = str(part.text).strip()
# 过滤掉调试信息和系统消息
if not text_content.startswith('Event from') and not 'API_KEY' in text_content:
agent1_final += text_content
elif hasattr(event, 'text') and event.text:
text_content = str(event.text).strip()
if not text_content.startswith('Event from') and not 'API_KEY' in text_content:
agent1_final += text_content
print(f"\n🗣️ {agent1.name}{perspective1})总结:")
print(f" {agent1_final}")
except Exception as e:
print(f"❌ 对角线辩论出现错误: {e}")
raise
async def conduct_baxian_debate():
"""进行八仙四对矛盾的完整辩论"""
print("\n🏛️ 稷下学宫 - 八仙论道系统启动")
print("📚 八仙者,南北朝的产物,男女老少,富贵贫贱,皆可成仙")
print("🎯 四对矛盾暗合先天八卦,智慧交锋即将开始")
topic = "雅江水电站对中印关系的影响"
print(f"\n📋 论道主题:{topic}")
# 创建八仙智能体
agents = create_baxian_agents()
print("\n🔥 八仙真实ADK论道模式")
# 四对矛盾的对角线辩论
debates = [
(agents['male_female'], "男性理性", "女性感性", "男女对立"),
(agents['old_young'], "长者经验", "青年创新", "老少对立"),
(agents['rich_poor'], "富者效率", "贫者公平", "富贫对立"),
(agents['noble_humble'], "贵族秩序", "底层真实", "贵贱对立")
]
for i, ((agent1, agent2), perspective1, perspective2, debate_type) in enumerate(debates, 1):
print(f"\n{'='*60}")
print(f"🎭 {debate_type}辩论")
print(f"{'='*60}")
await conduct_diagonal_debate(agent1, agent2, topic, perspective1, perspective2, i)
if i < len(debates):
print("\n⏳ 准备下一轮辩论...")
await asyncio.sleep(1)
print("\n🎉 八仙论道完成!")
print("\n📝 四对矛盾,八种视角,智慧的交锋展现了问题的多面性。")
print("💡 这就是稷下学宫八仙论道的魅力所在。")
def main():
"""主函数"""
print("🚀 稷下学宫 八仙ADK 真实论道系统")
# 检查API密钥
if not os.getenv('GOOGLE_API_KEY'):
print("❌ 请设置 GOOGLE_API_KEY 环境变量")
return
print("✅ API密钥已配置")
try:
asyncio.run(conduct_baxian_debate())
except KeyboardInterrupt:
print("\n👋 用户中断,论道结束")
except Exception as e:
print(f"❌ 系统错误: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,980 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
增强版优先级算法 v2.1.0
实现更复杂的权重计算和上下文分析能力
"""
import re
import math
from typing import Dict, List, Any, Optional, Tuple, Set
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from enum import Enum
import json
from collections import defaultdict, deque
import hashlib
import statistics
class ArgumentType(Enum):
"""论点类型"""
ATTACK = "攻击"
DEFENSE = "防御"
SUPPORT = "支持"
REFUTE = "反驳"
SUMMARY = "总结"
QUESTION = "质疑"
class EmotionLevel(Enum):
"""情绪强度"""
CALM = 1
MILD = 2
MODERATE = 3
INTENSE = 4
EXTREME = 5
@dataclass
class SpeechAnalysis:
"""发言分析结果"""
argument_type: ArgumentType
emotion_level: EmotionLevel
logic_strength: float # 0-1
evidence_quality: float # 0-1
relevance_score: float # 0-1
urgency_score: float # 0-1
target_speakers: List[str] # 针对的发言者
keywords: List[str]
sentiment_score: float # -1 to 1
@dataclass
class SpeakerProfile:
"""发言者档案"""
name: str
team: str
recent_speeches: List[Dict] = field(default_factory=list)
total_speech_count: int = 0
average_response_time: float = 30.0
expertise_areas: List[str] = field(default_factory=list)
debate_style: str = "analytical" # "aggressive", "analytical", "diplomatic", "creative"
current_energy: float = 1.0 # 0-1
last_speech_time: Optional[datetime] = None
# 新增字段
historical_performance: Dict[str, float] = field(default_factory=dict)
context_adaptability: float = 0.7 # 上下文适应能力
argument_effectiveness: Dict[str, float] = field(default_factory=dict) # 不同类型论点的有效性
collaboration_score: float = 0.5 # 团队协作得分
interruption_tendency: float = 0.3 # 打断倾向
topic_expertise: Dict[str, float] = field(default_factory=dict) # 话题专业度
class EnhancedPriorityAlgorithm:
"""增强版优先级算法"""
def __init__(self):
# 权重配置
self.weights = {
"rebuttal_urgency": 0.30, # 反驳紧急性
"argument_strength": 0.25, # 论点强度
"time_pressure": 0.20, # 时间压力
"audience_reaction": 0.15, # 观众反应
"strategy_need": 0.10 # 策略需要
}
# 情感关键词库
self.emotion_keywords = {
EmotionLevel.CALM: ["认为", "分析", "数据显示", "根据", "客观"],
EmotionLevel.MILD: ["不同意", "质疑", "担心", "建议"],
EmotionLevel.MODERATE: ["强烈", "明显", "严重", "重要"],
EmotionLevel.INTENSE: ["绝对", "完全", "彻底", "必须"],
EmotionLevel.EXTREME: ["荒谬", "愚蠢", "灾难", "危险"]
}
# 论点类型关键词
self.argument_keywords = {
ArgumentType.ATTACK: ["错误", "问题", "缺陷", "失败"],
ArgumentType.DEFENSE: ["解释", "澄清", "说明", "回应"],
ArgumentType.SUPPORT: ["支持", "赞同", "证实", "补充"],
ArgumentType.REFUTE: ["反驳", "否定", "驳斥", "反对"],
ArgumentType.SUMMARY: ["总结", "综上", "结论", "最后"],
ArgumentType.QUESTION: ["为什么", "如何", "是否", "难道"]
}
# 发言者档案
self.speaker_profiles: Dict[str, SpeakerProfile] = {}
# 辩论历史分析
self.debate_history: List[Dict] = []
# 新增: 高级分析器组件
self.context_analyzer = ContextAnalyzer()
self.learning_system = LearningSystem()
self.topic_drift_detector = TopicDriftDetector()
self.emotion_dynamics = EmotionDynamicsModel()
def analyze_speech(self, message: str, speaker: str, context: Dict) -> SpeechAnalysis:
"""分析发言内容"""
# 检测论点类型
argument_type = self._detect_argument_type(message)
# 检测情绪强度
emotion_level = self._detect_emotion_level(message)
# 计算逻辑强度
logic_strength = self._calculate_logic_strength(message)
# 计算证据质量
evidence_quality = self._calculate_evidence_quality(message)
# 计算相关性分数
relevance_score = self._calculate_relevance_score(message, context)
# 计算紧急性分数
urgency_score = self._calculate_urgency_score(message, context)
# 识别目标发言者
target_speakers = self._identify_target_speakers(message)
# 提取关键词
keywords = self._extract_keywords(message)
# 计算情感分数
sentiment_score = self._calculate_sentiment_score(message)
return SpeechAnalysis(
argument_type=argument_type,
emotion_level=emotion_level,
logic_strength=logic_strength,
evidence_quality=evidence_quality,
relevance_score=relevance_score,
urgency_score=urgency_score,
target_speakers=target_speakers,
keywords=keywords,
sentiment_score=sentiment_score
)
def calculate_speaker_priority(self, speaker: str, context: Dict,
recent_speeches: List[Dict]) -> float:
"""计算发言者优先级 - 增强版"""
# 获取或创建发言者档案
profile = self._get_or_create_speaker_profile(speaker)
# 更新发言者档案
self._update_speaker_profile(profile, recent_speeches)
# === 基础分数计算 ===
rebuttal_urgency = self._calculate_rebuttal_urgency(speaker, context, recent_speeches)
argument_strength = self._calculate_argument_strength(speaker, profile)
time_pressure = self._calculate_time_pressure(speaker, context)
audience_reaction = self._calculate_audience_reaction(speaker, context)
strategy_need = self._calculate_strategy_need(speaker, context, profile)
# === 新增高级分析 ===
# 1. 上下文流程分析
flow_analysis = self.context_analyzer.analyze_debate_flow(recent_speeches)
flow_bonus = self._calculate_flow_bonus(speaker, flow_analysis)
# 2. 话题漂移检测
if recent_speeches:
last_speech = recent_speeches[-1].get("content", "")
drift_analysis = self.topic_drift_detector.detect_drift(last_speech, context)
drift_penalty = self._calculate_drift_penalty(speaker, drift_analysis)
else:
drift_penalty = 0.0
# 3. 情绪动态分析
emotion_analysis = self.emotion_dynamics.analyze_emotion_dynamics(recent_speeches)
emotion_bonus = self._calculate_emotion_bonus(speaker, emotion_analysis, profile)
# 4. 学习系统适应
adaptation = self.learning_system.get_speaker_adaptation(speaker)
adaptation_factor = adaptation.get("confidence", 0.5)
# 5. 个性化权重调整
personalized_weights = self._get_personalized_weights(speaker, profile, context)
# === 加权计算总分 ===
base_score = (
rebuttal_urgency * personalized_weights["rebuttal_urgency"] +
argument_strength * personalized_weights["argument_strength"] +
time_pressure * personalized_weights["time_pressure"] +
audience_reaction * personalized_weights["audience_reaction"] +
strategy_need * personalized_weights["strategy_need"]
)
# 应用高级调整
enhanced_score = base_score + flow_bonus - drift_penalty + emotion_bonus
enhanced_score *= adaptation_factor
# 应用传统修正因子
final_score = self._apply_correction_factors(enhanced_score, speaker, profile, context)
return min(max(final_score, 0.0), 1.0) # 限制在0-1范围内
def get_next_speaker(self, available_speakers: List[str], context: Dict,
recent_speeches: List[Dict]) -> Tuple[str, float, Dict]:
"""获取下一个发言者"""
speaker_scores = {}
detailed_analysis = {}
for speaker in available_speakers:
score = self.calculate_speaker_priority(speaker, context, recent_speeches)
speaker_scores[speaker] = score
# 记录详细分析
detailed_analysis[speaker] = {
"priority_score": score,
"profile": self.speaker_profiles.get(speaker),
"analysis_timestamp": datetime.now().isoformat()
}
# 选择最高分发言者
best_speaker = max(speaker_scores, key=speaker_scores.get)
best_score = speaker_scores[best_speaker]
return best_speaker, best_score, detailed_analysis
def _detect_argument_type(self, message: str) -> ArgumentType:
"""检测论点类型"""
message_lower = message.lower()
type_scores = {}
for arg_type, keywords in self.argument_keywords.items():
score = sum(1 for keyword in keywords if keyword in message_lower)
type_scores[arg_type] = score
if not type_scores or max(type_scores.values()) == 0:
return ArgumentType.SUPPORT # 默认类型
return max(type_scores, key=type_scores.get)
def _detect_emotion_level(self, message: str) -> EmotionLevel:
"""检测情绪强度"""
message_lower = message.lower()
for emotion_level in reversed(list(EmotionLevel)):
keywords = self.emotion_keywords.get(emotion_level, [])
if any(keyword in message_lower for keyword in keywords):
return emotion_level
return EmotionLevel.CALM
def _calculate_logic_strength(self, message: str) -> float:
"""计算逻辑强度"""
logic_indicators = [
"因为", "所以", "因此", "由于", "根据", "数据显示",
"研究表明", "事实上", "例如", "比如", "首先", "其次", "最后"
]
message_lower = message.lower()
logic_count = sum(1 for indicator in logic_indicators if indicator in message_lower)
# 基于逻辑词汇密度计算
word_count = len(message.split())
if word_count == 0:
return 0.0
logic_density = logic_count / word_count
return min(logic_density * 10, 1.0) # 归一化到0-1
def _calculate_evidence_quality(self, message: str) -> float:
"""计算证据质量"""
evidence_indicators = [
"数据", "统计", "研究", "报告", "调查", "实验",
"案例", "例子", "证据", "资料", "文献", "来源"
]
message_lower = message.lower()
evidence_count = sum(1 for indicator in evidence_indicators if indicator in message_lower)
# 检查是否有具体数字
number_pattern = r'\d+(?:\.\d+)?%?'
numbers = re.findall(number_pattern, message)
number_bonus = min(len(numbers) * 0.1, 0.3)
base_score = min(evidence_count * 0.2, 0.7)
return min(base_score + number_bonus, 1.0)
def _calculate_relevance_score(self, message: str, context: Dict) -> float:
"""计算相关性分数"""
# 简化实现:基于关键词匹配
topic_keywords = context.get("topic_keywords", [])
if not topic_keywords:
return 0.5 # 默认中等相关性
message_lower = message.lower()
relevance_count = sum(1 for keyword in topic_keywords if keyword.lower() in message_lower)
return min(relevance_count / len(topic_keywords), 1.0)
def _calculate_urgency_score(self, message: str, context: Dict) -> float:
"""计算紧急性分数"""
urgency_keywords = ["紧急", "立即", "马上", "现在", "重要", "关键", "危险"]
message_lower = message.lower()
urgency_count = sum(1 for keyword in urgency_keywords if keyword in message_lower)
# 基于时间压力
time_factor = context.get("time_remaining", 1.0)
time_urgency = 1.0 - time_factor
keyword_urgency = min(urgency_count * 0.3, 1.0)
return min(keyword_urgency + time_urgency * 0.5, 1.0)
def _identify_target_speakers(self, message: str) -> List[str]:
"""识别目标发言者"""
# 简化实现:查找提及的发言者名称
speaker_names = ["正1", "正2", "正3", "正4", "反1", "反2", "反3", "反4"]
targets = []
for name in speaker_names:
if name in message:
targets.append(name)
return targets
def _extract_keywords(self, message: str) -> List[str]:
"""提取关键词"""
# 简化实现提取长度大于2的词汇
words = re.findall(r'\b\w{3,}\b', message)
return list(set(words))[:10] # 最多返回10个关键词
def _calculate_sentiment_score(self, message: str) -> float:
"""计算情感分数"""
positive_words = ["", "优秀", "正确", "支持", "赞同", "成功", "有效"]
negative_words = ["", "错误", "失败", "反对", "问题", "危险", "无效"]
message_lower = message.lower()
positive_count = sum(1 for word in positive_words if word in message_lower)
negative_count = sum(1 for word in negative_words if word in message_lower)
total_count = positive_count + negative_count
if total_count == 0:
return 0.0
return (positive_count - negative_count) / total_count
def _get_or_create_speaker_profile(self, speaker: str) -> SpeakerProfile:
"""获取或创建发言者档案"""
if speaker not in self.speaker_profiles:
self.speaker_profiles[speaker] = SpeakerProfile(
name=speaker,
team="positive" if "" in speaker else "negative",
recent_speeches=[],
total_speech_count=0,
average_response_time=3.0,
expertise_areas=[],
debate_style="analytical",
current_energy=1.0
)
return self.speaker_profiles[speaker]
def _update_speaker_profile(self, profile: SpeakerProfile, recent_speeches: List[Dict]):
"""更新发言者档案"""
# 更新发言历史
speaker_speeches = [s for s in recent_speeches if s.get("speaker") == profile.name]
profile.recent_speeches = speaker_speeches[-5:] # 保留最近5次发言
profile.total_speech_count = len(speaker_speeches)
# 更新能量水平(基于发言频率)
if profile.last_speech_time:
time_since_last = datetime.now() - profile.last_speech_time
energy_recovery = min(time_since_last.seconds / 300, 0.5) # 5分钟恢复50%
profile.current_energy = min(profile.current_energy + energy_recovery, 1.0)
profile.last_speech_time = datetime.now()
def _calculate_rebuttal_urgency(self, speaker: str, context: Dict,
recent_speeches: List[Dict]) -> float:
"""计算反驳紧急性"""
# 检查是否有针对该发言者团队的攻击
team = "positive" if "" in speaker else "negative"
opposing_team = "negative" if team == "positive" else "positive"
recent_attacks = 0
for speech in recent_speeches[-5:]: # 检查最近5次发言
if speech.get("team") == opposing_team:
analysis = speech.get("analysis", {})
if analysis.get("argument_type") in [ArgumentType.ATTACK, ArgumentType.REFUTE]:
recent_attacks += 1
# 基础紧急性 + 攻击响应紧急性
# 为不同发言者生成不同的基础紧急性
speaker_hash = hash(speaker) % 10 # 使用哈希值生成0-9的数字
base_urgency = 0.1 + speaker_hash * 0.05 # 不同发言者有不同的基础紧急性
attack_urgency = recent_attacks * 0.3
return min(base_urgency + attack_urgency, 1.0)
def _calculate_argument_strength(self, speaker: str, profile: SpeakerProfile) -> float:
"""计算论点强度"""
# 基于历史表现
if not profile.recent_speeches:
# 为不同发言者提供不同的基础论点强度
speaker_hash = hash(speaker) % 10 # 使用哈希值生成0-9的数字
team_prefix = "" if "" in speaker else ""
# 基础强度根据发言者哈希值变化
base_strength = 0.4 + speaker_hash * 0.06 # 0.4-1.0范围
# 团队差异化
team_factor = 1.05 if team_prefix == "" else 0.95
return min(base_strength * team_factor, 1.0)
avg_logic = sum(s.get("analysis", {}).get("logic_strength", 0.5)
for s in profile.recent_speeches) / len(profile.recent_speeches)
avg_evidence = sum(s.get("analysis", {}).get("evidence_quality", 0.5)
for s in profile.recent_speeches) / len(profile.recent_speeches)
return (avg_logic + avg_evidence) / 2
def _calculate_time_pressure(self, speaker: str, context: Dict) -> float:
"""计算时间压力"""
time_remaining = context.get("time_remaining", 1.0)
stage_progress = context.get("stage_progress", 0)
max_progress = context.get("max_progress", 1)
# 时间压力随剩余时间减少而增加
time_pressure = 1.0 - time_remaining
# 阶段进度压力
progress_pressure = stage_progress / max_progress
# 发言者个体差异
speaker_hash = hash(speaker) % 10 # 使用哈希值生成0-9的数字
speaker_factor = 0.8 + speaker_hash * 0.02 # 不同发言者有不同的时间敏感度
base_pressure = (time_pressure + progress_pressure) / 2
return min(base_pressure * speaker_factor, 1.0)
def _calculate_audience_reaction(self, speaker: str, context: Dict) -> float:
"""计算观众反应"""
# 简化实现:基于团队表现
team = "positive" if "" in speaker else "negative"
team_score = context.get(f"{team}_team_score", 0.5)
# 发言者个体魅力差异
speaker_hash = hash(speaker) % 10 # 使用哈希值生成0-9的数字
charisma_factor = 0.7 + speaker_hash * 0.03 # 不同发言者有不同的观众吸引力
# 如果团队表现不佳,需要更多发言机会
base_reaction = 1.0 - team_score
return min(base_reaction * charisma_factor, 1.0)
def _calculate_strategy_need(self, speaker: str, context: Dict,
profile: SpeakerProfile) -> float:
"""计算策略需要"""
# 基于发言者专长和当前需求
current_stage = context.get("current_stage", "")
# 为不同发言者提供差异化的策略需求
speaker_hash = hash(speaker) % 10 # 使用哈希值生成0-9的数字
team_prefix = "" if "" in speaker else ""
strategy_match = {
"": 0.8 if speaker_hash == 0 else 0.3 + speaker_hash * 0.05, # 开场需要主力,但有差异
"": 0.4 + speaker_hash * 0.06, # 承接阶段根据发言者哈希差异化
"": max(0.2, 1.0 - profile.current_energy + speaker_hash * 0.05), # 自由辩论看能量和哈希
"": 0.9 if speaker_hash == 0 else 0.3 + speaker_hash * 0.05 # 总结需要主力,但有差异
}
base_score = strategy_match.get(current_stage, 0.5)
# 添加团队差异化因子
team_factor = 1.1 if team_prefix == "" else 0.9
return min(base_score * team_factor, 1.0)
def _apply_correction_factors(self, base_score: float, speaker: str,
profile: SpeakerProfile, context: Dict) -> float:
"""应用修正因子"""
corrected_score = base_score
# 能量修正
corrected_score *= profile.current_energy
# 发言频率修正(避免某人发言过多)
recent_count = len([s for s in profile.recent_speeches
if s.get("timestamp", "") > (datetime.now() - timedelta(minutes=5)).isoformat()])
if recent_count > 2:
corrected_score *= 0.7 # 降低优先级
# 团队平衡修正
team = "positive" if "" in speaker else "negative"
team_recent_count = context.get(f"{team}_recent_speeches", 0)
opposing_recent_count = context.get(f"{'negative' if team == 'positive' else 'positive'}_recent_speeches", 0)
if team_recent_count > opposing_recent_count + 2:
corrected_score *= 0.8 # 平衡发言机会
return corrected_score
def calculate_priority(self, speaker: str, context: Dict, recent_speeches: List[Dict]) -> float:
"""计算发言者优先级(兼容性方法)"""
return self.calculate_speaker_priority(speaker, context, recent_speeches)
def get_algorithm_status(self) -> Dict[str, Any]:
"""获取算法状态"""
return {
"weights": self.weights,
"speaker_count": len(self.speaker_profiles),
"total_speeches_analyzed": len(self.debate_history),
"algorithm_version": "2.1.0",
"last_updated": datetime.now().isoformat()
}
def save_analysis_data(self, filename: str = "priority_analysis.json"):
"""保存分析数据"""
data = {
"algorithm_status": self.get_algorithm_status(),
"speaker_profiles": {
name: {
"name": profile.name,
"team": profile.team,
"total_speech_count": profile.total_speech_count,
"average_response_time": profile.average_response_time,
"expertise_areas": profile.expertise_areas,
"debate_style": profile.debate_style,
"current_energy": profile.current_energy,
"last_speech_time": profile.last_speech_time.isoformat() if profile.last_speech_time else None
}
for name, profile in self.speaker_profiles.items()
},
"debate_history": self.debate_history
}
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"💾 优先级分析数据已保存到 {filename}")
def main():
"""测试增强版优先级算法"""
print("🚀 增强版优先级算法测试")
print("=" * 50)
algorithm = EnhancedPriorityAlgorithm()
# 模拟辩论上下文
context = {
"current_stage": "",
"stage_progress": 10,
"max_progress": 36,
"time_remaining": 0.6,
"topic_keywords": ["人工智能", "投资", "风险", "收益"],
"positive_team_score": 0.6,
"negative_team_score": 0.4,
"positive_recent_speeches": 3,
"negative_recent_speeches": 2
}
# 模拟最近发言
recent_speeches = [
{
"speaker": "正1",
"team": "positive",
"message": "根据数据显示AI投资确实能带来显著收益",
"timestamp": datetime.now().isoformat(),
"analysis": {
"argument_type": ArgumentType.SUPPORT,
"logic_strength": 0.8,
"evidence_quality": 0.7
}
},
{
"speaker": "反2",
"team": "negative",
"message": "这种观点完全错误AI投资风险巨大",
"timestamp": datetime.now().isoformat(),
"analysis": {
"argument_type": ArgumentType.ATTACK,
"logic_strength": 0.3,
"evidence_quality": 0.2
}
}
]
available_speakers = ["正1", "正2", "正3", "正4", "反1", "反2", "反3", "反4"]
# 计算下一个发言者
next_speaker, score, analysis = algorithm.get_next_speaker(
available_speakers, context, recent_speeches
)
print(f"\n🎯 推荐发言者: {next_speaker}")
print(f"📊 优先级分数: {score:.3f}")
print(f"\n📈 详细分析:")
for speaker, data in analysis.items():
print(f" {speaker}: {data['priority_score']:.3f}")
# 保存分析数据
algorithm.save_analysis_data()
print("\n✅ 增强版优先级算法测试完成!")
if __name__ == "__main__":
main()
class ContextAnalyzer:
"""高级上下文分析器"""
def __init__(self):
self.context_memory = deque(maxlen=20) # 保留最近20轮的上下文
self.semantic_vectors = {} # 语义向量缓存
def analyze_debate_flow(self, recent_speeches: List[Dict]) -> Dict[str, Any]:
"""分析辩论流程"""
if not recent_speeches:
return {"flow_direction": "neutral", "momentum": 0.5, "tension": 0.3}
# 分析辩论动量
momentum = self._calculate_debate_momentum(recent_speeches)
# 分析辩论紧张度
tension = self._calculate_debate_tension(recent_speeches)
# 分析流程方向
flow_direction = self._analyze_flow_direction(recent_speeches)
# 检测话题转换点
topic_shifts = self._detect_topic_shifts(recent_speeches)
return {
"flow_direction": flow_direction,
"momentum": momentum,
"tension": tension,
"topic_shifts": topic_shifts,
"engagement_level": self._calculate_engagement_level(recent_speeches)
}
def _calculate_debate_momentum(self, speeches: List[Dict]) -> float:
"""计算辩论动量"""
if len(speeches) < 2:
return 0.5
# 基于发言长度和情绪强度变化
momentum_factors = []
for i in range(1, len(speeches)):
prev_speech = speeches[i-1]
curr_speech = speeches[i]
# 长度变化
length_change = len(curr_speech.get("content", "")) - len(prev_speech.get("content", ""))
length_factor = min(abs(length_change) / 100, 1.0) # 归一化
momentum_factors.append(length_factor)
return statistics.mean(momentum_factors) if momentum_factors else 0.5
def _calculate_debate_tension(self, speeches: List[Dict]) -> float:
"""计算辩论紧张度"""
if not speeches:
return 0.3
tension_keywords = ["反驳", "错误", "质疑", "不同意", "反对", "驳斥"]
tension_scores = []
for speech in speeches[-5:]: # 只看最近5轮
content = speech.get("content", "")
tension_count = sum(1 for keyword in tension_keywords if keyword in content)
tension_scores.append(min(tension_count / 3, 1.0))
return statistics.mean(tension_scores) if tension_scores else 0.3
def _analyze_flow_direction(self, speeches: List[Dict]) -> str:
"""分析流程方向"""
if len(speeches) < 3:
return "neutral"
recent_teams = [speech.get("team", "unknown") for speech in speeches[-3:]]
positive_count = recent_teams.count("positive")
negative_count = recent_teams.count("negative")
if positive_count > negative_count:
return "positive_dominant"
elif negative_count > positive_count:
return "negative_dominant"
else:
return "balanced"
def _detect_topic_shifts(self, speeches: List[Dict]) -> List[Dict]:
"""检测话题转换点"""
shifts = []
if len(speeches) < 2:
return shifts
# 简化的话题转换检测
for i in range(1, len(speeches)):
prev_keywords = set(speeches[i-1].get("content", "").split()[:10])
curr_keywords = set(speeches[i].get("content", "").split()[:10])
# 计算关键词重叠度
overlap = len(prev_keywords & curr_keywords) / max(len(prev_keywords | curr_keywords), 1)
if overlap < 0.3: # 重叠度低于30%认为是话题转换
shifts.append({
"position": i,
"speaker": speeches[i].get("speaker"),
"shift_intensity": 1 - overlap
})
return shifts
def _calculate_engagement_level(self, speeches: List[Dict]) -> float:
"""计算参与度"""
if not speeches:
return 0.5
# 基于发言频率和长度
total_length = sum(len(speech.get("content", "")) for speech in speeches)
avg_length = total_length / len(speeches)
# 归一化到0-1
engagement = min(avg_length / 100, 1.0)
return engagement
class LearningSystem:
"""学习系统,用于优化算法参数"""
def __init__(self):
self.performance_history = defaultdict(list)
self.weight_adjustments = defaultdict(float)
self.learning_rate = 0.05
def record_performance(self, speaker: str, predicted_priority: float,
actual_effectiveness: float, context: Dict):
"""记录表现数据"""
self.performance_history[speaker].append({
"predicted_priority": predicted_priority,
"actual_effectiveness": actual_effectiveness,
"context": context,
"timestamp": datetime.now(),
"error": abs(predicted_priority - actual_effectiveness)
})
def optimize_weights(self, algorithm_weights: Dict[str, float]) -> Dict[str, float]:
"""优化权重参数"""
if not self.performance_history:
return algorithm_weights
# 计算每个组件的平均误差
component_errors = {}
for component in algorithm_weights.keys():
errors = []
for speaker_data in self.performance_history.values():
for record in speaker_data[-10:]: # 只看最近10次
errors.append(record["error"])
if errors:
component_errors[component] = statistics.mean(errors)
# 根据误差调整权重
optimized_weights = algorithm_weights.copy()
for component, error in component_errors.items():
if error > 0.3: # 误差过大,降低权重
adjustment = -self.learning_rate * error
else: # 误差合理,略微增加权重
adjustment = self.learning_rate * (0.3 - error)
optimized_weights[component] = max(0.05, min(0.5,
optimized_weights[component] + adjustment))
# 归一化权重
total_weight = sum(optimized_weights.values())
if total_weight > 0:
optimized_weights = {k: v/total_weight for k, v in optimized_weights.items()}
return optimized_weights
def get_speaker_adaptation(self, speaker: str) -> Dict[str, float]:
"""获取发言者特定的适应参数"""
if speaker not in self.performance_history:
return {"confidence": 0.5, "adaptability": 0.5}
recent_records = self.performance_history[speaker][-5:]
if not recent_records:
return {"confidence": 0.5, "adaptability": 0.5}
# 计算准确性趋势
errors = [record["error"] for record in recent_records]
avg_error = statistics.mean(errors)
confidence = max(0.1, 1.0 - avg_error)
adaptability = min(1.0, 0.3 + (1.0 - statistics.stdev(errors)) if len(errors) > 1 else 0.7)
return {"confidence": confidence, "adaptability": adaptability}
class TopicDriftDetector:
"""话题漂移检测器"""
def __init__(self):
self.topic_history = deque(maxlen=50)
self.keywords_cache = {}
def detect_drift(self, current_speech: str, context: Dict) -> Dict[str, Any]:
"""检测话题漂移"""
current_keywords = self._extract_topic_keywords(current_speech)
if not self.topic_history:
self.topic_history.append(current_keywords)
return {"drift_detected": False, "drift_intensity": 0.0}
# 计算与历史话题的相似度
similarities = []
for historical_keywords in list(self.topic_history)[-5:]: # 最近5轮
similarity = self._calculate_keyword_similarity(current_keywords, historical_keywords)
similarities.append(similarity)
avg_similarity = statistics.mean(similarities)
drift_intensity = 1.0 - avg_similarity
# 更新历史
self.topic_history.append(current_keywords)
return {
"drift_detected": drift_intensity > 0.4, # 阈值40%
"drift_intensity": drift_intensity,
"current_keywords": current_keywords,
"recommendation": self._get_drift_recommendation(float(drift_intensity))
}
def _extract_topic_keywords(self, text: str) -> Set[str]:
"""提取话题关键词"""
# 简化的关键词提取
words = re.findall(r'\b\w{2,}\b', text.lower())
# 过滤停用词
stop_words = {"", "", "", "", "", "", "", "", "我们", "", ""}
keywords = {word for word in words if word not in stop_words and len(word) > 1}
return keywords
def _calculate_keyword_similarity(self, keywords1: Set[str], keywords2: Set[str]) -> float:
"""计算关键词相似度"""
if not keywords1 or not keywords2:
return 0.0
intersection = keywords1 & keywords2
union = keywords1 | keywords2
return len(intersection) / len(union) if union else 0.0
def _get_drift_recommendation(self, drift_intensity: float) -> str:
"""获取漂移建议"""
if drift_intensity > 0.7:
return "major_topic_shift_detected"
elif drift_intensity > 0.4:
return "moderate_drift_detected"
else:
return "topic_stable"
class EmotionDynamicsModel:
"""情绪动力学模型"""
def __init__(self):
self.emotion_history = deque(maxlen=30)
self.speaker_emotion_profiles = defaultdict(list)
def analyze_emotion_dynamics(self, recent_speeches: List[Dict]) -> Dict[str, Any]:
"""分析情绪动态"""
if not recent_speeches:
return {"overall_trend": "neutral", "intensity_change": 0.0}
# 提取情绪序列
emotion_sequence = []
for speech in recent_speeches:
emotion_score = self._calculate_emotion_score(speech.get("content", ""))
emotion_sequence.append(emotion_score)
# 更新发言者情绪档案
speaker = speech.get("speaker")
if speaker:
self.speaker_emotion_profiles[speaker].append(emotion_score)
if len(emotion_sequence) < 2:
return {"overall_trend": "neutral", "intensity_change": 0.0}
# 计算情绪趋势
trend = self._calculate_emotion_trend(emotion_sequence)
# 计算强度变化
intensity_change = emotion_sequence[-1] - emotion_sequence[0]
# 检测情绪拐点
turning_points = self._detect_emotion_turning_points(emotion_sequence)
return {
"overall_trend": trend,
"intensity_change": intensity_change,
"current_intensity": emotion_sequence[-1],
"turning_points": turning_points,
"volatility": statistics.stdev(emotion_sequence) if len(emotion_sequence) > 1 else 0.0
}
def _calculate_emotion_score(self, text: str) -> float:
"""计算情绪分数"""
positive_words = ["", "", "优秀", "正确", "支持", "赞同", "有效"]
negative_words = ["", "", "糟糕", "反对", "质疑", "问题", "失败"]
intense_words = ["强烈", "坚决", "绝对", "完全", "彻底"]
text_lower = text.lower()
positive_count = sum(1 for word in positive_words if word in text_lower)
negative_count = sum(1 for word in negative_words if word in text_lower)
intense_count = sum(1 for word in intense_words if word in text_lower)
base_emotion = (positive_count - negative_count) / max(len(text.split()), 1)
intensity_multiplier = 1 + (intense_count * 0.5)
return base_emotion * intensity_multiplier
def _calculate_emotion_trend(self, sequence: List[float]) -> str:
"""计算情绪趋势"""
if len(sequence) < 2:
return "neutral"
# 简单线性回归估算
if len(sequence) < 2:
return 0.0
# 计算斜率
n = len(sequence)
sum_x = sum(range(n))
sum_y = sum(sequence)
sum_xy = sum(i * sequence[i] for i in range(n))
sum_x2 = sum(i * i for i in range(n))
slope = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x * sum_x)
if slope > 0.1:
return "escalating"
elif slope < -0.1:
return "de_escalating"
else:
return "stable"
def _detect_emotion_turning_points(self, sequence: List[float]) -> List[int]:
"""检测情绪拐点"""
if len(sequence) < 3:
return []
turning_points = []
for i in range(1, len(sequence) - 1):
prev_val = sequence[i-1]
curr_val = sequence[i]
next_val = sequence[i+1]
# 检测峰值和谷值
if (curr_val > prev_val and curr_val > next_val) or \
(curr_val < prev_val and curr_val < next_val):
turning_points.append(i)
return turning_points

View File

@@ -0,0 +1,733 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
优化的辩论流程控制系统 v2.1.0
改进阶段转换和发言权争夺逻辑
"""
import asyncio
import json
import time
from datetime import datetime, timedelta
from typing import Dict, List, Any, Optional, Tuple, Callable
from dataclasses import dataclass, field
from enum import Enum
from collections import defaultdict, deque
import threading
import queue
class DebateStage(Enum):
"""辩论阶段枚举"""
QI = "" # 八仙按先天八卦顺序
CHENG = "" # 雁阵式承接
ZHUAN = "" # 自由辩论36次handoff
HE = "" # 交替总结
class FlowControlMode(Enum):
"""流程控制模式"""
STRICT = "严格模式" # 严格按规则执行
ADAPTIVE = "自适应模式" # 根据辩论质量调整
DYNAMIC = "动态模式" # 实时响应辩论状态
class TransitionTrigger(Enum):
"""阶段转换触发条件"""
TIME_BASED = "时间触发"
PROGRESS_BASED = "进度触发"
QUALITY_BASED = "质量触发"
CONSENSUS_BASED = "共识触发"
EMERGENCY = "紧急触发"
class SpeakerSelectionStrategy(Enum):
"""发言者选择策略"""
PRIORITY_ALGORITHM = "优先级算法"
ROUND_ROBIN = "轮询"
RANDOM_WEIGHTED = "加权随机"
CONTEXT_AWARE = "上下文感知"
COMPETITIVE = "竞争模式"
@dataclass
class FlowControlConfig:
"""流程控制配置"""
mode: FlowControlMode = FlowControlMode.ADAPTIVE
transition_triggers: List[TransitionTrigger] = field(default_factory=lambda: [TransitionTrigger.PROGRESS_BASED, TransitionTrigger.QUALITY_BASED])
speaker_selection_strategy: SpeakerSelectionStrategy = SpeakerSelectionStrategy.CONTEXT_AWARE
min_stage_duration: int = 60 # 秒
max_stage_duration: int = 900 # 秒
quality_threshold: float = 0.6 # 质量阈值
participation_balance_threshold: float = 0.3 # 参与平衡阈值
emergency_intervention_enabled: bool = True
auto_stage_transition: bool = True
speaker_timeout: int = 30 # 发言超时时间
@dataclass
class StageMetrics:
"""阶段指标"""
start_time: datetime
duration: float = 0.0
speech_count: int = 0
quality_score: float = 0.0
participation_balance: float = 0.0
engagement_level: float = 0.0
topic_coherence: float = 0.0
conflict_intensity: float = 0.0
speaker_distribution: Dict[str, int] = field(default_factory=dict)
transition_readiness: float = 0.0
@dataclass
class SpeakerRequest:
"""发言请求"""
speaker: str
priority: float
timestamp: datetime
reason: str
urgency_level: int = 1 # 1-5
estimated_duration: int = 30 # 秒
topic_relevance: float = 1.0
@dataclass
class FlowEvent:
"""流程事件"""
event_type: str
timestamp: datetime
data: Dict[str, Any]
source: str
priority: int = 1
class OptimizedDebateFlowController:
"""优化的辩论流程控制器"""
def __init__(self, config: FlowControlConfig = None):
self.config = config or FlowControlConfig()
# 当前状态
self.current_stage = DebateStage.QI
self.stage_progress = 0
self.total_handoffs = 0
self.current_speaker: Optional[str] = None
self.debate_start_time = datetime.now()
# 阶段配置
self.stage_configs = {
DebateStage.QI: {
"max_progress": 8,
"min_duration": 120,
"max_duration": 600,
"speaker_order": ["吕洞宾", "何仙姑", "铁拐李", "汉钟离", "曹国舅", "韩湘子", "蓝采和", "张果老"],
"selection_strategy": SpeakerSelectionStrategy.ROUND_ROBIN
},
DebateStage.CHENG: {
"max_progress": 8,
"min_duration": 180,
"max_duration": 600,
"speaker_order": ["正1", "正2", "正3", "正4", "反1", "反2", "反3", "反4"],
"selection_strategy": SpeakerSelectionStrategy.ROUND_ROBIN
},
DebateStage.ZHUAN: {
"max_progress": 36,
"min_duration": 300,
"max_duration": 900,
"speaker_order": ["正1", "正2", "正3", "正4", "反1", "反2", "反3", "反4"],
"selection_strategy": SpeakerSelectionStrategy.CONTEXT_AWARE
},
DebateStage.HE: {
"max_progress": 8,
"min_duration": 120,
"max_duration": 480,
"speaker_order": ["反1", "正1", "反2", "正2", "反3", "正3", "反4", "正4"],
"selection_strategy": SpeakerSelectionStrategy.ROUND_ROBIN
}
}
# 阶段指标
self.stage_metrics: Dict[DebateStage, StageMetrics] = {}
self.current_stage_metrics = StageMetrics(start_time=datetime.now())
# 发言请求队列
self.speaker_request_queue = queue.PriorityQueue()
self.pending_requests: Dict[str, SpeakerRequest] = {}
# 事件系统
self.event_queue = queue.Queue()
self.event_handlers: Dict[str, List[Callable]] = defaultdict(list)
# 历史记录
self.debate_history: List[Dict] = []
self.stage_transition_history: List[Dict] = []
self.speaker_performance: Dict[str, Dict] = defaultdict(dict)
# 实时监控
self.monitoring_active = False
self.monitoring_thread: Optional[threading.Thread] = None
# 流程锁
self.flow_lock = threading.RLock()
# 初始化当前阶段指标
self._initialize_stage_metrics()
def _initialize_stage_metrics(self):
"""初始化阶段指标"""
self.current_stage_metrics = StageMetrics(
start_time=datetime.now(),
speaker_distribution={}
)
def get_current_speaker(self) -> Optional[str]:
"""获取当前发言者"""
with self.flow_lock:
config = self.stage_configs[self.current_stage]
strategy = config.get("selection_strategy", self.config.speaker_selection_strategy)
if strategy == SpeakerSelectionStrategy.ROUND_ROBIN:
return self._get_round_robin_speaker()
elif strategy == SpeakerSelectionStrategy.CONTEXT_AWARE:
return self._get_context_aware_speaker()
elif strategy == SpeakerSelectionStrategy.PRIORITY_ALGORITHM:
return self._get_priority_speaker()
elif strategy == SpeakerSelectionStrategy.COMPETITIVE:
return self._get_competitive_speaker()
else:
return self._get_round_robin_speaker()
def _get_round_robin_speaker(self) -> str:
"""轮询方式获取发言者"""
config = self.stage_configs[self.current_stage]
speaker_order = config["speaker_order"]
return speaker_order[self.stage_progress % len(speaker_order)]
def _get_context_aware_speaker(self) -> Optional[str]:
"""上下文感知方式获取发言者"""
# 检查是否有紧急发言请求
if not self.speaker_request_queue.empty():
try:
priority, request = self.speaker_request_queue.get_nowait()
if request.urgency_level >= 4: # 高紧急度
return request.speaker
else:
# 重新放回队列
self.speaker_request_queue.put((priority, request))
except queue.Empty:
pass
# 分析当前上下文
context = self._analyze_current_context()
# 根据上下文选择最合适的发言者
available_speakers = self.stage_configs[self.current_stage]["speaker_order"]
best_speaker = None
best_score = -1
for speaker in available_speakers:
score = self._calculate_speaker_context_score(speaker, context)
if score > best_score:
best_score = score
best_speaker = speaker
return best_speaker
def _get_priority_speaker(self) -> Optional[str]:
"""优先级算法获取发言者"""
# 这里可以集成现有的优先级算法
# 暂时使用简化版本
return self._get_context_aware_speaker()
def _get_competitive_speaker(self) -> Optional[str]:
"""竞争模式获取发言者"""
# 让发言者竞争发言权
if not self.speaker_request_queue.empty():
try:
priority, request = self.speaker_request_queue.get_nowait()
return request.speaker
except queue.Empty:
pass
return self._get_round_robin_speaker()
def request_speaking_turn(self, speaker: str, reason: str, urgency: int = 1,
estimated_duration: int = 30, topic_relevance: float = 1.0):
"""请求发言权"""
request = SpeakerRequest(
speaker=speaker,
priority=self._calculate_request_priority(speaker, reason, urgency, topic_relevance),
timestamp=datetime.now(),
reason=reason,
urgency_level=urgency,
estimated_duration=estimated_duration,
topic_relevance=topic_relevance
)
# 使用负优先级因为PriorityQueue是最小堆
self.speaker_request_queue.put((-request.priority, request))
self.pending_requests[speaker] = request
# 触发事件
self._emit_event("speaker_request", {
"speaker": speaker,
"reason": reason,
"urgency": urgency,
"priority": request.priority
})
def _calculate_request_priority(self, speaker: str, reason: str, urgency: int,
topic_relevance: float) -> float:
"""计算发言请求优先级"""
base_priority = urgency * 10
# 主题相关性加权
relevance_bonus = topic_relevance * 5
# 发言频率调整
speaker_count = self.current_stage_metrics.speaker_distribution.get(speaker, 0)
frequency_penalty = speaker_count * 2
# 时间因素
time_factor = 1.0
if self.current_speaker and self.current_speaker != speaker:
time_factor = 1.2 # 鼓励轮换
priority = (base_priority + relevance_bonus - frequency_penalty) * time_factor
return max(0.1, priority)
def _analyze_current_context(self) -> Dict[str, Any]:
"""分析当前辩论上下文"""
recent_speeches = self.debate_history[-5:] if self.debate_history else []
context = {
"stage": self.current_stage.value,
"progress": self.stage_progress,
"recent_speakers": [speech.get("speaker") for speech in recent_speeches],
"topic_drift": self._calculate_topic_drift(),
"emotional_intensity": self._calculate_emotional_intensity(),
"argument_balance": self._calculate_argument_balance(),
"time_pressure": self._calculate_time_pressure(),
"participation_balance": self._calculate_participation_balance()
}
return context
def _calculate_speaker_context_score(self, speaker: str, context: Dict[str, Any]) -> float:
"""计算发言者在当前上下文下的适合度分数"""
score = 0.0
# 避免连续发言
recent_speakers = context.get("recent_speakers", [])
if speaker in recent_speakers[-2:]:
score -= 10
# 参与平衡
speaker_count = self.current_stage_metrics.speaker_distribution.get(speaker, 0)
avg_count = sum(self.current_stage_metrics.speaker_distribution.values()) / max(1, len(self.current_stage_metrics.speaker_distribution))
if speaker_count < avg_count:
score += 5
# 队伍平衡
if self.current_stage == DebateStage.ZHUAN:
positive_count = sum(1 for s in recent_speakers if "" in s)
negative_count = sum(1 for s in recent_speakers if "" in s)
if "" in speaker and positive_count < negative_count:
score += 3
elif "" in speaker and negative_count < positive_count:
score += 3
# 时间压力响应
time_pressure = context.get("time_pressure", 0)
if time_pressure > 0.7 and speaker.endswith("1"): # 主力发言者
score += 5
# 检查发言请求
if speaker in self.pending_requests:
request = self.pending_requests[speaker]
score += request.urgency_level * 2
score += request.topic_relevance * 3
return score
def advance_stage(self, force: bool = False) -> bool:
"""推进辩论阶段"""
with self.flow_lock:
if not force and not self._should_advance_stage():
return False
# 记录当前阶段结束
self._finalize_current_stage()
# 转换到下一阶段
success = self._transition_to_next_stage()
if success:
# 初始化新阶段
self._initialize_new_stage()
# 触发事件
self._emit_event("stage_advanced", {
"from_stage": self.current_stage.value,
"to_stage": self.current_stage.value,
"progress": self.stage_progress,
"forced": force
})
return success
def _should_advance_stage(self) -> bool:
"""判断是否应该推进阶段"""
config = self.stage_configs[self.current_stage]
# 检查进度触发
if TransitionTrigger.PROGRESS_BASED in self.config.transition_triggers:
if self.stage_progress >= config["max_progress"] - 1:
return True
# 检查时间触发
if TransitionTrigger.TIME_BASED in self.config.transition_triggers:
stage_duration = (datetime.now() - self.current_stage_metrics.start_time).total_seconds()
if stage_duration >= config.get("max_duration", 600):
return True
# 检查质量触发
if TransitionTrigger.QUALITY_BASED in self.config.transition_triggers:
if (self.current_stage_metrics.quality_score >= self.config.quality_threshold and
self.stage_progress >= config["max_progress"] // 2):
return True
# 检查共识触发
if TransitionTrigger.CONSENSUS_BASED in self.config.transition_triggers:
if self.current_stage_metrics.transition_readiness >= 0.8:
return True
return False
def _finalize_current_stage(self):
"""结束当前阶段"""
# 更新阶段指标
self.current_stage_metrics.duration = (datetime.now() - self.current_stage_metrics.start_time).total_seconds()
# 保存阶段指标
self.stage_metrics[self.current_stage] = self.current_stage_metrics
# 记录阶段转换历史
self.stage_transition_history.append({
"stage": self.current_stage.value,
"start_time": self.current_stage_metrics.start_time.isoformat(),
"duration": self.current_stage_metrics.duration,
"speech_count": self.current_stage_metrics.speech_count,
"quality_score": self.current_stage_metrics.quality_score,
"participation_balance": self.current_stage_metrics.participation_balance
})
def _transition_to_next_stage(self) -> bool:
"""转换到下一阶段"""
stage_transitions = {
DebateStage.QI: DebateStage.CHENG,
DebateStage.CHENG: DebateStage.ZHUAN,
DebateStage.ZHUAN: DebateStage.HE,
DebateStage.HE: None
}
next_stage = stage_transitions.get(self.current_stage)
if next_stage:
self.current_stage = next_stage
self.stage_progress = 0
return True
else:
# 辩论结束
self._emit_event("debate_finished", {
"total_duration": (datetime.now() - self.debate_start_time).total_seconds(),
"total_handoffs": self.total_handoffs,
"stages_completed": len(self.stage_metrics)
})
return False
def _initialize_new_stage(self):
"""初始化新阶段"""
self._initialize_stage_metrics()
# 清空发言请求队列
while not self.speaker_request_queue.empty():
try:
self.speaker_request_queue.get_nowait()
except queue.Empty:
break
self.pending_requests.clear()
def record_speech(self, speaker: str, message: str, metadata: Dict[str, Any] = None):
"""记录发言"""
with self.flow_lock:
speech_record = {
"timestamp": datetime.now().isoformat(),
"stage": self.current_stage.value,
"stage_progress": self.stage_progress,
"speaker": speaker,
"message": message,
"total_handoffs": self.total_handoffs,
"metadata": metadata or {}
}
self.debate_history.append(speech_record)
self.current_speaker = speaker
# 更新阶段指标
self._update_stage_metrics(speaker, message)
# 如果是转阶段增加handoff计数
if self.current_stage == DebateStage.ZHUAN:
self.total_handoffs += 1
# 推进进度
self.stage_progress += 1
# 移除已完成的发言请求
if speaker in self.pending_requests:
del self.pending_requests[speaker]
# 触发事件
self._emit_event("speech_recorded", {
"speaker": speaker,
"stage": self.current_stage.value,
"progress": self.stage_progress
})
def _update_stage_metrics(self, speaker: str, message: str):
"""更新阶段指标"""
# 更新发言计数
self.current_stage_metrics.speech_count += 1
# 更新发言者分布
if speaker not in self.current_stage_metrics.speaker_distribution:
self.current_stage_metrics.speaker_distribution[speaker] = 0
self.current_stage_metrics.speaker_distribution[speaker] += 1
# 计算参与平衡度
self.current_stage_metrics.participation_balance = self._calculate_participation_balance()
# 计算质量分数(简化版本)
self.current_stage_metrics.quality_score = self._calculate_quality_score(message)
# 计算转换准备度
self.current_stage_metrics.transition_readiness = self._calculate_transition_readiness()
def _calculate_topic_drift(self) -> float:
"""计算主题偏移度"""
# 简化实现
return 0.1
def _calculate_emotional_intensity(self) -> float:
"""计算情绪强度"""
# 简化实现
return 0.5
def _calculate_argument_balance(self) -> float:
"""计算论点平衡度"""
# 简化实现
return 0.7
def _calculate_time_pressure(self) -> float:
"""计算时间压力"""
config = self.stage_configs[self.current_stage]
stage_duration = (datetime.now() - self.current_stage_metrics.start_time).total_seconds()
max_duration = config.get("max_duration", 600)
return min(1.0, stage_duration / max_duration)
def _calculate_participation_balance(self) -> float:
"""计算参与平衡度"""
if not self.current_stage_metrics.speaker_distribution:
return 1.0
counts = list(self.current_stage_metrics.speaker_distribution.values())
if not counts:
return 1.0
avg_count = sum(counts) / len(counts)
variance = sum((count - avg_count) ** 2 for count in counts) / len(counts)
# 归一化到0-1范围
balance = 1.0 / (1.0 + variance)
return balance
def _calculate_quality_score(self, message: str) -> float:
"""计算质量分数"""
# 简化实现,基于消息长度和关键词
base_score = min(1.0, len(message) / 100)
# 检查关键词
quality_keywords = ["因为", "所以", "但是", "然而", "数据", "证据", "分析"]
keyword_bonus = sum(0.1 for keyword in quality_keywords if keyword in message)
return min(1.0, base_score + keyword_bonus)
def _calculate_transition_readiness(self) -> float:
"""计算转换准备度"""
# 综合多个因素
progress_factor = self.stage_progress / self.stage_configs[self.current_stage]["max_progress"]
quality_factor = self.current_stage_metrics.quality_score
balance_factor = self.current_stage_metrics.participation_balance
readiness = (progress_factor * 0.4 + quality_factor * 0.3 + balance_factor * 0.3)
return min(1.0, readiness)
def _emit_event(self, event_type: str, data: Dict[str, Any]):
"""发出事件"""
event = FlowEvent(
event_type=event_type,
timestamp=datetime.now(),
data=data,
source="flow_controller"
)
self.event_queue.put(event)
# 调用事件处理器
for handler in self.event_handlers.get(event_type, []):
try:
handler(event)
except Exception as e:
print(f"事件处理器错误: {e}")
def add_event_handler(self, event_type: str, handler: Callable):
"""添加事件处理器"""
self.event_handlers[event_type].append(handler)
def get_flow_status(self) -> Dict[str, Any]:
"""获取流程状态"""
return {
"current_stage": self.current_stage.value,
"stage_progress": self.stage_progress,
"total_handoffs": self.total_handoffs,
"current_speaker": self.current_speaker,
"stage_metrics": {
"duration": (datetime.now() - self.current_stage_metrics.start_time).total_seconds(),
"speech_count": self.current_stage_metrics.speech_count,
"quality_score": self.current_stage_metrics.quality_score,
"participation_balance": self.current_stage_metrics.participation_balance,
"transition_readiness": self.current_stage_metrics.transition_readiness
},
"pending_requests": len(self.pending_requests),
"config": {
"mode": self.config.mode.value,
"auto_transition": self.config.auto_stage_transition,
"quality_threshold": self.config.quality_threshold
}
}
def save_flow_data(self, filename: str = "debate_flow_data.json"):
"""保存流程数据"""
flow_data = {
"config": {
"mode": self.config.mode.value,
"transition_triggers": [t.value for t in self.config.transition_triggers],
"speaker_selection_strategy": self.config.speaker_selection_strategy.value,
"quality_threshold": self.config.quality_threshold,
"auto_stage_transition": self.config.auto_stage_transition
},
"current_state": {
"stage": self.current_stage.value,
"progress": self.stage_progress,
"total_handoffs": self.total_handoffs,
"current_speaker": self.current_speaker,
"debate_start_time": self.debate_start_time.isoformat()
},
"stage_metrics": {
stage.value: {
"start_time": metrics.start_time.isoformat(),
"duration": metrics.duration,
"speech_count": metrics.speech_count,
"quality_score": metrics.quality_score,
"participation_balance": metrics.participation_balance,
"speaker_distribution": metrics.speaker_distribution
} for stage, metrics in self.stage_metrics.items()
},
"current_stage_metrics": {
"start_time": self.current_stage_metrics.start_time.isoformat(),
"duration": (datetime.now() - self.current_stage_metrics.start_time).total_seconds(),
"speech_count": self.current_stage_metrics.speech_count,
"quality_score": self.current_stage_metrics.quality_score,
"participation_balance": self.current_stage_metrics.participation_balance,
"speaker_distribution": self.current_stage_metrics.speaker_distribution,
"transition_readiness": self.current_stage_metrics.transition_readiness
},
"debate_history": self.debate_history,
"stage_transition_history": self.stage_transition_history,
"timestamp": datetime.now().isoformat()
}
with open(filename, 'w', encoding='utf-8') as f:
json.dump(flow_data, f, ensure_ascii=False, indent=2)
print(f"✅ 流程数据已保存到 {filename}")
def main():
"""测试优化的辩论流程控制系统"""
print("🎭 测试优化的辩论流程控制系统")
print("=" * 50)
# 创建配置
config = FlowControlConfig(
mode=FlowControlMode.ADAPTIVE,
transition_triggers=[TransitionTrigger.PROGRESS_BASED, TransitionTrigger.QUALITY_BASED],
speaker_selection_strategy=SpeakerSelectionStrategy.CONTEXT_AWARE,
auto_stage_transition=True
)
# 创建流程控制器
controller = OptimizedDebateFlowController(config)
# 添加事件处理器
def on_stage_advanced(event):
print(f"🎭 阶段转换: {event.data}")
def on_speech_recorded(event):
print(f"🗣️ 发言记录: {event.data['speaker']}{event.data['stage']} 阶段")
controller.add_event_handler("stage_advanced", on_stage_advanced)
controller.add_event_handler("speech_recorded", on_speech_recorded)
# 模拟辩论流程
test_speeches = [
("吕洞宾", "我认为AI投资具有巨大的潜力和机会。"),
("何仙姑", "但我们也需要考虑其中的风险因素。"),
("铁拐李", "数据显示AI行业的增长率确实很高。"),
("汉钟离", "然而市场波动性也不容忽视。")
]
print("\n📋 开始模拟辩论流程")
print("-" * 30)
for i, (speaker, message) in enumerate(test_speeches):
print(f"\n{i+1} 轮发言:")
# 获取当前发言者
current_speaker = controller.get_current_speaker()
print(f"推荐发言者: {current_speaker}")
# 记录发言
controller.record_speech(speaker, message)
# 显示流程状态
status = controller.get_flow_status()
print(f"当前状态: {status['current_stage']} 阶段,进度 {status['stage_progress']}")
print(f"质量分数: {status['stage_metrics']['quality_score']:.3f}")
print(f"参与平衡: {status['stage_metrics']['participation_balance']:.3f}")
# 检查是否需要推进阶段
if controller._should_advance_stage():
print("🔄 准备推进到下一阶段")
controller.advance_stage()
# 测试发言请求
print("\n📢 测试发言请求系统")
print("-" * 30)
controller.request_speaking_turn("正1", "需要反驳对方观点", urgency=4, topic_relevance=0.9)
controller.request_speaking_turn("反2", "补充论据", urgency=2, topic_relevance=0.7)
next_speaker = controller.get_current_speaker()
print(f"基于请求的下一位发言者: {next_speaker}")
# 保存数据
controller.save_flow_data("test_flow_data.json")
print("\n✅ 测试完成")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,335 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
太公心易 - 起承转合辩论系统
基于先天八卦的八仙辩论架构
"""
import asyncio
import json
from datetime import datetime
from typing import Dict, List, Any, Optional
from dataclasses import dataclass
from enum import Enum
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from enhanced_priority_algorithm import EnhancedPriorityAlgorithm, SpeechAnalysis
class DebateStage(Enum):
"""辩论阶段枚举"""
QI = "" # 八仙按先天八卦顺序
CHENG = "" # 雁阵式承接
ZHUAN = "" # 自由辩论36次handoff
HE = "" # 交替总结
@dataclass
class Speaker:
"""发言者数据类"""
name: str
role: str
team: str # "positive" or "negative"
bagua_position: Optional[int] = None # 八卦位置0-7
@dataclass
class DebateContext:
"""辩论上下文"""
current_stage: DebateStage
stage_progress: int
total_handoffs: int
current_speaker: Optional[str] = None
last_message: Optional[str] = None
debate_history: List[Dict] = None
last_priority_analysis: Optional[Dict[str, Any]] = None
class QiChengZhuanHeDebateSystem:
"""起承转合辩论系统"""
def __init__(self):
# 八仙配置(按先天八卦顺序)
self.baxian_speakers = {
"吕洞宾": Speaker("吕洞宾", "剑仙投资顾问", "neutral", 0), # 乾
"何仙姑": Speaker("何仙姑", "慈悲风控专家", "neutral", 1), # 兑
"铁拐李": Speaker("铁拐李", "逆向思维专家", "neutral", 2), # 离
"汉钟离": Speaker("汉钟离", "平衡协调者", "neutral", 3), # 震
"蓝采和": Speaker("蓝采和", "创新思维者", "neutral", 4), # 巽
"张果老": Speaker("张果老", "历史智慧者", "neutral", 5), # 坎
"韩湘子": Speaker("韩湘子", "艺术感知者", "neutral", 6), # 艮
"曹国舅": Speaker("曹国舅", "实务执行者", "neutral", 7) # 坤
}
# 雁阵队伍配置
self.goose_formation = {
"positive": ["正1", "正2", "正3", "正4"],
"negative": ["反1", "反2", "反3", "反4"]
}
# 辩论状态
self.context = DebateContext(
current_stage=DebateStage.QI,
stage_progress=0,
total_handoffs=0,
debate_history=[]
)
# 阶段配置
self.stage_configs = {
DebateStage.QI: {
"duration": "8-10分钟",
"max_progress": 8, # 八仙轮流发言
"description": "八仙按先天八卦顺序阐述观点"
},
DebateStage.CHENG: {
"duration": "8-10分钟",
"max_progress": 8, # 正反各4人
"description": "雁阵式承接,总体阐述+讥讽"
},
DebateStage.ZHUAN: {
"duration": "12-15分钟",
"max_progress": 36, # 36次handoff
"description": "自由辩论,优先级算法决定发言"
},
DebateStage.HE: {
"duration": "8-10分钟",
"max_progress": 8, # 交替总结
"description": "交替总结,最终论证"
}
}
# 增强版优先级算法
self.priority_algorithm = EnhancedPriorityAlgorithm()
# 记忆系统
self.memory_system = DebateMemorySystem()
def get_current_speaker(self) -> str:
"""获取当前发言者"""
stage = self.context.current_stage
progress = self.context.stage_progress
if stage == DebateStage.QI:
return self._get_bagua_speaker(progress)
elif stage == DebateStage.CHENG:
return self._get_goose_formation_speaker(progress)
elif stage == DebateStage.ZHUAN:
return self._get_priority_speaker()
elif stage == DebateStage.HE:
return self._get_alternating_speaker(progress)
return "未知发言者"
def _get_bagua_speaker(self, progress: int) -> str:
"""获取八卦顺序发言者"""
bagua_sequence = ["吕洞宾", "何仙姑", "铁拐李", "汉钟离", "蓝采和", "张果老", "韩湘子", "曹国舅"]
return bagua_sequence[progress % 8]
def _get_goose_formation_speaker(self, progress: int) -> str:
"""获取雁阵发言者"""
if progress < 4:
# 正方雁阵
return self.goose_formation["positive"][progress]
else:
# 反方雁阵
return self.goose_formation["negative"][progress - 4]
def _get_priority_speaker(self) -> str:
"""获取优先级发言者(转阶段)"""
available_speakers = ["正1", "正2", "正3", "正4", "反1", "反2", "反3", "反4"]
# 构建上下文
context = {
"current_stage": self.context.current_stage.value,
"stage_progress": self.context.stage_progress,
"max_progress": self.stage_configs[self.context.current_stage]["max_progress"],
"time_remaining": max(0.1, 1.0 - (self.context.stage_progress / self.stage_configs[self.context.current_stage]["max_progress"])),
"topic_keywords": ["投资", "AI", "风险", "收益"], # 可配置
"positive_team_score": 0.5, # 可动态计算
"negative_team_score": 0.5, # 可动态计算
"positive_recent_speeches": len([h for h in self.context.debate_history[-10:] if "" in h.get("speaker", "")]),
"negative_recent_speeches": len([h for h in self.context.debate_history[-10:] if "" in h.get("speaker", "")])
}
# 获取最近发言历史
recent_speeches = self.context.debate_history[-10:] if self.context.debate_history else []
next_speaker, score, analysis = self.priority_algorithm.get_next_speaker(
available_speakers, context, recent_speeches
)
# 记录分析结果
self.context.last_priority_analysis = {
"recommended_speaker": next_speaker,
"priority_score": score,
"analysis": analysis,
"timestamp": datetime.now().isoformat()
}
return next_speaker
def _get_alternating_speaker(self, progress: int) -> str:
"""获取交替总结发言者"""
alternating_sequence = ["反1", "正1", "反2", "正2", "反3", "正3", "反4", "正4"]
return alternating_sequence[progress % 8]
def advance_stage(self):
"""推进辩论阶段"""
current_config = self.stage_configs[self.context.current_stage]
if self.context.stage_progress >= current_config["max_progress"] - 1:
# 当前阶段完成,进入下一阶段
self._transition_to_next_stage()
else:
# 当前阶段继续
self.context.stage_progress += 1
def _transition_to_next_stage(self):
"""转换到下一阶段"""
stage_transitions = {
DebateStage.QI: DebateStage.CHENG,
DebateStage.CHENG: DebateStage.ZHUAN,
DebateStage.ZHUAN: DebateStage.HE,
DebateStage.HE: None # 辩论结束
}
next_stage = stage_transitions[self.context.current_stage]
if next_stage:
self.context.current_stage = next_stage
self.context.stage_progress = 0
print(f"🎭 辩论进入{next_stage.value}阶段")
else:
print("🎉 辩论结束!")
def record_speech(self, speaker: str, message: str):
"""记录发言"""
speech_record = {
"timestamp": datetime.now().isoformat(),
"stage": self.context.current_stage.value,
"stage_progress": self.context.stage_progress,
"speaker": speaker,
"message": message,
"total_handoffs": self.context.total_handoffs
}
self.context.debate_history.append(speech_record)
self.context.last_message = message
self.context.current_speaker = speaker
# 更新记忆系统
self.memory_system.store_speech(speaker, message, self.context)
# 如果是转阶段增加handoff计数
if self.context.current_stage == DebateStage.ZHUAN:
self.context.total_handoffs += 1
def get_stage_info(self) -> Dict[str, Any]:
"""获取当前阶段信息"""
stage = self.context.current_stage
config = self.stage_configs[stage]
return {
"current_stage": stage.value,
"stage_progress": self.context.stage_progress,
"max_progress": config["max_progress"],
"description": config["description"],
"current_speaker": self.get_current_speaker(),
"total_handoffs": self.context.total_handoffs
}
def save_debate_state(self, filename: str = "debate_state.json"):
"""保存辩论状态"""
state_data = {
"context": {
"current_stage": self.context.current_stage.value,
"stage_progress": self.context.stage_progress,
"total_handoffs": self.context.total_handoffs,
"current_speaker": self.context.current_speaker,
"last_message": self.context.last_message
},
"debate_history": self.context.debate_history,
"memory_data": self.memory_system.get_memory_data()
}
with open(filename, 'w', encoding='utf-8') as f:
json.dump(state_data, f, ensure_ascii=False, indent=2)
print(f"💾 辩论状态已保存到 {filename}")
# 旧的PriorityAlgorithm类已被EnhancedPriorityAlgorithm替换
class DebateMemorySystem:
"""辩论记忆系统"""
def __init__(self):
self.speaker_memories = {}
self.debate_memories = []
def store_speech(self, speaker: str, message: str, context: DebateContext):
"""存储发言记忆"""
if speaker not in self.speaker_memories:
self.speaker_memories[speaker] = []
memory_entry = {
"timestamp": datetime.now().isoformat(),
"stage": context.current_stage.value,
"message": message,
"context": {
"stage_progress": context.stage_progress,
"total_handoffs": context.total_handoffs
}
}
self.speaker_memories[speaker].append(memory_entry)
self.debate_memories.append(memory_entry)
def get_speaker_memory(self, speaker: str, limit: int = 5) -> List[Dict]:
"""获取发言者记忆"""
if speaker in self.speaker_memories:
return self.speaker_memories[speaker][-limit:]
return []
def get_memory_data(self) -> Dict[str, Any]:
"""获取记忆数据"""
return {
"speaker_memories": self.speaker_memories,
"debate_memories": self.debate_memories
}
def main():
"""主函数 - 测试起承转合辩论系统"""
print("🚀 太公心易 - 起承转合辩论系统")
print("=" * 60)
# 创建辩论系统
debate_system = QiChengZhuanHeDebateSystem()
# 测试各阶段
test_messages = [
"起:八仙按先天八卦顺序阐述观点",
"承:雁阵式承接,总体阐述+讥讽",
"自由辩论36次handoff",
"合:交替总结,最终论证"
]
for i, message in enumerate(test_messages):
stage_info = debate_system.get_stage_info()
current_speaker = debate_system.get_current_speaker()
print(f"\n🎭 当前阶段: {stage_info['current_stage']}")
print(f"📊 进度: {stage_info['stage_progress'] + 1}/{stage_info['max_progress']}")
print(f"🗣️ 发言者: {current_speaker}")
print(f"💬 消息: {message}")
# 记录发言
debate_system.record_speech(current_speaker, message)
# 推进阶段
debate_system.advance_stage()
# 保存状态
debate_system.save_debate_state()
print("\n✅ 起承转合辩论系统测试完成!")
if __name__ == "__main__":
main()