python_两个大模型辩论并生成报告
·
import time
import json
import requests
from typing import List, Dict, Optional
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
# ===================== 工作流配置(两个不同模型的工作流) =====================
# Agent A:对接 Azure OpenAI GPT5.2 的工作流
AGENT_A_CONFIG = {
"name": "OpenClaw 支持者 (Azure OpenAI GPT5.2)",
"stance": "OpenClaw 是下一代智能自动化技术,在复杂场景中具备不可替代的优势,与RPA互补而非替代",
"core_arguments": [
"微服务架构适配复杂异构系统",
"多模态AI处理非结构化数据",
"长期维护成本更低",
"适配大型企业复杂场景"
],
"workflow": {
"api_url": "https://power-api.yingdao.com/oapi/power/v1/rest/flow/4fa38143-da21-4104-b4b2-93d2e5671ec6/execute", # A的工作流ID
"headers": {
"Authorization": "Bearer XXX", # A的鉴权Token
"Content-Type": "application/json"
},
"timeout": 60 # 请求超时时间
},
"debate_params": {
"temperature": 0.8,
"max_tokens": 500
}
}
# Agent B:对接火山引擎豆包 seed1.6 的工作流
AGENT_B_CONFIG = {
"name": "RPA 支持者 (火山引擎豆包 seed1.6)",
"stance": "RPA仍是企业自动化主流,成熟生态和低成本优势不可替代,OpenClaw是补充而非替代",
"core_arguments": [
"市场成熟度高,生态完善",
"实施成本低,落地速度快",
"规则驱动更稳定可控",
"适配80%标准化流程场景"
],
"workflow": {
"api_url": "https://power-api.yingdao.com/oapi/power/v1/rest/flow/1ff93694-2476-49e8-91f2-b2a8d7247058/execute", # B的工作流ID
"headers": {
"Authorization": "Bearer xxx", # B的鉴权Token
"Content-Type": "application/json"
},
"timeout": 60
},
"debate_params": {
"temperature": 0.6,
"max_tokens": 500
}
}
# 辩论规则
DEBATE_ROUNDS = 1
# ===================== 新增Word报告生成类 =====================
class WordReportGenerator:
"""Word报告生成器 - 生成结构化的辩论报告"""
def __init__(self, filename: str = "辩论报告.docx"):
self.doc = Document()
self.filename = filename
# 设置文档样式
self._setup_document_style()
def _setup_document_style(self):
"""设置文档基础样式(中文适配)"""
# 设置默认字体为宋体
style = self.doc.styles['Normal']
style.font.name = '宋体'
style._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
style.font.size = Pt(11)
def add_title(self, title: str):
"""添加文档标题"""
title_para = self.doc.add_heading(title, level=0)
title_para.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 设置标题字体
for run in title_para.runs:
run.font.name = '黑体'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
run.font.size = Pt(16)
def add_debate_metadata(self, agent_a_name: str, agent_b_name: str):
"""添加辩论元信息(参与方、时间)"""
meta_para = self.doc.add_paragraph()
meta_para.add_run(f"辩论主题:OpenClaw与RPA的竞争合作关系\n").bold = True
meta_para.add_run(f"辩论双方:{agent_a_name} VS {agent_b_name}\n")
meta_para.add_run(f"辩论时间:{time.strftime('%Y年%m月%d日 %H:%M:%S')}\n")
meta_para.add_run(f"辩论轮次:{DEBATE_ROUNDS + 1}轮(1轮开场 + {DEBATE_ROUNDS}轮交锋)")
meta_para.space_after = Pt(12)
def add_debate_records(self, records: List[Dict]):
"""添加完整的辩论记录(按轮次结构化)"""
# 添加辩论记录标题
self.doc.add_heading("一、完整辩论记录", level=1)
# 分类整理记录(开场 + 交锋)
opening_round = records[:2] # 前两条是开场立论
debate_rounds = records[2:] # 后面是交锋内容
# 1. 开场立论部分
self.doc.add_heading("1. 开场立论", level=2)
for i, record in enumerate(opening_round, 1):
self._add_speech_record(f"发言人{i}", record)
# 2. 多轮交锋部分
for round_num in range(1, DEBATE_ROUNDS + 1):
self.doc.add_heading(f"2. 第{round_num}轮交锋", level=2)
# 每轮有两条记录(A反驳B,B反驳A)
start_idx = (round_num - 1) * 2
end_idx = start_idx + 2
round_records = debate_rounds[start_idx:end_idx]
for i, record in enumerate(round_records, 1):
self._add_speech_record(f"交锋{i}", record)
def _add_speech_record(self, label: str, record: Dict):
"""添加单条发言记录"""
# 发言人信息
speaker_para = self.doc.add_paragraph()
speaker_para.add_run(f"{label} - {record['speaker']}:").bold = True
speaker_para.space_after = Pt(6)
# 发言内容
content_para = self.doc.add_paragraph(record['content'])
content_para.space_after = Pt(12)
content_para.line_spacing = 1.5 # 设置行间距
def add_summary_report(self, summary: str):
"""添加总结报告"""
self.doc.add_heading("二、辩论总结报告", level=1)
summary_para = self.doc.add_paragraph(summary)
summary_para.line_spacing = 1.5
summary_para.space_after = Pt(12)
def save_document(self):
"""保存Word文档"""
self.doc.save(self.filename)
print(f"\n📄 Word报告已保存:{self.filename}")
class WorkflowClient:
"""工作流客户端 - 封装你的API调用逻辑"""
def __init__(self, workflow_config: Dict):
self.api_url = workflow_config["api_url"]
self.headers = workflow_config["headers"]
self.timeout = workflow_config.get("timeout", 30)
def call_workflow(self, prompt: str) -> str:
"""调用工作流API,返回模型生成的文本"""
try:
# 构造你指定的请求格式
payload = {
"input": {
"input_text_0": prompt # 工作流要求的输入字段
}
}
# 发送请求
response = requests.post(
self.api_url,
headers=self.headers,
json=payload,
timeout=self.timeout
)
# 检查响应状态
response.raise_for_status()
result = response.json()
# 解析结果(关键:根据你的工作流返回格式调整)
# 这里假设工作流返回的结构是 {"output": {"output_text_0": "辩论内容"}}
# 如果你的返回格式不同,修改下面这行即可
debate_content = result['data']['result']['output_text_0']
if not debate_content:
return f"【解析失败】工作流返回格式异常:{json.dumps(result, ensure_ascii=False)[:200]}"
return debate_content.strip()
except requests.exceptions.Timeout:
return f"【请求超时】调用工作流超时({self.timeout}秒)"
except requests.exceptions.RequestException as e:
return f"【请求失败】{str(e)}"
except Exception as e:
return f"【解析异常】{str(e)}"
class WorkflowDebateAgent:
"""基于工作流的独立辩论Agent"""
def __init__(self, config: Dict):
self.name = config["name"]
self.stance = config["stance"]
self.core_arguments = config["core_arguments"]
self.workflow_client = WorkflowClient(config["workflow"])
self.debate_params = config["debate_params"]
self.private_history = [] # 仅自己可见的辩论历史
def add_to_history(self, speaker: str, content: str):
"""添加辩论记录到私有历史"""
self.private_history.append({
"speaker": speaker,
"content": content,
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
})
def _build_prompt(self, prompt_template: str, **kwargs) -> str:
"""构建带角色和上下文的prompt"""
# 拼接历史上下文
history_text = "\n".join([
f"【{item['speaker']}】:{item['content']}"
for item in self.private_history
])
# 填充模板变量
prompt = prompt_template.format(
agent_name=self.name,
stance=self.stance,
core_arguments="\n- ".join(self.core_arguments),
history=history_text,
temperature=self.debate_params["temperature"],
max_tokens=self.debate_params["max_tokens"],
**kwargs
)
return prompt
def make_opening(self) -> str:
"""生成开场立论(调用工作流)"""
prompt_template = """
你是{agent_name},请围绕 OpenClaw 和 RPA 的竞争合作关系发表开场论述,要求:
1. 核心立场:{stance}
2. 结合核心论点:
- {core_arguments}
3. 内容要求:
- 明确阐述你支持的技术核心优势
- 客观提及与另一技术的竞争点
- 提出可能的合作方向
- 语言专业但易懂,逻辑清晰,300字左右
- 只输出辩论内容,不要额外解释或开场白
4. 生成参数:temperature={temperature},max_tokens={max_tokens}
"""
# 生成prompt并调用工作流
prompt = self._build_prompt(prompt_template)
opening_content = self.workflow_client.call_workflow(prompt)
self.add_to_history(self.name, opening_content)
return opening_content
def refute(self, opponent_arg: str, round_num: int) -> str:
"""反驳对方论点(调用工作流)"""
prompt_template = """
【辩论背景】
你是{agent_name},核心立场:{stance}
已发生的辩论内容:
{history}
【本轮任务】
第{round_num}轮辩论,对方最新论点:
{opponent_arg}
请针对性反驳,要求:
1. 直击对方核心观点漏洞,不要泛泛而谈
2. 结合你的核心论点({core_arguments})提出新论据
3. 理性客观,不情绪化,200-300字
4. 只输出反驳内容,无其他文字
5. 生成参数:temperature={temperature},max_tokens={max_tokens}
"""
# 生成prompt并调用工作流
prompt = self._build_prompt(prompt_template, round_num=round_num, opponent_arg=opponent_arg)
refute_content = self.workflow_client.call_workflow(prompt)
self.add_to_history(self.name, refute_content)
return refute_content
class CrossWorkflowDebateManager:
"""跨工作流辩论管理器"""
def __init__(self, agent_a: WorkflowDebateAgent, agent_b: WorkflowDebateAgent):
self.agent_a = agent_a
self.agent_b = agent_b
self.public_record = [] # 公开的辩论记录
def _log_and_broadcast(self, speaker: str, content: str):
"""记录并广播发言(双方都添加到自己的历史)"""
self.public_record.append({
"speaker": speaker,
"content": content,
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
})
# 双方同步这条记录
self.agent_a.add_to_history(speaker, content)
self.agent_b.add_to_history(speaker, content)
# 打印输出
print(f"\n📢 【{speaker}】")
print(content,"\n")
# print("-" * 120)
time.sleep(3) # 工作流调用可能较慢,增加间隔
def run_debate(self) -> Dict:
"""运行跨工作流的双模型辩论"""
print(f"=== 跨平台辩论:{self.agent_a.name} vs {self.agent_b.name} ===\n")
# 第一轮:开场立论
print(f"===== 第1轮 - 开场立论 =====")
print(f"🤔 {self.agent_a.name} 正在生成开场论述...")
a_opening = self.agent_a.make_opening()
self._log_and_broadcast(self.agent_a.name, a_opening)
print(f"🤔 {self.agent_b.name} 正在生成开场论述...")
b_opening = self.agent_b.make_opening()
self._log_and_broadcast(self.agent_b.name, b_opening)
# 多轮交锋
last_a_arg = a_opening
last_b_arg = b_opening
for round_num in range(1, DEBATE_ROUNDS + 1):
print(f"\n===== 第{round_num+1}轮 - 交锋 =====")
# A反驳B
print(f"🤔 {self.agent_a.name} 正在反驳对方论点...")
a_refute = self.agent_a.refute(last_b_arg, round_num)
self._log_and_broadcast(self.agent_a.name, a_refute)
last_a_arg = a_refute
# B反驳A
print(f"🤔 {self.agent_b.name} 正在反驳对方论点...")
b_refute = self.agent_b.refute(last_a_arg, round_num)
self._log_and_broadcast(self.agent_b.name, b_refute)
last_b_arg = b_refute
# 生成总结报告(可选:调用其中一个工作流或独立模型)
summary = self._generate_summary()
print(f"\n===== 辩论总结报告 =====")
print(summary)
return {
"debate_record": self.public_record,
"summary_report": summary,
"agent_a": self.agent_a.name,
"agent_b": self.agent_b.name
}
def _generate_summary(self) -> str:
"""生成总结报告(调用Agent A的工作流)"""
record_text = "\n".join([
f"【{item['speaker']}】:{item['content']}"
for item in self.public_record
])
summary_prompt = f"""
请作为中立裁判,总结以下辩论的核心内容(OpenClaw vs RPA):
{record_text}
报告结构:
1. 核心分歧点(双方的主要争议)
2. 共识点(双方认可的内容)
3. 竞争合作建议(基于双方论点的客观建议)
4. 结论(总结整体关系)
要求:客观中立,500-600字,仅输出报告内容,无其他文字。
"""
# 调用Agent A的工作流生成总结
summary = self.agent_a.workflow_client.call_workflow(summary_prompt)
return summary
# ===================== 运行辩论 =====================
if __name__ == "__main__":
try:
# 创建两个基于工作流的Agent
agent_a = WorkflowDebateAgent(AGENT_A_CONFIG)
agent_b = WorkflowDebateAgent(AGENT_B_CONFIG)
# 启动辩论
manager = CrossWorkflowDebateManager(agent_a, agent_b)
debate_result = manager.run_debate()
# 生成Word报告
print("\n📝 正在生成Word报告...")
word_generator = WordReportGenerator("OpenClaw vs RPA 辩论报告.docx")
# 添加标题和元信息
word_generator.add_title("OpenClaw与RPA竞争合作关系辩论报告")
word_generator.add_debate_metadata(
agent_a_name=debate_result["agent_a"],
agent_b_name=debate_result["agent_b"]
)
# 添加完整辩论记录(每一轮的发言)
word_generator.add_debate_records(debate_result["debate_record"])
# 添加总结报告
word_generator.add_summary_report(debate_result["summary_report"])
# 保存Word文档
word_generator.save_document()
# 保存结果到文件
with open("cross_workflow_debate_report.json", "w", encoding="utf-8") as f:
json.dump(debate_result, f, ensure_ascii=False, indent=2)
print("\n✅ 跨工作流辩论完成!完整报告已保存到 cross_workflow_debate_report.json")
except Exception as e:
print(f"\n❌ 辩论执行失败:{str(e)}")
更多推荐

所有评论(0)