MarkTechPost@AI 14小时前
Building a Multi-Agent AI Research Team with LangGraph and Gemini for Automated Reporting
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本教程详细介绍了如何利用LangGraph和Google的Gemini API构建一个完整的、多智能体协同的研究团队系统。该系统包含具有特定角色的智能体,如研究员、分析师、写手和主管,它们各自负责研究流程中的不同环节,共同协作完成数据收集、洞察分析、报告撰写和工作流程协调。教程还涵盖了内存持久化、智能体协调、自定义智能体和性能监控等功能,最终目标是实现自动化、智能化的研究会话,并生成结构化的研究报告。

💡 **多智能体协同研究流程**:该系统设计了研究员、分析师、写手和主管四个独立但协同工作的智能体。研究员负责初步信息收集和分析,分析师深入挖掘数据并提供见解,写手则负责撰写最终报告,而主管则协调整个工作流程,确保任务按顺序和质量完成。这种分工明确的协作模式提高了研究效率和报告的专业性。

🚀 **LangGraph与Gemini API集成**:教程的核心技术是LangGraph,一个用于构建多状态、多智能体应用程序的框架,以及Google的Gemini API,用于提供强大的语言模型能力。通过将两者结合,系统能够实现复杂的、多步骤的推理和内容生成,为自动化研究提供了坚实的技术基础。

💾 **内存持久化与状态管理**:系统引入了内存持久化机制(MemorySaver),确保了研究过程中的状态信息得以保存,允许中断后恢复或进行回溯分析。TypedDict被用于定义AgentState和AgentResponse,为智能体之间的数据交换提供了清晰的结构化定义,保证了信息传递的准确性和一致性。

⚙️ **智能体定制与工作流编排**:通过`create_research_agent`、`create_analyst_agent`、`create_writer_agent`和`create_supervisor_agent`等函数,可以灵活地创建和配置各个智能体的行为。LangGraph的`StateGraph`和`conditional_edges`功能则用于编排这些智能体的执行顺序和逻辑分支,构建出高度可定制的研究工作流。

📈 **自动化报告生成**:整个系统的最终目标是实现对任何给定主题的自动化、智能化研究会话,并最终生成结构化的研究报告。这包括从初步研究到深入分析再到最终报告撰写的全过程自动化,极大地提升了研究工作的效率和智能化水平。

In this tutorial, we build a complete multi-agent research team system using LangGraph and Google’s Gemini API. We utilize role-specific agents, Researcher, Analyst, Writer, and Supervisor, each responsible for a distinct part of the research pipeline. Together, these agents collaboratively gather data, analyze insights, synthesize a report, and coordinate the workflow. We also incorporate features like memory persistence, agent coordination, custom agents, and performance monitoring. By the end of the setup, we can run automated, intelligent research sessions that generate structured reports on any given topic.

!pip install langgraph langchain-google-genai langchain-community langchain-core python-dotenvimport osfrom typing import Annotated, List, Tuple, Unionfrom typing_extensions import TypedDictimport operatorfrom langchain_core.messages import BaseMessage, HumanMessage, AIMessage, SystemMessagefrom langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholderfrom langchain_google_genai import ChatGoogleGenerativeAIfrom langgraph.graph import StateGraph, ENDfrom langgraph.prebuilt import ToolNodefrom langgraph.checkpoint.memory import MemorySaverimport functoolsimport getpassGOOGLE_API_KEY = getpass.getpass("Enter your Google API Key: ")os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY

We begin by installing the necessary libraries, including LangGraph and LangChain’s Google Gemini integration. Then, we import the essential modules and set up our environment by securely entering the Google API key using the getpass module. This ensures we can authenticate our Gemini LLM without exposing the key in the code.

class AgentState(TypedDict):    """State shared between all agents in the graph"""    messages: Annotated[list, operator.add]    next: str    current_agent: str    research_topic: str    findings: dict    final_report: strclass AgentResponse(TypedDict):    """Standard response format for all agents"""    content: str    next_agent: str    findings: dictdef create_llm(temperature: float = 0.1, model: str = "gemini-1.5-flash") -> ChatGoogleGenerativeAI:    """Create a configured Gemini LLM instance"""    return ChatGoogleGenerativeAI(        model=model,        temperature=temperature,        google_api_key=os.environ["GOOGLE_API_KEY"]    )

We define two TypedDict classes to maintain structured state and responses shared across all agents in the LangGraph. AgentState tracks messages, workflow status, topic, and collected findings, while AgentResponse standardizes each agent’s output. We also create a helper function to start the Gemini LLM with a specified model and temperature, ensuring consistent behavior across all agents.

