AI创想

标题: 理解AI 智能体:多智能体架构 [打印本页]

作者: 米落枫    时间: 昨天 18:20
标题: 理解AI 智能体:多智能体架构
作者:dylan55_you

(, 下载次数: 0)



1. 引言

智能体(Agent)是一个使用大语言模型(LLM)来决定应用程序控制流程的系统。随着这些系统的开发,它们可能会变得越来越复杂,难以管理和扩展。例如,你可能会遇到以下问题:
为了解决这些问题,你可能会考虑将应用程序分解为多个更小、独立的智能体,并将它们组合成一个多智能体系统。这些独立的智能体可以简单到一个提示词(prompt)加一次 LLM 调用,也可以复杂到一个 ReAct 智能体(甚至更复杂!)。
(, 下载次数: 0)


随着智能体框架的发展,许多公司开始构建自己的多智能体系统,并寻找能够解决所有智能体任务的“银弹”方案。两年前,研究人员设计了一个名为 ChatDev 的多智能体协作系统。ChatDev 是一个虚拟软件公司,通过拥有不同角色(如首席执行官、首席产品官、艺术设计师、程序员、评审员、测试员等,就像一个常规的软件工程公司一样)的各种智能体来运作。
(, 下载次数: 0)


所有这些智能体协同工作,相互交流,最终成功创建了一款视频游戏。在这一成就之后,许多人认为任何软件工程任务都可以使用这种多智能体架构来解决,即每个 AI 都有明确的角色分工。然而,现实世界的实验表明,并非所有问题都能用相同的架构解决。在某些情况下,更简单的架构可能提供更有效、更具成本效益的解决方案。
1.1 单智能体 vs. 多智能体架构

起初,单智能体方法(即一个 AI 智能体可以处理所有事情,从浏览器导航到文件操作)可能是合理的。然而,随着时间的推移,随着任务变得更加复杂和工具数量的增长,我们的单智能体方法将开始面临挑战。
(, 下载次数: 0)


当智能体开始出现异常行为时,我们会注意到以下影响,其原因可能包括:
当我们开始自动化多个不同的子任务(如数据提取或报告生成)时,可能就到了分离职责的时候了。通过使用多个 AI 智能体,每个智能体专注于自己的领域和工具集,我们可以提高解决方案的清晰度和质量。这不仅使智能体变得更有效,而且也简化了智能体本身的开发。

(, 下载次数: 0)



2. 多智能体架构

正如你所见,单智能体和多智能体架构都各有优缺点。当任务直接且定义明确,并且没有特定的资源限制时,单智能体架构是理想的选择。另一方面,当用例复杂且动态、需要更专业的知识和协作、或有可扩展性和适应性要求时,多智能体架构会很有帮助。
2.1 多智能体系统中的模式

在多智能体系统中,有多种连接智能体的方式:
2.1.1 并行 (Parallel)

多个智能体同时处理任务的不同部分。
(, 下载次数: 0)


