Files
ai-agent-dev/20_多智能体架构.ipynb
2026-07-08 10:09:42 +08:00

967 lines
35 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 20 多智能体架构\n",
"\n",
"## 学习目标\n",
"1. 理解多智能体系统的典型架构(如监督者、协作、竞争)\n",
"2. 掌握使用LangGraph设计多节点多智能体工作流\n",
"3. 能够实现多个智能体节点之间的消息传递与协作"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. 为什么需要多智能体\n",
"\n",
"在之前的课程中,我们构建的智能体都是**单智能体**:一个智能体完成所有任务。\n",
"\n",
"但真实场景中,很多任务需要**多个智能体协作**才能完成:\n",
"\n",
"- **复杂任务分解**:一个任务太大,需要分给多个专业智能体\n",
"- **专业分工**:不同智能体有不同的专业知识(如代码专家、写作专家、数据分析专家)\n",
"- **协作决策**:需要多个智能体共同讨论才能做出最佳决策\n",
"- **竞争博弈**:多个智能体竞争完成同一任务\n",
"\n",
"简单来说:\n",
"\n",
"- **单智能体**:一个人做所有事\n",
"- **多智能体**:一个团队分工合作"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. 多智能体的典型架构模式\n",
"\n",
"多智能体系统有几种经典的架构模式:\n",
"\n",
"### 2.1 监督者模式Supervisor Pattern\n",
"\n",
"一个监督者智能体负责协调多个工作智能体:\n",
"\n",
"```\n",
" 监督者\n",
" │\n",
" ┌──────┼──────┬──────┐\n",
" ▼ ▼ ▼ ▼\n",
" 智能体A 智能体B 智能体C 智能体D\n",
"```\n",
"\n",
"**适用场景**:任务需要多种专业能力,监督者分配任务并汇总结果。\n",
"\n",
"### 2.2 协作模式Collaborative Pattern\n",
"\n",
"多个智能体平等协作,共同完成任务:\n",
"\n",
"```\n",
" 智能体A ←→ 智能体B\n",
" ↑ ↑\n",
" │ │\n",
" 智能体C ←→ 智能体D\n",
"```\n",
"\n",
"**适用场景**:任务需要多个智能体之间频繁交流和协同。\n",
"\n",
"### 2.3 竞争模式Competitive Pattern\n",
"\n",
"多个智能体竞争完成同一任务,胜者获得奖励:\n",
"\n",
"```\n",
" 智能体A ─┐\n",
" ├──→ 比较器 → 最佳结果\n",
" 智能体B ─┘\n",
"```\n",
"\n",
"**适用场景**:需要从多个方案中选择最优解。\n",
"\n",
"### 2.4 流水线模式Pipeline Pattern\n",
"\n",
"多个智能体按顺序处理任务,像流水线一样:\n",
"\n",
"```\n",
" 智能体A → 智能体B → 智能体C → 智能体D\n",
"```\n",
"\n",
"**适用场景**:任务可以分解为多个顺序步骤。\n",
"\n",
"### 2.5 辩论模式Debate Pattern\n",
"\n",
"多个智能体就某个问题展开辩论,最终达成共识:\n",
"\n",
"```\n",
" 正方智能体 ←→ 反方智能体\n",
" │ │\n",
" └────┬──────┘\n",
" ▼\n",
" 裁判智能体\n",
"```\n",
"\n",
"**适用场景**:需要深入分析某个问题的正反两面。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. 第一个例子:简单的协作智能体\n",
"\n",
"我们用一个简单的例子来演示多智能体协作。\n",
"\n",
"场景:\n",
"- 用户提出一个问题\n",
"- 研究智能体负责收集信息\n",
"- 写作智能体负责整理成报告\n",
"- 监督者智能体负责协调整个流程"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from typing_extensions import TypedDict\n",
"from langgraph.graph import StateGraph, START, END\n",
"from openai import OpenAI\n",
"import os\n",
"from dotenv import load_dotenv\n",
"\n",
"load_dotenv()\n",
"\n",
"client = OpenAI(\n",
" base_url=os.getenv(\"OPENAI_BASE_URL\"),\n",
" api_key=os.getenv(\"OPENAI_API_KEY\")\n",
")\n",
"\n",
"def call_llm(system_prompt: str, user_prompt: str) -> str:\n",
" response = client.chat.completions.create(\n",
" model=\"qwen3.6-35b-A3b\",\n",
" messages=[\n",
" {\"role\": \"system\", \"content\": system_prompt},\n",
" {\"role\": \"user\", \"content\": user_prompt}\n",
" ],\n",
" temperature=0.7,\n",
" max_tokens=500\n",
" )\n",
" return response.choices[0].message.content\n",
"\n",
"class AgentState(TypedDict):\n",
" user_question: str\n",
" research_info: str\n",
" report: str\n",
" current_agent: str\n",
"\n",
"def supervisor(state: AgentState):\n",
" print(f'监督者:收到用户问题:{state[\"user_question\"]}')\n",
" if not state['research_info']:\n",
" print('监督者:分配给研究智能体')\n",
" return {'current_agent': 'research'}\n",
" elif not state['report']:\n",
" print('监督者:分配给写作智能体')\n",
" return {'current_agent': 'writer'}\n",
" else:\n",
" print('监督者:任务完成')\n",
" return {'current_agent': 'finish'}\n",
"\n",
"def research_agent(state: AgentState):\n",
" print(f'研究智能体:正在研究 \"{state[\"user_question\"]}\"')\n",
" system_prompt = '你是一个专业的研究助手,请针对用户问题提供详细的研究信息和分析。'\n",
" user_prompt = f'请研究并总结关于\"{state[\"user_question\"]}\"的最新信息,包括主要趋势、关键技术和未来展望。'\n",
" research_info = call_llm(system_prompt, user_prompt)\n",
" print(f'研究智能体:完成研究,收集到信息')\n",
" return {'research_info': research_info}\n",
"\n",
"def writer_agent(state: AgentState):\n",
" print(f'写作智能体:正在撰写报告')\n",
" system_prompt = '你是一个专业的报告撰写者,请根据提供的研究信息撰写结构化的报告。'\n",
" user_prompt = f'请根据以下研究信息撰写一份完整的报告:\\n\\n研究信息{state[\"research_info\"]}'\n",
" report = call_llm(system_prompt, user_prompt)\n",
" print(f'写作智能体:报告完成')\n",
" return {'report': report}\n",
"\n",
"def route(state: AgentState):\n",
" if state['current_agent'] == 'research':\n",
" return 'research'\n",
" elif state['current_agent'] == 'writer':\n",
" return 'writer'\n",
" elif state['current_agent'] == 'finish':\n",
" return END\n",
" return 'supervisor'\n",
"\n",
"builder = StateGraph(AgentState)\n",
"builder.add_node('supervisor', supervisor)\n",
"builder.add_node('research', research_agent)\n",
"builder.add_node('writer', writer_agent)\n",
"\n",
"builder.add_edge(START, 'supervisor')\n",
"builder.add_edge('research', 'supervisor')\n",
"builder.add_edge('writer', 'supervisor')\n",
"builder.add_conditional_edges(\n",
" 'supervisor',\n",
" route,\n",
" {\n",
" 'research': 'research',\n",
" 'writer': 'writer',\n",
" END: END\n",
" }\n",
")\n",
"\n",
"graph = builder.compile()\n",
"\n",
"result = graph.invoke({\n",
" 'user_question': '人工智能的发展趋势',\n",
" 'research_info': '',\n",
" 'report': '',\n",
" 'current_agent': ''\n",
"})\n",
"\n",
"print()\n",
"print('最终报告:')\n",
"print(result['report'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 代码解释\n",
"\n",
"1. **环境配置**\n",
" - 加载 `.env` 文件中的 API 密钥\n",
" - 创建 OpenAI 客户端\n",
" - 定义 `call_llm` 函数,封装大模型调用逻辑\n",
"\n",
"2. **AgentState**:定义状态包含四个字段:\n",
" - `user_question`:用户的问题\n",
" - `research_info`:研究智能体收集的信息\n",
" - `report`:写作智能体生成的报告\n",
" - `current_agent`:当前应该执行的智能体\n",
"\n",
"3. **supervisor**:监督者智能体\n",
" - 检查当前状态,决定下一步分配给哪个智能体\n",
" - 如果没有研究信息,分配给研究智能体\n",
" - 如果有研究信息但没有报告,分配给写作智能体\n",
" - 如果报告已完成,标记任务结束\n",
"\n",
"4. **research_agent**:研究智能体(使用真实大模型)\n",
" - 构建系统提示词和用户提示词\n",
" - 调用大模型获取研究结果\n",
" - 将结果保存到 `research_info`\n",
"\n",
"5. **writer_agent**:写作智能体(使用真实大模型)\n",
" - 构建系统提示词和用户提示词\n",
" - 调用大模型根据研究信息生成报告\n",
" - 将结果保存到 `report`\n",
"\n",
"6. **route**:路由函数\n",
" - 根据 `current_agent` 字段决定下一步执行哪个节点\n",
"\n",
"7. **图结构**\n",
" - START -> supervisor\n",
" - supervisor 根据条件边分配给 research 或 writer\n",
" - research 和 writer 执行完后都回到 supervisor\n",
" - supervisor 判断完成后走到 END\n",
"\n",
"流程图:\n",
"\n",
"```\n",
"START -> supervisor\n",
" │\n",
" ┌──────┴──────┐\n",
" ▼ ▼\n",
"research writer\n",
" │ │\n",
" └──────┬──────┘\n",
" ▼\n",
" supervisor -> END\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. 流水线模式:多智能体顺序处理\n",
"\n",
"流水线模式是最直观的多智能体架构,智能体按顺序处理任务。\n",
"\n",
"场景:\n",
"- 用户输入一段原始文本\n",
"- 翻译智能体将其翻译成英文\n",
"- 摘要智能体生成摘要\n",
"- 情感分析智能体分析情感倾向"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from typing_extensions import TypedDict\n",
"from langgraph.graph import StateGraph, START, END\n",
"\n",
"class PipelineState(TypedDict):\n",
" original_text: str\n",
" translated_text: str\n",
" summary: str\n",
" sentiment: str\n",
"\n",
"def translate_agent(state: PipelineState):\n",
" print(f'翻译智能体:正在翻译')\n",
" text = state['original_text']\n",
" translated = f'[Translated] {text}'\n",
" print(f'翻译智能体:{translated}')\n",
" return {'translated_text': translated}\n",
"\n",
"def summarize_agent(state: PipelineState):\n",
" print(f'摘要智能体:正在生成摘要')\n",
" text = state['translated_text']\n",
" summary = f'[Summary] {text[:20]}...'\n",
" print(f'摘要智能体:{summary}')\n",
" return {'summary': summary}\n",
"\n",
"def sentiment_agent(state: PipelineState):\n",
" print(f'情感分析智能体:正在分析情感')\n",
" text = state['translated_text']\n",
" if '好' in text or '高兴' in text:\n",
" sentiment = '积极'\n",
" elif '坏' in text or '难过' in text:\n",
" sentiment = '消极'\n",
" else:\n",
" sentiment = '中性'\n",
" print(f'情感分析智能体:情感倾向为 {sentiment}')\n",
" return {'sentiment': sentiment}\n",
"\n",
"builder = StateGraph(PipelineState)\n",
"builder.add_node('translate', translate_agent)\n",
"builder.add_node('summarize', summarize_agent)\n",
"builder.add_node('sentiment', sentiment_agent)\n",
"\n",
"builder.add_edge(START, 'translate')\n",
"builder.add_edge('translate', 'summarize')\n",
"builder.add_edge('summarize', 'sentiment')\n",
"builder.add_edge('sentiment', END)\n",
"\n",
"graph = builder.compile()\n",
"\n",
"result = graph.invoke({\n",
" 'original_text': '今天天气很好,我很高兴。',\n",
" 'translated_text': '',\n",
" 'summary': '',\n",
" 'sentiment': ''\n",
"})\n",
"\n",
"print()\n",
"print('处理结果:')\n",
"print(f'原文:{result[\"original_text\"]}')\n",
"print(f'翻译:{result[\"translated_text\"]}')\n",
"print(f'摘要:{result[\"summary\"]}')\n",
"print(f'情感:{result[\"sentiment\"]}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 代码解释\n",
"\n",
"1. **PipelineState**:定义流水线的状态,包含四个字段,分别对应每个智能体的输入/输出。\n",
"\n",
"2. **translate_agent**:翻译智能体\n",
" - 接收原始文本\n",
" - 输出翻译结果\n",
"\n",
"3. **summarize_agent**:摘要智能体\n",
" - 接收翻译后的文本\n",
" - 输出摘要\n",
"\n",
"4. **sentiment_agent**:情感分析智能体\n",
" - 接收翻译后的文本\n",
" - 分析情感倾向\n",
"\n",
"5. **图结构**:简单的顺序流程\n",
" - START -> translate -> summarize -> sentiment -> END\n",
"\n",
"流程图:\n",
"\n",
"```\n",
"START -> translate -> summarize -> sentiment -> END\n",
"```\n",
"\n",
"这种模式的优点:\n",
"- 结构简单,易于理解\n",
"- 每个智能体只关注自己的任务\n",
"- 便于扩展,可以随时添加新的智能体"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. 竞争模式:多个智能体竞争\n",
"\n",
"竞争模式中,多个智能体同时处理同一个任务,然后比较结果选择最优解。\n",
"\n",
"场景:\n",
"- 用户提出一个问题\n",
"- 多个回答智能体给出不同的答案\n",
"- 评估智能体选择最佳答案"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from typing_extensions import TypedDict\n",
"from langgraph.graph import StateGraph, START, END\n",
"\n",
"class CompetitionState(TypedDict):\n",
" question: str\n",
" answers: list\n",
" best_answer: str\n",
"\n",
"def answer_agent_a(state: CompetitionState):\n",
" print(f'回答智能体A正在回答问题')\n",
" answer = f'A的回答关于\"{state[\"question\"]}\",这是一个详细的回答。'\n",
" print(f'回答智能体A{answer}')\n",
" return {'answers': state['answers'] + [{'agent': 'A', 'content': answer, 'score': 85}]}\n",
"\n",
"def answer_agent_b(state: CompetitionState):\n",
" print(f'回答智能体B正在回答问题')\n",
" answer = f'B的回答对于\"{state[\"question\"]}\",我的见解是...'\n",
" print(f'回答智能体B{answer}')\n",
" return {'answers': state['answers'] + [{'agent': 'B', 'content': answer, 'score': 92}]}\n",
"\n",
"def answer_agent_c(state: CompetitionState):\n",
" print(f'回答智能体C正在回答问题')\n",
" answer = f'C的回答\"{state[\"question\"]}\"的答案如下...'\n",
" print(f'回答智能体C{answer}')\n",
" return {'answers': state['answers'] + [{'agent': 'C', 'content': answer, 'score': 88}]}\n",
"\n",
"def evaluator_agent(state: CompetitionState):\n",
" print(f'评估智能体:正在评估所有回答')\n",
" if not state['answers']:\n",
" return {'best_answer': '没有回答'}\n",
"\n",
" best = max(state['answers'], key=lambda x: x['score'])\n",
" print(f'评估智能体:最佳回答来自智能体{best[\"agent\"]},得分{best[\"score\"]}')\n",
" return {'best_answer': best['content']}\n",
"\n",
"builder = StateGraph(CompetitionState)\n",
"builder.add_node('answer_a', answer_agent_a)\n",
"builder.add_node('answer_b', answer_agent_b)\n",
"builder.add_node('answer_c', answer_agent_c)\n",
"builder.add_node('evaluator', evaluator_agent)\n",
"\n",
"builder.add_edge(START, 'answer_a')\n",
"builder.add_edge('answer_a', 'answer_b')\n",
"builder.add_edge('answer_b', 'answer_c')\n",
"builder.add_edge('answer_c', 'evaluator')\n",
"builder.add_edge('evaluator', END)\n",
"\n",
"graph = builder.compile()\n",
"\n",
"result = graph.invoke({\n",
" 'question': '什么是人工智能?',\n",
" 'answers': [],\n",
" 'best_answer': ''\n",
"})\n",
"\n",
"print()\n",
"print('最佳回答:')\n",
"print(result['best_answer'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 代码解释\n",
"\n",
"1. **CompetitionState**:定义竞争状态,包含:\n",
" - `question`:用户问题\n",
" - `answers`:所有智能体的回答列表\n",
" - `best_answer`:评估后的最佳回答\n",
"\n",
"2. **answer_agent_a/b/c**:三个回答智能体\n",
" - 每个智能体给出自己的回答\n",
" - 回答包含智能体标识、内容和得分\n",
" - 将回答追加到 `answers` 列表\n",
"\n",
"3. **evaluator_agent**:评估智能体\n",
" - 比较所有回答的得分\n",
" - 选择得分最高的回答作为最佳答案\n",
"\n",
"4. **图结构**:顺序执行三个回答智能体,然后评估\n",
" - START -> answer_a -> answer_b -> answer_c -> evaluator -> END\n",
"\n",
"流程图:\n",
"\n",
"```\n",
"START -> answer_a -> answer_b -> answer_c -> evaluator -> END\n",
"```\n",
"\n",
"这种模式的优点:\n",
"- 可以从多个角度解决问题\n",
"- 通过竞争提高回答质量\n",
"- 易于扩展,随时可以添加新的智能体"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 6. 辩论模式:智能体之间的辩论\n",
"\n",
"辩论模式中,多个智能体就某个问题展开辩论,最终达成共识或由裁判做出裁决。\n",
"\n",
"场景:\n",
"- 用户提出一个有争议的问题\n",
"- 正方智能体支持某个观点\n",
"- 反方智能体反对该观点\n",
"- 裁判智能体总结辩论结果"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from typing_extensions import TypedDict\n",
"from langgraph.graph import StateGraph, START, END\n",
"\n",
"class DebateState(TypedDict):\n",
" question: str\n",
" debate_history: list\n",
" round: int\n",
" conclusion: str\n",
"\n",
"def pro_agent(state: DebateState):\n",
" print(f'正方智能体(第{state[\"round\"]}轮):')\n",
" arguments = [\n",
" f'支持\"{state[\"question\"]}\"的理由:它可以提高效率。',\n",
" f'进一步论证:从长远来看,这是必然趋势。'\n",
" ]\n",
" arg = arguments[state['round'] - 1]\n",
" print(f' {arg}')\n",
" return {\n",
" 'debate_history': state['debate_history'] + [{'side': '正方', 'argument': arg}],\n",
" 'round': state['round']\n",
" }\n",
"\n",
"def con_agent(state: DebateState):\n",
" print(f'反方智能体(第{state[\"round\"]}轮):')\n",
" arguments = [\n",
" f'反对\"{state[\"question\"]}\"的理由:它可能带来风险。',\n",
" f'进一步反驳:我们需要更谨慎地对待。'\n",
" ]\n",
" arg = arguments[state['round'] - 1]\n",
" print(f' {arg}')\n",
" new_round = state['round'] + 1\n",
" return {\n",
" 'debate_history': state['debate_history'] + [{'side': '反方', 'argument': arg}],\n",
" 'round': new_round\n",
" }\n",
"\n",
"def judge_agent(state: DebateState):\n",
" print(f'裁判智能体:总结辩论')\n",
" conclusion = f'关于\"{state[\"question\"]}\"的辩论总结:\\n'\n",
" for entry in state['debate_history']:\n",
" conclusion += f'- {entry[\"side\"]}{entry[\"argument\"]}\\n'\n",
" conclusion += '\\n结论双方观点都有道理需要权衡利弊。'\n",
" print(f'裁判智能体:{conclusion}')\n",
" return {'conclusion': conclusion}\n",
"\n",
"def after_con_route(state: DebateState):\n",
" if state['round'] <= 2:\n",
" return 'pro'\n",
" return 'judge'\n",
"\n",
"builder = StateGraph(DebateState)\n",
"builder.add_node('pro', pro_agent)\n",
"builder.add_node('con', con_agent)\n",
"builder.add_node('judge', judge_agent)\n",
"\n",
"builder.add_edge(START, 'pro')\n",
"builder.add_edge('pro', 'con')\n",
"builder.add_conditional_edges(\n",
" 'con',\n",
" after_con_route,\n",
" {\n",
" 'pro': 'pro',\n",
" 'judge': 'judge'\n",
" }\n",
")\n",
"builder.add_edge('judge', END)\n",
"\n",
"graph = builder.compile()\n",
"\n",
"result = graph.invoke({\n",
" 'question': '人工智能是否应该取代人类工作?',\n",
" 'debate_history': [],\n",
" 'round': 1,\n",
" 'conclusion': ''\n",
"})\n",
"\n",
"print()\n",
"print('辩论总结:')\n",
"print(result['conclusion'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 代码解释\n",
"\n",
"1. **DebateState**:定义辩论状态,包含:\n",
" - `question`:辩论的问题\n",
" - `debate_history`:辩论历史记录\n",
" - `round`:当前辩论轮次\n",
" - `conclusion`:最终结论\n",
"\n",
"2. **pro_agent**:正方智能体\n",
" - 根据当前轮次给出支持观点\n",
" - 将论点添加到辩论历史\n",
"\n",
"3. **con_agent**:反方智能体\n",
" - 根据当前轮次给出反对观点\n",
" - 将论点添加到辩论历史\n",
"\n",
"4. **judge_agent**:裁判智能体\n",
" - 总结所有辩论内容\n",
" - 给出最终结论\n",
"\n",
"5. **after_con_route**:反方发言后的路由\n",
" - 如果还没到第2轮回到正方开始下一轮\n",
" - 如果已经第2轮结束进入裁判\n",
"\n",
"6. **图结构**\n",
" - START -> pro -> con\n",
" - con 根据轮次决定回到 pro 还是进入 judge\n",
" - judge -> END\n",
"\n",
"流程图:\n",
"\n",
"```\n",
"START -> pro -> con\n",
" │\n",
" ┌────────┴────────┐\n",
" ▼ ▼\n",
" pro → con judge -> END\n",
"```\n",
"\n",
"这种模式的优点:\n",
"- 可以全面分析问题的正反两面\n",
"- 通过辩论深入探讨复杂问题\n",
"- 最终结论更加客观全面"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 7. 综合案例:多智能体协作完成复杂任务\n",
"\n",
"现在我们将多种模式结合起来,构建一个复杂的多智能体系统。\n",
"\n",
"场景:\n",
"- 用户提出一个数据分析需求\n",
"- 监督者智能体负责协调\n",
"- 数据收集智能体收集数据\n",
"- 数据处理智能体处理数据\n",
"- 数据分析智能体分析数据\n",
"- 报告生成智能体生成报告\n",
"- 使用MemorySaver保存状态"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from typing_extensions import TypedDict\n",
"from langgraph.graph import StateGraph, START, END\n",
"from langgraph.checkpoint.memory import MemorySaver\n",
"from openai import OpenAI\n",
"import os\n",
"from dotenv import load_dotenv\n",
"\n",
"load_dotenv()\n",
"\n",
"client = OpenAI(\n",
" base_url=os.getenv(\"OPENAI_BASE_URL\"),\n",
" api_key=os.getenv(\"OPENAI_API_KEY\")\n",
")\n",
"\n",
"def call_llm(system_prompt: str, user_prompt: str) -> str:\n",
" response = client.chat.completions.create(\n",
" model=\"qwen3.6-35b-A3b\",\n",
" messages=[\n",
" {\"role\": \"system\", \"content\": system_prompt},\n",
" {\"role\": \"user\", \"content\": user_prompt}\n",
" ],\n",
" temperature=0.7,\n",
" max_tokens=500\n",
" )\n",
" return response.choices[0].message.content\n",
"\n",
"class DataAgentState(TypedDict):\n",
" user_request: str\n",
" raw_data: str\n",
" processed_data: str\n",
" analysis_result: str\n",
" report: str\n",
" next_agent: str\n",
"\n",
"def supervisor(state: DataAgentState):\n",
" print(f'监督者:收到请求:{state[\"user_request\"]}')\n",
" \n",
" if not state['raw_data']:\n",
" print('监督者:分配给数据收集智能体')\n",
" return {'next_agent': 'collect'}\n",
" elif not state['processed_data']:\n",
" print('监督者:分配给数据处理智能体')\n",
" return {'next_agent': 'process'}\n",
" elif not state['analysis_result']:\n",
" print('监督者:分配给数据分析智能体')\n",
" return {'next_agent': 'analyze'}\n",
" elif not state['report']:\n",
" print('监督者:分配给报告生成智能体')\n",
" return {'next_agent': 'report'}\n",
" else:\n",
" print('监督者:任务完成')\n",
" return {'next_agent': 'finish'}\n",
"\n",
"def collect_agent(state: DataAgentState):\n",
" print(f'数据收集智能体:正在收集数据')\n",
" raw_data = f'原始数据:关于\"{state[\"user_request\"]}\"的统计数据、趋势数据、对比数据。'\n",
" print(f'数据收集智能体:完成数据收集')\n",
" return {'raw_data': raw_data}\n",
"\n",
"def process_agent(state: DataAgentState):\n",
" print(f'数据处理智能体:正在处理数据')\n",
" processed_data = f'处理后数据:清洗、转换、标准化后的\"{state[\"user_request\"]}\"数据。'\n",
" print(f'数据处理智能体:完成数据处理')\n",
" return {'processed_data': processed_data}\n",
"\n",
"def analyze_agent(state: DataAgentState):\n",
" print(f'数据分析智能体:正在分析数据')\n",
" \n",
" system_prompt = '你是一个专业的数据分析师,请根据提供的数据进行深入分析。'\n",
" user_prompt = f'请分析以下数据,找出关键发现和趋势:\\n\\n原始数据{state[\"raw_data\"]}\\n\\n处理后数据{state[\"processed_data\"]}'\n",
" \n",
" analysis_result = call_llm(system_prompt, user_prompt)\n",
" \n",
" print(f'数据分析智能体:完成数据分析')\n",
" return {'analysis_result': analysis_result}\n",
"\n",
"def report_agent(state: DataAgentState):\n",
" print(f'报告生成智能体:正在生成报告')\n",
" \n",
" system_prompt = '你是一个专业的报告撰写者,请根据数据分析结果撰写结构化的报告。'\n",
" user_prompt = f'请根据以下信息撰写一份完整的数据分析报告:\\n\\n请求{state[\"user_request\"]}\\n\\n分析结果{state[\"analysis_result\"]}'\n",
" \n",
" report = call_llm(system_prompt, user_prompt)\n",
" print(f'报告生成智能体:完成报告生成')\n",
" return {'report': report}\n",
"\n",
"def route(state: DataAgentState):\n",
" if state['next_agent'] == 'collect':\n",
" return 'collect'\n",
" elif state['next_agent'] == 'process':\n",
" return 'process'\n",
" elif state['next_agent'] == 'analyze':\n",
" return 'analyze'\n",
" elif state['next_agent'] == 'report':\n",
" return 'report'\n",
" elif state['next_agent'] == 'finish':\n",
" return END\n",
" return 'supervisor'\n",
"\n",
"builder = StateGraph(DataAgentState)\n",
"builder.add_node('supervisor', supervisor)\n",
"builder.add_node('collect', collect_agent)\n",
"builder.add_node('process', process_agent)\n",
"builder.add_node('analyze', analyze_agent)\n",
"builder.add_node('report', report_agent)\n",
"\n",
"builder.add_edge(START, 'supervisor')\n",
"builder.add_edge('collect', 'supervisor')\n",
"builder.add_edge('process', 'supervisor')\n",
"builder.add_edge('analyze', 'supervisor')\n",
"builder.add_edge('report', 'supervisor')\n",
"builder.add_conditional_edges(\n",
" 'supervisor',\n",
" route,\n",
" {\n",
" 'collect': 'collect',\n",
" 'process': 'process',\n",
" 'analyze': 'analyze',\n",
" 'report': 'report',\n",
" END: END\n",
" }\n",
")\n",
"\n",
"memory = MemorySaver()\n",
"graph = builder.compile(checkpointer=memory)\n",
"\n",
"config = {'configurable': {'thread_id': 'data_analysis_session'}}\n",
"\n",
"result = graph.invoke({\n",
" 'user_request': '分析过去一年的销售趋势',\n",
" 'raw_data': '',\n",
" 'processed_data': '',\n",
" 'analysis_result': '',\n",
" 'report': '',\n",
" 'next_agent': ''\n",
"}, config)\n",
"\n",
"print()\n",
"print('最终报告:')\n",
"print(result['report'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 代码解释\n",
"\n",
"这个案例展示了一个完整的多智能体协作系统:\n",
"\n",
"1. **环境配置**\n",
" - 加载 `.env` 文件中的 API 密钥\n",
" - 创建 OpenAI 客户端\n",
" - 定义 `call_llm` 函数,封装大模型调用逻辑\n",
"\n",
"2. **DataAgentState**:定义状态,包含六个字段,分别对应每个阶段的数据。\n",
"\n",
"3. **supervisor**:监督者智能体\n",
" - 根据当前状态决定下一步分配给哪个智能体\n",
" - 按照数据收集→数据处理→数据分析→报告生成的顺序分配\n",
"\n",
"4. **collect_agent**:数据收集智能体\n",
" - 收集原始数据\n",
" - 保存到 `raw_data`\n",
"\n",
"5. **process_agent**:数据处理智能体\n",
" - 处理原始数据\n",
" - 保存到 `processed_data`\n",
"\n",
"6. **analyze_agent**:数据分析智能体(使用真实大模型)\n",
" - 构建系统提示词和用户提示词\n",
" - 调用大模型分析数据\n",
" - 保存到 `analysis_result`\n",
"\n",
"7. **report_agent**:报告生成智能体(使用真实大模型)\n",
" - 构建系统提示词和用户提示词\n",
" - 调用大模型生成报告\n",
" - 保存到 `report`\n",
"\n",
"8. **MemorySaver**:保存状态\n",
" - 使用 `thread_id` 隔离不同会话\n",
" - 支持多轮交互\n",
"\n",
"流程图:\n",
"\n",
"```\n",
"START -> supervisor\n",
" │\n",
" ┌──────┼──────┬──────┬──────┐\n",
" ▼ ▼ ▼ ▼ ▼\n",
" collect process analyze report finish\n",
" │ │ │ │\n",
" └──────┴──────┴──────┘\n",
" │\n",
" ▼\n",
" supervisor -> END\n",
"```\n",
"\n",
"这个系统结合了监督者模式和流水线模式,展示了多智能体协作的强大能力。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 8. 总结\n",
"\n",
"### 核心知识点\n",
"\n",
"1. **监督者模式**:一个监督者智能体协调多个工作智能体\n",
"2. **协作模式**:多个智能体平等协作,共同完成任务\n",
"3. **竞争模式**:多个智能体竞争,选择最优解\n",
"4. **流水线模式**:多个智能体按顺序处理任务\n",
"5. **辩论模式**:多个智能体展开辩论,最终达成共识\n",
"\n",
"### 架构选择指南\n",
"\n",
"| 模式 | 适用场景 | 特点 |\n",
"| --- | --- | --- |\n",
"| 监督者 | 需要多种专业能力 | 集中控制,易于管理 |\n",
"| 协作 | 需要频繁交流 | 平等协作,灵活适应 |\n",
"| 竞争 | 需要最优解 | 多方竞争,提高质量 |\n",
"| 流水线 | 可分解为顺序步骤 | 结构清晰,易于扩展 |\n",
"| 辩论 | 需要深入分析 | 全面探讨,结论客观 |\n",
"\n",
"### 实践要点\n",
"\n",
"- 根据任务特点选择合适的架构模式\n",
"- 智能体之间通过共享状态传递信息\n",
"- 使用监督者模式时,确保监督者逻辑清晰\n",
"- 使用MemorySaver保存状态支持多轮交互\n",
"- 可以组合多种模式构建复杂系统\n",
"- 智能体可以调用真实大模型如GPT、Qwen等来生成内容\n",
"- 使用环境变量管理API密钥确保安全性\n",
"- 通过封装call_llm函数统一管理大模型调用"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 练习\n",
"\n",
"1. 修改监督者模式示例,添加一个\"质量检查智能体\"\n",
"2. 修改流水线模式示例,添加一个\"校对智能体\"\n",
"3. 修改竞争模式示例,让智能体可以互相评价\n",
"4. 创建一个新的辩论模式示例增加到3轮辩论\n",
"5. 设计一个综合多智能体系统,包含监督者、协作和竞争模式"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"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.14.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}