def create_research_agent(llm: ChatGoogleGenerativeAI) -> callable:    """Creates a research specialist agent for initial data gathering"""       research_prompt = ChatPromptTemplate.from_messages([        ("system", """You are a Research Specialist AI. Your role is to:        1. Analyze the research topic thoroughly        2. Identify key areas that need investigation        3. Provide initial research findings and insights        4. Suggest specific angles for deeper analysis               Focus on providing comprehensive, accurate information and clear research directions.        Always structure your response with clear sections and bullet points.        """),        MessagesPlaceholder(variable_name="messages"),        ("human", "Research Topic: {research_topic}")    ])       research_chain = research_prompt | llm       def research_agent(state: AgentState) -> AgentState:        """Execute research analysis"""        try:            response = research_chain.invoke({                "messages": state["messages"],                "research_topic": state["research_topic"]            })                       findings = {                "research_overview": response.content,                "key_areas": ["area1", "area2", "area3"],                "initial_insights": response.content[:500] + "..."            }                       return {                "messages": state["messages"] + [AIMessage(content=response.content)],                "next": "analyst",                "current_agent": "researcher",                "research_topic": state["research_topic"],                "findings": {**state.get("findings", {}), "research": findings},                "final_report": state.get("final_report", "")            }                   except Exception as e:            error_msg = f"Research agent error: {str(e)}"            return {                "messages": state["messages"] + [AIMessage(content=error_msg)],                "next": "analyst",                "current_agent": "researcher",                "research_topic": state["research_topic"],                "findings": state.get("findings", {}),                "final_report": state.get("final_report", "")            }       return research_agent

We now create our first specialized agent, the Research Specialist AI. This agent is prompted to deeply analyze a given topic, extract key areas of interest, and suggest directions for further exploration. Using a ChatPromptTemplate, we define its behavior and connect it with our Gemini LLM. The research_agent function executes this logic, updates the shared state with findings and messages, and passes control to the next agent in line, the Analyst.

def create_analyst_agent(llm: ChatGoogleGenerativeAI) -> callable:    """Creates a data analyst agent for deep analysis"""       analyst_prompt = ChatPromptTemplate.from_messages([        ("system", """You are a Data Analyst AI. Your role is to:        1. Analyze data and information provided by the research team        2. Identify patterns, trends, and correlations        3. Provide statistical insights and data-driven conclusions        4. Suggest actionable recommendations based on analysis               Focus on quantitative analysis, data interpretation, and evidence-based insights.        Use clear metrics and concrete examples in your analysis.        """),        MessagesPlaceholder(variable_name="messages"),        ("human", "Analyze the research findings for: {research_topic}")    ])       analyst_chain = analyst_prompt | llm       def analyst_agent(state: AgentState) -> AgentState:        """Execute data analysis"""        try:            response = analyst_chain.invoke({                "messages": state["messages"],                "research_topic": state["research_topic"]            })                       analysis_findings = {                "analysis_summary": response.content,                "key_metrics": ["metric1", "metric2", "metric3"],                "recommendations": response.content.split("recommendations:")[-1] if "recommendations:" in response.content.lower() else "No specific recommendations found"            }                       return {                "messages": state["messages"] + [AIMessage(content=response.content)],                "next": "writer",                "current_agent": "analyst",                "research_topic": state["research_topic"],                "findings": {**state.get("findings", {}), "analysis": analysis_findings},                "final_report": state.get("final_report", "")            }                   except Exception as e:            error_msg = f"Analyst agent error: {str(e)}"            return {                "messages": state["messages"] + [AIMessage(content=error_msg)],                "next": "writer",                "current_agent": "analyst",                "research_topic": state["research_topic"],                "findings": state.get("findings", {}),                "final_report": state.get("final_report", "")            }       return analyst_agent

We now define the Data Analyst AI, which dives deeper into the research findings generated by the previous agent. This agent identifies key patterns, trends, and metrics, offering actionable insights backed by evidence. Using a tailored system prompt and the Gemini LLM, the analyst_agent function enriches the state with structured analysis, preparing the groundwork for the report writer to synthesize everything into a final document.