示例:我们希望使用 3 个智能体同时对给定文本进行摘要、翻译和情绪分析。
(, 下载次数: 0)

  1. from typing import Dict, Any, TypedDict
  2. from langgraph.graph import StateGraph, END
  3. from langchain_core.runnables import RunnableConfig
  4. from textblob import TextBlob
  5. import re
  6. import time
  7. # Define the state
  8. class AgentState(TypedDict):
  9.     text: str
  10.     summary: str
  11.     translation: str
  12.     sentiment: str
  13.     summary_time: float
  14.     translation_time: float
  15.     sentiment_time: float
  16. # Summarization Agent
  17. def summarize_agent(state: AgentState) -> Dict[str, Any]:
  18.     print("Summarization Agent: Running")
  19.     start_time = time.time()
  20.    
  21.     try:
  22.         text = state["text"]
  23.         if not text.strip():
  24.             return {
  25.                 "summary": "No text provided for summarization.",
  26.                 "summary_time": 0.0
  27.             }
  28.             
  29.         time.sleep(2)
  30.         sentences = re.split(r'(?<=[.!?]) +', text.strip())
  31.         scored_sentences = [(s, len(s.split())) for s in sentences if s]
  32.         top_sentences = [s for s, _ in sorted(scored_sentences, key=lambda x: x[1], reverse=True)[:2]]
  33.         summary = " ".join(top_sentences) if top_sentences else "Text too short to summarize."
  34.         
  35.         processing_time = time.time() - start_time
  36.         print(f"Summarization Agent: Completed in {processing_time:.2f} seconds")
  37.         
  38.         return {
  39.             "summary": summary,
  40.             "summary_time": processing_time
  41.         }
  42.     except Exception as e:
  43.         return {
  44.             "summary": f"Error in summarization: {str(e)}",
  45.             "summary_time": 0.0
  46.         }
  47. # Translation Agent
  48. def translate_agent(state: AgentState) -> Dict[str, Any]:
  49.     print("Translation Agent: Running")
  50.     start_time = time.time()
  51.    
  52.     try:
  53.         text = state["text"]
  54.         if not text.strip():
  55.             return {
  56.                 "translation": "No text provided for translation.",
  57.                 "translation_time": 0.0
  58.             }
  59.             
  60.         time.sleep(3)
  61.         translation = (
  62.             "El nuevo parque en la ciudad es una maravillosa adición. "
  63.             "Las familias disfrutan de los espacios abiertos, y a los niños les encanta el parque infantil. "
  64.             "Sin embargo, algunas personas piensan que el área de estacionamiento es demasiado pequeña."
  65.         )
  66.         
  67.         processing_time = time.time() - start_time
  68.         print(f"Translation Agent: Completed in {processing_time:.2f} seconds")
  69.         
  70.         return {
  71.             "translation": translation,
  72.             "translation_time": processing_time
  73.         }
  74.     except Exception as e:
  75.         return {
  76.             "translation": f"Error in translation: {str(e)}",
  77.             "translation_time": 0.0
  78.         }
  79. # Sentiment Agent
  80. def sentiment_agent(state: AgentState) -> Dict[str, Any]:
  81.     print("Sentiment Agent: Running")
  82.     start_time = time.time()
  83.    
  84.     try:
  85.         text = state["text"]
  86.         if not text.strip():
  87.             return {
  88.                 "sentiment": "No text provided for sentiment analysis.",
  89.                 "sentiment_time": 0.0
  90.             }
  91.             
  92.         time.sleep(1.5)
  93.         blob = TextBlob(text)
  94.         polarity = blob.sentiment.polarity
  95.         subjectivity = blob.sentiment.subjectivity
  96.         
  97.         sentiment = "Positive" if polarity > 0 else "Negative" if polarity < 0 else "Neutral"
  98.         result = f"{sentiment} (Polarity: {polarity:.2f}, Subjectivity: {subjectivity:.2f})"
  99.         
  100.         processing_time = time.time() - start_time
  101.         print(f"Sentiment Agent: Completed in {processing_time:.2f} seconds")
  102.         
  103.         return {
  104.             "sentiment": result,
  105.             "sentiment_time": processing_time
  106.         }
  107.     except Exception as e:
  108.         return {
  109.             "sentiment": f"Error in sentiment analysis: {str(e)}",
  110.             "sentiment_time": 0.0
  111.         }
  112. # Join Node
  113. def join_parallel_results(state: AgentState) -> AgentState:
  114.     return state
  115. # Build the Graph
  116. def build_parallel_graph() -> StateGraph:
  117.     workflow = StateGraph(AgentState)
  118.    
  119.     # Define parallel branches
  120.     parallel_branches = {
  121.         "summarize_node": summarize_agent,
  122.         "translate_node": translate_agent,
  123.         "sentiment_node": sentiment_agent
  124.     }
  125.    
  126.     # Add parallel processing nodes
  127.     for name, agent in parallel_branches.items():
  128.         workflow.add_node(name, agent)
  129.    
  130.     # Add branching and joining nodes
  131.     workflow.add_node("branch", lambda state: state)  # Simplified branch function
  132.     workflow.add_node("join", join_parallel_results)
  133.    
  134.     # Set entry point
  135.     workflow.set_entry_point("branch")
  136.    
  137.     # Add edges for parallel execution
  138.     for name in parallel_branches:
  139.         workflow.add_edge("branch", name)
  140.         workflow.add_edge(name, "join")
  141.    
  142.     workflow.add_edge("join", END)
  143.    
  144.     return workflow.compile()
  145. # Main function
  146. def main():
  147.     text = (
  148.         "The new park in the city is a wonderful addition. Families are enjoying the open spaces, "
  149.         "and children love the playground. However, some people think the parking area is too small."
  150.     )
  151.    
  152.     initial_state: AgentState = {
  153.         "text": text,
  154.         "summary": "",
  155.         "translation": "",
  156.         "sentiment": "",
  157.         "summary_time": 0.0,
  158.         "translation_time": 0.0,
  159.         "sentiment_time": 0.0
  160.     }
  161.    
  162.     print("\\nBuilding new graph...")
  163.     app = build_parallel_graph()
  164.    
  165.     print("\\nStarting parallel processing...")
  166.     start_time = time.time()
  167.    
  168.     config = RunnableConfig(parallel=True)
  169.     result = app.invoke(initial_state, config=config)
  170.    
  171.     total_time = time.time() - start_time
  172.    
  173.     print("\\n=== Parallel Task Results ===")
  174.     print(f"Input Text:\\n{text}\\n")
  175.     print(f"Summary:\\n{result['summary']}\\n")
  176.     print(f"Translation (Spanish):\\n{result['translation']}\\n")
  177.     print(f"Sentiment Analysis:\\n{result['sentiment']}\\n")
  178.    
  179.     print("\\n=== Processing Times ===")
  180.     processing_times = {
  181.         "summary": result["summary_time"],
  182.         "translation": result["translation_time"],
  183.         "sentiment": result["sentiment_time"]
  184.     }
  185.     for agent, time_taken in processing_times.items():
  186.         print(f"{agent.capitalize()}: {time_taken:.2f} seconds")
  187.    
  188.     print(f"\\nTotal Wall Clock Time: {total_time:.2f} seconds")
  189.     print(f"Sum of Individual Processing Times: {sum(processing_times.values()):.2f} seconds")
  190.     print(f"Time Saved by Parallel Processing: {sum(processing_times.values()) - total_time:.2f} seconds")
  191. if __name__ == "__main__":
  192.     main()
