
AI Agents-7 | Muti-Agent的架构解析 原创
在当今快速发展的AI领域,多智能体架构正逐渐成为解决复杂任务的强大工具。从简单的单智能体系统到复杂的多智能体协同,我们看到了AI在任务管理、资源分配和决策效率上的巨大潜力。今天,就让我们深入探讨多智能体架构的魅力,看看它是如何通过不同的模式和策略,为我们的生活和工作带来变革的。
一、单智能体与多智能体架构:选择适合的路径
在AI的世界里,单智能体架构就像是一个“全能型选手”,它试图用一个智能体来完成所有任务,无论是浏览网页还是处理文件操作。这种架构在任务简单且明确时非常高效,但随着任务复杂度的增加和工具数量的增多,单智能体系统往往会陷入困境。比如,当智能体需要处理过多的工具或面对过于复杂的上下文时,它可能会开始犯错,甚至产生次优或错误的结果。
而多智能体架构则像是一个“团队作战”的模式,每个智能体专注于自己的领域和工具集。这种架构在面对复杂、动态的用例时表现得尤为出色,尤其是在需要专业知识和协作的场景中。例如,一个软件开发项目中,可以有规划者、研究者、数学专家等多个智能体协同工作,每个智能体各司其职,共同完成任务。
二、多智能体架构的模式:解锁协同的力量
多智能体架构的魅力在于其多样性和灵活性。不同的任务和场景需要不同的协同模式,下面我们来看看几种常见的模式。
(一)并行模式:多任务处理的高效方式
并行模式是多智能体架构中最直观的一种。在这种模式下,多个智能体同时处理任务的不同部分。比如,我们需要对一段文本进行总结、翻译和情感分析,三个智能体可以同时开始工作,分别完成各自的任务。这种方式大大提高了任务处理的效率,因为它可以充分利用多核处理器的并行计算能力。
代码示例:
from typing import Dict, Any, TypedDict
from langgraph.graph import StateGraph, END
from langchain_core.runnables import RunnableConfig
from textblob import TextBlob
import re
import time
# 定义状态
class AgentState(TypedDict):
text: str
summary: str
translation: str
sentiment: str
summary_time: float
translation_time: float
sentiment_time: float
# 总结智能体
def summarize_agent(state: AgentState) -> Dict[str, Any]:
print("总结智能体:正在运行")
start_time = time.time()
try:
text = state["text"]
ifnot text.strip():
return {
"summary": "未提供文本进行总结。",
"summary_time": 0.0
}
time.sleep(2)
sentences = re.split(r'(?<=[.!?]) +', text.strip())
scored_sentences = [(s, len(s.split())) for s in sentences if s]
top_sentences = [s for s, _ in sorted(scored_sentences, key=lambda x: x[1], reverse=True)[:2]]
summary = " ".join(top_sentences) if top_sentences else"文本太短,无法总结。"
processing_time = time.time() - start_time
print(f"总结智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"summary": summary,
"summary_time": processing_time
}
except Exception as e:
return {
"summary": f"总结错误:{str(e)}",
"summary_time": 0.0
}
# 翻译智能体
def translate_agent(state: AgentState) -> Dict[str, Any]:
print("翻译智能体:正在运行")
start_time = time.time()
try:
text = state["text"]
ifnot text.strip():
return {
"translation": "未提供文本进行翻译。",
"translation_time": 0.0
}
time.sleep(3)
translation = (
"El nuevo parque en la ciudad es una maravillosa adición. "
"Las familias disfrutan de los espacios abiertos, y a los niños les encanta el parque infantil. "
"Sin embargo, algunas personas piensan que el área de estacionamiento es demasiado pequeña."
)
processing_time = time.time() - start_time
print(f"翻译智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"translation": translation,
"translation_time": processing_time
}
except Exception as e:
return {
"translation": f"翻译错误:{str(e)}",
"translation_time": 0.0
}
# 情感分析智能体
def sentiment_agent(state: AgentState) -> Dict[str, Any]:
print("情感分析智能体:正在运行")
start_time = time.time()
try:
text = state["text"]
ifnot text.strip():
return {
"sentiment": "未提供文本进行情感分析。",
"sentiment_time": 0.0
}
time.sleep(1.5)
blob = TextBlob(text)
polarity = blob.sentiment.polarity
subjectivity = blob.sentiment.subjectivity
sentiment = "Positive"if polarity > 0else"Negative"if polarity < 0else"Neutral"
result = f"{sentiment} (Polarity: {polarity:.2f}, Subjectivity: {subjectivity:.2f})"
processing_time = time.time() - start_time
print(f"情感分析智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"sentiment": result,
"sentiment_time": processing_time
}
except Exception as e:
return {
"sentiment": f"情感分析错误:{str(e)}",
"sentiment_time": 0.0
}
# 合并节点
def join_parallel_results(state: AgentState) -> AgentState:
return state
# 构建图
def build_parallel_graph() -> StateGraph:
workflow = StateGraph(AgentState)
parallel_branches = {
"summarize_node": summarize_agent,
"translate_node": translate_agent,
"sentiment_node": sentiment_agent
}
for name, agent in parallel_branches.items():
workflow.add_node(name, agent)
workflow.add_node("branch", lambda state: state)
workflow.add_node("join", join_parallel_results)
workflow.set_entry_point("branch")
for name in parallel_branches:
workflow.add_edge("branch", name)
workflow.add_edge(name, "join")
workflow.add_edge("join", END)
return workflow.compile()
# 主函数
def main():
text = (
"The new park in the city is a wonderful addition. Families are enjoying the open spaces, "
"and children love the playground. However, some people think the parking area is too small."
)
initial_state: AgentState = {
"text": text,
"summary": "",
"translation": "",
"sentiment": "",
"summary_time": 0.0,
"translation_time": 0.0,
"sentiment_time": 0.0
}
print("\n构建新图...")
app = build_parallel_graph()
print("\n开始并行处理...")
start_time = time.time()
config = RunnableConfig(parallel=True)
result = app.invoke(initial_state, cnotallow=config)
total_time = time.time() - start_time
print("\n=== 并行任务结果 ===")
print(f"输入文本:\n{text}\n")
print(f"总结:\n{result['summary']}\n")
print(f"翻译(西班牙语):\n{result['translation']}\n")
print(f"情感分析:\n{result['sentiment']}\n")
print("\n=== 处理时间 ===")
processing_times = {
"summary": result["summary_time"],
"translation": result["translation_time"],
"sentiment": result["sentiment_time"]
}
for agent, time_taken in processing_times.items():
print(f"{agent.capitalize()}: {time_taken:.2f} 秒")
print(f"\n总耗时: {total_time:.2f} 秒")
print(f"各任务总耗时: {sum(processing_times.values()):.2f} 秒")
print(f"并行节省时间: {sum(processing_times.values()) - total_time:.2f} 秒")
if __name__ == "__main__":
main()
(二)顺序模式:按部就班的协同
顺序模式则是一种“接力棒”式的协同方式。在这种模式下,任务按照一定的顺序依次传递给不同的智能体,每个智能体的输出成为下一个智能体的输入。比如,在一个多步骤的审批流程中,团队负责人先审批,然后是部门经理,最后是财务总监。这种方式适合那些需要严格顺序执行的任务。
代码示例:
from typing import Dict
from langgraph.graph import StateGraph, MessagesState, END
from langchain_core.runnables import RunnableConfig
from langchain_core.messages import HumanMessage, AIMessage
import json
# 团队负责人
def team_lead_agent(state: MessagesState, config: RunnableConfig) -> Dict:
print("团队负责人:开始审批")
messages = state["messages"]
proposal = json.loads(messages[0].content)
title = proposal.get("title", "")
amount = proposal.get("amount", 0.0)
ifnot title or amount <= 0:
status = "Rejected"
comment = "团队负责人:提案因缺少标题或金额无效而被拒绝。"
goto = END
else:
status = "Approved by Team Lead"
comment = "团队负责人:提案完整且已批准。"
goto = "dept_manager"
print(f"团队负责人:审批完成 - {status}")
messages.append(AIMessage(
cnotallow=json.dumps({"status": status, "comment": comment}),
additional_kwargs={"agent": "team_lead", "goto": goto}
))
return {"messages": messages}
# 部门经理
def dept_manager_agent(state: MessagesState, config: RunnableConfig) -> Dict:
print("部门经理:开始审批")
messages = state["messages"]
team_lead_msg = next((m for m in messages if m.additional_kwargs.get("agent") == "team_lead"), None)
proposal = json.loads(messages[0].content)
amount = proposal.get("amount", 0.0)
if json.loads(team_lead_msg.content)["status"] != "Approved by Team Lead":
status = "Rejected"
comment = "部门经理:因团队负责人拒绝而跳过。"
goto = END
elif amount > 100000:
status = "Rejected"
comment = "部门经理:预算超出限制。"
goto = END
else:
status = "Approved by Department Manager"
comment = "部门经理:预算在限制范围内。"
goto = "finance_director"
print(f"部门经理:审批完成 - {status}")
messages.append(AIMessage(
cnotallow=json.dumps({"status": status, "comment": comment}),
additional_kwargs={"agent": "dept_manager", "goto": goto}
))
return {"messages": messages}
# 财务总监
def finance_director_agent(state: MessagesState, config: RunnableConfig) -> Dict:
print("财务总监:开始审批")
messages = state["messages"]
dept_msg = next((m for m in messages if m.additional_kwargs.get("agent") == "dept_manager"), None)
proposal = json.loads(messages[0].content)
amount = proposal.get("amount", 0.0)
if json.loads(dept_msg.content)["status"] != "Approved by Department Manager":
status = "Rejected"
comment = "财务总监:因部门经理拒绝而跳过。"
elif amount > 50000:
status = "Rejected"
comment = "财务总监:预算不足。"
else:
status = "Approved"
comment = "财务总监:批准且可行。"
print(f"财务总监:审批完成 - {status}")
messages.append(AIMessage(
cnotallow=json.dumps({"status": status, "comment": comment}),
additional_kwargs={"agent": "finance_director", "goto": END}
))
return {"messages": messages}
# 路由函数
def route_step(state: MessagesState) -> str:
for msg in reversed(state["messages"]):
goto = msg.additional_kwargs.get("goto")
if goto:
print(f"路由:智能体 {msg.additional_kwargs.get('agent')} 设置跳转到 {goto}")
return goto
return END
# 构建 LangGraph
builder = StateGraph(MessagesState)
builder.add_node("team_lead", team_lead_agent)
builder.add_node("dept_manager", dept_manager_agent)
builder.add_node("finance_director", finance_director_agent)
builder.set_entry_point("team_lead")
builder.add_conditional_edges("team_lead", route_step, {
"dept_manager": "dept_manager",
END: END
})
builder.add_conditional_edges("dept_manager", route_step, {
"finance_director": "finance_director",
END: END
})
builder.add_conditional_edges("finance_director", route_step, {
END: END
})
workflow = builder.compile()
# 主运行器
def main():
initial_state = {
"messages": [
HumanMessage(
cnotallow=json.dumps({
"title": "New Equipment Purchase",
"amount": 40000.0,
"department": "Engineering"
})
)
]
}
result = workflow.invoke(initial_state)
messages = result["messages"]
proposal = json.loads(messages[0].content)
print("\n=== 审批结果 ===")
print(f"提案标题:{proposal['title']}")
final_status = "Unknown"
comments = []
for msg in messages[1:]:
if isinstance(msg, AIMessage):
try:
data = json.loads(msg.content)
if"status"in data:
final_status = data["status"]
if"comment"in data:
comments.append(data["comment"])
except Exception:
continue
print(f"最终状态:{final_status}")
print("评论:")
for comment in comments:
print(f" - {comment}")
if __name__ == "__main__":
main()
(三)循环模式:持续改进的协同
循环模式则像是一个“精益求精”的过程。在这种模式下,智能体们会不断地迭代,根据其他智能体的反馈来改进自己的输出。比如,在代码编写和测试的场景中,代码编写智能体会根据测试智能体的反馈不断优化代码,直到代码通过所有测试为止。
代码示例:
from typing import Dict, Any, List
from langgraph.graph import StateGraph, END
from langchain_core.runnables import RunnableConfig
import textwrap
# 定义状态
class EvaluationState(Dict[str, Any]):
code: str = ""
feedback: str = ""
passed: bool = False
iteration: int = 0
max_iterations: int = 3
history: List[Dict] = []
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setdefault("code", "")
self.setdefault("feedback", "")
self.setdefault("passed", False)
self.setdefault("iteration", 0)
self.setdefault("max_iterations", 3)
self.setdefault("history", [])
# 代码编写智能体
def code_writer_agent(state: EvaluationState, config: RunnableConfig) -> Dict[str, Any]:
print(f"迭代 {state['iteration'] + 1} - 代码编写智能体:生成代码")
print(f"迭代 {state['iteration'] + 1} - 代码编写智能体:收到反馈:{state['feedback']}")
iteration = state["iteration"] + 1
feedback = state["feedback"]
if iteration == 1:
code = textwrap.dedent("""
def factorial(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
""")
writer_feedback = "初始代码已生成。"
elif"factorial(0)"in feedback.lower():
code = textwrap.dedent("""
def factorial(n):
if n == 0:
return 1
result = 1
for i in range(1, n + 1):
result *= i
return result
""")
writer_feedback = "已修复 n=0 的处理。"
elif"factorial(-1)"in feedback.lower() or"negative"in feedback.lower():
code = textwrap.dedent("""
def factorial(n):
if n < 0:
raise ValueError("Factorial not defined for negative numbers")
if n == 0:
return 1
result = 1
for i in range(1, n + 1):
result *= i
return result
""")
writer_feedback = "已添加对负数输入的错误处理。"
else:
code = state["code"]
writer_feedback = "未发现进一步改进的内容。"
print(f"迭代 {iteration} - 代码编写智能体:代码生成完成")
return {
"code": code,
"feedback": writer_feedback,
"iteration": iteration
}
# 代码测试智能体
def code_tester_agent(state: EvaluationState, config: RunnableConfig) -> Dict[str, Any]:
print(f"迭代 {state['iteration']} - 代码测试智能体:测试代码")
code = state["code"]
try:
test_cases = [
(0, 1),
(1, 1),
(5, 120),
(-1, None)
]
namespace = {}
exec(code, namespace)
factorial = namespace.get('factorial')
ifnot callable(factorial):
return {"passed": False, "feedback": "未找到阶乘函数。"}
feedback_parts = []
passed = True
for input_val, expected in test_cases:
try:
result = factorial(input_val)
if expected isNone:
passed = False
feedback_parts.append(f"测试失败:factorial({input_val}) 应该抛出错误。")
elif result != expected:
passed = False
feedback_parts.append(f"测试失败:factorial({input_val}) 返回 {result},预期为 {expected}。")
except ValueError as ve:
if expected isnotNone:
passed = False
feedback_parts.append(f"测试失败:factorial({input_val}) 意外抛出 ValueError:{str(ve)}")
except Exception as e:
passed = False
feedback_parts.append(f"测试失败:factorial({input_val}) 抛出错误:{str(e)}")
feedback = "所有测试通过!"if passed else"\n".join(feedback_parts)
print(f"迭代 {state['iteration']} - 代码测试智能体:测试完成 - {'通过' if passed else '失败'}")
history = state["history"]
history.append({
"iteration": state["iteration"],
"code": code,
"feedback": feedback,
"passed": passed
})
return {
"passed": passed,
"feedback": feedback,
"history": history
}
except Exception as e:
print(f"迭代 {state['iteration']} - 代码测试智能体:测试失败")
return {"passed": False, "feedback": f"测试错误:{str(e)}"}
# 条件边:决定是否继续循环
def should_continue(state: EvaluationState) -> str:
if state["passed"] or state["iteration"] >= state["max_iterations"]:
print(f"迭代 {state['iteration']} - {'循环停止:测试通过' if state['passed'] else '循环停止:达到最大迭代次数'}")
return"end"
print(f"迭代 {state['iteration']} - 循环继续:测试失败")
return"code_writer"
# 构建 LangGraph 工作流
workflow = StateGraph(EvaluationState)
workflow.add_node("code_writer", code_writer_agent)
workflow.add_node("code_tester", code_tester_agent)
workflow.set_entry_point("code_writer")
workflow.add_edge("code_writer", "code_tester")
workflow.add_conditional_edges(
"code_tester",
should_continue,
{
"code_writer": "code_writer",
"end": END
}
)
app = workflow.compile()
# 运行工作流
def main():
initial_state = EvaluationState()
result = app.invoke(initial_state)
print("\n=== 评估结果 ===")
print(f"最终状态:{'通过' if result['passed'] else '失败'},经过 {result['iteration']} 次迭代")
print(f"最终代码:\n{result['code']}")
print(f"最终反馈:\n{result['feedback']}")
print("\n迭代历史:")
for attempt in result["history"]:
print(f"迭代 {attempt['iteration']}:")
print(f" 代码:\n{attempt['code']}")
print(f" 反馈:{attempt['feedback']}")
print(f" 是否通过:{attempt['passed']}\n")
if __name__ == "__main__":
main()
(四)路由器模式:智能分配任务
路由器模式则像是一个“任务分发中心”。在这种模式下,一个中央路由器智能体根据任务或输入的内容,决定调用哪些智能体。比如,在一个客户支持系统中,路由器可以根据客户的问题内容,将问题分配给不同的支持团队,如账单团队、技术支持团队或普通咨询团队。
代码示例:
from typing import Dict, Any, TypedDict, Literal
from langgraph.graph import StateGraph, END
from langchain_core.runnables import RunnableConfig
import re
import time
# 定义状态
class TicketState(TypedDict):
ticket_text: str
category: str
resolution: str
processing_time: float
# 路由器智能体
def router_agent(state: TicketState) -> Dict[str, Any]:
print("路由器智能体:分析工单...")
start_time = time.time()
ticket_text = state["ticket_text"].lower()
if any(keyword in ticket_text for keyword in ["billing", "payment", "invoice", "charge"]):
category = "Billing"
elif any(keyword in ticket_text for keyword in ["technical", "bug", "error", "crash"]):
category = "Technical"
elif any(keyword in ticket_text for keyword in ["general", "question", "inquiry", "info"]):
category = "General"
else:
category = "Unknown"
processing_time = time.time() - start_time
print(f"路由器智能体:分类为 '{category}',耗时 {processing_time:.2f} 秒")
return {
"category": category,
"processing_time": processing_time
}
# 账单团队
def billing_team_agent(state: TicketState) -> Dict[str, Any]:
print("账单团队:处理工单...")
start_time = time.time()
ticket_text = state["ticket_text"]
resolution = f"账单团队:已审核工单 '{ticket_text}'。请检查您的账单详情或联系我们的账单部门以获取进一步帮助。"
processing_time = time.time() - start_time
time.sleep(1)
print(f"账单团队:完成,耗时 {processing_time:.2f} 秒")
return {
"resolution": resolution,
"processing_time": state["processing_time"] + processing_time
}
# 技术支持团队
def technical_team_agent(state: TicketState) -> Dict[str, Any]:
print("技术支持团队:处理工单...")
start_time = time.time()
ticket_text = state["ticket_text"]
resolution = f"技术支持团队:已审核工单 '{ticket_text}'。请尝试重启您的设备或提交详细的错误日志以供进一步调查。"
processing_time = time.time() - start_time
time.sleep(1.5)
print(f"技术支持团队:完成,耗时 {processing_time:.2f} 秒")
return {
"resolution": resolution,
"processing_time": state["processing_time"] + processing_time
}
# 普通咨询团队
def general_team_agent(state: TicketState) -> Dict[str, Any]:
print("普通咨询团队:处理工单...")
start_time = time.time()
ticket_text = state["ticket_text"]
resolution = f"普通咨询团队:已审核工单 '{ticket_text}'。更多信息,请参考我们的常见问题解答或通过电子邮件联系我们。"
processing_time = time.time() - start_time
time.sleep(0.8)
print(f"普通咨询团队:完成,耗时 {processing_time:.2f} 秒")
return {
"resolution": resolution,
"processing_time": state["processing_time"] + processing_time
}
# 手动审核团队
def manual_review_agent(state: TicketState) -> Dict[str, Any]:
print("手动审核团队:处理工单...")
start_time = time.time()
ticket_text = state["ticket_text"]
resolution = f"手动审核:工单 '{ticket_text}' 无法分类。标记为人工审核。请手动分配到适当的团队。"
processing_time = time.time() - start_time
time.sleep(0.5)
print(f"手动审核团队:完成,耗时 {processing_time:.2f} 秒")
return {
"resolution": resolution,
"processing_time": state["processing_time"] + processing_time
}
# 路由函数
def route_ticket(state: TicketState) -> Literal["billing_team", "technical_team", "general_team", "manual_review"]:
category = state["category"]
print(f"路由:工单分类为 '{category}'")
if category == "Billing":
return"billing_team"
elif category == "Technical":
return"technical_team"
elif category == "General":
return"general_team"
else:
return"manual_review"
# 构建路由器模式的图
def build_router_graph() -> StateGraph:
workflow = StateGraph(TicketState)
workflow.add_node("router", router_agent)
workflow.add_node("billing_team", billing_team_agent)
workflow.add_node("technical_team", technical_team_agent)
workflow.add_node("general_team", general_team_agent)
workflow.add_node("manual_review", manual_review_agent)
workflow.set_entry_point("router")
workflow.add_conditional_edges(
"router",
route_ticket,
{
"billing_team": "billing_team",
"technical_team": "technical_team",
"general_team": "general_team",
"manual_review": "manual_review"
}
)
workflow.add_edge("billing_team", END)
workflow.add_edge("technical_team", END)
workflow.add_edge("general_team", END)
workflow.add_edge("manual_review", END)
return workflow.compile()
# 运行工作流
def main():
test_tickets = [
"I have a billing issue with my last invoice. It seems I was overcharged.",
"My app keeps crashing with a technical error. Please help!",
"I have a general question about your services. Can you provide more info?",
"I need assistance with something unrelated to billing or technical issues."
]
for ticket_text in test_tickets:
initial_state: TicketState = {
"ticket_text": ticket_text,
"category": "",
"resolution": "",
"processing_time": 0.0
}
print(f"\n=== 处理工单:'{ticket_text}' ===")
app = build_router_graph()
start_time = time.time()
result = app.invoke(initial_state, cnotallow=RunnableConfig())
total_time = time.time() - start_time
print("\n=== 工单结果 ===")
print(f"分类:{result['category']}")
print(f"解决方案:{result['resolution']}")
print(f"总处理时间:{result['processing_time']:.2f} 秒")
print(f"总耗时:{total_time:.2f} 秒")
print("-" * 50)
if __name__ == "__main__":
main()
(五)聚合模式:整合输出
聚合模式则像是一个“信息汇总中心”。在这种模式下,多个智能体分别完成自己的任务后,将输出传递给一个聚合智能体,由聚合智能体将所有结果整合成一个最终结果。比如,在社交媒体情感分析中,可以有多个智能体分别收集不同平台的帖子并进行情感分析,最后由聚合智能体生成一份综合报告。
代码示例:
from typing import Dict, Any, TypedDict, List
from langgraph.graph import StateGraph, END
from langchain_core.runnables import RunnableConfig
from textblob import TextBlob
import time
from typing_extensions import Annotated
from operator import add
# 定义状态
class SocialMediaState(TypedDict):
twitter_posts: List[str]
instagram_posts: List[str]
reddit_posts: List[str]
twitter_sentiment: Dict[str, float]
instagram_sentiment: Dict[str, float]
reddit_sentiment: Dict[str, float]
final_report: str
processing_time: Annotated[float, add]
# 收集推特帖子
def collect_twitter_posts(state: SocialMediaState) -> Dict[str, Any]:
print("推特智能体:收集帖子...")
start_time = time.time()
posts = [
"Loving the new product from this brand! Amazing quality.",
"Terrible customer service from this brand. Very disappointed."
]
time.sleep(1)
processing_time = time.time() - start_time
print(f"推特智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"twitter_posts": posts,
"processing_time": processing_time
}
# 收集 Instagram 帖子
def collect_instagram_posts(state: SocialMediaState) -> Dict[str, Any]:
print("Instagram 智能体:收集帖子...")
start_time = time.time()
posts = [
"Beautiful design by this brand! #loveit",
"Not impressed with the latest release. Expected better."
]
time.sleep(1.2)
processing_time = time.time() - start_time
print(f"Instagram 智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"instagram_posts": posts,
"processing_time": processing_time
}
# 收集 Reddit 帖子
def collect_reddit_posts(state: SocialMediaState) -> Dict[str, Any]:
print("Reddit 智能体:收集帖子...")
start_time = time.time()
posts = [
"This brand is awesome! Great value for money.",
"Had a bad experience with their support team. Not happy."
]
time.sleep(0.8)
processing_time = time.time() - start_time
print(f"Reddit 智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"reddit_posts": posts,
"processing_time": processing_time
}
# 分析推特情感
def analyze_twitter_sentiment(state: SocialMediaState) -> Dict[str, Any]:
print("推特情感智能体:分析情感...")
start_time = time.time()
posts = state["twitter_posts"]
polarities = [TextBlob(post).sentiment.polarity for post in posts]
avg_polarity = sum(polarities) / len(polarities) if polarities else0.0
time.sleep(0.5)
processing_time = time.time() - start_time
print(f"推特情感智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"twitter_sentiment": {"average_polarity": avg_polarity, "num_posts": len(posts)},
"processing_time": processing_time
}
# 分析 Instagram 情感
def analyze_instagram_sentiment(state: SocialMediaState) -> Dict[str, Any]:
print("Instagram 情感智能体:分析情感...")
start_time = time.time()
posts = state["instagram_posts"]
polarities = [TextBlob(post).sentiment.polarity for post in posts]
avg_polarity = sum(polarities) / len(polarities) if polarities else0.0
time.sleep(0.6)
processing_time = time.time() - start_time
print(f"Instagram 情感智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"instagram_sentiment": {"average_polarity": avg_polarity, "num_posts": len(posts)},
"processing_time": processing_time
}
# 分析 Reddit 情感
def analyze_reddit_sentiment(state: SocialMediaState) -> Dict[str, Any]:
print("Reddit 情感智能体:分析情感...")
start_time = time.time()
posts = state["reddit_posts"]
polarities = [TextBlob(post).sentiment.polarity for post in posts]
avg_polarity = sum(polarities) / len(polarities) if polarities else0.0
time.sleep(0.4)
processing_time = time.time() - start_time
print(f"Reddit 情感智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"reddit_sentiment": {"average_polarity": avg_polarity, "num_posts": len(posts)},
"processing_time": processing_time
}
# 聚合结果
def aggregate_results(state: SocialMediaState) -> Dict[str, Any]:
print("聚合智能体:生成最终报告...")
start_time = time.time()
twitter_sentiment = state["twitter_sentiment"]
instagram_sentiment = state["instagram_sentiment"]
reddit_sentiment = state["reddit_sentiment"]
total_posts = (twitter_sentiment["num_posts"] +
instagram_sentiment["num_posts"] +
reddit_sentiment["num_posts"])
weighted_polarity = (
twitter_sentiment["average_polarity"] * twitter_sentiment["num_posts"] +
instagram_sentiment["average_polarity"] * instagram_sentiment["num_posts"] +
reddit_sentiment["average_polarity"] * reddit_sentiment["num_posts"]
) / total_posts if total_posts > 0else0.0
overall_sentiment = ("Positive"if weighted_polarity > 0else
"Negative"if weighted_polarity < 0else"Neutral")
report = (
f"总体情感:{overall_sentiment} (平均极性:{weighted_polarity:.2f})\n"
f"推特情感:{twitter_sentiment['average_polarity']:.2f} (帖子数:{twitter_sentiment['num_posts']})\n"
f"Instagram 情感:{instagram_sentiment['average_polarity']:.2f} (帖子数:{instagram_sentiment['num_posts']})\n"
f"Reddit 情感:{reddit_sentiment['average_polarity']:.2f} (帖子数:{reddit_sentiment['num_posts']})"
)
time.sleep(0.3)
processing_time = time.time() - start_time
print(f"聚合智能体:完成,耗时 {processing_time:.2f} 秒")
return {
"final_report": report,
"processing_time": processing_time
}
# 构建聚合模式的图
def build_aggregator_graph() -> StateGraph:
workflow = StateGraph(SocialMediaState)
workflow.add_node("collect_twitter", collect_twitter_posts)
workflow.add_node("collect_instagram", collect_instagram_posts)
workflow.add_node("collect_reddit", collect_reddit_posts)
workflow.add_node("analyze_twitter", analyze_twitter_sentiment)
workflow.add_node("analyze_instagram", analyze_instagram_sentiment)
workflow.add_node("analyze_reddit", analyze_reddit_sentiment)
workflow.add_node("aggregate", aggregate_results)
workflow.add_node("branch", lambda state: state)
workflow.set_entry_point("branch")
workflow.add_edge("branch", "collect_twitter")
workflow.add_edge("branch", "collect_instagram")
workflow.add_edge("branch", "collect_reddit")
workflow.add_edge("collect_twitter", "analyze_twitter")
workflow.add_edge("collect_instagram", "analyze_instagram")
workflow.add_edge("collect_reddit", "analyze_reddit")
workflow.add_edge("analyze_twitter", "aggregate")
workflow.add_edge("analyze_instagram", "aggregate")
workflow.add_edge("analyze_reddit", "aggregate")
workflow.add_edge("aggregate", END)
return workflow.compile()
# 运行工作流
def main():
initial_state: SocialMediaState = {
"twitter_posts": [],
"instagram_posts": [],
"reddit_posts": [],
"twitter_sentiment": {"average_polarity": 0.0, "num_posts": 0},
"instagram_sentiment": {"average_polarity": 0.0, "num_posts": 0},
"reddit_sentiment": {"average_polarity": 0.0, "num_posts": 0},
"final_report": "",
"processing_time": 0.0
}
print("\n开始社交媒体情感分析...")
app = build_aggregator_graph()
start_time = time.time()
config = RunnableConfig(parallel=True)
result = app.invoke(initial_state, cnotallow=config)
total_time = time.time() - start_time
print("\n=== 情感分析结果 ===")
print(result["final_report"])
print(f"\n总处理时间:{result['processing_time']:.2f} 秒")
print(f"总耗时:{total_time:.2f} 秒")
if __name__ == "__main__":
main()
(六)网络模式(Network or Horizontal)
在多智能体系统中,网络模式是一种去中心化的架构,智能体之间以多对多的方式直接通信,形成一个分散的网络。这种架构非常适合那些没有明确智能体层级或调用顺序的任务。
优点与挑战
优点:
- 分布式协作:每个智能体都可以独立运行,即使部分智能体失败,系统仍然可以正常工作。
- 群体决策:智能体之间可以相互协作,共同做出决策。
挑战:
- 通信管理:智能体之间的通信可能会变得复杂,导致效率低下。
- 重复工作:如果没有良好的协调机制,智能体可能会重复执行相同的工作。
代码示例:
from typing import Literal
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.types import Command
model = ChatOpenAI()
# 定义智能体 1
def agent_1(state: MessagesState) -> Command[Literal["agent_2", "agent_3", END]]:
response = model.invoke(state["messages"])
next_agent = response.get("next_agent", END)
return Command(
goto=next_agent,
update={"messages": [response["content"]]}
)
# 定义智能体 2
def agent_2(state: MessagesState) -> Command[Literal["agent_1", "agent_3", END]]:
response = model.invoke(state["messages"])
next_agent = response.get("next_agent", END)
return Command(
goto=next_agent,
update={"messages": [response["content"]]}
)
# 定义智能体 3
def agent_3(state: MessagesState) -> Command[Literal["agent_1", "agent_2", END]]:
response = model.invoke(state["messages"])
next_agent = response.get("next_agent", END)
return Command(
goto=next_agent,
update={"messages": [response["content"]]}
)
# 构建图
builder = StateGraph(MessagesState)
builder.add_node(agent_1)
builder.add_node(agent_2)
builder.add_node(agent_3)
builder.add_edge(START, "agent_1")
network = builder.compile()
(七)交接模式(Handoffs)
在多智能体架构中,交接模式是一种常见的交互方式,其中一个智能体在完成自己的任务后,将控制权交给另一个智能体。这种模式允许智能体在执行过程中灵活地将任务传递给其他智能体,甚至可以返回到自己。
代码示例:
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.types import Command
# 定义一个智能体
def agent(state: MessagesState) -> Command[Literal["another_agent"]]:
# 假设 get_next_agent 是一个函数,用于决定下一个智能体
next_agent = get_next_agent(state)
return Command(
goto=next_agent,
update={"messages": ["Message from current agent"]}
)
(八)监督者模式(Supervisor)
监督者模式是一种集中式的架构,其中有一个中央监督者(Supervisor)智能体,负责决定下一个调用的智能体。这种模式适合需要集中管理和协调的场景。
代码示例:
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.types import Command
model = ChatOpenAI()
# 定义监督者
def supervisor(state: MessagesState) -> Command[Literal["agent_1", "agent_2", END]]:
response = model.invoke(state["messages"])
next_agent = response.get("next_agent", END)
return Command(goto=next_agent)
# 定义智能体 1
def agent_1(state: MessagesState) -> Command[Literal["supervisor"]]:
response = model.invoke(state["messages"])
return Command(goto="supervisor", update={"messages": [response]})
# 定义智能体 2
def agent_2(state: MessagesState) -> Command[Literal["supervisor"]]:
response = model.invoke(state["messages"])
return Command(goto="supervisor", update={"messages": [response]})
# 构建图
builder = StateGraph(MessagesState)
builder.add_node(supervisor)
builder.add_node(agent_1)
builder.add_node(agent_2)
builder.add_edge(START, "supervisor")
supervisor_graph = builder.compile()
(九)层次化模式(Hierarchical)
层次化模式是一种树状结构,其中高级智能体(监督者)管理低级智能体。这种架构适合大型系统,可以清晰地划分角色和职责。
代码示例:
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.types import Command
model = ChatOpenAI()
# 定义团队 1 的监督者
def team_1_supervisor(state: MessagesState) -> Command[Literal["team_1_agent_1", "team_1_agent_2", END]]:
response = model.invoke(state["messages"])
next_agent = response.get("next_agent", END)
return Command(goto=next_agent)
# 定义团队 1 的智能体 1
def team_1_agent_1(state: MessagesState) -> Command[Literal["team_1_supervisor"]]:
response = model.invoke(state["messages"])
return Command(goto="team_1_supervisor", update={"messages": [response]})
# 定义团队 1 的智能体 2
def team_1_agent_2(state: MessagesState) -> Command[Literal["team_1_supervisor"]]:
response = model.invoke(state["messages"])
return Command(goto="team_1_supervisor", update={"messages": [response]})
# 构建团队 1 的图
team_1_builder = StateGraph(MessagesState)
team_1_builder.add_node(team_1_supervisor)
team_1_builder.add_node(team_1_agent_1)
team_1_builder.add_node(team_1_agent_2)
team_1_builder.add_edge(START, "team_1_supervisor")
team_1_graph = team_1_builder.compile()
# 定义顶层监督者
def top_level_supervisor(state: MessagesState) -> Command[Literal["team_1_graph", END]]:
response = model.invoke(state["messages"])
next_team = response.get("next_team", END)
return Command(goto=next_team)
# 构建顶层图
top_builder = StateGraph(MessagesState)
top_builder.add_node(top_level_supervisor)
top_builder.add_node("team_1_graph", team_1_graph)
top_builder.add_edge(START, "top_level_supervisor")
top_builder.add_edge("team_1_graph", "top_level_supervisor")
top_graph = top_builder.compile()
(十)自定义工作流(Custom Multi-Agent Workflow)
自定义工作流允许开发者根据具体需求定义智能体之间的调用顺序。这种模式结合了显式控制流和动态控制流的优点,提供了更高的灵活性。
代码示例:
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START
model = ChatOpenAI()
# 定义智能体 1
def agent_1(state: MessagesState):
response = model.invoke(state["messages"])
return {"messages": [response]}
# 定义智能体 2
def agent_2(state: MessagesState):
response = model.invoke(state["messages"])
return {"messages": [response]}
# 构建图
builder = StateGraph(MessagesState)
builder.add_node(agent_1)
builder.add_node(agent_2)
builder.add_edge(START, "agent_1")
builder.add_edge("agent_1", "agent_2")
custom_workflow = builder.compile()
三、智能体之间的通信:协同的关键
在多智能体系统中,智能体之间的通信是协同工作的核心。我们需要考虑以下几个问题:
- 通过图状态还是工具调用通信?在大多数架构中,智能体通过图状态通信。而在工具调用的架构中,通信的内容则是工具调用的参数。
- 不同状态模式的智能体如何通信?如果一个智能体需要与其他智能体有不同的状态模式,可以通过定义子图智能体或具有私有输入状态模式的智能体节点来实现。
- 共享消息列表如何通信?最常见的通信方式是通过共享状态通道(通常是消息列表)。智能体可以选择共享完整的思考过程(“草稿”),也可以只共享最终结果。
四、多智能体架构的优势与挑战
多智能体架构为我们解决复杂任务提供了强大的工具,但也带来了新的挑战。它通过并行、顺序、路由器和聚合等多种工作流模式,实现了高效的协同工作。然而,随着智能体数量的增加和任务复杂度的提升,如何管理智能体之间的通信、避免重复工作以及确保系统的可扩展性,成为了我们需要面对的问题。
五、结论
多智能体架构为我们提供了一个全新的视角来解决复杂任务。通过不同的协同模式和通信机制,我们可以构建出高效、灵活且可扩展的系统。无论是并行处理、顺序执行、智能路由还是结果聚合,多智能体架构都能根据具体需求提供合适的解决方案。在未来,随着AI技术的不断发展,多智能体架构必将在更多领域发挥更大的作用,为我们的生活和工作带来更多的便利和效率。
本文转载自Halo咯咯 作者:基咯咯