def create_writer_agent(llm: ChatGoogleGenerativeAI) -> callable:    """Creates a report writer agent for final documentation"""       writer_prompt = ChatPromptTemplate.from_messages([        ("system", """You are a Report Writer AI. Your role is to:        1. Synthesize all research and analysis into a comprehensive report        2. Create clear, professional documentation        3. Ensure proper structure with executive summary, findings, and conclusions        4. Make complex information accessible to various audiences               Focus on clarity, completeness, and professional presentation.        Include specific examples and actionable insights.        """),        MessagesPlaceholder(variable_name="messages"),        ("human", "Create a comprehensive report for: {research_topic}")    ])       writer_chain = writer_prompt | llm       def writer_agent(state: AgentState) -> AgentState:        """Execute report writing"""        try:            response = writer_chain.invoke({                "messages": state["messages"],                "research_topic": state["research_topic"]            })                       return {                "messages": state["messages"] + [AIMessage(content=response.content)],                "next": "supervisor",                "current_agent": "writer",                "research_topic": state["research_topic"],                "findings": state.get("findings", {}),                "final_report": response.content            }                   except Exception as e:            error_msg = f"Writer agent error: {str(e)}"            return {                "messages": state["messages"] + [AIMessage(content=error_msg)],                "next": "supervisor",                "current_agent": "writer",                "research_topic": state["research_topic"],                "findings": state.get("findings", {}),                "final_report": f"Error generating report: {str(e)}"            }       return writer_agent

We now create the Report Writer AI, which is responsible for transforming the collected research and analysis into a polished, structured document. This agent synthesizes all previous insights into a clear, professional report with an executive summary, detailed findings, and conclusions. By invoking the Gemini model with a structured prompt, the writer agent updates the final report in the shared state and hands control over to the Supervisor agent for review.

def create_supervisor_agent(llm: ChatGoogleGenerativeAI, members: List[str]) -> callable:    """Creates a supervisor agent to coordinate the team"""       options = ["FINISH"] + members       supervisor_prompt = ChatPromptTemplate.from_messages([        ("system", f"""You are a Supervisor AI managing a research team. Your team members are:        {', '.join(members)}               Your responsibilities:        1. Coordinate the workflow between team members        2. Ensure each agent completes their specialized tasks        3. Determine when the research is complete        4. Maintain quality standards throughout the process               Given the conversation, determine the next step:        - If research is needed: route to "researcher"        - If analysis is needed: route to "analyst"          - If report writing is needed: route to "writer"        - If work is complete: route to "FINISH"               Available options: {options}               Respond with just the name of the next agent or "FINISH".        """),        MessagesPlaceholder(variable_name="messages"),        ("human", "Current status: {current_agent} just completed their task for topic: {research_topic}")    ])       supervisor_chain = supervisor_prompt | llm       def supervisor_agent(state: AgentState) -> AgentState:        """Execute supervisor coordination"""        try:            response = supervisor_chain.invoke({                "messages": state["messages"],                "current_agent": state.get("current_agent", "none"),                "research_topic": state["research_topic"]            })                       next_agent = response.content.strip().lower()                       if "finish" in next_agent or "complete" in next_agent:                next_step = "FINISH"            elif "research" in next_agent:                next_step = "researcher"            elif "analy" in next_agent:                next_step = "analyst"            elif "writ" in next_agent:                next_step = "writer"            else:                current = state.get("current_agent", "")                if current == "researcher":                    next_step = "analyst"                elif current == "analyst":                    next_step = "writer"                elif current == "writer":                    next_step = "FINISH"                else:                    next_step = "researcher"                       return {                "messages": state["messages"] + [AIMessage(content=f"Supervisor decision: Next agent is {next_step}")],                "next": next_step,                "current_agent": "supervisor",                "research_topic": state["research_topic"],                "findings": state.get("findings", {}),                "final_report": state.get("final_report", "")            }                   except Exception as e:            error_msg = f"Supervisor error: {str(e)}"            return {                "messages": state["messages"] + [AIMessage(content=error_msg)],                "next": "FINISH",                "current_agent": "supervisor",                "research_topic": state["research_topic"],                "findings": state.get("findings", {}),                "final_report": state.get("final_report", "")            }       return supervisor_agent

We now bring in the Supervisor AI, which oversees and orchestrates the entire multi-agent workflow. This agent evaluates the current progress, knowing which team member just finished their task, and intelligently decides the next step: whether to continue with research, proceed to analysis, initiate report writing, or mark the project as complete. By parsing the conversation context and utilizing Gemini for reasoning, the supervisor agent ensures smooth transitions and quality control throughout the research pipeline.