复制代码
输出:
  1. Building new graph...
  2. Starting parallel processing...
  3. Sentiment Agent: Running
  4. Summarization Agent: Running
  5. Translation Agent: Running
  6. Sentiment Agent: Completed in 1.50 seconds
  7. Summarization Agent: Completed in 2.00 seconds
  8. Translation Agent: Completed in 3.00 seconds
  9. === Parallel Task Results ===
  10. Input Text:
  11. 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.
  12. Summary:
  13. Families are enjoying the open spaces, and children love the playground. The new park in the city is a wonderful addition.
  14. Translation (Spanish):
  15. 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.
  16. Sentiment Analysis:
  17. Positive (Polarity: 0.31, Subjectivity: 0.59)
  18. === Processing Times ===
  19. Summary: 2.00 seconds
  20. Translation: 3.00 seconds
  21. Sentiment: 1.50 seconds
  22. Total Wall Clock Time: 3.01 seconds
  23. Sum of Individual Processing Times: 6.50 seconds
  24. Time Saved by Parallel Processing: 3.50 seconds
复制代码
2.1.2 顺序 (Sequential)

任务按顺序处理,一个智能体的输出成为下一个智能体的输入。
(, 下载次数: 0)


示例:多步审批流程。
  1. from typing import Dict
  2. from langgraph.graph import StateGraph, MessagesState, END
  3. from langchain_core.runnables import RunnableConfig
  4. from langchain_core.messages import HumanMessage, AIMessage
  5. import json
  6. # Agent 1: Team Lead
  7. def team_lead_agent(state: MessagesState, config: RunnableConfig) -> Dict:
  8.     print("Agent (Team Lead): Starting review")
  9.     messages = state["messages"]
  10.     proposal = json.loads(messages[0].content)
  11.     title = proposal.get("title", "")
  12.     amount = proposal.get("amount", 0.0)
  13.     if not title or amount <= 0:
  14.         status = "Rejected"
  15.         comment = "Team Lead: Proposal rejected due to missing title or invalid amount."
  16.         goto = END
  17.     else:
  18.         status = "Approved by Team Lead"
  19.         comment = "Team Lead: Proposal is complete and approved."
  20.         goto = "dept_manager"
  21.     print(f"Agent (Team Lead): Review complete - {status}")
  22.     messages.append(AIMessage(
  23.         content=json.dumps({"status": status, "comment": comment}),
  24.         additional_kwargs={"agent": "team_lead", "goto": goto}
  25.     ))
  26.     return {"messages": messages}
  27. # Agent 2: Department Manager
  28. def dept_manager_agent(state: MessagesState, config: RunnableConfig) -> Dict:
  29.     print("Agent (Department Manager): Starting review")
  30.     messages = state["messages"]
  31.     team_lead_msg = next((m for m in messages if m.additional_kwargs.get("agent") == "team_lead"), None)
  32.     proposal = json.loads(messages[0].content)
  33.     amount = proposal.get("amount", 0.0)
  34.     if json.loads(team_lead_msg.content)["status"] != "Approved by Team Lead":
  35.         status = "Rejected"
  36.         comment = "Department Manager: Skipped due to Team Lead rejection."
  37.         
复制代码
原文地址:https://blog.csdn.net/charce_you/article/details/150851671




欢迎光临 AI创想 (http://llms-ai.com/) Powered by Discuz! X3.4