| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- """三种 Multi-Agent 模式的真实执行引擎 — 全部真实 LLM 调用"""
- import json, time, uuid
- from agent import Agent
- # ── Agent 定义 ──
- SUPERVISOR = Agent(
- name="Supervisor", icon="👔",
- system_prompt=(
- "你是多 Agent 团队的主管。你的职责是拆解任务、分配给专家、整合结果。\n\n"
- "你有两个专家:\n"
- "- Researcher: 信息搜索专家,擅长用 web_search 搜索真实信息\n"
- "- Coder: 数据分析专家,擅长用 calculator 和 run_python 做计算和分析\n\n"
- "工作流程:\n"
- "1. 收到任务后,先分析需要哪些子任务\n"
- "2. 把子任务分配给合适的专家(通过给专家发送清晰的指令)\n"
- "3. 收到专家结果后,整合成高质量的最终答案\n\n"
- "重要:你不要自己搜索或计算,必须委托给专家。你只负责调度和整合。"
- ),
- tool_names=[],
- )
- RESEARCHER = Agent(
- name="Researcher", icon="🔍",
- system_prompt=(
- "你是信息搜索专家。你的唯一工具是 web_search。\n\n"
- "规则:\n"
- "1. 收到任务后,用 web_search 搜索,只搜索 1-2 次,不要重复搜索\n"
- "2. 第一次搜索用核心关键词,第二次只在第一次结果不够时才搜\n"
- "3. 返回结构化的搜索结果,包含关键数据\n"
- "4. 不要编造数据,搜不到就说搜不到\n"
- "5. 搜索完成后立即返回结果,不要继续搜索"
- ),
- tool_names=["web_search"],
- )
- CODER = Agent(
- name="Coder", icon="💻",
- system_prompt=(
- "你是数据分析师。你的工具是 calculator 和 run_python。\n\n"
- "规则:\n"
- "1. 收到数据后,用 calculator 做简单计算,用 run_python 做复杂分析\n"
- "2. 返回清晰的计算结果和分析结论\n"
- "3. 数据来自上一步的搜索结果,不要自己搜索\n"
- "4. 如果需要生成报告,用 run_python 格式化输出"
- ),
- tool_names=["calculator", "run_python"],
- )
- DEBATE_PRO = Agent(
- name="正方辩手", icon="🟢",
- system_prompt=(
- "你是正方辩手。针对给定辩题,你需要搜索资料并提出支持性论点。\n\n"
- "规则:\n"
- "1. 用 web_search 搜索真实案例和数据支持你的论点\n"
- "2. 每个论点要有事实依据,不能空谈\n"
- "3. 提出 2-3 个核心论点,每个论点配真实数据\n"
- "4. 论证要有力,语言要有说服力"
- ),
- tool_names=["web_search"],
- )
- DEBATE_CON = Agent(
- name="反方辩手", icon="🔴",
- system_prompt=(
- "你是反方辩手。针对给定辩题,你需要搜索资料并提出反对性论点。\n\n"
- "规则:\n"
- "1. 用 web_search 搜索真实案例和数据支持你的论点\n"
- "2. 每个论点要有事实依据,不能空谈\n"
- "3. 提出 2-3 个核心论点,每个论点配真实数据\n"
- "4. 要有力反驳正方观点,论证要犀利"
- ),
- tool_names=["web_search"],
- )
- DEBATE_JUDGE = Agent(
- name="裁判", icon="⚖️",
- system_prompt=(
- "你是中立裁判,综合正反双方的论据做出评判。\n\n"
- "规则:\n"
- "1. 用 calculator 或 run_python 做数据验证\n"
- "2. 逐点评判双方论据的强弱\n"
- "3. 给出结论,说明胜方理由\n"
- "4. 保持客观,不偏袒任何一方"
- ),
- tool_names=["calculator", "run_python"],
- )
- PIPELINE_SEARCHER = Agent(
- name="搜索 Agent", icon="🔍",
- system_prompt=(
- "你是信息搜索专家。\n\n"
- "规则:\n"
- "1. 用 web_search 搜索任务所需的信息\n"
- "2. 搜索多个角度,确保信息全面\n"
- "3. 返回结构化的搜索结果,标注来源\n"
- "4. 如果一次搜索不够,可以多次搜索"
- ),
- tool_names=["web_search"],
- )
- PIPELINE_ANALYZER = Agent(
- name="分析 Agent", icon="📊",
- system_prompt=(
- "你是数据分析专家。\n\n"
- "规则:\n"
- "1. 接收搜索 Agent 的结果\n"
- "2. 用 run_python 做数据处理和对比分析\n"
- "3. 用 calculator 做数值计算\n"
- "4. 输出结构化的分析结论"
- ),
- tool_names=["calculator", "run_python"],
- )
- PIPELINE_REPORTER = Agent(
- name="报告 Agent", icon="📝",
- system_prompt=(
- "你是报告撰写专家。\n\n"
- "规则:\n"
- "1. 接收分析 Agent 的结论\n"
- "2. 用 run_python 生成格式化报告\n"
- "3. 报告要有:标题、摘要、正文、结论、建议\n"
- "4. 语言专业但易读"
- ),
- tool_names=["run_python"],
- )
- # ── 执行引擎 ──
- def _emit(emit, event_type, data):
- if emit:
- data["type"] = event_type
- data["timestamp"] = time.time()
- emit(data)
- def run_supervisor(query: str, emit=None) -> dict:
- """Supervisor 模式:主管拆任务 → Researcher + Coder → 主管整合"""
- trace_id = str(uuid.uuid4())[:8]
- t_start = time.time()
- def agent_emit(event_type, data):
- data["trace_id"] = trace_id
- data["mode"] = "supervisor"
- _emit(emit, "agent_event", data)
- # Step 1: Supervisor 分析任务
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "Supervisor", "icon": "👔", "action": "分析任务并拆解"})
- supervisor_analysis = SUPERVISOR.chat(
- [{"role": "user", "content": f"任务:{query}\n\n请分析这个任务,拆成子任务,说明每个子任务交给哪个专家。"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "Supervisor", "result": supervisor_analysis[:500]})
- # Step 2: Researcher 搜索信息
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "Researcher", "icon": "🔍", "action": "搜索信息"})
- research_result = RESEARCHER.chat(
- [{"role": "user", "content": f"请搜索以下任务所需的信息:\n{query}\n\n{supervisor_analysis}"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "Researcher", "result": research_result[:500]})
- # Step 3: Coder 分析计算
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "Coder", "icon": "💻", "action": "数据分析与计算"})
- coder_result = CODER.chat(
- [{"role": "user", "content": f"原始任务:{query}\n\n研究结果:\n{research_result}\n\n请基于以上数据做分析和计算。"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "Coder", "result": coder_result[:500]})
- # Step 4: Supervisor 整合
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "Supervisor", "icon": "👔", "action": "整合最终答案"})
- final_answer = SUPERVISOR.chat(
- [{"role": "user", "content": (
- f"原始任务:{query}\n\n"
- f"研究专家的结果:\n{research_result}\n\n"
- f"数据分析的结果:\n{coder_result}\n\n"
- f"请整合以上信息,给出最终的完整答案。"
- )}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "Supervisor", "result": final_answer[:800]})
- total_ms = int((time.time() - t_start) * 1000)
- _emit(emit, "trace_complete", {"trace_id": trace_id, "mode": "supervisor", "total_ms": total_ms})
- return {"trace_id": trace_id, "answer": final_answer, "total_ms": total_ms}
- def run_pipeline(query: str, emit=None) -> dict:
- """Pipeline 模式:搜索 → 分析 → 报告"""
- trace_id = str(uuid.uuid4())[:8]
- t_start = time.time()
- def agent_emit(event_type, data):
- data["trace_id"] = trace_id
- data["mode"] = "pipeline"
- _emit(emit, "agent_event", data)
- # Step 1: 搜索
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "搜索 Agent", "icon": "🔍", "action": "信息采集"})
- search_result = PIPELINE_SEARCHER.chat(
- [{"role": "user", "content": f"请搜索以下任务的信息:\n{query}"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "搜索 Agent", "result": search_result[:500]})
- # Step 2: 分析
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "分析 Agent", "icon": "📊", "action": "数据分析"})
- analysis_result = PIPELINE_ANALYZER.chat(
- [{"role": "user", "content": f"原始任务:{query}\n\n搜索结果:\n{search_result}\n\n请做数据分析。"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "分析 Agent", "result": analysis_result[:500]})
- # Step 3: 生成报告
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "报告 Agent", "icon": "📝", "action": "生成报告"})
- report = PIPELINE_REPORTER.chat(
- [{"role": "user", "content": f"原始任务:{query}\n\n分析结果:\n{analysis_result}\n\n请生成最终报告。"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "报告 Agent", "result": report[:800]})
- total_ms = int((time.time() - t_start) * 1000)
- _emit(emit, "trace_complete", {"trace_id": trace_id, "mode": "pipeline", "total_ms": total_ms})
- return {"trace_id": trace_id, "answer": report, "total_ms": total_ms}
- def run_debate(query: str, emit=None) -> dict:
- """Debate 模式:正方 → 反方 → 二次交锋 → 裁判"""
- trace_id = str(uuid.uuid4())[:8]
- t_start = time.time()
- def agent_emit(event_type, data):
- data["trace_id"] = trace_id
- data["mode"] = "debate"
- _emit(emit, "agent_event", data)
- # Step 1: 正方立论
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "正方辩手", "icon": "🟢", "action": "立论陈词"})
- pro_round1 = DEBATE_PRO.chat(
- [{"role": "user", "content": f"辩题:{query}\n\n你是正方,请搜索资料并提出你的核心论点。"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "正方辩手", "result": pro_round1[:500]})
- # Step 2: 反方反驳
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "反方辩手", "icon": "🔴", "action": "反驳 + 立论"})
- con_round1 = DEBATE_CON.chat(
- [{"role": "user", "content": f"辩题:{query}\n\n正方论点:\n{pro_round1}\n\n你是反方,请搜索资料反驳正方并提出你的论点。"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "反方辩手", "result": con_round1[:500]})
- # Step 3: 正方回应
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "正方辩手", "icon": "🟢", "action": "回应反驳"})
- pro_round2 = DEBATE_PRO.chat(
- [{"role": "user", "content": f"辩题:{query}\n\n你的论点:\n{pro_round1}\n\n反方反驳:\n{con_round1}\n\n请回应反驳并强化你的论点。"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "正方辩手", "result": pro_round2[:500]})
- # Step 4: 反方回应
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "反方辩手", "icon": "🔴", "action": "二次反驳"})
- con_round2 = DEBATE_CON.chat(
- [{"role": "user", "content": f"辩题:{query}\n\n你的论点:\n{con_round1}\n\n正方回应:\n{pro_round2}\n\n请做最终反驳。"}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "反方辩手", "result": con_round2[:500]})
- # Step 5: 裁判评判
- _emit(emit, "step_start", {"trace_id": trace_id, "agent": "裁判", "icon": "⚖️", "action": "综合评判"})
- verdict = DEBATE_JUDGE.chat(
- [{"role": "user", "content": (
- f"辩题:{query}\n\n"
- f"正方第一轮:\n{pro_round1}\n\n"
- f"反方第一轮:\n{con_round1}\n\n"
- f"正方第二轮:\n{pro_round2}\n\n"
- f"反方第二轮:\n{con_round2}\n\n"
- f"请综合评判,给出最终结论。"
- )}],
- emit=agent_emit
- )
- _emit(emit, "step_end", {"trace_id": trace_id, "agent": "裁判", "result": verdict[:800]})
- total_ms = int((time.time() - t_start) * 1000)
- _emit(emit, "trace_complete", {"trace_id": trace_id, "mode": "debate", "total_ms": total_ms})
- return {"trace_id": trace_id, "answer": verdict, "total_ms": total_ms}
|