def create_research_team_graph() -> StateGraph:    """Creates the complete research team workflow graph"""       llm = create_llm()       members = ["researcher", "analyst", "writer"]    researcher = create_research_agent(llm)    analyst = create_analyst_agent(llm)    writer = create_writer_agent(llm)    supervisor = create_supervisor_agent(llm, members)       workflow = StateGraph(AgentState)       workflow.add_node("researcher", researcher)    workflow.add_node("analyst", analyst)    workflow.add_node("writer", writer)    workflow.add_node("supervisor", supervisor)       workflow.add_edge("researcher", "supervisor")    workflow.add_edge("analyst", "supervisor")    workflow.add_edge("writer", "supervisor")       workflow.add_conditional_edges(        "supervisor",        lambda x: x["next"],        {            "researcher": "researcher",            "analyst": "analyst",            "writer": "writer",            "FINISH": END        }    )       workflow.set_entry_point("supervisor")       return workflowdef compile_research_team():    """Compile the research team graph with memory"""    workflow = create_research_team_graph()       memory = MemorySaver()       app = workflow.compile(checkpointer=memory)       return appdef run_research_team(topic: str, thread_id: str = "research_session_1"):    """Run the complete research team workflow"""       app = compile_research_team()       initial_state = {        "messages": [HumanMessage(content=f"Research the topic: {topic}")],        "research_topic": topic,        "next": "researcher",        "current_agent": "start",        "findings": {},        "final_report": ""    }       config = {"configurable": {"thread_id": thread_id}}       print(f" Starting research on: {topic}")    print("=" * 50)       try:        final_state = None        for step, state in enumerate(app.stream(initial_state, config=config)):            print(f"\n Step {step + 1}: {list(state.keys())[0]}")                       current_state = list(state.values())[0]            if current_state["messages"]:                last_message = current_state["messages"][-1]                if isinstance(last_message, AIMessage):                    print(f" {last_message.content[:200]}...")                       final_state = current_state                       if step > 10:                print("  Maximum steps reached. Stopping execution.")                break               return final_state           except Exception as e:        print(f" Error during execution: {str(e)}")        return None

Check out the full Codes

We now assemble and execute the entire multi-agent workflow using LangGraph. First, we define the research team graph, which consists of nodes for each agent, Researcher, Analyst, Writer, and Supervisor, connected by logical transitions. Then, we compile this graph with memory using MemorySaver to persist conversation history. Finally, the run_research_team() function initializes the process with a topic and streams execution step by step, allowing us to track each agent’s contribution in real-time. This orchestration ensures a fully automated, collaborative research pipeline.

if __name__ == "__main__":    result = run_research_team("Artificial Intelligence in Healthcare")       if result:        print("\n" + "=" * 50)        print(" FINAL RESULTS")        print("=" * 50)        print(f" Final Agent: {result['current_agent']}")        print(f" Findings: {len(result['findings'])} sections")        print(f" Report Length: {len(result['final_report'])} characters")               if result['final_report']:            print("\n FINAL REPORT:")            print("-" * 30)            print(result['final_report'])def interactive_research_session():    """Run an interactive research session"""       app = compile_research_team()       print(" Interactive Research Team Session")    print("Enter 'quit' to exit\n")       session_count = 0       while True:        topic = input(" Enter research topic: ").strip()               if topic.lower() in ['quit', 'exit', 'q']:            print(" Goodbye!")            break               if not topic:            print(" Please enter a valid topic.")            continue               session_count += 1        thread_id = f"interactive_session_{session_count}"               result = run_research_team(topic, thread_id)               if result and result['final_report']:            print(f"\n Research completed for: {topic}")            print(f" Report preview: {result['final_report'][:300]}...")                       show_full = input("\n Show full report? (y/n): ").lower()            if show_full.startswith('y'):                print("\n" + "=" * 60)                print(" COMPLETE RESEARCH REPORT")                print("=" * 60)                print(result['final_report'])               print("\n" + "-" * 50)def create_custom_agent(role: str, instructions: str, llm: ChatGoogleGenerativeAI) -> callable:    """Create a custom agent with specific role and instructions"""       custom_prompt = ChatPromptTemplate.from_messages([        ("system", f"""You are a {role} AI.               Your specific instructions:        {instructions}               Always provide detailed, professional responses relevant to your role.        """),        MessagesPlaceholder(variable_name="messages"),        ("human", "Task: {task}")    ])       custom_chain = custom_prompt | llm       def custom_agent(state: AgentState) -> AgentState:        """Execute custom agent task"""        try:            response = custom_chain.invoke({                "messages": state["messages"],                "task": state["research_topic"]            })                       return {                "messages": state["messages"] + [AIMessage(content=response.content)],                "next": "supervisor",                "current_agent": role.lower().replace(" ", "_"),                "research_topic": state["research_topic"],                "findings": state.get("findings", {}),                "final_report": state.get("final_report", "")            }                   except Exception as e:            error_msg = f"{role} agent error: {str(e)}"            return {                "messages": state["messages"] + [AIMessage(content=error_msg)],                "next": "supervisor",                "current_agent": role.lower().replace(" ", "_"),                "research_topic": state["research_topic"],                "findings": state.get("findings", {}),                "final_report": state.get("final_report", "")            }       return custom_agent

