967 lines
35 KiB
Plaintext
967 lines
35 KiB
Plaintext
{
|
||
"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
|
||
}
|