Check out the full Codes

We wrap up our system with runtime and customization capabilities. The main block allows us to trigger a research run directly, making it perfect for testing the pipeline with a real-world topic, such as Artificial Intelligence in Healthcare. For more dynamic use, the interactive_research_session() enables multiple topic queries in a loop, simulating real-time exploration. Lastly, the create_custom_agent() function allows us to integrate new agents with unique roles and instructions, making the framework flexible and extensible for specialized workflows.

def visualize_graph():    """Visualize the research team graph structure"""       try:        app = compile_research_team()               graph_repr = app.get_graph()               print("  Research Team Graph Structure")        print("=" * 40)        print(f"Nodes: {list(graph_repr.nodes.keys())}")        print(f"Edges: {[(edge.source, edge.target) for edge in graph_repr.edges]}")               try:            graph_repr.draw_mermaid()        except:            print(" Visual graph requires mermaid-py package")            print("Install with: !pip install mermaid-py")               except Exception as e:        print(f" Error visualizing graph: {str(e)}")import timefrom datetime import datetimedef monitor_research_performance(topic: str):    """Monitor and report performance metrics"""       start_time = time.time()    print(f"  Starting performance monitoring for: {topic}")       result = run_research_team(topic, f"perf_test_{int(time.time())}")       end_time = time.time()    duration = end_time - start_time       metrics = {        "duration": duration,        "total_messages": len(result["messages"]) if result else 0,        "findings_sections": len(result["findings"]) if result else 0,        "report_length": len(result["final_report"]) if result and result["final_report"] else 0,        "success": result is not None    }       print("\n PERFORMANCE METRICS")    print("=" * 30)    print(f"  Duration: {duration:.2f} seconds")    print(f" Total Messages: {metrics['total_messages']}")    print(f" Findings Sections: {metrics['findings_sections']}")    print(f" Report Length: {metrics['report_length']} chars")    print(f" Success: {metrics['success']}")       return metricsdef quick_start_demo():    """Complete demo of the research team system"""       print(" LangGraph Research Team - Quick Start Demo")    print("=" * 50)       topics = [        "Climate Change Impact on Agriculture",        "Quantum Computing Applications",        "Digital Privacy in the Modern Age"    ]       for i, topic in enumerate(topics, 1):        print(f"\n Demo {i}: {topic}")        print("-" * 40)               try:            result = run_research_team(topic, f"demo_{i}")                       if result and result['final_report']:                print(f" Research completed successfully!")                print(f" Report preview: {result['final_report'][:150]}...")            else:                print(" Research failed")                       except Exception as e:            print(f" Error in demo {i}: {str(e)}")               print("\n" + "="*30)       print(" Demo completed!")quick_start_demo()

We finalize the system by adding powerful utilities for graph visualization, performance monitoring, and a quick start demo. The visualize_graph() function provides a structural overview of agent connections, ideal for debugging or presentation purposes. The monitor_research_performance() tracks runtime, message volume, and report size, helping us evaluate the system’s efficiency. Finally, quick_start_demo() runs multiple sample research topics in sequence, showing how seamlessly the agents collaborate to generate insightful reports.

In conclusion, we’ve successfully built and tested a fully functional, modular AI research assistant framework using LangGraph. With clear agent roles and automated task routing, we streamline research from raw topic input to a well-structured final report. Whether we use the quick start demo, run interactive sessions, or monitor performance, this system empowers us to handle complex research tasks with minimal intervention. We’re now equipped to adapt or extend this setup further by integrating custom agents, visualizing workflows, or even deploying it into real-world applications.


Check out the full Codes | Sponsorship Opportunity: Want to reach the most influential AI developers across the US and Europe? Join our ecosystem of 1M+ monthly readers and 500K+ engaged community members. [Explore Sponsorship]

The post Building a Multi-Agent AI Research Team with LangGraph and Gemini for Automated Reporting appeared first on MarkTechPost.

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

LangGraph Gemini API 多智能体系统 AI研究 自动化报告
相关文章